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 #ifndef NOMINMAX
18 #define NOMINMAX
19 #endif
20 #include "oneapi/tbb/concurrent_set.h"
21 #include <common/test.h>
22 #include <common/utils.h>
23 #include <common/concurrent_ordered_common.h>
24 #include <memory>
25 #include <type_traits>
26
27 //! \file conformance_concurrent_set.cpp
28 //! \brief Test for [containers.concurrent_set containers.concurrent_multiset] specifications
29
30 template <typename... Args>
31 struct AllowMultimapping<oneapi::tbb::concurrent_multiset<Args...>> : std::true_type {};
32
33 template <typename Key>
34 using Allocator = LocalCountingAllocator<std::allocator<Key>>;
35
36 using set_type = oneapi::tbb::concurrent_set<int, std::less<int>, Allocator<int>>;
37 using multiset_type = oneapi::tbb::concurrent_multiset<int, std::less<int>, Allocator<int>>;
38
39 template <template <typename...> class ContainerType>
test_member_types()40 void test_member_types() {
41 using default_container_type = ContainerType<int>;
42 static_assert(std::is_same<typename default_container_type::key_compare, std::less<int>>::value,
43 "Incorrect default template comparator");
44 static_assert(std::is_same<typename default_container_type::allocator_type, oneapi::tbb::tbb_allocator<int>>::value,
45 "Incorrect default template allocator");
46
47 auto test_comparator = [](const int&, const int&)->bool { return true; };
48 using test_allocator_type = std::allocator<int>;
49
50 using container_type = ContainerType<int, decltype(test_comparator), test_allocator_type>;
51
52 static_assert(std::is_same<typename container_type::key_type, int>::value,
53 "Incorrect container key_type member type");
54 static_assert(std::is_same<typename container_type::value_type, int>::value,
55 "Incorrect container value_type member type");
56
57 static_assert(std::is_unsigned<typename container_type::size_type>::value,
58 "Incorrect container size_type member type");
59 static_assert(std::is_signed<typename container_type::difference_type>::value,
60 "Incorrect container difference_type member type");
61
62 static_assert(std::is_same<typename container_type::key_compare, decltype(test_comparator)>::value,
63 "Incorrect container key_compare member type");
64 static_assert(std::is_same<typename container_type::allocator_type, test_allocator_type>::value,
65 "Incorrect container allocator_type member type");
66
67 using value_type = typename container_type::value_type;
68 static_assert(std::is_same<typename container_type::reference, value_type&>::value,
69 "Incorrect container reference member type");
70 static_assert(std::is_same<typename container_type::const_reference, const value_type&>::value,
71 "Incorrect container const_reference member type");
72 using allocator_type = typename container_type::allocator_type;
73 static_assert(std::is_same<typename container_type::pointer, typename std::allocator_traits<allocator_type>::pointer>::value,
74 "Incorrect container pointer member type");
75 static_assert(std::is_same<typename container_type::const_pointer, typename std::allocator_traits<allocator_type>::const_pointer>::value,
76 "Incorrect container const_pointer member type");
77
78 static_assert(utils::is_forward_iterator<typename container_type::iterator>::value,
79 "Incorrect container iterator member type");
80 static_assert(!std::is_const<typename container_type::iterator::value_type>::value,
81 "Incorrect container iterator member type");
82 static_assert(utils::is_forward_iterator<typename container_type::const_iterator>::value,
83 "Incorrect container const_iterator member type");
84 static_assert(std::is_const<typename container_type::const_iterator::value_type>::value,
85 "Incorrect container const_iterator member type");
86 }
87
88 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
89 template <template <typename ...> typename TSet>
test_deduction_guides()90 void test_deduction_guides() {
91 std::vector<int> vc({1, 2, 3});
92 TSet set(vc.begin(), vc.end());
93 static_assert(std::is_same_v<decltype(set), TSet<int>>, "Wrong");
94
95 std::greater<int> compare;
96 std::allocator<int> allocator;
97
98 TSet set2(vc.begin(), vc.end(), compare);
99 static_assert(std::is_same_v<decltype(set2), TSet<int, decltype(compare)>>, "Wrong");
100
101 TSet set3(vc.begin(), vc.end(), allocator);
102 static_assert(std::is_same_v<decltype(set3), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong");
103
104 TSet set4(vc.begin(), vc.end(), compare, allocator);
105 static_assert(std::is_same_v<decltype(set4), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong");
106
107 auto init_list = { int(1), int(2), int(3) };
108
109 TSet set5(init_list);
110 static_assert(std::is_same_v<decltype(set5), TSet<int>>, "Wrong");
111
112 TSet set6(init_list, compare);
113 static_assert(std::is_same_v<decltype(set6), TSet<int, decltype(compare)>>, "Wrong");
114
115 TSet set7(init_list, allocator);
116 static_assert(std::is_same_v<decltype(set7), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong");
117
118 TSet set8(init_list, compare, allocator);
119 static_assert(std::is_same_v<decltype(set8), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong");
120 }
121 #endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/
122
123 template <template <typename...> class SetType>
test_heterogeneous_functions()124 void test_heterogeneous_functions() {
125 check_heterogeneous_functions_key_int<SetType, int>();
126 check_heterogeneous_functions_key_string<SetType, std::string>();
127 check_heterogeneous_bound_functions<SetType<int, TransparentLess>>();
128 }
129
130 struct COSetTraits : OrderedMoveTraitsBase {
131 template <typename T, typename Allocator>
132 using container_type = oneapi::tbb::concurrent_set<T, std::less<T>, Allocator>;
133
134 template <typename T>
135 using container_value_type = T;
136
137 using init_iterator_type = move_support_tests::FooIterator;
138 }; // struct COSetTraits
139
140 struct COMultisetTraits : OrderedMoveTraitsBase {
141 template <typename T, typename Allocator>
142 using container_type = oneapi::tbb::concurrent_multiset<T, std::less<T>, Allocator>;
143
144 template <typename T>
145 using container_value_type = T;
146
147 using init_iterator_type = move_support_tests::FooIterator;
148 }; // struct COMultisetTraits
149
150 //! Testing concurrent_set member types
151 //! \brief \ref interface \ref requirement
152 TEST_CASE("concurrent_set member types") {
153 test_member_types<oneapi::tbb::concurrent_set>();
154 }
155
156 //! Testing multithreading support in concurrent_set
157 //! \brief \ref requirement
158 TEST_CASE("concurrent_set multithreading support") {
159 test_concurrent<set_type>();
160 }
161
162 //! Testing move constructors and assignment operator in concurrent_set
163 //! \brief \ref interface \ref requirement
164 TEST_CASE("concurrent_set move semantics support") {
165 test_rvalue_ref_support<COSetTraits>();
166 }
167
168 //! Testing std::initializer_list constructors and modifiers in concurrent_set
169 //! \brief \ref interface \ref requirement
170 TEST_CASE("std::initializer_list support in concurrent_set") {
171 test_initializer_list_support<set_type>({1, 2, 3, 4});
172 }
173
174 //! Testing node handling in concurrent_set
175 //! \brief \ref interface \ref requirement
176 TEST_CASE("node handling support in concurrent_set") {
177 node_handling_tests::test_node_handling_support<set_type>();
178 }
179
180 //! Testing std::allocator_traits support in concurrent_set
181 //! \brief \ref interface \ref requirement
182 TEST_CASE("std::allocator_traits support in concurrent_set") {
183 test_allocator_traits_support<COSetTraits>();
184 }
185
186 //! Testing heterogeneous overloads in concurrent_set
187 //! \brief \ref interface \ref requirement
188 TEST_CASE("heterogeneous overloads in concurrent_set") {
189 test_heterogeneous_functions<oneapi::tbb::concurrent_set>();
190 }
191
192 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
193 //! Testing Class Template Argument Deduction in concurrent_set
194 //! \brief \ref interface \ref requirement
195 TEST_CASE("CTAD support in concurrent_set") {
196 test_deduction_guides<oneapi::tbb::concurrent_set>();
197 }
198 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
199
200 //! Testing comparison operators in concurrent_set
201 //! \brief \ref interface \ref requirement
202 TEST_CASE("test concurrent_set comparisons") {
203 test_set_comparisons<oneapi::tbb::concurrent_set>();
204 }
205
206 //! Testing concurrent_multiset member types
207 //! \brief \ref interface \ref requirement
208 TEST_CASE("concurrent_multiset member types") {
209 test_member_types<oneapi::tbb::concurrent_multiset>();
210 }
211
212 //! Testing requirements of concurrent_multiset
213 //! \brief \ref interface \ref requirement
214 TEST_CASE("concurrent_multiset requirements") {
215 test_basic<multiset_type>();
216 }
217
218 //! Testing multithreading support in concurrent_multiset
219 //! \brief \ref requirement
220 TEST_CASE("concurrent_multiset multithreading support") {
221 test_concurrent<multiset_type>();
222 }
223
224 //! Testing move constructors and assignment operator in concurrent_multiset
225 //! \brief \ref interface \ref requirement
226 TEST_CASE("concurrent_multiset multithreading support") {
227 test_rvalue_ref_support<COMultisetTraits>();
228 }
229
230 //! Testing std::initializer_list constructors and modifiers in concurrent_multiset
231 //! \brief \ref interface \ref requirement
232 TEST_CASE("std::initializer_list support in concurrent_multimap") {
233 test_initializer_list_support<multiset_type>({1, 2, 3, 4, 4});
234 }
235
236 //! Testing node handling support in concurrent_multiset
237 //! \brief \ref interface \ref requirement
238 TEST_CASE("node handling support in concurrent_multiset") {
239 node_handling_tests::test_node_handling_support<multiset_type>();
240 }
241
242 //! Testing std::allocator_traits support in concurrent_multiset
243 //! \brief \ref interface \ref requirement
244 TEST_CASE("std::allocator_traits support in concurrent_multiset") {
245 test_allocator_traits_support<COMultisetTraits>();
246 }
247
248 //! Testing heterogeneous overloads in concurrent_multiset
249 //! \brief \ref interface \ref requirement
250 TEST_CASE("heterogeneous overloads in concurrent_multiset") {
251 test_heterogeneous_functions<oneapi::tbb::concurrent_multiset>();
252 }
253
254 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
255 //! Testing Class Template Argument Deduction in concurrent_multiset
256 //! \brief \ref interface \ref requirement
257 TEST_CASE("CTAD support in concurrent_multiset") {
258 test_deduction_guides<oneapi::tbb::concurrent_multiset>();
259 }
260 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
261
262 //! Testing comparison operators in concurrent_multiset
263 //! \brief \ref interface \ref requirement
264 TEST_CASE("test concurrent_set comparisons") {
265 test_set_comparisons<oneapi::tbb::concurrent_multiset>();
266 }
267
268 //! Testing of merge operations in concurrent_set and concurrent_multiset
269 //! \brief \ref interface \ref requirement
270 TEST_CASE("merge operations") {
271 node_handling_tests::test_merge<set_type, multiset_type>(1000);
272 }
273