1 /* 2 Copyright (c) 2019-2021 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 #ifndef NOMINMAX 22 #define NOMINMAX 23 #endif 24 #include "oneapi/tbb/concurrent_map.h" 25 #include <common/test.h> 26 #include <common/utils.h> 27 #include <common/concurrent_ordered_common.h> 28 #include <memory> 29 #include <type_traits> 30 31 //! \file conformance_concurrent_map.cpp 32 //! \brief Test for [containers.concurrent_map containers.concurrent_multimap] specifications 33 34 template <typename... Args> 35 struct AllowMultimapping<oneapi::tbb::concurrent_multimap<Args...>> : std::true_type {}; 36 37 template <typename Key, typename Mapped> 38 using Allocator = LocalCountingAllocator<std::allocator<std::pair<const Key, Mapped>>>; 39 40 using map_type = oneapi::tbb::concurrent_map<int, int, std::less<int>, Allocator<int, int>>; 41 using multimap_type = oneapi::tbb::concurrent_multimap<int, int, std::less<int>, Allocator<int, int>>; 42 43 template <> 44 struct SpecialTests<map_type> { 45 static void Test() { 46 SpecialMapTests<map_type>(); 47 } 48 }; 49 50 template <> 51 struct SpecialTests<multimap_type> { 52 static void Test() { 53 SpecialMultiMapTests<multimap_type>(); 54 } 55 }; 56 57 template <template <typename...> class ContainerType> 58 void test_member_types() { 59 using default_container_type = ContainerType<int, int>; 60 static_assert(std::is_same<typename default_container_type::key_compare, std::less<int>>::value, 61 "Incorrect default template comparator"); 62 static_assert(std::is_same<typename default_container_type::allocator_type, oneapi::tbb::tbb_allocator<std::pair<const int, int>>>::value, 63 "Incorrect default template allocator"); 64 65 auto test_comparator = [](const int&, const int&)->bool { return true; }; 66 using test_allocator_type = std::allocator<std::pair<const int, int>>; 67 68 using container_type = ContainerType<int, int, decltype(test_comparator), test_allocator_type>; 69 70 static_assert(std::is_same<typename container_type::key_type, int>::value, 71 "Incorrect container key_type member type"); 72 static_assert(std::is_same<typename container_type::mapped_type, int>::value, 73 "Incorrect container mapped_type member type"); 74 static_assert(std::is_same<typename container_type::value_type, std::pair<const int, int>>::value, 75 "Incorrect container value_type member type"); 76 77 static_assert(std::is_unsigned<typename container_type::size_type>::value, 78 "Incorrect container size_type member type"); 79 static_assert(std::is_signed<typename container_type::difference_type>::value, 80 "Incorrect container difference_type member type"); 81 82 static_assert(std::is_same<typename container_type::key_compare, decltype(test_comparator)>::value, 83 "Incorrect container key_compare member type"); 84 static_assert(std::is_same<typename container_type::allocator_type, test_allocator_type>::value, 85 "Incorrect container allocator_type member type"); 86 87 using value_type = typename container_type::value_type; 88 static_assert(std::is_same<typename container_type::reference, value_type&>::value, 89 "Incorrect container reference member type"); 90 static_assert(std::is_same<typename container_type::const_reference, const value_type&>::value, 91 "Incorrect container const_reference member type"); 92 using allocator_type = typename container_type::allocator_type; 93 static_assert(std::is_same<typename container_type::pointer, typename std::allocator_traits<allocator_type>::pointer>::value, 94 "Incorrect container pointer member type"); 95 static_assert(std::is_same<typename container_type::const_pointer, typename std::allocator_traits<allocator_type>::const_pointer>::value, 96 "Incorrect container const_pointer member type"); 97 98 static_assert(utils::is_forward_iterator<typename container_type::iterator>::value, 99 "Incorrect container iterator member type"); 100 static_assert(!std::is_const<typename container_type::iterator::value_type>::value, 101 "Incorrect container iterator member type"); 102 static_assert(utils::is_forward_iterator<typename container_type::const_iterator>::value, 103 "Incorrect container const_iterator member type"); 104 static_assert(std::is_const<typename container_type::const_iterator::value_type>::value, 105 "Incorrect container const_iterator member type"); 106 } 107 108 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 109 template <template <typename...> typename TMap> 110 void test_deduction_guides() { 111 std::vector<std::pair<int, int>> v(10, {0, 0}); 112 TMap map(v.begin(), v.end()); 113 static_assert(std::is_same_v<decltype(map), TMap<int, int> >, "WRONG\n"); 114 115 std::greater<int> compare; 116 std::allocator<std::pair<const int, int>> allocator; 117 TMap map2(v.begin(), v.end(), compare); 118 static_assert(std::is_same_v<decltype(map2), TMap<int, int, decltype(compare)> >, "WRONG\n"); 119 120 TMap map3(v.begin(), v.end(), allocator); 121 static_assert(std::is_same_v<decltype(map3), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n"); 122 123 TMap map4(v.begin(), v.end(), compare, allocator); 124 static_assert(std::is_same_v<decltype(map4), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n"); 125 126 using pair_t = std::pair<const int, int>; 127 auto init = { pair_t{1, 1}, pair_t{2, 2}, pair_t{3, 3} }; 128 TMap map5(init); 129 static_assert(std::is_same_v<decltype(map5), TMap<int, int> >, "WRONG\n"); 130 131 TMap map6(init, compare); 132 static_assert(std::is_same_v<decltype(map6), TMap<int, int, decltype(compare)> >, "WRONG\n"); 133 134 TMap map7(init, allocator); 135 static_assert(std::is_same_v<decltype(map7), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n"); 136 137 TMap map8(init, compare, allocator); 138 static_assert(std::is_same_v<decltype(map8), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n"); 139 } 140 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 141 142 template <template <typename...> class MapType> 143 void test_heterogeneous_functions() { 144 check_heterogeneous_functions_key_int<MapType, int, int>(); 145 check_heterogeneous_functions_key_string<MapType, std::string, std::string>(); 146 check_heterogeneous_bound_functions<MapType<int, int, TransparentLess>>(); 147 } 148 149 struct COMapTraits : OrderedMoveTraitsBase { 150 template <typename T, typename Allocator> 151 using container_type = oneapi::tbb::concurrent_map<T, T, std::less<T>, Allocator>; 152 153 template <typename T> 154 using container_value_type = std::pair<const T, T>; 155 156 using init_iterator_type = move_support_tests::FooPairIterator; 157 }; // struct COMapTraits 158 159 struct COMultimapTraits : OrderedMoveTraitsBase { 160 template <typename T, typename Allocator> 161 using container_type = oneapi::tbb::concurrent_multimap<T, T, std::less<T>, Allocator>; 162 163 template <typename T> 164 using container_value_type = std::pair<const T, T>; 165 166 using init_iterator_type = move_support_tests::FooPairIterator; 167 }; // struct COMultimapTraits 168 169 //! Testing concurrent_map member types 170 //! \brief \ref interface \ref requirement 171 TEST_CASE("concurrent_map member types") { 172 test_member_types<oneapi::tbb::concurrent_map>(); 173 } 174 175 //! Testing requirements of concurrent_map 176 //! \brief \ref interface \ref requirement 177 TEST_CASE("concurrent_map requirements") { 178 test_basic<map_type>(); 179 } 180 181 //! Testing multithreading support in concurrent_map 182 //! \brief \ref requirement 183 TEST_CASE("concurrent_map multithreading support") { 184 test_concurrent<map_type>(); 185 } 186 187 //! Testing move constructors and assignment operator in concurrent_map 188 //! \brief \ref interface \ref requirement 189 TEST_CASE("concurrent_map move semantics support") { 190 test_rvalue_ref_support<COMapTraits>(); 191 } 192 193 //! Testing std::initializer_list constructors and modifiers in concurrent_map 194 //! \brief \ref interface \ref requirement 195 TEST_CASE("std::initializer_list support in concurrent_map") { 196 test_initializer_list_support<map_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}}); 197 } 198 199 //! Testing node handling in concurrent_map 200 //! \brief \ref interface \ref requirement 201 TEST_CASE("node handling support in concurrent_map") { 202 node_handling_tests::test_node_handling_support<map_type>(); 203 } 204 205 //! Testing std::allocator_traits support in concurrent_map 206 //! \brief \ref interface \ref requirement 207 TEST_CASE("std::allocator_traits support in concurrent_map") { 208 test_allocator_traits_support<COMapTraits>(); 209 } 210 211 //! Testing heterogeneous overloads in concurrent_map 212 //! \brief \ref interface \ref requirement 213 TEST_CASE("heterogeneous overloads in concurrent_map") { 214 test_heterogeneous_functions<oneapi::tbb::concurrent_map>(); 215 } 216 217 //! Testing insert overloads with generic pair in concurrent_map 218 //! \brief \ref interface \ref requirement 219 TEST_CASE("insertion by generic pair in concurrent_map") { 220 test_insert_by_generic_pair<oneapi::tbb::concurrent_map>(); 221 } 222 223 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 224 //! Testing Class Template Argument Deduction in concurrent_map 225 //! \brief \ref interface \ref requirement 226 TEST_CASE("CTAD support in concurrent_map") { 227 test_deduction_guides<oneapi::tbb::concurrent_map>(); 228 } 229 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 230 231 //! Testing comparisons of concurrent_map 232 //! \brief \ref interface \ref requirement 233 TEST_CASE("test concurrent_map comparisons") { 234 test_map_comparisons<oneapi::tbb::concurrent_map>(); 235 } 236 237 //! Testing concurrent_multimap member types 238 //! \brief \ref interface \ref requirement 239 TEST_CASE("concurrent_multimap member types") { 240 test_member_types<oneapi::tbb::concurrent_multimap>(); 241 } 242 243 //! Testing requirements of concurrent_multimap 244 //! \brief \ref interface \ref requirement 245 TEST_CASE("concurrent_multimap requirements") { 246 test_basic<multimap_type>(); 247 } 248 249 //! Testing multithreading support in concurrent_multimap 250 //! \brief \ref requirement 251 TEST_CASE("concurrent_multimap multithreading support") { 252 test_concurrent<multimap_type>(); 253 } 254 255 //! Testing move constructors and assignment operator in concurrent_multimap 256 //! \brief \ref interface \ref requirement 257 TEST_CASE("concurrent_multimap multithreading support") { 258 test_rvalue_ref_support<COMultimapTraits>(); 259 } 260 261 //! Testing std::initializer_list constructors and modifiers in concurrent_multimap 262 //! \brief \ref interface \ref requirement 263 TEST_CASE("std::initializer_list support in concurrent_multimap") { 264 test_initializer_list_support<multimap_type>({{1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 40}}); 265 } 266 267 //! Testing node handling support in concurrent_multimap 268 //! \brief \ref interface \ref requirement 269 TEST_CASE("node handling support in concurrent_multimap") { 270 node_handling_tests::test_node_handling_support<multimap_type>(); 271 } 272 273 //! Testing std::allocator_traits support in concurrent_multimap 274 //! \brief \ref interface \ref requirement 275 TEST_CASE("std::allocator_traits support in concurrent_multimap") { 276 test_allocator_traits_support<COMultimapTraits>(); 277 } 278 279 //! Testing heterogeneous overloads in concurrent_multimap 280 //! \brief \ref interface \ref requirement 281 TEST_CASE("heterogeneous overloads in concurrent_multimap") { 282 test_heterogeneous_functions<oneapi::tbb::concurrent_multimap>(); 283 } 284 285 //! Testing insert overloads with generic pair in concurrent_multimap 286 //! \brief \ref interface \ref requirement 287 TEST_CASE("insertion by generic pair in concurrent_multimap") { 288 test_insert_by_generic_pair<oneapi::tbb::concurrent_multimap>(); 289 } 290 291 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 292 //! Testing Class Template Argument Deduction in concurrent_multimap 293 //! \brief \ref interface \ref requirement 294 TEST_CASE("CTAD support in concurrent_multimap") { 295 test_deduction_guides<oneapi::tbb::concurrent_multimap>(); 296 } 297 #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 298 299 //! Testing comparison operators in concurrent_multimap 300 //! \brief \ref interface \ref requirement 301 TEST_CASE("test concurrent_multimap comparisons") { 302 test_map_comparisons<oneapi::tbb::concurrent_multimap>(); 303 } 304 305 //! Testing of merge operations in concurrent_map and concurrent_multimap 306 //! \brief \ref interface \ref requirement 307 TEST_CASE("merge operations") { 308 node_handling_tests::test_merge<map_type, multimap_type>(1000); 309 } 310