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_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 );
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 );
42 #endif /* __TBB_INITIALIZER_LISTS_PRESENT */
43 #include "test_concurrent_ordered_common.h"
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;
54 struct SpecialTests <MyMap> {
55 static void Test( const char *str ) {
56 SpecialMapTests<MyMap>(str);
61 struct SpecialTests <MyMultiMap> {
62 static void Test( const char *str ) {
63 SpecialMultiMapTests<MyMultiMap>(str);
67 struct co_map_type : ordered_move_traits_base {
68 template<typename element_type, typename allocator_type>
70 typedef tbb::concurrent_map<element_type, element_type, std::less<element_type>, allocator_type > type;
73 typedef FooPairIterator init_iterator_type;
76 struct co_multimap_type : ordered_move_traits_base {
77 template<typename element_type, typename allocator_type>
79 typedef tbb::concurrent_multimap<element_type, element_type, std::less<element_type>, allocator_type > type;
82 typedef FooPairIterator init_iterator_type;
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);
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 );
104 TestMapCommonTypes<OrderedMapTypesTester>();
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*/
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");
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");
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");
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");
134 using pair_t = std::pair<const int, int>;
135 auto init = { pair_t{1, 1}, pair_t{2, 2}, pair_t{3, 3} };
137 static_assert(std::is_same_v<decltype(map5), TMap<int, int> >, "WRONG\n");
139 TMap map6(init, compare);
140 static_assert(std::is_same_v<decltype(map6), TMap<int, int, decltype(compare)> >, "WRONG\n");
142 TMap map7(init, allocator);
143 static_assert(std::is_same_v<decltype(map7), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n");
145 TMap map8(init, compare, allocator);
146 static_assert(std::is_same_v<decltype(map8), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n");
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> >();
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> > >();
160 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
161 #include <scoped_allocator>
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>;
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);
174 typename map_type::value_type v1(key1, data1), v2(key2, data2);
176 auto init_list = { v1, v2 };
178 allocator_data_type::assert_on_constructions = true;
179 map1.emplace(key1, data1);
180 map2.emplace(key2, std::move(data2));
186 map2.insert(std::move(v2));
191 map1.insert(init_list);
197 map2 = std::move(map1);
201 allocator_data_type::assert_on_constructions = false;
203 #endif // !__TBB_SCOPED_ALLOCATOR_BROKEN
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" );
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)");
222 { Check<MyCheckedMultiMap::value_type> checkit; test_basic<MyCheckedMultiMap>( "concurrent MultiMap (checked)" ); }
223 { Check<MyCheckedMultiMap::value_type> checkit; test_concurrent<MyCheckedMultiMap>( "concurrent MultiMap (checked)" ); }
225 multicontainer_specific_test();
227 TestInitList< tbb::concurrent_map<int, int>,
228 tbb::concurrent_multimap<int, int> >( {{1,1},{2,2},{3,3},{4,4},{5,5}} );
230 #if __TBB_RANGE_BASED_FOR_PRESENT
231 TestRangeBasedFor<MyMap>();
232 TestRangeBasedFor<MyMultiMap>();
235 test_rvalue_ref_support<co_map_type>( "concurrent map" );
236 test_rvalue_ref_support<co_multimap_type>( "concurrent multimap" );
240 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
241 TestDeductionGuides<tbb::concurrent_map>();
242 TestDeductionGuides<tbb::concurrent_multimap>();
243 #endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/
245 node_handling::TestNodeHandling<MyMap>();
246 node_handling::TestNodeHandling<MyMultiMap>();
247 node_handling::TestMerge<MyMap, MyMultiMap>(1000);
249 test_heterogeneous_functions();
251 test_allocator_traits<tbb::concurrent_map, int, int, std::less<int>>();
252 test_allocator_traits<tbb::concurrent_multimap, int, int, std::less<int>>();
254 #if !__TBB_SCOPED_ALLOCATOR_BROKEN
255 test_scoped_allocator<tbb::concurrent_map>();
256 test_scoped_allocator<tbb::concurrent_multimap>();
259 return Harness::Done;
263 return Harness::Skipped;