1 /* 2 Copyright (c) 2019-2020 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 <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<tbb::concurrent_multiset<Args...>> : std::true_type {}; 32 33 template <typename Key> 34 using Allocator = LocalCountingAllocator<std::allocator<Key>>; 35 36 using set_type = tbb::concurrent_set<int, std::less<int>, Allocator<int>>; 37 using multiset_type = 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, 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 TSet set5(init_list); 109 static_assert(std::is_same_v<decltype(set5), TSet<int>>, "Wrong"); 110 111 TSet set6(init_list, compare); 112 static_assert(std::is_same_v<decltype(set6), TSet<int, decltype(compare)>>, "Wrong"); 113 114 TSet set7(init_list, allocator); 115 static_assert(std::is_same_v<decltype(set7), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong"); 116 117 TSet set8(init_list, compare, allocator); 118 static_assert(std::is_same_v<decltype(set8), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong"); 119 } 120 #endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/ 121 122 template <template <typename...> class SetType> 123 void test_heterogeneous_functions() { 124 check_heterogeneous_functions_key_int<SetType, int>(); 125 check_heterogeneous_functions_key_string<SetType, std::string>(); 126 check_heterogeneous_bound_functions<SetType<int, TransparentLess>>(); 127 } 128 129 struct COSetTraits : OrderedMoveTraitsBase { 130 template <typename T, typename Allocator> 131 using container_type = tbb::concurrent_set<T, std::less<T>, Allocator>; 132 133 template <typename T> 134 using container_value_type = T; 135 136 using init_iterator_type = move_support_tests::FooIterator; 137 }; // struct COSetTraits 138 139 struct COMultisetTraits : OrderedMoveTraitsBase { 140 template <typename T, typename Allocator> 141 using container_type = tbb::concurrent_multiset<T, std::less<T>, Allocator>; 142 143 template <typename T> 144 using container_value_type = T; 145 146 using init_iterator_type = move_support_tests::FooIterator; 147 }; // struct COMultisetTraits 148 149 //! Testing concurrent_set member types 150 //! \brief \ref interface \ref requirement 151 TEST_CASE("concurrent_set member types") { 152 test_member_types<tbb::concurrent_set>(); 153 } 154 155 //! Testing multithreading support in concurrent_set 156 //! \brief \ref requirement 157 TEST_CASE("concurrent_set multithreading support") { 158 test_concurrent<set_type>(); 159 } 160 161 //! Testing move constructors and assignment operator in concurrent_set 162 //! \brief \ref interface \ref requirement 163 TEST_CASE("concurrent_set move semantics support") { 164 test_rvalue_ref_support<COSetTraits>(); 165 } 166 167 //! Testing std::initializer_list constructors and modifiers in concurrent_set 168 //! \brief \ref interface \ref requirement 169 TEST_CASE("std::initializer_list support in concurrent_set") { 170 test_initializer_list_support<set_type>({1, 2, 3, 4}); 171 } 172 173 //! Testing node handling in concurrent_set 174 //! \brief \ref interface \ref requirement 175 TEST_CASE("node handling support in concurrent_set") { 176 node_handling_tests::test_node_handling_support<set_type>(); 177 } 178 179 //! Testing std::allocator_traits support in concurrent_set 180 //! \brief \ref interface \ref requirement 181 TEST_CASE("std::allocator_traits support in concurrent_set") { 182 test_allocator_traits_support<COSetTraits>(); 183 } 184 185 //! Testing heterogeneous overloads in concurrent_set 186 //! \brief \ref interface \ref requirement 187 TEST_CASE("heterogeneous overloads in concurrent_set") { 188 test_heterogeneous_functions<tbb::concurrent_set>(); 189 } 190 191 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 192 //! Testing Class Template Argument Deduction in concurrent_set 193 //! \brief \ref interface \ref requirement 194 TEST_CASE("CTAD support in concurrent_set") { 195 test_deduction_guides<tbb::concurrent_set>(); 196 } 197 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 198 199 //! Testing comparison operators in concurrent_set 200 //! \brief \ref interface \ref requirement 201 TEST_CASE("test concurrent_set comparisons") { 202 test_set_comparisons<tbb::concurrent_set>(); 203 } 204 205 //! Testing concurrent_multiset member types 206 //! \brief \ref interface \ref requirement 207 TEST_CASE("concurrent_multiset member types") { 208 test_member_types<tbb::concurrent_multiset>(); 209 } 210 211 //! Testing requirements of concurrent_multiset 212 //! \brief \ref interface \ref requirement 213 TEST_CASE("concurrent_multiset requirements") { 214 test_basic<multiset_type>(); 215 } 216 217 //! Testing multithreading support in concurrent_multiset 218 //! \brief \ref requirement 219 TEST_CASE("concurrent_multiset multithreading support") { 220 test_concurrent<multiset_type>(); 221 } 222 223 //! Testing move constructors and assignment operator in concurrent_multiset 224 //! \brief \ref interface \ref requirement 225 TEST_CASE("concurrent_multiset multithreading support") { 226 test_rvalue_ref_support<COMultisetTraits>(); 227 } 228 229 //! Testing std::initializer_list constructors and modifiers in concurrent_multiset 230 //! \brief \ref interface \ref requirement 231 TEST_CASE("std::initializer_list support in concurrent_multimap") { 232 test_initializer_list_support<multiset_type>({1, 2, 3, 4, 4}); 233 } 234 235 //! Testing node handling support in concurrent_multiset 236 //! \brief \ref interface \ref requirement 237 TEST_CASE("node handling support in concurrent_multiset") { 238 node_handling_tests::test_node_handling_support<multiset_type>(); 239 } 240 241 //! Testing std::allocator_traits support in concurrent_multiset 242 //! \brief \ref interface \ref requirement 243 TEST_CASE("std::allocator_traits support in concurrent_multiset") { 244 test_allocator_traits_support<COMultisetTraits>(); 245 } 246 247 //! Testing heterogeneous overloads in concurrent_multiset 248 //! \brief \ref interface \ref requirement 249 TEST_CASE("heterogeneous overloads in concurrent_multiset") { 250 test_heterogeneous_functions<tbb::concurrent_multiset>(); 251 } 252 253 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 254 //! Testing Class Template Argument Deduction in concurrent_multiset 255 //! \brief \ref interface \ref requirement 256 TEST_CASE("CTAD support in concurrent_multiset") { 257 test_deduction_guides<tbb::concurrent_multiset>(); 258 } 259 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 260 261 //! Testing comparison operators in concurrent_multiset 262 //! \brief \ref interface \ref requirement 263 TEST_CASE("test concurrent_set comparisons") { 264 test_set_comparisons<tbb::concurrent_multiset>(); 265 } 266 267 //! Testing of merge operations in concurrent_set and concurrent_multiset 268 //! \brief \ref interface \ref requirement 269 TEST_CASE("merge operations") { 270 node_handling_tests::test_merge<set_type, multiset_type>(1000); 271 } 272