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