2 Copyright (c) 2019 Intel Corporation
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
17 #define __TBB_EXTRA_DEBUG 1
19 #define _SCL_SECURE_NO_WARNINGS
22 #include "tbb/tbb_config.h"
24 #if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT
26 #define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1
27 #include "tbb/concurrent_set.h"
28 #if __TBB_INITIALIZER_LISTS_PRESENT
29 // These operator== are used implicitly in test_initializer_list.h.
30 // For some unknown reason clang is not able to find the if they a declared after the
31 // inclusion of test_initializer_list.h.
32 template<typename container_type>
33 bool equal_containers( container_type const& lhs, container_type const& rhs );
35 bool operator==(tbb::concurrent_set<T> const& lhs, tbb::concurrent_set<T> const& rhs) {
36 return equal_containers( lhs, rhs );
40 bool operator==(tbb::concurrent_multiset<T> const& lhs, tbb::concurrent_multiset<T> const& rhs) {
41 return equal_containers( lhs, rhs );
43 #endif /* __TBB_INITIALIZER_LISTS_PRESENT */
44 #include "test_concurrent_ordered_common.h"
46 typedef tbb::concurrent_set<int, std::less<int>, MyAllocator> MySet;
47 typedef tbb::concurrent_set<int, std::greater<int>, MyAllocator> MyGreaterSet;
48 typedef tbb::concurrent_set<check_type<int>, std::less<int>, MyAllocator> MyCheckedSet;
49 typedef tbb::concurrent_set<FooWithAssign, std::less<Foo>, MyAllocator> MyCheckedStateSet;
50 typedef tbb::concurrent_multiset<int, std::less<int>, MyAllocator> MyMultiSet;
51 typedef tbb::concurrent_multiset<int, std::greater<int>, MyAllocator> MyGreaterMultiSet;
52 typedef tbb::concurrent_multiset<check_type<int>, std::less<int>, MyAllocator> MyCheckedMultiSet;
54 struct co_set_type : ordered_move_traits_base {
55 template<typename element_type, typename allocator_type>
57 typedef tbb::concurrent_set<element_type, std::less<element_type>, allocator_type > type;
60 typedef FooIterator init_iterator_type;
63 struct co_multiset_type : ordered_move_traits_base {
64 template<typename element_type, typename allocator_type>
66 typedef tbb::concurrent_multiset<element_type, std::less<element_type>, allocator_type > type;
69 typedef FooIterator init_iterator_type;
72 struct OrderedSetTypesTester{
73 template <bool defCtorPresent, typename ValueType>
74 void check( const std::list<ValueType> &lst ) {
75 TypeTester< defCtorPresent, tbb::concurrent_set< ValueType >,
76 tbb::concurrent_set< ValueType , std::less<ValueType>, debug_allocator<ValueType> > >( lst );
77 TypeTester< defCtorPresent, tbb::concurrent_multiset< ValueType >,
78 tbb::concurrent_multiset< ValueType , std::less<ValueType>, debug_allocator<ValueType> > >( lst );
83 TestSetCommonTypes<OrderedSetTypesTester>();
85 #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT
86 // Regression test for a problem with excessive requirements of emplace()
87 test_emplace_insert<tbb::concurrent_set< test::unique_ptr<int> >,
88 tbb::internal::false_type>( new int, new int );
89 test_emplace_insert<tbb::concurrent_multiset< test::unique_ptr<int> >,
90 tbb::internal::false_type>( new int, new int );
91 #endif /*__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT*/
94 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
95 template <template <typename ...> typename TSet>
96 void TestDeductionGuides() {
97 std::vector<int> vc({1, 2, 3});
98 TSet set(vc.begin(), vc.end());
99 static_assert(std::is_same_v<decltype(set), TSet<int>>, "Wrong");
101 std::greater<int> compare;
102 std::allocator<int> allocator;
104 TSet set2(vc.begin(), vc.end(), compare);
105 static_assert(std::is_same_v<decltype(set2), TSet<int, decltype(compare)>>, "Wrong");
107 TSet set3(vc.begin(), vc.end(), allocator);
108 static_assert(std::is_same_v<decltype(set3), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong");
110 TSet set4(vc.begin(), vc.end(), compare, allocator);
111 static_assert(std::is_same_v<decltype(set4), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong");
113 auto init_list = { int(1), int(2), int(3) };
114 TSet set5(init_list);
115 static_assert(std::is_same_v<decltype(set5), TSet<int>>, "Wrong");
117 TSet set6(init_list, compare);
118 static_assert(std::is_same_v<decltype(set6), TSet<int, decltype(compare)>>, "Wrong");
120 TSet set7(init_list, allocator);
121 static_assert(std::is_same_v<decltype(set7), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong");
123 TSet set8(init_list, compare, allocator);
124 static_assert(std::is_same_v<decltype(set8), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong");
126 #endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/
128 void test_heterogenious_lookup() {
129 tbb::concurrent_set<int, transparent_compare> set = {1, 2, 3};
130 tbb::concurrent_multiset<int, transparent_compare> mset = {1, 1, 2, 3};
131 check_heterogenious_lookup(set);
132 check_heterogenious_lookup(mset);
135 struct compare_keys_less {
136 bool operator() (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const {
137 return std::less<int>()(lhs.first, rhs.first);
141 struct compare_keys_greater {
142 bool operator() (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const {
143 return std::greater<int>()(lhs.first, rhs.first);
147 void multicontainer_specific_test() {
148 check_multicontainer_internal_order<tbb::concurrent_multiset<std::pair<int, int>, compare_keys_less > >();
149 check_multicontainer_internal_order<tbb::concurrent_multiset<std::pair<int, int>, compare_keys_greater > >();
152 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
153 #include <scoped_allocator>
155 template <template<typename...> class Set>
156 void test_scoped_allocator() {
157 using allocator_data_type = allocator_aware_data<std::scoped_allocator_adaptor<tbb::tbb_allocator<int>>>;
158 using allocator_type = std::scoped_allocator_adaptor<tbb::tbb_allocator<allocator_data_type>>;
159 using set_type = Set<allocator_data_type, allocator_data_compare, allocator_type>;
161 allocator_type allocator;
162 allocator_data_type v1(1, allocator), v2(2, allocator);
163 set_type set1(allocator), set2(allocator);
165 auto init_list = { v1, v2 };
167 allocator_data_type::assert_on_constructions = true;
169 set2.emplace(std::move(v1));
175 set2.insert(std::move(v1));
180 set1.insert(init_list);
186 set2 = std::move(set1);
190 allocator_data_type::assert_on_constructions = false;
193 #endif // !__TBB_SCOPED_ALLOCATOR_BROKEN
198 test_basic<MySet>( "concurrent Set" );
199 test_basic<MyGreaterSet>( "concurrent greater Set" );
200 test_concurrent<MySet>( "concurrent Set" );
201 test_concurrent<MyGreaterSet>( "concurrent greater Set" );
202 test_basic<MyMultiSet>( "concurrent MultiSet" );
203 test_basic<MyGreaterMultiSet>( "concurrent greater MultiSet" );
204 test_concurrent<MyMultiSet>( "concurrent MultiSet" );
205 test_concurrent<MyGreaterMultiSet>( "concurrent greater MultiSet" );
207 { Check<MyCheckedSet::value_type> checkit; test_basic<MyCheckedSet>( "concurrent set (checked)" ); }
208 { Check<MyCheckedSet::value_type> checkit; test_concurrent<MyCheckedSet>( "concurrent set (checked)" ); }
209 test_basic<MyCheckedStateSet>("concurrent set (checked state of elements)", tbb::internal::true_type());
210 test_concurrent<MyCheckedStateSet>("concurrent set (checked state of elements)");
212 { Check<MyCheckedMultiSet::value_type> checkit; test_basic<MyCheckedMultiSet>( "concurrent MultiSet (checked)" ); }
213 { Check<MyCheckedMultiSet::value_type> checkit; test_concurrent<MyCheckedMultiSet>( "concurrent MultiSet (checked)" ); }
215 multicontainer_specific_test();
217 TestInitList< tbb::concurrent_set<int>,
218 tbb::concurrent_multiset<int> >( {1,2,3,4,5} );
220 #if __TBB_RANGE_BASED_FOR_PRESENT
221 TestRangeBasedFor<MySet>();
222 TestRangeBasedFor<MyMultiSet>();
225 test_rvalue_ref_support<co_set_type>( "concurrent map" );
226 test_rvalue_ref_support<co_multiset_type>( "concurrent multimap" );
230 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
231 TestDeductionGuides<tbb::concurrent_set>();
232 TestDeductionGuides<tbb::concurrent_multiset>();
235 node_handling::TestNodeHandling<MySet>();
236 node_handling::TestNodeHandling<MyMultiSet>();
237 node_handling::TestMerge<MySet, MyMultiSet>(1000);
239 test_heterogenious_lookup();
241 test_allocator_traits<tbb::concurrent_set, int, std::less<int>>();
242 test_allocator_traits<tbb::concurrent_multiset, int, std::less<int>>();
244 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
245 test_scoped_allocator<tbb::concurrent_set>();
246 test_scoped_allocator<tbb::concurrent_multiset>();
249 return Harness::Done;
253 return Harness::Skipped;