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