1 /* 2 Copyright (c) 2005-2023 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 #define TBB_DEFINE_STD_HASH_SPECIALIZATIONS 1 22 #include <tbb/concurrent_unordered_set.h> 23 #include "common/concurrent_unordered_common.h" 24 25 //! \file test_concurrent_unordered_set.cpp 26 //! \brief Test for [containers.concurrent_unordered_set containers.concurrent_unordered_multiset] specifications 27 28 template <typename... Args> 29 struct AllowMultimapping<tbb::concurrent_unordered_multiset<Args...>> : std::true_type {}; 30 31 template <typename Value> 32 using MyAllocator = LocalCountingAllocator<std::allocator<Value>>; 33 34 using move_support_tests::FooWithAssign; 35 36 using set_type = tbb::concurrent_unordered_set<int, std::hash<int>, std::equal_to<int>, MyAllocator<int>>; 37 using multiset_type = tbb::concurrent_unordered_multiset<int, std::hash<int>, std::equal_to<int>, MyAllocator<int>>; 38 using degenerate_set_type = tbb::concurrent_unordered_set<int, degenerate_hash<int>, std::equal_to<int>, MyAllocator<int>>; 39 using degenerate_multiset_type = tbb::concurrent_unordered_multiset<int, degenerate_hash<int>, std::equal_to<int>, MyAllocator<int>>; 40 41 using checked_set_type = tbb::concurrent_unordered_set<CheckType<int>, std::hash<CheckType<int>>, std::equal_to<CheckType<int>>, MyAllocator<CheckType<int>>>; 42 using checked_multiset_type = tbb::concurrent_unordered_multiset<CheckType<int>, std::hash<CheckType<int>>, 43 std::equal_to<CheckType<int>>, MyAllocator<CheckType<int>>>; 44 using checked_state_set_type = tbb::concurrent_unordered_set<FooWithAssign, std::hash<FooWithAssign>, std::equal_to<FooWithAssign>, 45 MyAllocator<FooWithAssign>>; 46 using checked_state_multiset_type = tbb::concurrent_unordered_multiset<FooWithAssign, std::hash<FooWithAssign>, std::equal_to<FooWithAssign>, 47 MyAllocator<FooWithAssign>>; 48 49 struct CusetTraits : UnorderedMoveTraitsBase { 50 template <typename T, typename Allocator> 51 using container_type = tbb::concurrent_unordered_set<T, std::hash<T>, std::equal_to<T>, Allocator>; 52 53 template <typename T> 54 using container_value_type = T; 55 56 using init_iterator_type = move_support_tests::FooIterator; 57 }; // struct CusetTraits 58 59 struct CumultisetTraits : UnorderedMoveTraitsBase { 60 template <typename T, typename Allocator> 61 using container_type = tbb::concurrent_unordered_multiset<T, std::hash<T>, std::equal_to<T>, Allocator>; 62 63 template <typename T> 64 using container_value_type = T; 65 66 using init_iterator_type = move_support_tests::FooIterator; 67 }; // struct CumultisetTraits 68 69 struct UnorderedSetTypesTester { 70 template <bool DefCtorPresent, typename ValueType> 71 void check( const std::list<ValueType>& lst ) { 72 TypeTester<DefCtorPresent, tbb::concurrent_unordered_set<ValueType, std::hash<ValueType>, utils::IsEqual>>(lst); 73 TypeTester<DefCtorPresent, tbb::concurrent_unordered_multiset<ValueType, std::hash<ValueType>, utils::IsEqual>>(lst); 74 } 75 }; 76 77 void test_specific_types() { 78 test_set_specific_types<UnorderedSetTypesTester>(); 79 80 // Regressiong test for a problem with excessive requirements of emplace() 81 test_emplace_insert<tbb::concurrent_unordered_set<test::unique_ptr<int>>, 82 std::false_type>(new int, new int); 83 test_emplace_insert<tbb::concurrent_unordered_multiset<test::unique_ptr<int>>, 84 std::false_type>(new int, new int); 85 } 86 87 //! \brief \ref stress \ref error_guessing 88 TEST_CASE("basic test for concurrent_unordered_set with degenerate hash") { 89 test_basic<degenerate_set_type>(); 90 } 91 92 //! \brief \ref stress \ref error_guessing 93 TEST_CASE("basic test for concurrent_unordered_multiset with degenerate hash") { 94 test_basic<degenerate_multiset_type>(); 95 } 96 97 //! \brief \ref resource_usage 98 TEST_CASE("basic test for concurrent_unordered_set with elements ctor and dtor check") { 99 Checker<checked_set_type::value_type> checker; 100 test_basic<checked_set_type>(); 101 } 102 103 //! \brief \ref resource_usage 104 TEST_CASE("basic test for concurrent_unordered_multiset with elements ctor and dtor check") { 105 Checker<checked_multiset_type::value_type> checker; 106 test_basic<checked_multiset_type>(); 107 } 108 109 //! \brief \ref resource_usage 110 TEST_CASE("basic test for concurrent_unordered_set with elements state check") { 111 test_basic<checked_state_set_type, /*CheckState = */std::true_type>(); 112 } 113 114 //! \brief \ref resource_usage 115 TEST_CASE("basic test for concurrent_unordered_multiset with elements state check") { 116 test_basic<checked_state_multiset_type, /*CheckState = */std::true_type>(); 117 } 118 119 //! \brief \ref stress \ref error_guessing 120 TEST_CASE("multithreading support in concurrent_unordered_set with degenerate hash") { 121 test_concurrent<degenerate_set_type>(); 122 } 123 124 //! \brief \ref stress \ref error_guessing 125 TEST_CASE("multithreading support in concurrent_unordered_multiset with degenerate hash") { 126 test_concurrent<degenerate_multiset_type>(); 127 } 128 129 //! \brief \ref stress \ref error_guessing 130 TEST_CASE("multithreading support in concurrent_unordered_multiset with no unique keys") { 131 test_concurrent<multiset_type>(true); 132 } 133 134 //! \brief \ref stress \ref error_guessing 135 TEST_CASE("multithreading support in concurrent_unordered_multiset with degenerate hash and no unique keys") { 136 test_concurrent<degenerate_multiset_type>(true); 137 } 138 139 //! \brief \ref resource_usage 140 TEST_CASE("multithreading support in concurrent_unordered_set with elements ctor and dtor check") { 141 Checker<checked_set_type::value_type> checker; 142 test_concurrent<checked_set_type>(); 143 } 144 145 //! \brief \ref resource_usage 146 TEST_CASE("multithreading support in concurrent_unordered_multiset with elements ctor and dtor check") { 147 Checker<checked_multiset_type::value_type> checker; 148 test_concurrent<checked_multiset_type>(); 149 } 150 151 //! \brief \ref resource_usage 152 TEST_CASE("multithreading support in concurrent_unordered_set with elements state check") { 153 test_concurrent<checked_state_set_type>(); 154 } 155 156 //! \brief \ref resource_usage 157 TEST_CASE("multithreading support in concurrent_unordered_multiset with elements state check") { 158 test_concurrent<checked_state_multiset_type>(); 159 } 160 161 //! \brief \ref interface \ref error_guessing 162 TEST_CASE("range based for support in concurrent_unordered_set") { 163 test_range_based_for_support<set_type>(); 164 } 165 166 //! \brief \ref interface \ref error_guessing 167 TEST_CASE("range based for support in concurrent_unordered_multiset") { 168 test_range_based_for_support<multiset_type>(); 169 } 170 171 //! \brief \ref stress \ref error_guessing 172 TEST_CASE("merge and concurrent merge in concurrent_unordered_set and set with degenerate hash") { 173 node_handling_tests::test_merge<set_type, degenerate_set_type>(1000); 174 } 175 176 //! \brief \ref regression 177 TEST_CASE("concurrent_unordered_set/multiset with specific key types") { 178 test_specific_types(); 179 } 180 181 //! \brief \ref error_guessing 182 TEST_CASE("concurrent_unordered_set with std::scoped_allocator_adaptor") { 183 test_scoped_allocator<CusetTraits>(); 184 } 185 186 //! \brief \ref error_guessing 187 TEST_CASE("concurrent_unordered_multiset with std::scoped_allocator_adaptor") { 188 test_scoped_allocator<CumultisetTraits>(); 189 } 190 191 //! \brief \ref error_guessing 192 TEST_CASE("concurrent_unordered_set::swap with not always equal allocator") { 193 using not_always_equal_alloc_set_type = tbb::concurrent_unordered_set<int, std::hash<int>, std::equal_to<int>, 194 NotAlwaysEqualAllocator<int>>; 195 test_swap_not_always_equal_allocator<not_always_equal_alloc_set_type>(); 196 } 197 198 //! \brief \ref error_guessing 199 TEST_CASE("concurrent_unordered_multiset::swap with not always equal allocator") { 200 using not_always_equal_alloc_mset_type = tbb::concurrent_unordered_multiset<int, std::hash<int>, std::equal_to<int>, 201 NotAlwaysEqualAllocator<int>>; 202 test_swap_not_always_equal_allocator<not_always_equal_alloc_mset_type>(); 203 } 204 205 #if __TBB_USE_EXCEPTIONS 206 //! \brief \ref error_guessing 207 TEST_CASE("concurrent_unordered_set throwing copy constructor") { 208 using exception_set_type = tbb::concurrent_unordered_set<ThrowOnCopy>; 209 test_exception_on_copy_ctor<exception_set_type>(); 210 } 211 212 //! \brief \ref error_guessing 213 TEST_CASE("concurrent_unordered_multimap throwing copy constructor") { 214 using exception_mset_type = tbb::concurrent_unordered_multiset<ThrowOnCopy>; 215 test_exception_on_copy_ctor<exception_mset_type>(); 216 } 217 #endif // __TBB_USE_EXCEPTIONS 218 219 #if __TBB_CPP20_CONCEPTS_PRESENT 220 //! \brief \ref error_guessing 221 TEST_CASE("container_range concept for concurrent_unordered_set ranges") { 222 static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_set<int>::range_type>); 223 static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_set<int>::const_range_type>); 224 } 225 226 //! \brief \ref error_guessing 227 TEST_CASE("container_range concept for concurrent_unordered_multiset ranges") { 228 static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_multiset<int>::range_type>); 229 static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_multiset<int>::const_range_type>); 230 } 231 #endif // __TBB_CPP20_CONCEPTS_PRESENT 232 233 //! \brief \ref regression 234 TEST_CASE("reserve(0) issue regression test") { 235 test_reserve_regression<oneapi::tbb::concurrent_unordered_set<int>>(); 236 test_reserve_regression<oneapi::tbb::concurrent_unordered_multiset<int>>(); 237 } 238