151c0b2f7Stbbdev /*
2*b15aabb3Stbbdev     Copyright (c) 2019-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 
2151c0b2f7Stbbdev #ifndef NOMINMAX
2251c0b2f7Stbbdev #define NOMINMAX
2351c0b2f7Stbbdev #endif
2449e08aacStbbdev #include "oneapi/tbb/concurrent_map.h"
2551c0b2f7Stbbdev #include <common/test.h>
2651c0b2f7Stbbdev #include <common/utils.h>
2751c0b2f7Stbbdev #include <common/concurrent_ordered_common.h>
2851c0b2f7Stbbdev #include <memory>
2951c0b2f7Stbbdev #include <type_traits>
3051c0b2f7Stbbdev 
3151c0b2f7Stbbdev //! \file conformance_concurrent_map.cpp
3251c0b2f7Stbbdev //! \brief Test for [containers.concurrent_map containers.concurrent_multimap] specifications
3351c0b2f7Stbbdev 
3451c0b2f7Stbbdev template <typename... Args>
3549e08aacStbbdev struct AllowMultimapping<oneapi::tbb::concurrent_multimap<Args...>> : std::true_type {};
3651c0b2f7Stbbdev 
3751c0b2f7Stbbdev template <typename Key, typename Mapped>
3851c0b2f7Stbbdev using Allocator = LocalCountingAllocator<std::allocator<std::pair<const Key, Mapped>>>;
3951c0b2f7Stbbdev 
4049e08aacStbbdev using map_type = oneapi::tbb::concurrent_map<int, int, std::less<int>, Allocator<int, int>>;
4149e08aacStbbdev using multimap_type = oneapi::tbb::concurrent_multimap<int, int, std::less<int>, Allocator<int, int>>;
4251c0b2f7Stbbdev 
4351c0b2f7Stbbdev template <>
4451c0b2f7Stbbdev struct SpecialTests<map_type> {
TestSpecialTests4551c0b2f7Stbbdev     static void Test() {
4651c0b2f7Stbbdev         SpecialMapTests<map_type>();
4751c0b2f7Stbbdev     }
4851c0b2f7Stbbdev };
4951c0b2f7Stbbdev 
5051c0b2f7Stbbdev template <>
5151c0b2f7Stbbdev struct SpecialTests<multimap_type> {
TestSpecialTests5251c0b2f7Stbbdev     static void Test() {
5351c0b2f7Stbbdev         SpecialMultiMapTests<multimap_type>();
5451c0b2f7Stbbdev     }
5551c0b2f7Stbbdev };
5651c0b2f7Stbbdev 
5751c0b2f7Stbbdev template <template <typename...> class ContainerType>
test_member_types()5851c0b2f7Stbbdev void test_member_types() {
5951c0b2f7Stbbdev     using default_container_type = ContainerType<int, int>;
6051c0b2f7Stbbdev     static_assert(std::is_same<typename default_container_type::key_compare, std::less<int>>::value,
6151c0b2f7Stbbdev                   "Incorrect default template comparator");
6249e08aacStbbdev     static_assert(std::is_same<typename default_container_type::allocator_type, oneapi::tbb::tbb_allocator<std::pair<const int, int>>>::value,
6351c0b2f7Stbbdev                   "Incorrect default template allocator");
6451c0b2f7Stbbdev 
6551c0b2f7Stbbdev     auto test_comparator = [](const int&, const int&)->bool { return true; };
6651c0b2f7Stbbdev     using test_allocator_type = std::allocator<std::pair<const int, int>>;
6751c0b2f7Stbbdev 
6851c0b2f7Stbbdev     using container_type = ContainerType<int, int, decltype(test_comparator), test_allocator_type>;
6951c0b2f7Stbbdev 
7051c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::key_type, int>::value,
7151c0b2f7Stbbdev                   "Incorrect container key_type member type");
7251c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::mapped_type, int>::value,
7351c0b2f7Stbbdev                   "Incorrect container mapped_type member type");
7451c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::value_type, std::pair<const int, int>>::value,
7551c0b2f7Stbbdev                   "Incorrect container value_type member type");
7651c0b2f7Stbbdev 
7751c0b2f7Stbbdev     static_assert(std::is_unsigned<typename container_type::size_type>::value,
7851c0b2f7Stbbdev                   "Incorrect container size_type member type");
7951c0b2f7Stbbdev     static_assert(std::is_signed<typename container_type::difference_type>::value,
8051c0b2f7Stbbdev                   "Incorrect container difference_type member type");
8151c0b2f7Stbbdev 
8251c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::key_compare, decltype(test_comparator)>::value,
8351c0b2f7Stbbdev                   "Incorrect container key_compare member type");
8451c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::allocator_type, test_allocator_type>::value,
8551c0b2f7Stbbdev                   "Incorrect container allocator_type member type");
8651c0b2f7Stbbdev 
8751c0b2f7Stbbdev     using value_type = typename container_type::value_type;
8851c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::reference, value_type&>::value,
8951c0b2f7Stbbdev                   "Incorrect container reference member type");
9051c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::const_reference, const value_type&>::value,
9151c0b2f7Stbbdev                   "Incorrect container const_reference member type");
9251c0b2f7Stbbdev     using allocator_type = typename container_type::allocator_type;
9351c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::pointer, typename std::allocator_traits<allocator_type>::pointer>::value,
9451c0b2f7Stbbdev                   "Incorrect container pointer member type");
9551c0b2f7Stbbdev     static_assert(std::is_same<typename container_type::const_pointer, typename std::allocator_traits<allocator_type>::const_pointer>::value,
9651c0b2f7Stbbdev                   "Incorrect container const_pointer member type");
9751c0b2f7Stbbdev 
9851c0b2f7Stbbdev     static_assert(utils::is_forward_iterator<typename container_type::iterator>::value,
9951c0b2f7Stbbdev                   "Incorrect container iterator member type");
10051c0b2f7Stbbdev     static_assert(!std::is_const<typename container_type::iterator::value_type>::value,
10151c0b2f7Stbbdev                   "Incorrect container iterator member type");
10251c0b2f7Stbbdev     static_assert(utils::is_forward_iterator<typename container_type::const_iterator>::value,
10351c0b2f7Stbbdev                   "Incorrect container const_iterator member type");
10451c0b2f7Stbbdev     static_assert(std::is_const<typename container_type::const_iterator::value_type>::value,
10551c0b2f7Stbbdev                   "Incorrect container const_iterator member type");
10651c0b2f7Stbbdev }
10751c0b2f7Stbbdev 
10851c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
10951c0b2f7Stbbdev template <template <typename...> typename TMap>
test_deduction_guides()11051c0b2f7Stbbdev void test_deduction_guides() {
11151c0b2f7Stbbdev     std::vector<std::pair<int, int>> v(10, {0, 0});
11251c0b2f7Stbbdev     TMap map(v.begin(), v.end());
11351c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map), TMap<int, int> >, "WRONG\n");
11451c0b2f7Stbbdev 
11551c0b2f7Stbbdev     std::greater<int> compare;
11651c0b2f7Stbbdev     std::allocator<std::pair<const int, int>> allocator;
11751c0b2f7Stbbdev     TMap map2(v.begin(), v.end(), compare);
11851c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map2), TMap<int, int, decltype(compare)> >, "WRONG\n");
11951c0b2f7Stbbdev 
12051c0b2f7Stbbdev     TMap map3(v.begin(), v.end(), allocator);
12151c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map3), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n");
12251c0b2f7Stbbdev 
12351c0b2f7Stbbdev     TMap map4(v.begin(), v.end(), compare, allocator);
12451c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map4), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n");
12551c0b2f7Stbbdev 
12651c0b2f7Stbbdev     using pair_t = std::pair<const int, int>;
12751c0b2f7Stbbdev     auto init = { pair_t{1, 1}, pair_t{2, 2}, pair_t{3, 3} };
12851c0b2f7Stbbdev     TMap map5(init);
12951c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map5), TMap<int, int> >, "WRONG\n");
13051c0b2f7Stbbdev 
13151c0b2f7Stbbdev     TMap map6(init, compare);
13251c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map6), TMap<int, int, decltype(compare)> >, "WRONG\n");
13351c0b2f7Stbbdev 
13451c0b2f7Stbbdev     TMap map7(init, allocator);
13551c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map7), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n");
13651c0b2f7Stbbdev 
13751c0b2f7Stbbdev     TMap map8(init, compare, allocator);
13851c0b2f7Stbbdev     static_assert(std::is_same_v<decltype(map8), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n");
13951c0b2f7Stbbdev }
14051c0b2f7Stbbdev #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
14151c0b2f7Stbbdev 
14251c0b2f7Stbbdev template <template <typename...> class MapType>
test_heterogeneous_functions()14351c0b2f7Stbbdev void test_heterogeneous_functions() {
14451c0b2f7Stbbdev     check_heterogeneous_functions_key_int<MapType, int, int>();
14551c0b2f7Stbbdev     check_heterogeneous_functions_key_string<MapType, std::string, std::string>();
14651c0b2f7Stbbdev     check_heterogeneous_bound_functions<MapType<int, int, TransparentLess>>();
14751c0b2f7Stbbdev }
14851c0b2f7Stbbdev 
14951c0b2f7Stbbdev struct COMapTraits : OrderedMoveTraitsBase {
15051c0b2f7Stbbdev     template <typename T, typename Allocator>
15149e08aacStbbdev     using container_type = oneapi::tbb::concurrent_map<T, T, std::less<T>, Allocator>;
15251c0b2f7Stbbdev 
15351c0b2f7Stbbdev     template <typename T>
15451c0b2f7Stbbdev     using container_value_type = std::pair<const T, T>;
15551c0b2f7Stbbdev 
15651c0b2f7Stbbdev     using init_iterator_type = move_support_tests::FooPairIterator;
15751c0b2f7Stbbdev }; // struct COMapTraits
15851c0b2f7Stbbdev 
15951c0b2f7Stbbdev struct COMultimapTraits : OrderedMoveTraitsBase {
16051c0b2f7Stbbdev     template <typename T, typename Allocator>
16149e08aacStbbdev     using container_type = oneapi::tbb::concurrent_multimap<T, T, std::less<T>, Allocator>;
16251c0b2f7Stbbdev 
16351c0b2f7Stbbdev     template <typename T>
16451c0b2f7Stbbdev     using container_value_type = std::pair<const T, T>;
16551c0b2f7Stbbdev 
16651c0b2f7Stbbdev     using init_iterator_type = move_support_tests::FooPairIterator;
16751c0b2f7Stbbdev }; // struct COMultimapTraits
16851c0b2f7Stbbdev 
16951c0b2f7Stbbdev //! Testing concurrent_map member types
17051c0b2f7Stbbdev //! \brief \ref interface \ref requirement
17151c0b2f7Stbbdev TEST_CASE("concurrent_map member types") {
17249e08aacStbbdev     test_member_types<oneapi::tbb::concurrent_map>();
17351c0b2f7Stbbdev }
17451c0b2f7Stbbdev 
17551c0b2f7Stbbdev //! Testing requirements of concurrent_map
17651c0b2f7Stbbdev //! \brief \ref interface \ref requirement
17751c0b2f7Stbbdev TEST_CASE("concurrent_map requirements") {
17851c0b2f7Stbbdev     test_basic<map_type>();
17951c0b2f7Stbbdev }
18051c0b2f7Stbbdev 
18151c0b2f7Stbbdev //! Testing multithreading support in concurrent_map
18251c0b2f7Stbbdev //! \brief \ref requirement
18351c0b2f7Stbbdev TEST_CASE("concurrent_map multithreading support") {
18451c0b2f7Stbbdev     test_concurrent<map_type>();
18551c0b2f7Stbbdev }
18651c0b2f7Stbbdev 
18751c0b2f7Stbbdev //! Testing move constructors and assignment operator in concurrent_map
18851c0b2f7Stbbdev //! \brief \ref interface \ref requirement
18951c0b2f7Stbbdev TEST_CASE("concurrent_map move semantics support") {
19051c0b2f7Stbbdev     test_rvalue_ref_support<COMapTraits>();
19151c0b2f7Stbbdev }
19251c0b2f7Stbbdev 
19351c0b2f7Stbbdev //! Testing std::initializer_list constructors and modifiers in concurrent_map
19451c0b2f7Stbbdev //! \brief \ref interface \ref requirement
19551c0b2f7Stbbdev TEST_CASE("std::initializer_list support in concurrent_map") {
19651c0b2f7Stbbdev     test_initializer_list_support<map_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}});
19751c0b2f7Stbbdev }
19851c0b2f7Stbbdev 
19951c0b2f7Stbbdev //! Testing node handling in concurrent_map
20051c0b2f7Stbbdev //! \brief \ref interface \ref requirement
20151c0b2f7Stbbdev TEST_CASE("node handling support in concurrent_map") {
20251c0b2f7Stbbdev     node_handling_tests::test_node_handling_support<map_type>();
20351c0b2f7Stbbdev }
20451c0b2f7Stbbdev 
20551c0b2f7Stbbdev //! Testing std::allocator_traits support in concurrent_map
20651c0b2f7Stbbdev //! \brief \ref interface \ref requirement
20751c0b2f7Stbbdev TEST_CASE("std::allocator_traits support in concurrent_map") {
20851c0b2f7Stbbdev     test_allocator_traits_support<COMapTraits>();
20951c0b2f7Stbbdev }
21051c0b2f7Stbbdev 
21151c0b2f7Stbbdev //! Testing heterogeneous overloads in concurrent_map
21251c0b2f7Stbbdev //! \brief \ref interface \ref requirement
21351c0b2f7Stbbdev TEST_CASE("heterogeneous overloads in concurrent_map") {
21449e08aacStbbdev     test_heterogeneous_functions<oneapi::tbb::concurrent_map>();
21551c0b2f7Stbbdev }
21651c0b2f7Stbbdev 
21751c0b2f7Stbbdev //! Testing insert overloads with generic pair in concurrent_map
21851c0b2f7Stbbdev //! \brief \ref interface \ref requirement
21951c0b2f7Stbbdev TEST_CASE("insertion by generic pair in concurrent_map") {
22049e08aacStbbdev     test_insert_by_generic_pair<oneapi::tbb::concurrent_map>();
22151c0b2f7Stbbdev }
22251c0b2f7Stbbdev 
22351c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
22451c0b2f7Stbbdev //! Testing Class Template Argument Deduction in concurrent_map
22551c0b2f7Stbbdev //! \brief \ref interface \ref requirement
22651c0b2f7Stbbdev TEST_CASE("CTAD support in concurrent_map") {
22749e08aacStbbdev     test_deduction_guides<oneapi::tbb::concurrent_map>();
22851c0b2f7Stbbdev }
22951c0b2f7Stbbdev #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
23051c0b2f7Stbbdev 
231*b15aabb3Stbbdev //! Testing comparisons of concurrent_map
23251c0b2f7Stbbdev //! \brief \ref interface \ref requirement
23351c0b2f7Stbbdev TEST_CASE("test concurrent_map comparisons") {
23449e08aacStbbdev     test_map_comparisons<oneapi::tbb::concurrent_map>();
23551c0b2f7Stbbdev }
23651c0b2f7Stbbdev 
23751c0b2f7Stbbdev //! Testing concurrent_multimap member types
23851c0b2f7Stbbdev //! \brief \ref interface \ref requirement
23951c0b2f7Stbbdev TEST_CASE("concurrent_multimap member types") {
24049e08aacStbbdev     test_member_types<oneapi::tbb::concurrent_multimap>();
24151c0b2f7Stbbdev }
24251c0b2f7Stbbdev 
24351c0b2f7Stbbdev //! Testing requirements of concurrent_multimap
24451c0b2f7Stbbdev //! \brief \ref interface \ref requirement
24551c0b2f7Stbbdev TEST_CASE("concurrent_multimap requirements") {
24651c0b2f7Stbbdev     test_basic<multimap_type>();
24751c0b2f7Stbbdev }
24851c0b2f7Stbbdev 
24951c0b2f7Stbbdev //! Testing multithreading support in concurrent_multimap
25051c0b2f7Stbbdev //! \brief \ref requirement
25151c0b2f7Stbbdev TEST_CASE("concurrent_multimap multithreading support") {
25251c0b2f7Stbbdev     test_concurrent<multimap_type>();
25351c0b2f7Stbbdev }
25451c0b2f7Stbbdev 
25551c0b2f7Stbbdev //! Testing move constructors and assignment operator in concurrent_multimap
25651c0b2f7Stbbdev //! \brief \ref interface \ref requirement
25751c0b2f7Stbbdev TEST_CASE("concurrent_multimap multithreading support") {
25851c0b2f7Stbbdev     test_rvalue_ref_support<COMultimapTraits>();
25951c0b2f7Stbbdev }
26051c0b2f7Stbbdev 
26151c0b2f7Stbbdev //! Testing std::initializer_list constructors and modifiers in concurrent_multimap
26251c0b2f7Stbbdev //! \brief \ref interface \ref requirement
26351c0b2f7Stbbdev TEST_CASE("std::initializer_list support in concurrent_multimap") {
26451c0b2f7Stbbdev     test_initializer_list_support<multimap_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 40}});
26551c0b2f7Stbbdev }
26651c0b2f7Stbbdev 
26751c0b2f7Stbbdev //! Testing node handling support in concurrent_multimap
26851c0b2f7Stbbdev //! \brief \ref interface \ref requirement
26951c0b2f7Stbbdev TEST_CASE("node handling support in concurrent_multimap") {
27051c0b2f7Stbbdev     node_handling_tests::test_node_handling_support<multimap_type>();
27151c0b2f7Stbbdev }
27251c0b2f7Stbbdev 
27351c0b2f7Stbbdev //! Testing std::allocator_traits support in concurrent_multimap
27451c0b2f7Stbbdev //! \brief \ref interface \ref requirement
27551c0b2f7Stbbdev TEST_CASE("std::allocator_traits support in concurrent_multimap") {
27651c0b2f7Stbbdev     test_allocator_traits_support<COMultimapTraits>();
27751c0b2f7Stbbdev }
27851c0b2f7Stbbdev 
27951c0b2f7Stbbdev //! Testing heterogeneous overloads in concurrent_multimap
28051c0b2f7Stbbdev //! \brief \ref interface \ref requirement
28151c0b2f7Stbbdev TEST_CASE("heterogeneous overloads in concurrent_multimap") {
28249e08aacStbbdev     test_heterogeneous_functions<oneapi::tbb::concurrent_multimap>();
28351c0b2f7Stbbdev }
28451c0b2f7Stbbdev 
28551c0b2f7Stbbdev //! Testing insert overloads with generic pair in concurrent_multimap
28651c0b2f7Stbbdev //! \brief \ref interface \ref requirement
28751c0b2f7Stbbdev TEST_CASE("insertion by generic pair in concurrent_multimap") {
28849e08aacStbbdev     test_insert_by_generic_pair<oneapi::tbb::concurrent_multimap>();
28951c0b2f7Stbbdev }
29051c0b2f7Stbbdev 
29151c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
29251c0b2f7Stbbdev //! Testing Class Template Argument Deduction in concurrent_multimap
29351c0b2f7Stbbdev //! \brief \ref interface \ref requirement
29451c0b2f7Stbbdev TEST_CASE("CTAD support in concurrent_multimap") {
29549e08aacStbbdev     test_deduction_guides<oneapi::tbb::concurrent_multimap>();
29651c0b2f7Stbbdev }
29751c0b2f7Stbbdev #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
29851c0b2f7Stbbdev 
29951c0b2f7Stbbdev //! Testing comparison operators in concurrent_multimap
30051c0b2f7Stbbdev //! \brief \ref interface \ref requirement
30151c0b2f7Stbbdev TEST_CASE("test concurrent_multimap comparisons") {
30249e08aacStbbdev     test_map_comparisons<oneapi::tbb::concurrent_multimap>();
30351c0b2f7Stbbdev }
30451c0b2f7Stbbdev 
30551c0b2f7Stbbdev //! Testing of merge operations in concurrent_map and concurrent_multimap
30651c0b2f7Stbbdev //! \brief \ref interface \ref requirement
30751c0b2f7Stbbdev TEST_CASE("merge operations") {
30851c0b2f7Stbbdev     node_handling_tests::test_merge<map_type, multimap_type>(1000);
30951c0b2f7Stbbdev }
310