151c0b2f7Stbbdev /*
2*b15aabb3Stbbdev     Copyright (c) 2005-2021 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 
17*b15aabb3Stbbdev #if __INTEL_COMPILER && _MSC_VER
18*b15aabb3Stbbdev #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
19*b15aabb3Stbbdev #endif
20*b15aabb3Stbbdev 
2149e08aacStbbdev #include "oneapi/tbb/concurrent_unordered_map.h"
2251c0b2f7Stbbdev #include <common/test.h>
2351c0b2f7Stbbdev #include <common/utils.h>
2451c0b2f7Stbbdev #include <common/concurrent_unordered_common.h>
2551c0b2f7Stbbdev #include <memory>
2651c0b2f7Stbbdev #include <type_traits>
2751c0b2f7Stbbdev 
2851c0b2f7Stbbdev //! \file conformance_concurrent_unordered_map.cpp
2951c0b2f7Stbbdev //! \brief Test for [containers.concurrent_unordered_map containers.concurrent_unordered_multimap] specifications
3051c0b2f7Stbbdev 
3151c0b2f7Stbbdev template <typename... Args>
3249e08aacStbbdev struct AllowMultimapping<oneapi::tbb::concurrent_unordered_multimap<Args...>> : std::true_type {};
3351c0b2f7Stbbdev 
3451c0b2f7Stbbdev template <typename Key, typename Mapped>
3551c0b2f7Stbbdev using Allocator = LocalCountingAllocator<std::allocator<std::pair<const Key, Mapped>>>;
3651c0b2f7Stbbdev 
3749e08aacStbbdev using map_type = oneapi::tbb::concurrent_unordered_map<int, int, std::hash<int>, std::equal_to<int>, Allocator<int, int>>;
3849e08aacStbbdev using multimap_type = oneapi::tbb::concurrent_unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, Allocator<int, int>>;
3951c0b2f7Stbbdev 
4051c0b2f7Stbbdev template <>
4151c0b2f7Stbbdev struct SpecialTests<map_type> {
TestSpecialTests4251c0b2f7Stbbdev     static void Test() {
4351c0b2f7Stbbdev         SpecialMapTests<map_type>();
4451c0b2f7Stbbdev     }
4551c0b2f7Stbbdev };
4651c0b2f7Stbbdev 
4751c0b2f7Stbbdev template <>
4851c0b2f7Stbbdev struct SpecialTests<multimap_type> {
TestSpecialTests4951c0b2f7Stbbdev     static void Test() {
5051c0b2f7Stbbdev         SpecialMultiMapTests<multimap_type>();
5151c0b2f7Stbbdev     }
5251c0b2f7Stbbdev };
5351c0b2f7Stbbdev 
5451c0b2f7Stbbdev template <template <typename... > class ContainerType>
test_member_types()5551c0b2f7Stbbdev void test_member_types() {
5651c0b2f7Stbbdev     using default_container_type = ContainerType<int, int>;
5751c0b2f7Stbbdev     static_assert(std::is_same<typename default_container_type::hasher, std::hash<int>>::value,
5851c0b2f7Stbbdev                   "Incorrect default template hasher");
5951c0b2f7Stbbdev     static_assert(std::is_same<typename default_container_type::key_equal, std::equal_to<int>>::value,
6051c0b2f7Stbbdev                   "Incorrect default template key equality");
6151c0b2f7Stbbdev     static_assert(std::is_same<typename default_container_type::allocator_type,
6249e08aacStbbdev                                oneapi::tbb::tbb_allocator<std::pair<const int, int>>>::value,
6351c0b2f7Stbbdev                   "Incorrect default template allocator");
6451c0b2f7Stbbdev 
6551c0b2f7Stbbdev     auto test_hasher = [](const int&)->std::size_t { return 0; };
6651c0b2f7Stbbdev     auto test_equality = [](const int&, const int&)->bool { return true; };
6751c0b2f7Stbbdev     using test_allocator_type = std::allocator<std::pair<const int, int>>;
6851c0b2f7Stbbdev 
6951c0b2f7Stbbdev     using container_type = ContainerType<int, int, decltype(test_hasher),
7051c0b2f7Stbbdev                                          decltype(test_equality), test_allocator_type>;
7151c0b2f7Stbbdev 
7251c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::key_type, int>::value,
7351c0b2f7Stbbdev                   "Incorrect container key_type member type");
7451c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::mapped_type, int>::value,
7551c0b2f7Stbbdev                   "Incorrect container mapped_type member type");
7651c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::value_type, std::pair<const int, int>>::value,
7751c0b2f7Stbbdev                   "Incorrect container value_type member type");
7851c0b2f7Stbbdev 
7951c0b2f7Stbbdev     static_assert(std::is_unsigned<typename container_type::size_type>::value,
8051c0b2f7Stbbdev                   "Incorrect container size_type member type");
8151c0b2f7Stbbdev     static_assert(std::is_signed<typename container_type::difference_type>::value,
8251c0b2f7Stbbdev                   "Incorrect container difference_type member type");
8351c0b2f7Stbbdev 
8451c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::hasher, decltype(test_hasher)>::value,
8551c0b2f7Stbbdev                   "Incorrect container hasher member type");
8651c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::key_equal, decltype(test_equality)>::value,
8751c0b2f7Stbbdev                   "Incorrect container key_equal member type");
8851c0b2f7Stbbdev 
8951c0b2f7Stbbdev     using transparent_container_type = ContainerType<int, int, hasher_with_transparent_key_equal,
9051c0b2f7Stbbdev                                                      std::equal_to<int>, test_allocator_type>;
9151c0b2f7Stbbdev 
9251c0b2f7Stbbdev     static_assert(std::is_same<typename transparent_container_type::key_equal, transparent_key_equality>::value,
9351c0b2f7Stbbdev                   "Incorrect container key_equal member type");
9451c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::allocator_type, test_allocator_type>::value,
9551c0b2f7Stbbdev                   "Incorrect container allocator_type member type");
9651c0b2f7Stbbdev 
9751c0b2f7Stbbdev     using value_type = typename container_type::value_type;
9851c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::reference, value_type&>::value,
9951c0b2f7Stbbdev                   "Incorrect container reference member type");
10051c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::const_reference, const value_type&>::value,
10151c0b2f7Stbbdev                   "Incorrect container const_reference member type");
10251c0b2f7Stbbdev     using allocator_type = typename container_type::allocator_type;
10351c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::pointer, typename std::allocator_traits<allocator_type>::pointer>::value,
10451c0b2f7Stbbdev                   "Incorrect container pointer member type");
10551c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::const_pointer, typename std::allocator_traits<allocator_type>::const_pointer>::value,
10651c0b2f7Stbbdev                   "Incorrect container const_pointer member type");
10751c0b2f7Stbbdev 
10851c0b2f7Stbbdev     static_assert(utils::is_forward_iterator<typename container_type::iterator>::value,
10951c0b2f7Stbbdev                   "Incorrect container iterator member type");
11051c0b2f7Stbbdev     static_assert(!std::is_const<typename container_type::iterator::value_type>::value,
11151c0b2f7Stbbdev                   "Incorrect container iterator member type");
11251c0b2f7Stbbdev     static_assert(utils::is_forward_iterator<typename container_type::const_iterator>::value,
11351c0b2f7Stbbdev                   "Incorrect container const_iterator member type");
11451c0b2f7Stbbdev     static_assert(std::is_const<typename container_type::const_iterator::value_type>::value,
11551c0b2f7Stbbdev                   "Incorrect container iterator member type");
11651c0b2f7Stbbdev     static_assert(utils::is_forward_iterator<typename container_type::local_iterator>::value,
11751c0b2f7Stbbdev                   "Incorrect container local_iterator member type");
11851c0b2f7Stbbdev     static_assert(!std::is_const<typename container_type::local_iterator::value_type>::value,
11951c0b2f7Stbbdev                   "Incorrect container local_iterator member type");
12051c0b2f7Stbbdev     static_assert(utils::is_forward_iterator<typename container_type::const_local_iterator>::value,
12151c0b2f7Stbbdev                   "Incorrect container const_local_iterator member type");
12251c0b2f7Stbbdev     static_assert(std::is_const<typename container_type::const_local_iterator::value_type>::value,
12351c0b2f7Stbbdev                   "Incorrect container const_local_iterator member type");
12451c0b2f7Stbbdev }
12551c0b2f7Stbbdev 
12651c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
12751c0b2f7Stbbdev template <template <typename...> typename TMap>
test_deduction_guides()12851c0b2f7Stbbdev void test_deduction_guides() {
12951c0b2f7Stbbdev     using ComplexType = std::pair<int, std::string>;
13051c0b2f7Stbbdev     using ComplexTypeConst = std::pair<const int, std::string>;
13151c0b2f7Stbbdev     std::vector<ComplexType> v;
13251c0b2f7Stbbdev     auto l = { ComplexTypeConst(1, "one"), ComplexTypeConst(2, "two")};
13351c0b2f7Stbbdev     using custom_allocator_type = std::allocator<ComplexTypeConst>;
13451c0b2f7Stbbdev 
13551c0b2f7Stbbdev     // check TMap(InputIterator, InputIterator)
13651c0b2f7Stbbdev     TMap m0(v.begin(), v.end());
13751c0b2f7Stbbdev     static_assert(std::is_same<decltype(m0), TMap<int, std::string>>::value);
13851c0b2f7Stbbdev 
13951c0b2f7Stbbdev     // check TMap(InputIterator, InputIterator, size_t)
14051c0b2f7Stbbdev     TMap m1(v.begin(), v.end(), 1);
14151c0b2f7Stbbdev     static_assert(std::is_same<decltype(m1), TMap<int, std::string>>::value);
14251c0b2f7Stbbdev 
14351c0b2f7Stbbdev     // check TMap(InputIterator, InputIterator, size_t, Hasher)
14451c0b2f7Stbbdev     TMap m2(v.begin(), v.end(), 4, degenerate_hash<int>());
14551c0b2f7Stbbdev     static_assert(std::is_same<decltype(m2), TMap<int, std::string, degenerate_hash<int>>>::value);
14651c0b2f7Stbbdev 
14751c0b2f7Stbbdev     // check TMap(InputIterator, InputIterator, size_t, Hasher, Equality)
14851c0b2f7Stbbdev     TMap m3(v.begin(), v.end(), 4, degenerate_hash<int>(), std::less<int>());
14951c0b2f7Stbbdev     static_assert(std::is_same<decltype(m3), TMap<int, std::string, degenerate_hash<int>, std::less<int>>>::value);
15051c0b2f7Stbbdev 
15151c0b2f7Stbbdev     // check TMap(InputIterator, InputIterator, size_t, Hasher, Equality, Allocator)
15251c0b2f7Stbbdev     TMap m4(v.begin(), v.end(), 4, degenerate_hash<int>(), std::less<int>(), custom_allocator_type{});
15351c0b2f7Stbbdev     static_assert(std::is_same<decltype(m4), TMap<int, std::string, degenerate_hash<int>,
15451c0b2f7Stbbdev         std::less<int>, custom_allocator_type>>::value);
15551c0b2f7Stbbdev 
15651c0b2f7Stbbdev     // check TMap(InputIterator, InputIterator, size_t, Allocator)
15751c0b2f7Stbbdev     TMap m5(v.begin(), v.end(), 5, custom_allocator_type{});
15851c0b2f7Stbbdev     static_assert(std::is_same<decltype(m5), TMap<int, std::string, std::hash<int>,
15951c0b2f7Stbbdev         std::equal_to<int>, custom_allocator_type>>::value);
16051c0b2f7Stbbdev 
16151c0b2f7Stbbdev     // check TMap(InputIterator, InputIterator, size_t, Hasher, Allocator)
16251c0b2f7Stbbdev     TMap m6(v.begin(), v.end(), 4, degenerate_hash<int>(), custom_allocator_type{});
16351c0b2f7Stbbdev     static_assert(std::is_same<decltype(m6), TMap<int, std::string, degenerate_hash<int>,
16451c0b2f7Stbbdev         std::equal_to<int>, custom_allocator_type>>::value);
16551c0b2f7Stbbdev 
16651c0b2f7Stbbdev     // check TMap(std::initializer_list)
16751c0b2f7Stbbdev     TMap m7(l);
16851c0b2f7Stbbdev     static_assert(std::is_same<decltype(m7), TMap<int, std::string>>::value);
16951c0b2f7Stbbdev 
17051c0b2f7Stbbdev     // check TMap(std::initializer_list, size_t)
17151c0b2f7Stbbdev     TMap m8(l, 1);
17251c0b2f7Stbbdev     static_assert(std::is_same<decltype(m8), TMap<int, std::string>>::value);
17351c0b2f7Stbbdev 
17451c0b2f7Stbbdev     // check TMap(std::initializer_list, size_t, Hasher)
17551c0b2f7Stbbdev     TMap m9(l, 4, degenerate_hash<int>());
17651c0b2f7Stbbdev     static_assert(std::is_same<decltype(m9), TMap<int, std::string, degenerate_hash<int>>>::value);
17751c0b2f7Stbbdev 
17851c0b2f7Stbbdev     // check TMap(std::initializer_list, size_t, Hasher, Equality)
17951c0b2f7Stbbdev     TMap m10(l, 4, degenerate_hash<int>(), std::less<int>());
18051c0b2f7Stbbdev     static_assert(std::is_same<decltype(m10), TMap<int, std::string, degenerate_hash<int>, std::less<int>>>::value);
18151c0b2f7Stbbdev 
18251c0b2f7Stbbdev     // check TMap(std::initializer_list, size_t, Hasher, Equality, Allocator)
18351c0b2f7Stbbdev     TMap m11(l, 4, degenerate_hash<int>(), std::less<int>(), custom_allocator_type{});
18451c0b2f7Stbbdev     static_assert(std::is_same<decltype(m11), TMap<int, std::string, degenerate_hash<int>,
18551c0b2f7Stbbdev         std::less<int>, custom_allocator_type>>::value);
18651c0b2f7Stbbdev 
18751c0b2f7Stbbdev     // check TMap(std::initializer_list, size_t, Allocator)
18851c0b2f7Stbbdev     TMap m12(l, 4, custom_allocator_type{});
18951c0b2f7Stbbdev     static_assert(std::is_same<decltype(m12), TMap<int, std::string, std::hash<int>,
19051c0b2f7Stbbdev         std::equal_to<int>, custom_allocator_type>>::value);
19151c0b2f7Stbbdev 
19251c0b2f7Stbbdev     // check TMap(std::initializer_list, size_t, Hasher, Allocator)
19351c0b2f7Stbbdev     TMap m13(l, 4, degenerate_hash<int>(), custom_allocator_type{});
19451c0b2f7Stbbdev     static_assert(std::is_same<decltype(m13), TMap<int, std::string, degenerate_hash<int>,
19551c0b2f7Stbbdev         std::equal_to<int>, custom_allocator_type>>::value);
19651c0b2f7Stbbdev 
19751c0b2f7Stbbdev     // check TMap(TMap &)
19851c0b2f7Stbbdev     TMap m14(m1);
19951c0b2f7Stbbdev     static_assert(std::is_same<decltype(m14), decltype(m1)>::value);
20051c0b2f7Stbbdev 
20151c0b2f7Stbbdev     // check TMap(TMap &, Allocator)
20251c0b2f7Stbbdev     // TODO: investigate why no implicit deduction guides generated for this ctor
20351c0b2f7Stbbdev     TMap m15(m5, custom_allocator_type{});
20451c0b2f7Stbbdev     static_assert(std::is_same<decltype(m15), decltype(m5)>::value);
20551c0b2f7Stbbdev 
20651c0b2f7Stbbdev     // check TMap(TMap &&)
20751c0b2f7Stbbdev     TMap m16(std::move(m1));
20851c0b2f7Stbbdev     static_assert(std::is_same<decltype(m16), decltype(m1)>::value);
20951c0b2f7Stbbdev 
21051c0b2f7Stbbdev     // check TMap(TMap &&, Allocator)
21151c0b2f7Stbbdev     // TODO: investigate why no implicit deduction guides generated for this ctor
21251c0b2f7Stbbdev     TMap m17(std::move(m5), custom_allocator_type{});
21351c0b2f7Stbbdev     static_assert(std::is_same<decltype(m17), decltype(m5)>::value);
21451c0b2f7Stbbdev }
21551c0b2f7Stbbdev #endif
21651c0b2f7Stbbdev 
test_heterogeneous_functions()21751c0b2f7Stbbdev void test_heterogeneous_functions() {
21849e08aacStbbdev     check_heterogeneous_functions_key_int<oneapi::tbb::concurrent_unordered_map, int, int>();
21949e08aacStbbdev     check_heterogeneous_functions_key_int<oneapi::tbb::concurrent_unordered_multimap, int, int>();
22049e08aacStbbdev     check_heterogeneous_functions_key_string<oneapi::tbb::concurrent_unordered_map, std::string, std::string>();
22149e08aacStbbdev     check_heterogeneous_functions_key_string<oneapi::tbb::concurrent_unordered_multimap, std::string, std::string>();
22251c0b2f7Stbbdev }
22351c0b2f7Stbbdev 
22451c0b2f7Stbbdev struct CumapTraits : UnorderedMoveTraitsBase {
22551c0b2f7Stbbdev     template <typename T, typename Allocator>
22649e08aacStbbdev     using container_type = oneapi::tbb::concurrent_unordered_map<T, T, std::hash<T>, std::equal_to<T>, Allocator>;
22751c0b2f7Stbbdev 
22851c0b2f7Stbbdev     template <typename T>
22951c0b2f7Stbbdev     using container_value_type = std::pair<const T, T>;
23051c0b2f7Stbbdev 
23151c0b2f7Stbbdev     using init_iterator_type = move_support_tests::FooPairIterator;
23251c0b2f7Stbbdev }; // struct CumapTraits
23351c0b2f7Stbbdev 
23451c0b2f7Stbbdev struct CumultimapTraits : UnorderedMoveTraitsBase {
23551c0b2f7Stbbdev     template <typename T, typename Allocator>
23649e08aacStbbdev     using container_type = oneapi::tbb::concurrent_unordered_multimap<T, T, std::hash<T>, std::equal_to<T>, Allocator>;
23751c0b2f7Stbbdev 
23851c0b2f7Stbbdev     template <typename T>
23951c0b2f7Stbbdev     using container_value_type = std::pair<const T, T>;
24051c0b2f7Stbbdev 
24151c0b2f7Stbbdev     using init_iterator_type = move_support_tests::FooPairIterator;
24251c0b2f7Stbbdev }; // struct CumultimapTraits
24351c0b2f7Stbbdev 
24451c0b2f7Stbbdev //! Testing concurrent_unordered_map member types
24551c0b2f7Stbbdev //! \brief \ref interface \ref requirement
24651c0b2f7Stbbdev TEST_CASE("concurrent_unordered_map member types") {
24749e08aacStbbdev     test_member_types<oneapi::tbb::concurrent_unordered_map>();
24851c0b2f7Stbbdev }
24951c0b2f7Stbbdev 
25051c0b2f7Stbbdev //! Testing requirements of concurrent_unordered_map
25151c0b2f7Stbbdev //! \brief \ref interface \ref requirement
25251c0b2f7Stbbdev TEST_CASE("concurrent_unordered_map requirements") {
25351c0b2f7Stbbdev     test_basic<map_type>();
25451c0b2f7Stbbdev }
25551c0b2f7Stbbdev 
25651c0b2f7Stbbdev //! Testing multithreading support in concurrent_unordered_map
25751c0b2f7Stbbdev //! \brief \ref requirement
25851c0b2f7Stbbdev TEST_CASE("concurrent_unordered_map multithreading support") {
25951c0b2f7Stbbdev     test_concurrent<map_type>();
26051c0b2f7Stbbdev }
26151c0b2f7Stbbdev 
26251c0b2f7Stbbdev //! Testing move constructors and assignment operator in concurrent_unordered_map
26351c0b2f7Stbbdev //! \brief \ref interface \ref requirement
26451c0b2f7Stbbdev TEST_CASE("concurrent_unordered_map move semantics support") {
26551c0b2f7Stbbdev     test_rvalue_ref_support<CumapTraits>();
26651c0b2f7Stbbdev }
26751c0b2f7Stbbdev 
26851c0b2f7Stbbdev //! Testing std::initializer_list constructors and modifiers in concurrent_unordered_map
26951c0b2f7Stbbdev //! \brief \ref interface \ref requirement
27051c0b2f7Stbbdev TEST_CASE("std::initializer_list support in concurrent_unordered_map") {
27151c0b2f7Stbbdev     test_initializer_list_support<map_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}});
27251c0b2f7Stbbdev }
27351c0b2f7Stbbdev 
27451c0b2f7Stbbdev //! Testing node handling in concurrent_unordered_map
27551c0b2f7Stbbdev //! \brief \ref interface \ref requirement
27651c0b2f7Stbbdev TEST_CASE("node handling support in concurrent_unordered_map") {
27751c0b2f7Stbbdev     node_handling_tests::test_node_handling_support<map_type>();
27851c0b2f7Stbbdev }
27951c0b2f7Stbbdev 
28051c0b2f7Stbbdev //! Testing std::allocator_traits support in concurrent_unordered_map
28151c0b2f7Stbbdev //! \brief \ref interface \ref requirement
28251c0b2f7Stbbdev TEST_CASE("std::allocator_traits support in concurrent_unordered_map") {
28351c0b2f7Stbbdev     test_allocator_traits_support<CumapTraits>();
28451c0b2f7Stbbdev }
28551c0b2f7Stbbdev 
28651c0b2f7Stbbdev //! Testing heterogeneous overloads in concurrent_unordered_map
28751c0b2f7Stbbdev //! \brief \ref interface \ref requirement
28851c0b2f7Stbbdev TEST_CASE("heterogeneous overloads in concurrent_unordered_map") {
28949e08aacStbbdev     check_heterogeneous_functions_key_int<oneapi::tbb::concurrent_unordered_map, int, int>();
29049e08aacStbbdev     check_heterogeneous_functions_key_string<oneapi::tbb::concurrent_unordered_map, std::string, std::string>();
29151c0b2f7Stbbdev }
29251c0b2f7Stbbdev 
29351c0b2f7Stbbdev //! Testing insert overloads with generic pair in concurrent_unordered_map
29451c0b2f7Stbbdev //! \brief \ref interface \ref requirement
29551c0b2f7Stbbdev TEST_CASE("insertion by generic pair in concurrent_unordered_map") {
29649e08aacStbbdev     test_insert_by_generic_pair<oneapi::tbb::concurrent_unordered_map>();
29751c0b2f7Stbbdev }
29851c0b2f7Stbbdev 
29951c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
30051c0b2f7Stbbdev //! Testing Class Template Argument Deduction in concurrent_unordered_map
30151c0b2f7Stbbdev //! \brief \ref interface \ref requirement
30251c0b2f7Stbbdev TEST_CASE("CTAD support in concurrent_unordered_map") {
30349e08aacStbbdev     test_deduction_guides<oneapi::tbb::concurrent_unordered_map>();
30451c0b2f7Stbbdev }
30551c0b2f7Stbbdev #endif
30651c0b2f7Stbbdev 
307*b15aabb3Stbbdev //! Testing comparisons in concurrent_unordered_map
308*b15aabb3Stbbdev //! \brief \ref interface \ref requirement
309*b15aabb3Stbbdev TEST_CASE("concurrent_unordered_map comparisons") {
310*b15aabb3Stbbdev     test_map_comparisons<oneapi::tbb::concurrent_unordered_map>();
311*b15aabb3Stbbdev }
312*b15aabb3Stbbdev 
31351c0b2f7Stbbdev //! Testing concurrent_unordered_multimap member types
31451c0b2f7Stbbdev //! \brief \ref interface \ref requirement
31551c0b2f7Stbbdev TEST_CASE("concurrent_unordered_multimap member types") {
31649e08aacStbbdev     test_member_types<oneapi::tbb::concurrent_unordered_multimap>();
31751c0b2f7Stbbdev }
31851c0b2f7Stbbdev 
31951c0b2f7Stbbdev //! Testing requirements of concurrent_unordered_multimap
32051c0b2f7Stbbdev //! \brief \ref interface \ref requirement
32151c0b2f7Stbbdev TEST_CASE("concurrent_unordered_multimap requirements") {
32251c0b2f7Stbbdev     test_basic<multimap_type>();
32351c0b2f7Stbbdev }
32451c0b2f7Stbbdev 
32551c0b2f7Stbbdev //! Testing multithreading support in concurrent_unordered_multimap
32651c0b2f7Stbbdev //! \brief \ref requirement
32751c0b2f7Stbbdev TEST_CASE("concurrent_unordered_multimap multithreading support") {
32851c0b2f7Stbbdev     test_concurrent<multimap_type>();
32951c0b2f7Stbbdev }
33051c0b2f7Stbbdev 
33151c0b2f7Stbbdev //! Testing move constructors and assignment operator in concurrent_unordered_multimap
33251c0b2f7Stbbdev //! \brief \ref interface \ref requirement
33351c0b2f7Stbbdev TEST_CASE("concurrent_unordered_multimap move semantics support") {
33451c0b2f7Stbbdev     test_rvalue_ref_support<CumultimapTraits>();
33551c0b2f7Stbbdev }
33651c0b2f7Stbbdev 
33751c0b2f7Stbbdev //! Testing std::initializer_list constructors and modifiers in concurrent_unordered_multimap
33851c0b2f7Stbbdev //! \brief \ref interface \ref requirement
33951c0b2f7Stbbdev TEST_CASE("std::initializer_list support in concurrent_unordered_multimap") {
34051c0b2f7Stbbdev     test_initializer_list_support<multimap_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 40}});
34151c0b2f7Stbbdev }
34251c0b2f7Stbbdev 
34351c0b2f7Stbbdev //! Testing node handling support in concurrent_unordered_multimap
34451c0b2f7Stbbdev //! \brief \ref interface \ref requirement
34551c0b2f7Stbbdev TEST_CASE("node handling support in concurrent_unordered_multimap") {
34651c0b2f7Stbbdev     node_handling_tests::test_node_handling_support<multimap_type>();
34751c0b2f7Stbbdev }
34851c0b2f7Stbbdev 
34951c0b2f7Stbbdev //! Testing std::allocator_traits support in concurrent_unordered_multimap
35051c0b2f7Stbbdev //! \brief \ref interface \ref requirement
35151c0b2f7Stbbdev TEST_CASE("std::allocator_traits support in concurrent_unordered_multimap") {
35251c0b2f7Stbbdev     test_allocator_traits_support<CumultimapTraits>();
35351c0b2f7Stbbdev }
35451c0b2f7Stbbdev 
35551c0b2f7Stbbdev //! Testing heterogeneous overloads in concurrent_unordered_multimap
35651c0b2f7Stbbdev //! \brief \ref interface \ref requirement
35751c0b2f7Stbbdev TEST_CASE("heterogeneous overloads in concurrent_unordered_multimap") {
35849e08aacStbbdev     check_heterogeneous_functions_key_int<oneapi::tbb::concurrent_unordered_multimap, int, int>();
35949e08aacStbbdev     check_heterogeneous_functions_key_string<oneapi::tbb::concurrent_unordered_multimap, std::string, std::string>();
36051c0b2f7Stbbdev }
36151c0b2f7Stbbdev 
36251c0b2f7Stbbdev //! Testing insert overloads with generic pair in concurrent_unordered_multimap
36351c0b2f7Stbbdev //! \brief \ref interface \ref requirement
36451c0b2f7Stbbdev TEST_CASE("insertion by generic pair in concurrent_unordered_multimap") {
36549e08aacStbbdev     test_insert_by_generic_pair<oneapi::tbb::concurrent_unordered_multimap>();
36651c0b2f7Stbbdev }
36751c0b2f7Stbbdev 
36851c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
36951c0b2f7Stbbdev //! Testing Class Template Argument Deduction in concurrent_unordered_multimap
37051c0b2f7Stbbdev //! \brief \ref interface \ref requirement
37151c0b2f7Stbbdev TEST_CASE("CTAD support in concurrent_unordered_multimap") {
37249e08aacStbbdev     test_deduction_guides<oneapi::tbb::concurrent_unordered_multimap>();
37351c0b2f7Stbbdev }
37451c0b2f7Stbbdev #endif
37551c0b2f7Stbbdev 
376*b15aabb3Stbbdev //! Testing comparisons in concurrent_unordered_multimap
377*b15aabb3Stbbdev //! \brief \ref interface \ref requirement
378*b15aabb3Stbbdev TEST_CASE("concurrent_unordered_multimap comparisons") {
379*b15aabb3Stbbdev     test_map_comparisons<oneapi::tbb::concurrent_unordered_multimap>();
380*b15aabb3Stbbdev }
381*b15aabb3Stbbdev 
38251c0b2f7Stbbdev //! Testing of merge operations in concurrent_unordered_map and concurrent_unordered_multimap
38351c0b2f7Stbbdev //! \brief \ref interface \ref requirement
38451c0b2f7Stbbdev TEST_CASE("merge operations") {
38551c0b2f7Stbbdev     node_handling_tests::test_merge<map_type, multimap_type>(1000);
38651c0b2f7Stbbdev }
387