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> 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> 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> 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