Committing TBB 2019 Update 9 source code
[platform/upstream/tbb.git] / src / test / test_concurrent_map.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_map.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 Key, typename Value>
35 bool operator==( tbb::concurrent_map<Key, Value> const& lhs, tbb::concurrent_map<Key, Value> const& rhs ) {
36     return equal_containers( lhs, rhs );
37 }
38 template<typename Key, typename Value>
39 bool operator==( tbb::concurrent_multimap<Key, Value> const& lhs, tbb::concurrent_multimap<Key, Value> const& rhs ) {
40     return equal_containers( lhs, rhs );
41 }
42 #endif /* __TBB_INITIALIZER_LISTS_PRESENT */
43 #include "test_concurrent_ordered_common.h"
44
45 typedef tbb::concurrent_map<int, int, std::less<int>, MyAllocator> MyMap;
46 typedef tbb::concurrent_map<int, int, std::greater<int>, MyAllocator> MyGreaterMap;
47 typedef tbb::concurrent_map<int, check_type<int>, std::less<int>, MyAllocator> MyCheckedMap;
48 typedef tbb::concurrent_map<intptr_t, FooWithAssign, std::less<intptr_t>, MyAllocator> MyCheckedStateMap;
49 typedef tbb::concurrent_multimap<int, int, std::less<int>, MyAllocator> MyMultiMap;
50 typedef tbb::concurrent_multimap<int, int, std::greater<int>, MyAllocator> MyGreaterMultiMap;
51 typedef tbb::concurrent_multimap<int, check_type<int>, std::less<int>, MyAllocator> MyCheckedMultiMap;
52
53 template <>
54 struct SpecialTests <MyMap> {
55     static void Test( const char *str ) {
56         SpecialMapTests<MyMap>(str);
57     }
58 };
59
60 template <>
61 struct SpecialTests <MyMultiMap> {
62     static void Test( const char *str ) {
63         SpecialMultiMapTests<MyMultiMap>(str);
64     }
65 };
66
67 struct co_map_type : ordered_move_traits_base {
68     template<typename element_type, typename allocator_type>
69     struct apply {
70         typedef tbb::concurrent_map<element_type, element_type, std::less<element_type>, allocator_type > type;
71     };
72
73     typedef FooPairIterator init_iterator_type;
74 };
75
76 struct co_multimap_type : ordered_move_traits_base {
77     template<typename element_type, typename allocator_type>
78     struct apply {
79         typedef tbb::concurrent_multimap<element_type, element_type, std::less<element_type>, allocator_type > type;
80     };
81
82     typedef FooPairIterator init_iterator_type;
83 };
84
85 template <bool defCtorPresent, typename Key, typename Element, typename Compare, typename Allocator>
86 void TestMapSpecificMethods( tbb::concurrent_map<Key, Element, Compare, Allocator> &c,
87     const typename tbb::concurrent_map<Key, Element, Compare, Allocator>::value_type &value ) {
88         TestMapSpecificMethodsImpl<defCtorPresent>(c, value);
89     }
90
91 struct OrderedMapTypesTester{
92     template <bool defCtorPresent, typename ValueType>
93     void check( const std::list<ValueType> &lst ) {
94         typedef typename ValueType::first_type KeyType;
95         typedef typename ValueType::second_type ElemType;
96         TypeTester< defCtorPresent, tbb::concurrent_map< KeyType, ElemType>,
97                                     tbb::concurrent_map< KeyType, ElemType, std::less<KeyType>, debug_allocator<ValueType> > >( lst );
98         TypeTester< defCtorPresent, tbb::concurrent_multimap< KeyType, ElemType>,
99                                     tbb::concurrent_multimap< KeyType, ElemType, std::less<KeyType>, debug_allocator<ValueType> > >( lst );
100     }
101 };
102
103 void TestTypes() {
104     TestMapCommonTypes<OrderedMapTypesTester>();
105
106     #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT
107     // Regression test for a problem with excessive requirements of emplace()
108     test_emplace_insert<tbb::concurrent_map< int*, test::unique_ptr<int> >,
109                         tbb::internal::false_type>( new int, new int );
110     test_emplace_insert<tbb::concurrent_multimap< int*, test::unique_ptr<int> >,
111                         tbb::internal::false_type>( new int, new int );
112     #endif /*__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT*/
113 }
114
115 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
116 template <template <typename...> typename TMap>
117 void TestDeductionGuides() {
118     std::vector<std::pair<int, int>> v(10, {0, 0});
119     TMap map(v.begin(), v.end());
120     static_assert(std::is_same_v<decltype(map), TMap<int, int> >, "WRONG\n");
121     //print(map);
122
123     std::greater<int> compare;
124     std::allocator<int> allocator;
125     TMap map2(v.begin(), v.end(), compare);
126     static_assert(std::is_same_v<decltype(map2), TMap<int, int, decltype(compare)> >, "WRONG\n");
127
128     TMap map3(v.begin(), v.end(), allocator);
129     static_assert(std::is_same_v<decltype(map3), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n");
130
131     TMap map4(v.begin(), v.end(), compare, allocator);
132     static_assert(std::is_same_v<decltype(map4), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n");
133
134     using pair_t = std::pair<const int, int>;
135     auto init = { pair_t{1, 1}, pair_t{2, 2}, pair_t{3, 3} };
136     TMap map5(init);
137     static_assert(std::is_same_v<decltype(map5), TMap<int, int> >, "WRONG\n");
138
139     TMap map6(init, compare);
140     static_assert(std::is_same_v<decltype(map6), TMap<int, int, decltype(compare)> >, "WRONG\n");
141
142     TMap map7(init, allocator);
143     static_assert(std::is_same_v<decltype(map7), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n");
144
145     TMap map8(init, compare, allocator);
146     static_assert(std::is_same_v<decltype(map8), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n");
147 }
148 #endif
149
150 void test_heterogeneous_functions() {
151     check_heterogeneous_functions<tbb::concurrent_map<int, int, transparent_less> >();
152     check_heterogeneous_functions<tbb::concurrent_multimap<int, int, transparent_less> >();
153 }
154
155 void multicontainer_specific_test() {
156     check_multicontainer_internal_order<tbb::concurrent_multimap<int, int> >();
157     check_multicontainer_internal_order<tbb::concurrent_multimap<int, int, std::greater<int> > >();
158 }
159
160 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
161 #include <scoped_allocator>
162
163 template <template<typename...> class Map>
164 void test_scoped_allocator() {
165     using allocator_data_type = allocator_aware_data<std::scoped_allocator_adaptor<tbb::tbb_allocator<int>>>;
166     using allocator_type = std::scoped_allocator_adaptor<tbb::tbb_allocator<allocator_data_type>>;
167     using map_type = Map<allocator_data_type, allocator_data_type, allocator_data_compare, allocator_type>;
168
169     allocator_type allocator;
170     allocator_data_type key1(1, allocator), key2(2, allocator);
171     allocator_data_type data1(1, allocator), data2(2, allocator);
172     map_type map1(allocator), map2(allocator);
173
174     typename map_type::value_type v1(key1, data1), v2(key2, data2);
175
176     auto init_list = { v1, v2 };
177
178     allocator_data_type::assert_on_constructions = true;
179     map1.emplace(key1, data1);
180     map2.emplace(key2, std::move(data2));
181
182     map1.clear();
183     map2.clear();
184
185     map1.insert(v1);
186     map2.insert(std::move(v2));
187
188     map1.clear();
189     map2.clear();
190
191     map1.insert(init_list);
192
193     map1.clear();
194     map2.clear();
195
196     map1 = map2;
197     map2 = std::move(map1);
198
199     map1.swap(map2);
200
201     allocator_data_type::assert_on_constructions = false;
202 }
203 #endif // !__TBB_SCOPED_ALLOCATOR_BROKEN
204
205 int TestMain() {
206     test_machine();
207
208     test_basic<MyMap>( "concurrent Map" );
209     test_basic<MyGreaterMap>( "concurrent greater Map" );
210     test_concurrent<MyMap>( "concurrent Map" );
211     test_concurrent<MyGreaterMap>( "concurrent greater Map" );
212     test_basic<MyMultiMap>( "concurrent MultiMap" );
213     test_basic<MyGreaterMultiMap>( "concurrent greater MultiMap" );
214     test_concurrent<MyMultiMap>( "concurrent MultiMap" );
215     test_concurrent<MyGreaterMultiMap>( "concurrent greater MultiMap" );
216
217     { Check<MyCheckedMap::value_type> checkit; test_basic<MyCheckedMap>( "concurrent map (checked)" ); }
218     { Check<MyCheckedMap::value_type> checkit; test_concurrent<MyCheckedMap>( "concurrent map (checked)" ); }
219     test_basic<MyCheckedStateMap>("concurrent map (checked state of elements)", tbb::internal::true_type());
220     test_concurrent<MyCheckedStateMap>("concurrent map (checked state of elements)");
221
222     { Check<MyCheckedMultiMap::value_type> checkit; test_basic<MyCheckedMultiMap>( "concurrent MultiMap (checked)" ); }
223     { Check<MyCheckedMultiMap::value_type> checkit; test_concurrent<MyCheckedMultiMap>( "concurrent MultiMap (checked)" ); }
224
225     multicontainer_specific_test();
226
227     TestInitList< tbb::concurrent_map<int, int>,
228                   tbb::concurrent_multimap<int, int> >( {{1,1},{2,2},{3,3},{4,4},{5,5}} );
229
230 #if __TBB_RANGE_BASED_FOR_PRESENT
231     TestRangeBasedFor<MyMap>();
232     TestRangeBasedFor<MyMultiMap>();
233 #endif
234
235     test_rvalue_ref_support<co_map_type>( "concurrent map" );
236     test_rvalue_ref_support<co_multimap_type>( "concurrent multimap" );
237
238     TestTypes();
239
240 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
241     TestDeductionGuides<tbb::concurrent_map>();
242     TestDeductionGuides<tbb::concurrent_multimap>();
243 #endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/
244
245     node_handling::TestNodeHandling<MyMap>();
246     node_handling::TestNodeHandling<MyMultiMap>();
247     node_handling::TestMerge<MyMap, MyMultiMap>(1000);
248
249     test_heterogeneous_functions();
250
251     test_allocator_traits<tbb::concurrent_map, int, int, std::less<int>>();
252     test_allocator_traits<tbb::concurrent_multimap, int, int, std::less<int>>();
253
254 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
255     test_scoped_allocator<tbb::concurrent_map>();
256     test_scoped_allocator<tbb::concurrent_multimap>();
257 #endif
258
259     return Harness::Done;
260 }
261 #else
262 int TestMain() {
263     return Harness::Skipped;
264 }
265 #endif