c66d237f0e21a4b4984d198542f62f76430b6e9c
[platform/upstream/tbb.git] / src / test / test_concurrent_set.cpp
1 /*
2     Copyright (c) 2019 Intel Corporation
3
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
7
8         http://www.apache.org/licenses/LICENSE-2.0
9
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.
15 */
16
17 #define __TBB_EXTRA_DEBUG 1
18 #if _MSC_VER
19 #define _SCL_SECURE_NO_WARNINGS
20 #endif
21
22 #include "tbb/tbb_config.h"
23 #include "harness.h"
24 #if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT
25
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 );
34 template<typename T>
35 bool operator==(tbb::concurrent_set<T> const& lhs, tbb::concurrent_set<T> const& rhs) {
36     return equal_containers( lhs, rhs );
37 }
38
39 template<typename T>
40 bool operator==(tbb::concurrent_multiset<T> const& lhs, tbb::concurrent_multiset<T> const& rhs) {
41     return equal_containers( lhs, rhs );
42 }
43 #endif /* __TBB_INITIALIZER_LISTS_PRESENT */
44 #include "test_concurrent_ordered_common.h"
45
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;
53
54 struct co_set_type : ordered_move_traits_base {
55     template<typename element_type, typename allocator_type>
56     struct apply {
57         typedef tbb::concurrent_set<element_type, std::less<element_type>, allocator_type > type;
58     };
59
60     typedef FooIterator init_iterator_type;
61 };
62
63 struct co_multiset_type : ordered_move_traits_base {
64     template<typename element_type, typename allocator_type>
65     struct apply {
66         typedef tbb::concurrent_multiset<element_type, std::less<element_type>, allocator_type > type;
67     };
68
69     typedef FooIterator init_iterator_type;
70 };
71
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 );
79     }
80 };
81
82 void TestTypes() {
83     TestSetCommonTypes<OrderedSetTypesTester>();
84
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*/
92 }
93
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");
100
101     std::greater<int> compare;
102     std::allocator<int> allocator;
103
104     TSet set2(vc.begin(), vc.end(), compare);
105     static_assert(std::is_same_v<decltype(set2), TSet<int, decltype(compare)>>, "Wrong");
106
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");
109
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");
112
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");
116
117     TSet set6(init_list, compare);
118     static_assert(std::is_same_v<decltype(set6), TSet<int, decltype(compare)>>, "Wrong");
119
120     TSet set7(init_list, allocator);
121     static_assert(std::is_same_v<decltype(set7), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong");
122
123     TSet set8(init_list, compare, allocator);
124     static_assert(std::is_same_v<decltype(set8), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong");
125 }
126 #endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/
127
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);
133 }
134
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);
138     }
139 };
140
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);
144     }
145 };
146
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 > >();
150 }
151
152 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
153 #include <scoped_allocator>
154
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>;
160
161     allocator_type allocator;
162     allocator_data_type v1(1, allocator), v2(2, allocator);
163     set_type set1(allocator), set2(allocator);
164
165     auto init_list = { v1, v2 };
166
167     allocator_data_type::assert_on_constructions = true;
168     set1.emplace(v1);
169     set2.emplace(std::move(v1));
170
171     set1.clear();
172     set2.clear();
173
174     set1.insert(v1);
175     set2.insert(std::move(v1));
176
177     set1.clear();
178     set2.clear();
179
180     set1.insert(init_list);
181
182     set1.clear();
183     set2.clear();
184
185     set1 = set2;
186     set2 = std::move(set1);
187
188     set1.swap(set2);
189
190     allocator_data_type::assert_on_constructions = false;
191 }
192
193 #endif // !__TBB_SCOPED_ALLOCATOR_BROKEN
194
195 int TestMain() {
196     test_machine();
197
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" );
206
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)");
211
212     { Check<MyCheckedMultiSet::value_type> checkit; test_basic<MyCheckedMultiSet>( "concurrent MultiSet (checked)" ); }
213     { Check<MyCheckedMultiSet::value_type> checkit; test_concurrent<MyCheckedMultiSet>( "concurrent MultiSet (checked)" ); }
214
215     multicontainer_specific_test();
216
217     TestInitList< tbb::concurrent_set<int>,
218                   tbb::concurrent_multiset<int> >( {1,2,3,4,5} );
219
220 #if __TBB_RANGE_BASED_FOR_PRESENT
221     TestRangeBasedFor<MySet>();
222     TestRangeBasedFor<MyMultiSet>();
223 #endif
224
225     test_rvalue_ref_support<co_set_type>( "concurrent map" );
226     test_rvalue_ref_support<co_multiset_type>( "concurrent multimap" );
227
228     TestTypes();
229
230 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
231     TestDeductionGuides<tbb::concurrent_set>();
232     TestDeductionGuides<tbb::concurrent_multiset>();
233 #endif
234
235     node_handling::TestNodeHandling<MySet>();
236     node_handling::TestNodeHandling<MyMultiSet>();
237     node_handling::TestMerge<MySet, MyMultiSet>(1000);
238
239     test_heterogenious_lookup();
240
241     test_allocator_traits<tbb::concurrent_set, int, std::less<int>>();
242     test_allocator_traits<tbb::concurrent_multiset, int, std::less<int>>();
243
244 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
245     test_scoped_allocator<tbb::concurrent_set>();
246     test_scoped_allocator<tbb::concurrent_multiset>();
247 #endif
248
249     return Harness::Done;
250 }
251 #else
252 int TestMain() {
253     return Harness::Skipped;
254 }
255 #endif