1 /*
2 Copyright (c) 2019-2021 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 #if __INTEL_COMPILER && _MSC_VER
18 #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
19 #endif
20
21 #ifndef NOMINMAX
22 #define NOMINMAX
23 #endif
24 #include "oneapi/tbb/concurrent_map.h"
25 #include <common/test.h>
26 #include <common/utils.h>
27 #include <common/concurrent_ordered_common.h>
28 #include <memory>
29 #include <type_traits>
30
31 //! \file conformance_concurrent_map.cpp
32 //! \brief Test for [containers.concurrent_map containers.concurrent_multimap] specifications
33
34 template <typename... Args>
35 struct AllowMultimapping<oneapi::tbb::concurrent_multimap<Args...>> : std::true_type {};
36
37 template <typename Key, typename Mapped>
38 using Allocator = LocalCountingAllocator<std::allocator<std::pair<const Key, Mapped>>>;
39
40 using map_type = oneapi::tbb::concurrent_map<int, int, std::less<int>, Allocator<int, int>>;
41 using multimap_type = oneapi::tbb::concurrent_multimap<int, int, std::less<int>, Allocator<int, int>>;
42
43 template <>
44 struct SpecialTests<map_type> {
TestSpecialTests45 static void Test() {
46 SpecialMapTests<map_type>();
47 }
48 };
49
50 template <>
51 struct SpecialTests<multimap_type> {
TestSpecialTests52 static void Test() {
53 SpecialMultiMapTests<multimap_type>();
54 }
55 };
56
57 template <template <typename...> class ContainerType>
test_member_types()58 void test_member_types() {
59 using default_container_type = ContainerType<int, int>;
60 static_assert(std::is_same<typename default_container_type::key_compare, std::less<int>>::value,
61 "Incorrect default template comparator");
62 static_assert(std::is_same<typename default_container_type::allocator_type, oneapi::tbb::tbb_allocator<std::pair<const int, int>>>::value,
63 "Incorrect default template allocator");
64
65 auto test_comparator = [](const int&, const int&)->bool { return true; };
66 using test_allocator_type = std::allocator<std::pair<const int, int>>;
67
68 using container_type = ContainerType<int, int, decltype(test_comparator), test_allocator_type>;
69
70 static_assert(std::is_same<typename container_type::key_type, int>::value,
71 "Incorrect container key_type member type");
72 static_assert(std::is_same<typename container_type::mapped_type, int>::value,
73 "Incorrect container mapped_type member type");
74 static_assert(std::is_same<typename container_type::value_type, std::pair<const int, int>>::value,
75 "Incorrect container value_type member type");
76
77 static_assert(std::is_unsigned<typename container_type::size_type>::value,
78 "Incorrect container size_type member type");
79 static_assert(std::is_signed<typename container_type::difference_type>::value,
80 "Incorrect container difference_type member type");
81
82 static_assert(std::is_same<typename container_type::key_compare, decltype(test_comparator)>::value,
83 "Incorrect container key_compare member type");
84 static_assert(std::is_same<typename container_type::allocator_type, test_allocator_type>::value,
85 "Incorrect container allocator_type member type");
86
87 using value_type = typename container_type::value_type;
88 static_assert(std::is_same<typename container_type::reference, value_type&>::value,
89 "Incorrect container reference member type");
90 static_assert(std::is_same<typename container_type::const_reference, const value_type&>::value,
91 "Incorrect container const_reference member type");
92 using allocator_type = typename container_type::allocator_type;
93 static_assert(std::is_same<typename container_type::pointer, typename std::allocator_traits<allocator_type>::pointer>::value,
94 "Incorrect container pointer member type");
95 static_assert(std::is_same<typename container_type::const_pointer, typename std::allocator_traits<allocator_type>::const_pointer>::value,
96 "Incorrect container const_pointer member type");
97
98 static_assert(utils::is_forward_iterator<typename container_type::iterator>::value,
99 "Incorrect container iterator member type");
100 static_assert(!std::is_const<typename container_type::iterator::value_type>::value,
101 "Incorrect container iterator member type");
102 static_assert(utils::is_forward_iterator<typename container_type::const_iterator>::value,
103 "Incorrect container const_iterator member type");
104 static_assert(std::is_const<typename container_type::const_iterator::value_type>::value,
105 "Incorrect container const_iterator member type");
106 }
107
108 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
109 template <template <typename...> typename TMap>
test_deduction_guides()110 void test_deduction_guides() {
111 std::vector<std::pair<int, int>> v(10, {0, 0});
112 TMap map(v.begin(), v.end());
113 static_assert(std::is_same_v<decltype(map), TMap<int, int> >, "WRONG\n");
114
115 std::greater<int> compare;
116 std::allocator<std::pair<const int, int>> allocator;
117 TMap map2(v.begin(), v.end(), compare);
118 static_assert(std::is_same_v<decltype(map2), TMap<int, int, decltype(compare)> >, "WRONG\n");
119
120 TMap map3(v.begin(), v.end(), allocator);
121 static_assert(std::is_same_v<decltype(map3), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n");
122
123 TMap map4(v.begin(), v.end(), compare, allocator);
124 static_assert(std::is_same_v<decltype(map4), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n");
125
126 using pair_t = std::pair<const int, int>;
127 auto init = { pair_t{1, 1}, pair_t{2, 2}, pair_t{3, 3} };
128 TMap map5(init);
129 static_assert(std::is_same_v<decltype(map5), TMap<int, int> >, "WRONG\n");
130
131 TMap map6(init, compare);
132 static_assert(std::is_same_v<decltype(map6), TMap<int, int, decltype(compare)> >, "WRONG\n");
133
134 TMap map7(init, allocator);
135 static_assert(std::is_same_v<decltype(map7), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n");
136
137 TMap map8(init, compare, allocator);
138 static_assert(std::is_same_v<decltype(map8), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n");
139 }
140 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
141
142 template <template <typename...> class MapType>
test_heterogeneous_functions()143 void test_heterogeneous_functions() {
144 check_heterogeneous_functions_key_int<MapType, int, int>();
145 check_heterogeneous_functions_key_string<MapType, std::string, std::string>();
146 check_heterogeneous_bound_functions<MapType<int, int, TransparentLess>>();
147 }
148
149 struct COMapTraits : OrderedMoveTraitsBase {
150 template <typename T, typename Allocator>
151 using container_type = oneapi::tbb::concurrent_map<T, T, std::less<T>, Allocator>;
152
153 template <typename T>
154 using container_value_type = std::pair<const T, T>;
155
156 using init_iterator_type = move_support_tests::FooPairIterator;
157 }; // struct COMapTraits
158
159 struct COMultimapTraits : OrderedMoveTraitsBase {
160 template <typename T, typename Allocator>
161 using container_type = oneapi::tbb::concurrent_multimap<T, T, std::less<T>, Allocator>;
162
163 template <typename T>
164 using container_value_type = std::pair<const T, T>;
165
166 using init_iterator_type = move_support_tests::FooPairIterator;
167 }; // struct COMultimapTraits
168
169 //! Testing concurrent_map member types
170 //! \brief \ref interface \ref requirement
171 TEST_CASE("concurrent_map member types") {
172 test_member_types<oneapi::tbb::concurrent_map>();
173 }
174
175 //! Testing requirements of concurrent_map
176 //! \brief \ref interface \ref requirement
177 TEST_CASE("concurrent_map requirements") {
178 test_basic<map_type>();
179 }
180
181 //! Testing multithreading support in concurrent_map
182 //! \brief \ref requirement
183 TEST_CASE("concurrent_map multithreading support") {
184 test_concurrent<map_type>();
185 }
186
187 //! Testing move constructors and assignment operator in concurrent_map
188 //! \brief \ref interface \ref requirement
189 TEST_CASE("concurrent_map move semantics support") {
190 test_rvalue_ref_support<COMapTraits>();
191 }
192
193 //! Testing std::initializer_list constructors and modifiers in concurrent_map
194 //! \brief \ref interface \ref requirement
195 TEST_CASE("std::initializer_list support in concurrent_map") {
196 test_initializer_list_support<map_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}});
197 }
198
199 //! Testing node handling in concurrent_map
200 //! \brief \ref interface \ref requirement
201 TEST_CASE("node handling support in concurrent_map") {
202 node_handling_tests::test_node_handling_support<map_type>();
203 }
204
205 //! Testing std::allocator_traits support in concurrent_map
206 //! \brief \ref interface \ref requirement
207 TEST_CASE("std::allocator_traits support in concurrent_map") {
208 test_allocator_traits_support<COMapTraits>();
209 }
210
211 //! Testing heterogeneous overloads in concurrent_map
212 //! \brief \ref interface \ref requirement
213 TEST_CASE("heterogeneous overloads in concurrent_map") {
214 test_heterogeneous_functions<oneapi::tbb::concurrent_map>();
215 }
216
217 //! Testing insert overloads with generic pair in concurrent_map
218 //! \brief \ref interface \ref requirement
219 TEST_CASE("insertion by generic pair in concurrent_map") {
220 test_insert_by_generic_pair<oneapi::tbb::concurrent_map>();
221 }
222
223 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
224 //! Testing Class Template Argument Deduction in concurrent_map
225 //! \brief \ref interface \ref requirement
226 TEST_CASE("CTAD support in concurrent_map") {
227 test_deduction_guides<oneapi::tbb::concurrent_map>();
228 }
229 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
230
231 //! Testing comparisons of concurrent_map
232 //! \brief \ref interface \ref requirement
233 TEST_CASE("test concurrent_map comparisons") {
234 test_map_comparisons<oneapi::tbb::concurrent_map>();
235 }
236
237 //! Testing concurrent_multimap member types
238 //! \brief \ref interface \ref requirement
239 TEST_CASE("concurrent_multimap member types") {
240 test_member_types<oneapi::tbb::concurrent_multimap>();
241 }
242
243 //! Testing requirements of concurrent_multimap
244 //! \brief \ref interface \ref requirement
245 TEST_CASE("concurrent_multimap requirements") {
246 test_basic<multimap_type>();
247 }
248
249 //! Testing multithreading support in concurrent_multimap
250 //! \brief \ref requirement
251 TEST_CASE("concurrent_multimap multithreading support") {
252 test_concurrent<multimap_type>();
253 }
254
255 //! Testing move constructors and assignment operator in concurrent_multimap
256 //! \brief \ref interface \ref requirement
257 TEST_CASE("concurrent_multimap multithreading support") {
258 test_rvalue_ref_support<COMultimapTraits>();
259 }
260
261 //! Testing std::initializer_list constructors and modifiers in concurrent_multimap
262 //! \brief \ref interface \ref requirement
263 TEST_CASE("std::initializer_list support in concurrent_multimap") {
264 test_initializer_list_support<multimap_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 40}});
265 }
266
267 //! Testing node handling support in concurrent_multimap
268 //! \brief \ref interface \ref requirement
269 TEST_CASE("node handling support in concurrent_multimap") {
270 node_handling_tests::test_node_handling_support<multimap_type>();
271 }
272
273 //! Testing std::allocator_traits support in concurrent_multimap
274 //! \brief \ref interface \ref requirement
275 TEST_CASE("std::allocator_traits support in concurrent_multimap") {
276 test_allocator_traits_support<COMultimapTraits>();
277 }
278
279 //! Testing heterogeneous overloads in concurrent_multimap
280 //! \brief \ref interface \ref requirement
281 TEST_CASE("heterogeneous overloads in concurrent_multimap") {
282 test_heterogeneous_functions<oneapi::tbb::concurrent_multimap>();
283 }
284
285 //! Testing insert overloads with generic pair in concurrent_multimap
286 //! \brief \ref interface \ref requirement
287 TEST_CASE("insertion by generic pair in concurrent_multimap") {
288 test_insert_by_generic_pair<oneapi::tbb::concurrent_multimap>();
289 }
290
291 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
292 //! Testing Class Template Argument Deduction in concurrent_multimap
293 //! \brief \ref interface \ref requirement
294 TEST_CASE("CTAD support in concurrent_multimap") {
295 test_deduction_guides<oneapi::tbb::concurrent_multimap>();
296 }
297 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
298
299 //! Testing comparison operators in concurrent_multimap
300 //! \brief \ref interface \ref requirement
301 TEST_CASE("test concurrent_multimap comparisons") {
302 test_map_comparisons<oneapi::tbb::concurrent_multimap>();
303 }
304
305 //! Testing of merge operations in concurrent_map and concurrent_multimap
306 //! \brief \ref interface \ref requirement
307 TEST_CASE("merge operations") {
308 node_handling_tests::test_merge<map_type, multimap_type>(1000);
309 }
310