151c0b2f7Stbbdev /*
2*d5fd1e97SKonstantin Boyarinov     Copyright (c) 2005-2023 Intel Corporation
351c0b2f7Stbbdev 
451c0b2f7Stbbdev     Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev     you may not use this file except in compliance with the License.
651c0b2f7Stbbdev     You may obtain a copy of the License at
751c0b2f7Stbbdev 
851c0b2f7Stbbdev         http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev 
1051c0b2f7Stbbdev     Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev     See the License for the specific language governing permissions and
1451c0b2f7Stbbdev     limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev 
17b15aabb3Stbbdev #if __INTEL_COMPILER && _MSC_VER
18b15aabb3Stbbdev #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
19b15aabb3Stbbdev #endif
20b15aabb3Stbbdev 
2151c0b2f7Stbbdev #define TBB_DEFINE_STD_HASH_SPECIALIZATIONS 1
2251c0b2f7Stbbdev #include <tbb/concurrent_unordered_set.h>
2351c0b2f7Stbbdev #include "common/concurrent_unordered_common.h"
2451c0b2f7Stbbdev 
2551c0b2f7Stbbdev //! \file test_concurrent_unordered_set.cpp
2651c0b2f7Stbbdev //! \brief Test for [containers.concurrent_unordered_set containers.concurrent_unordered_multiset] specifications
2751c0b2f7Stbbdev 
2851c0b2f7Stbbdev template <typename... Args>
2951c0b2f7Stbbdev struct AllowMultimapping<tbb::concurrent_unordered_multiset<Args...>> : std::true_type {};
3051c0b2f7Stbbdev 
3151c0b2f7Stbbdev template <typename Value>
3251c0b2f7Stbbdev using MyAllocator = LocalCountingAllocator<std::allocator<Value>>;
3351c0b2f7Stbbdev 
3451c0b2f7Stbbdev using move_support_tests::FooWithAssign;
3551c0b2f7Stbbdev 
3651c0b2f7Stbbdev using set_type = tbb::concurrent_unordered_set<int, std::hash<int>, std::equal_to<int>, MyAllocator<int>>;
3751c0b2f7Stbbdev using multiset_type = tbb::concurrent_unordered_multiset<int, std::hash<int>, std::equal_to<int>, MyAllocator<int>>;
3851c0b2f7Stbbdev using degenerate_set_type = tbb::concurrent_unordered_set<int, degenerate_hash<int>, std::equal_to<int>, MyAllocator<int>>;
3951c0b2f7Stbbdev using degenerate_multiset_type = tbb::concurrent_unordered_multiset<int, degenerate_hash<int>, std::equal_to<int>, MyAllocator<int>>;
4051c0b2f7Stbbdev 
4151c0b2f7Stbbdev using checked_set_type = tbb::concurrent_unordered_set<CheckType<int>, std::hash<CheckType<int>>, std::equal_to<CheckType<int>>, MyAllocator<CheckType<int>>>;
4251c0b2f7Stbbdev using checked_multiset_type = tbb::concurrent_unordered_multiset<CheckType<int>, std::hash<CheckType<int>>,
4351c0b2f7Stbbdev                                                                  std::equal_to<CheckType<int>>, MyAllocator<CheckType<int>>>;
4451c0b2f7Stbbdev using checked_state_set_type = tbb::concurrent_unordered_set<FooWithAssign, std::hash<FooWithAssign>, std::equal_to<FooWithAssign>,
4551c0b2f7Stbbdev                                                              MyAllocator<FooWithAssign>>;
4651c0b2f7Stbbdev using checked_state_multiset_type = tbb::concurrent_unordered_multiset<FooWithAssign, std::hash<FooWithAssign>, std::equal_to<FooWithAssign>,
4751c0b2f7Stbbdev                                                                        MyAllocator<FooWithAssign>>;
4851c0b2f7Stbbdev 
4951c0b2f7Stbbdev struct CusetTraits : UnorderedMoveTraitsBase {
5051c0b2f7Stbbdev     template <typename T, typename Allocator>
5151c0b2f7Stbbdev     using container_type = tbb::concurrent_unordered_set<T, std::hash<T>, std::equal_to<T>, Allocator>;
5251c0b2f7Stbbdev 
5351c0b2f7Stbbdev     template <typename T>
5451c0b2f7Stbbdev     using container_value_type = T;
5551c0b2f7Stbbdev 
5651c0b2f7Stbbdev     using init_iterator_type = move_support_tests::FooIterator;
5751c0b2f7Stbbdev }; // struct CusetTraits
5851c0b2f7Stbbdev 
5951c0b2f7Stbbdev struct CumultisetTraits : UnorderedMoveTraitsBase {
6051c0b2f7Stbbdev     template <typename T, typename Allocator>
6151c0b2f7Stbbdev     using container_type = tbb::concurrent_unordered_multiset<T, std::hash<T>, std::equal_to<T>, Allocator>;
6251c0b2f7Stbbdev 
6351c0b2f7Stbbdev     template <typename T>
6451c0b2f7Stbbdev     using container_value_type = T;
6551c0b2f7Stbbdev 
6651c0b2f7Stbbdev     using init_iterator_type = move_support_tests::FooIterator;
6751c0b2f7Stbbdev }; // struct CumultisetTraits
6851c0b2f7Stbbdev 
6951c0b2f7Stbbdev struct UnorderedSetTypesTester {
7051c0b2f7Stbbdev     template <bool DefCtorPresent, typename ValueType>
checkUnorderedSetTypesTester7151c0b2f7Stbbdev     void check( const std::list<ValueType>& lst ) {
7251c0b2f7Stbbdev         TypeTester<DefCtorPresent, tbb::concurrent_unordered_set<ValueType, std::hash<ValueType>, utils::IsEqual>>(lst);
7351c0b2f7Stbbdev         TypeTester<DefCtorPresent, tbb::concurrent_unordered_multiset<ValueType, std::hash<ValueType>, utils::IsEqual>>(lst);
7451c0b2f7Stbbdev     }
7551c0b2f7Stbbdev };
7651c0b2f7Stbbdev 
test_specific_types()7751c0b2f7Stbbdev void test_specific_types() {
7851c0b2f7Stbbdev     test_set_specific_types<UnorderedSetTypesTester>();
7951c0b2f7Stbbdev 
8051c0b2f7Stbbdev     // Regressiong test for a problem with excessive requirements of emplace()
8151c0b2f7Stbbdev     test_emplace_insert<tbb::concurrent_unordered_set<test::unique_ptr<int>>,
8251c0b2f7Stbbdev                         std::false_type>(new int, new int);
8351c0b2f7Stbbdev     test_emplace_insert<tbb::concurrent_unordered_multiset<test::unique_ptr<int>>,
8451c0b2f7Stbbdev                         std::false_type>(new int, new int);
8551c0b2f7Stbbdev }
8651c0b2f7Stbbdev 
8751c0b2f7Stbbdev //! \brief \ref stress \ref error_guessing
8851c0b2f7Stbbdev TEST_CASE("basic test for concurrent_unordered_set with degenerate hash") {
8951c0b2f7Stbbdev     test_basic<degenerate_set_type>();
9051c0b2f7Stbbdev }
9151c0b2f7Stbbdev 
9251c0b2f7Stbbdev //! \brief \ref stress \ref error_guessing
9351c0b2f7Stbbdev TEST_CASE("basic test for concurrent_unordered_multiset with degenerate hash") {
9451c0b2f7Stbbdev     test_basic<degenerate_multiset_type>();
9551c0b2f7Stbbdev }
9651c0b2f7Stbbdev 
9751c0b2f7Stbbdev //! \brief \ref resource_usage
9851c0b2f7Stbbdev TEST_CASE("basic test for concurrent_unordered_set with elements ctor and dtor check") {
9951c0b2f7Stbbdev     Checker<checked_set_type::value_type> checker;
10051c0b2f7Stbbdev     test_basic<checked_set_type>();
10151c0b2f7Stbbdev }
10251c0b2f7Stbbdev 
10351c0b2f7Stbbdev //! \brief \ref resource_usage
10451c0b2f7Stbbdev TEST_CASE("basic test for concurrent_unordered_multiset with elements ctor and dtor check") {
10551c0b2f7Stbbdev     Checker<checked_multiset_type::value_type> checker;
10651c0b2f7Stbbdev     test_basic<checked_multiset_type>();
10751c0b2f7Stbbdev }
10851c0b2f7Stbbdev 
10951c0b2f7Stbbdev //! \brief \ref resource_usage
11051c0b2f7Stbbdev TEST_CASE("basic test for concurrent_unordered_set with elements state check") {
11151c0b2f7Stbbdev     test_basic<checked_state_set_type, /*CheckState = */std::true_type>();
11251c0b2f7Stbbdev }
11351c0b2f7Stbbdev 
11451c0b2f7Stbbdev //! \brief \ref resource_usage
11551c0b2f7Stbbdev TEST_CASE("basic test for concurrent_unordered_multiset with elements state check") {
11651c0b2f7Stbbdev     test_basic<checked_state_multiset_type, /*CheckState = */std::true_type>();
11751c0b2f7Stbbdev }
11851c0b2f7Stbbdev 
11951c0b2f7Stbbdev //! \brief \ref stress \ref error_guessing
12051c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_set with degenerate hash") {
12151c0b2f7Stbbdev     test_concurrent<degenerate_set_type>();
12251c0b2f7Stbbdev }
12351c0b2f7Stbbdev 
12451c0b2f7Stbbdev //! \brief \ref stress \ref error_guessing
12551c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_multiset with degenerate hash") {
12651c0b2f7Stbbdev     test_concurrent<degenerate_multiset_type>();
12751c0b2f7Stbbdev }
12851c0b2f7Stbbdev 
12951c0b2f7Stbbdev //! \brief \ref stress \ref error_guessing
13051c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_multiset with no unique keys") {
13151c0b2f7Stbbdev     test_concurrent<multiset_type>(true);
13251c0b2f7Stbbdev }
13351c0b2f7Stbbdev 
13451c0b2f7Stbbdev //! \brief \ref stress \ref error_guessing
13551c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_multiset with degenerate hash and no unique keys") {
13651c0b2f7Stbbdev     test_concurrent<degenerate_multiset_type>(true);
13751c0b2f7Stbbdev }
13851c0b2f7Stbbdev 
13951c0b2f7Stbbdev //! \brief \ref resource_usage
14051c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_set with elements ctor and dtor check") {
14151c0b2f7Stbbdev     Checker<checked_set_type::value_type> checker;
14251c0b2f7Stbbdev     test_concurrent<checked_set_type>();
14351c0b2f7Stbbdev }
14451c0b2f7Stbbdev 
14551c0b2f7Stbbdev //! \brief \ref resource_usage
14651c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_multiset with elements ctor and dtor check") {
14751c0b2f7Stbbdev     Checker<checked_multiset_type::value_type> checker;
14851c0b2f7Stbbdev     test_concurrent<checked_multiset_type>();
14951c0b2f7Stbbdev }
15051c0b2f7Stbbdev 
15151c0b2f7Stbbdev //! \brief \ref resource_usage
15251c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_set with elements state check") {
15351c0b2f7Stbbdev     test_concurrent<checked_state_set_type>();
15451c0b2f7Stbbdev }
15551c0b2f7Stbbdev 
15651c0b2f7Stbbdev //! \brief \ref resource_usage
15751c0b2f7Stbbdev TEST_CASE("multithreading support in concurrent_unordered_multiset with elements state check") {
15851c0b2f7Stbbdev     test_concurrent<checked_state_multiset_type>();
15951c0b2f7Stbbdev }
16051c0b2f7Stbbdev 
16151c0b2f7Stbbdev //! \brief \ref interface \ref error_guessing
16251c0b2f7Stbbdev TEST_CASE("range based for support in concurrent_unordered_set") {
16351c0b2f7Stbbdev     test_range_based_for_support<set_type>();
16451c0b2f7Stbbdev }
16551c0b2f7Stbbdev 
16651c0b2f7Stbbdev //! \brief \ref interface \ref error_guessing
16751c0b2f7Stbbdev TEST_CASE("range based for support in concurrent_unordered_multiset") {
16851c0b2f7Stbbdev     test_range_based_for_support<multiset_type>();
16951c0b2f7Stbbdev }
17051c0b2f7Stbbdev 
17151c0b2f7Stbbdev //! \brief \ref stress \ref error_guessing
17251c0b2f7Stbbdev TEST_CASE("merge and concurrent merge in concurrent_unordered_set and set with degenerate hash") {
17351c0b2f7Stbbdev     node_handling_tests::test_merge<set_type, degenerate_set_type>(1000);
17451c0b2f7Stbbdev }
17551c0b2f7Stbbdev 
17651c0b2f7Stbbdev //! \brief \ref regression
17751c0b2f7Stbbdev TEST_CASE("concurrent_unordered_set/multiset with specific key types") {
17851c0b2f7Stbbdev     test_specific_types();
17951c0b2f7Stbbdev }
18051c0b2f7Stbbdev 
18151c0b2f7Stbbdev //! \brief \ref error_guessing
18251c0b2f7Stbbdev TEST_CASE("concurrent_unordered_set with std::scoped_allocator_adaptor") {
18351c0b2f7Stbbdev     test_scoped_allocator<CusetTraits>();
18451c0b2f7Stbbdev }
18551c0b2f7Stbbdev 
18651c0b2f7Stbbdev //! \brief \ref error_guessing
18751c0b2f7Stbbdev TEST_CASE("concurrent_unordered_multiset with std::scoped_allocator_adaptor") {
18851c0b2f7Stbbdev     test_scoped_allocator<CumultisetTraits>();
18951c0b2f7Stbbdev }
19051c0b2f7Stbbdev 
19151c0b2f7Stbbdev //! \brief \ref error_guessing
19251c0b2f7Stbbdev TEST_CASE("concurrent_unordered_set::swap with not always equal allocator") {
19351c0b2f7Stbbdev     using not_always_equal_alloc_set_type = tbb::concurrent_unordered_set<int, std::hash<int>, std::equal_to<int>,
19451c0b2f7Stbbdev                                                                           NotAlwaysEqualAllocator<int>>;
19551c0b2f7Stbbdev     test_swap_not_always_equal_allocator<not_always_equal_alloc_set_type>();
19651c0b2f7Stbbdev }
19751c0b2f7Stbbdev 
19851c0b2f7Stbbdev //! \brief \ref error_guessing
19951c0b2f7Stbbdev TEST_CASE("concurrent_unordered_multiset::swap with not always equal allocator") {
20051c0b2f7Stbbdev     using not_always_equal_alloc_mset_type = tbb::concurrent_unordered_multiset<int, std::hash<int>, std::equal_to<int>,
20151c0b2f7Stbbdev                                                                                 NotAlwaysEqualAllocator<int>>;
20251c0b2f7Stbbdev     test_swap_not_always_equal_allocator<not_always_equal_alloc_mset_type>();
20351c0b2f7Stbbdev }
20451c0b2f7Stbbdev 
20551c0b2f7Stbbdev #if __TBB_USE_EXCEPTIONS
20651c0b2f7Stbbdev //! \brief \ref error_guessing
20751c0b2f7Stbbdev TEST_CASE("concurrent_unordered_set throwing copy constructor") {
20851c0b2f7Stbbdev     using exception_set_type = tbb::concurrent_unordered_set<ThrowOnCopy>;
20951c0b2f7Stbbdev     test_exception_on_copy_ctor<exception_set_type>();
21051c0b2f7Stbbdev }
21151c0b2f7Stbbdev 
21251c0b2f7Stbbdev //! \brief \ref error_guessing
21351c0b2f7Stbbdev TEST_CASE("concurrent_unordered_multimap throwing copy constructor") {
21451c0b2f7Stbbdev     using exception_mset_type = tbb::concurrent_unordered_multiset<ThrowOnCopy>;
21551c0b2f7Stbbdev     test_exception_on_copy_ctor<exception_mset_type>();
21651c0b2f7Stbbdev }
21751c0b2f7Stbbdev #endif // __TBB_USE_EXCEPTIONS
218478de5b1Stbbdev 
219478de5b1Stbbdev #if __TBB_CPP20_CONCEPTS_PRESENT
220478de5b1Stbbdev //! \brief \ref error_guessing
221478de5b1Stbbdev TEST_CASE("container_range concept for concurrent_unordered_set ranges") {
222478de5b1Stbbdev     static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_set<int>::range_type>);
223478de5b1Stbbdev     static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_set<int>::const_range_type>);
224478de5b1Stbbdev }
225478de5b1Stbbdev 
226478de5b1Stbbdev //! \brief \ref error_guessing
227478de5b1Stbbdev TEST_CASE("container_range concept for concurrent_unordered_multiset ranges") {
228478de5b1Stbbdev     static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_multiset<int>::range_type>);
229478de5b1Stbbdev     static_assert(test_concepts::container_range<typename tbb::concurrent_unordered_multiset<int>::const_range_type>);
230478de5b1Stbbdev }
231478de5b1Stbbdev #endif // __TBB_CPP20_CONCEPTS_PRESENT
232*d5fd1e97SKonstantin Boyarinov 
233*d5fd1e97SKonstantin Boyarinov //! \brief \ref regression
234*d5fd1e97SKonstantin Boyarinov TEST_CASE("reserve(0) issue regression test") {
235*d5fd1e97SKonstantin Boyarinov     test_reserve_regression<oneapi::tbb::concurrent_unordered_set<int>>();
236*d5fd1e97SKonstantin Boyarinov     test_reserve_regression<oneapi::tbb::concurrent_unordered_multiset<int>>();
237*d5fd1e97SKonstantin Boyarinov }
238