File indexing completed on 2025-01-18 10:12:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef __TBB_concurrent_unordered_map_H
0021 #define __TBB_concurrent_unordered_map_H
0022
0023 #define __TBB_concurrent_unordered_map_H_include_area
0024 #include "internal/_warning_suppress_enable_notice.h"
0025
0026 #include "internal/_concurrent_unordered_impl.h"
0027
0028 namespace tbb
0029 {
0030
0031 namespace interface5 {
0032
0033
0034 template<typename Key, typename T, typename Hash_compare, typename Allocator, bool Allow_multimapping>
0035 class concurrent_unordered_map_traits
0036 {
0037 protected:
0038 typedef std::pair<const Key, T> value_type;
0039 typedef Key key_type;
0040 typedef Hash_compare hash_compare;
0041 typedef typename tbb::internal::allocator_rebind<Allocator, value_type>::type allocator_type;
0042 #if __TBB_UNORDERED_NODE_HANDLE_PRESENT
0043 typedef tbb::internal::node_handle<key_type, value_type,
0044 typename internal::split_ordered_list<value_type, allocator_type>::node,
0045 allocator_type> node_type;
0046 #endif
0047
0048 enum { allow_multimapping = Allow_multimapping };
0049
0050 concurrent_unordered_map_traits() : my_hash_compare() {}
0051 concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {}
0052
0053 template<class Type1, class Type2>
0054 static const Key& get_key(const std::pair<Type1, Type2>& value) {
0055 return (value.first);
0056 }
0057
0058 hash_compare my_hash_compare;
0059 };
0060
0061 template<typename Key, typename T, typename Hasher, typename Key_equality, typename Allocator>
0062 class concurrent_unordered_multimap;
0063
0064 template <typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
0065 typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
0066 class concurrent_unordered_map :
0067 public internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T,
0068 internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> >
0069 {
0070
0071 typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
0072 typedef concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, false> traits_type;
0073 typedef internal::concurrent_unordered_base< traits_type > base_type;
0074 #if __TBB_EXTRA_DEBUG
0075 public:
0076 #endif
0077 using traits_type::allow_multimapping;
0078 public:
0079 using base_type::end;
0080 using base_type::find;
0081 using base_type::insert;
0082
0083
0084 typedef Key key_type;
0085 typedef typename base_type::value_type value_type;
0086 typedef T mapped_type;
0087 typedef Hasher hasher;
0088 typedef Key_equality key_equal;
0089 typedef hash_compare key_compare;
0090
0091 typedef typename base_type::allocator_type allocator_type;
0092 typedef typename base_type::pointer pointer;
0093 typedef typename base_type::const_pointer const_pointer;
0094 typedef typename base_type::reference reference;
0095 typedef typename base_type::const_reference const_reference;
0096
0097 typedef typename base_type::size_type size_type;
0098 typedef typename base_type::difference_type difference_type;
0099
0100 typedef typename base_type::iterator iterator;
0101 typedef typename base_type::const_iterator const_iterator;
0102 typedef typename base_type::iterator local_iterator;
0103 typedef typename base_type::const_iterator const_local_iterator;
0104 #if __TBB_UNORDERED_NODE_HANDLE_PRESENT
0105 typedef typename base_type::node_type node_type;
0106 #endif
0107
0108
0109 explicit concurrent_unordered_map(size_type n_of_buckets = base_type::initial_bucket_number,
0110 const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(),
0111 const allocator_type& a = allocator_type())
0112 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
0113 {}
0114
0115 concurrent_unordered_map(size_type n_of_buckets, const allocator_type& a)
0116 : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a)
0117 {}
0118
0119 concurrent_unordered_map(size_type n_of_buckets, const hasher& a_hasher, const allocator_type& a)
0120 : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a)
0121 {}
0122
0123 explicit concurrent_unordered_map(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
0124 {}
0125
0126 template <typename Iterator>
0127 concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
0128 const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(),
0129 const allocator_type& a = allocator_type())
0130 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
0131 {
0132 insert(first, last);
0133 }
0134
0135 template <typename Iterator>
0136 concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets, const allocator_type& a)
0137 : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a)
0138 {
0139 insert(first, last);
0140 }
0141
0142 template <typename Iterator>
0143 concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets, const hasher& a_hasher,
0144 const allocator_type& a)
0145 : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a)
0146 {
0147 insert(first, last);
0148 }
0149
0150 #if __TBB_INITIALIZER_LISTS_PRESENT
0151
0152 concurrent_unordered_map(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number,
0153 const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(),
0154 const allocator_type& a = allocator_type())
0155 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
0156 {
0157 insert(il.begin(),il.end());
0158 }
0159
0160 concurrent_unordered_map(std::initializer_list<value_type> il, size_type n_of_buckets, const allocator_type& a)
0161 : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a)
0162 {
0163 insert(il.begin(), il.end());
0164 }
0165
0166 concurrent_unordered_map(std::initializer_list<value_type> il, size_type n_of_buckets, const hasher& a_hasher,
0167 const allocator_type& a)
0168 : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a)
0169 {
0170 insert(il.begin(), il.end());
0171 }
0172
0173 #endif
0174
0175
0176 #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT
0177 concurrent_unordered_map(const concurrent_unordered_map& table)
0178 : base_type(table)
0179 {}
0180
0181 concurrent_unordered_map& operator=(const concurrent_unordered_map& table)
0182 {
0183 return static_cast<concurrent_unordered_map&>(base_type::operator=(table));
0184 }
0185
0186 concurrent_unordered_map(concurrent_unordered_map&& table)
0187 : base_type(std::move(table))
0188 {}
0189
0190 concurrent_unordered_map& operator=(concurrent_unordered_map&& table)
0191 {
0192 return static_cast<concurrent_unordered_map&>(base_type::operator=(std::move(table)));
0193 }
0194 #endif
0195
0196 #if __TBB_CPP11_RVALUE_REF_PRESENT
0197 concurrent_unordered_map(concurrent_unordered_map&& table, const Allocator& a) : base_type(std::move(table), a)
0198 {}
0199 #endif
0200
0201 #if __TBB_UNORDERED_NODE_HANDLE_PRESENT
0202 template<typename Hash, typename Equality>
0203 void merge(concurrent_unordered_map<Key, T, Hash, Equality, Allocator>& source)
0204 { this->internal_merge(source); }
0205
0206 template<typename Hash, typename Equality>
0207 void merge(concurrent_unordered_map<Key, T, Hash, Equality, Allocator>&& source)
0208 { this->internal_merge(source); }
0209
0210 template<typename Hash, typename Equality>
0211 void merge(concurrent_unordered_multimap<Key, T, Hash, Equality, Allocator>& source)
0212 { this->internal_merge(source); }
0213
0214 template<typename Hash, typename Equality>
0215 void merge(concurrent_unordered_multimap<Key, T, Hash, Equality, Allocator>&& source)
0216 { this->internal_merge(source); }
0217
0218 #endif
0219
0220 concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
0221 : base_type(table, a)
0222 {}
0223
0224
0225 mapped_type& operator[](const key_type& key)
0226 {
0227 iterator where = find(key);
0228
0229 if (where == end())
0230 {
0231 where = insert(std::pair<key_type, mapped_type>(key, mapped_type())).first;
0232 }
0233
0234 return ((*where).second);
0235 }
0236
0237 mapped_type& at(const key_type& key)
0238 {
0239 iterator where = find(key);
0240
0241 if (where == end())
0242 {
0243 tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
0244 }
0245
0246 return ((*where).second);
0247 }
0248
0249 const mapped_type& at(const key_type& key) const
0250 {
0251 const_iterator where = find(key);
0252
0253 if (where == end())
0254 {
0255 tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
0256 }
0257
0258 return ((*where).second);
0259 }
0260 };
0261
0262 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
0263
0264 namespace internal {
0265 using namespace tbb::internal;
0266
0267 template<template<typename...> typename Map, typename Key, typename Element, typename... Args>
0268 using cu_map_t = Map<
0269 Key, Element,
0270 std::conditional_t< (sizeof...(Args)>0) && !is_allocator_v< pack_element_t<0, Args...> >,
0271 pack_element_t<0, Args...>, tbb_hash<Key> >,
0272 std::conditional_t< (sizeof...(Args)>1) && !is_allocator_v< pack_element_t<1, Args...> >,
0273 pack_element_t<1, Args...>, std::equal_to<Key> >,
0274 std::conditional_t< (sizeof...(Args)>0) && is_allocator_v< pack_element_t<sizeof...(Args)-1, Args...> >,
0275 pack_element_t<sizeof...(Args)-1, Args...>, tbb_allocator<std::pair<const Key, Element> > >
0276 >;
0277 }
0278
0279
0280 template<typename I>
0281 concurrent_unordered_map (I, I)
0282 -> internal::cu_map_t<concurrent_unordered_map, internal::iterator_key_t<I>, internal::iterator_mapped_t<I>>;
0283
0284
0285 template<typename I, typename... Args>
0286 concurrent_unordered_map(I, I, size_t, Args...)
0287 -> internal::cu_map_t<concurrent_unordered_map, internal::iterator_key_t<I>, internal::iterator_mapped_t<I>, Args...>;
0288
0289
0290 template<typename Key, typename Element>
0291 concurrent_unordered_map(std::initializer_list<std::pair<const Key, Element>>)
0292 -> internal::cu_map_t<concurrent_unordered_map, Key, Element>;
0293
0294
0295 template<typename Key, typename Element, typename... Args>
0296 concurrent_unordered_map(std::initializer_list<std::pair<const Key, Element>>, size_t, Args...)
0297 -> internal::cu_map_t<concurrent_unordered_map, Key, Element, Args...>;
0298
0299 #endif
0300
0301 template < typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
0302 typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
0303 class concurrent_unordered_multimap :
0304 public internal::concurrent_unordered_base< concurrent_unordered_map_traits< Key, T,
0305 internal::hash_compare<Key, Hasher, Key_equality>, Allocator, true> >
0306 {
0307
0308 typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
0309 typedef concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, true> traits_type;
0310 typedef internal::concurrent_unordered_base<traits_type> base_type;
0311 #if __TBB_EXTRA_DEBUG
0312 public:
0313 #endif
0314 using traits_type::allow_multimapping;
0315 public:
0316 using base_type::insert;
0317
0318
0319 typedef Key key_type;
0320 typedef typename base_type::value_type value_type;
0321 typedef T mapped_type;
0322 typedef Hasher hasher;
0323 typedef Key_equality key_equal;
0324 typedef hash_compare key_compare;
0325
0326 typedef typename base_type::allocator_type allocator_type;
0327 typedef typename base_type::pointer pointer;
0328 typedef typename base_type::const_pointer const_pointer;
0329 typedef typename base_type::reference reference;
0330 typedef typename base_type::const_reference const_reference;
0331
0332 typedef typename base_type::size_type size_type;
0333 typedef typename base_type::difference_type difference_type;
0334
0335 typedef typename base_type::iterator iterator;
0336 typedef typename base_type::const_iterator const_iterator;
0337 typedef typename base_type::iterator local_iterator;
0338 typedef typename base_type::const_iterator const_local_iterator;
0339 #if __TBB_UNORDERED_NODE_HANDLE_PRESENT
0340 typedef typename base_type::node_type node_type;
0341 #endif
0342
0343
0344 explicit concurrent_unordered_multimap(size_type n_of_buckets = base_type::initial_bucket_number,
0345 const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(),
0346 const allocator_type& a = allocator_type())
0347 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
0348 {}
0349
0350 concurrent_unordered_multimap(size_type n_of_buckets, const allocator_type& a)
0351 : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a)
0352 {}
0353
0354 concurrent_unordered_multimap(size_type n_of_buckets, const hasher& a_hasher, const allocator_type& a)
0355 : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a)
0356 {}
0357
0358 explicit concurrent_unordered_multimap(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
0359 {}
0360
0361 template <typename Iterator>
0362 concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
0363 const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(),
0364 const allocator_type& a = allocator_type())
0365 : base_type(n_of_buckets,key_compare(a_hasher,a_keyeq), a)
0366 {
0367 insert(first, last);
0368 }
0369
0370 template <typename Iterator>
0371 concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets, const allocator_type& a)
0372 : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a)
0373 {
0374 insert(first, last);
0375 }
0376
0377 template <typename Iterator>
0378 concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets, const hasher& a_hasher,
0379 const allocator_type& a)
0380 : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a)
0381 {
0382 insert(first, last);
0383 }
0384
0385 #if __TBB_INITIALIZER_LISTS_PRESENT
0386
0387 concurrent_unordered_multimap(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number,
0388 const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(),
0389 const allocator_type& a = allocator_type())
0390 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
0391 {
0392 insert(il.begin(),il.end());
0393 }
0394
0395 concurrent_unordered_multimap(std::initializer_list<value_type> il, size_type n_of_buckets, const allocator_type& a)
0396 : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a)
0397 {
0398 insert(il.begin(), il.end());
0399 }
0400
0401 concurrent_unordered_multimap(std::initializer_list<value_type> il, size_type n_of_buckets, const hasher& a_hasher,
0402 const allocator_type& a)
0403 : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a)
0404 {
0405 insert(il.begin(), il.end());
0406 }
0407
0408 #endif
0409
0410 #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT
0411 concurrent_unordered_multimap(const concurrent_unordered_multimap& table)
0412 : base_type(table)
0413 {}
0414
0415 concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table)
0416 {
0417 return static_cast<concurrent_unordered_multimap&>(base_type::operator=(table));
0418 }
0419
0420 concurrent_unordered_multimap(concurrent_unordered_multimap&& table)
0421 : base_type(std::move(table))
0422 {}
0423
0424 concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table)
0425 {
0426 return static_cast<concurrent_unordered_multimap&>(base_type::operator=(std::move(table)));
0427 }
0428 #endif
0429
0430 #if __TBB_CPP11_RVALUE_REF_PRESENT
0431 concurrent_unordered_multimap(concurrent_unordered_multimap&& table, const Allocator& a) : base_type(std::move(table), a)
0432 {}
0433 #endif
0434
0435 #if __TBB_UNORDERED_NODE_HANDLE_PRESENT
0436 template<typename Hash, typename Equality>
0437 void merge(concurrent_unordered_map<Key, T, Hash, Equality, Allocator>& source)
0438 { this->internal_merge(source); }
0439
0440 template<typename Hash, typename Equality>
0441 void merge(concurrent_unordered_map<Key, T, Hash, Equality, Allocator>&& source)
0442 { this->internal_merge(source); }
0443
0444 template<typename Hash, typename Equality>
0445 void merge(concurrent_unordered_multimap<Key, T, Hash, Equality, Allocator>& source)
0446 { this->internal_merge(source); }
0447
0448 template<typename Hash, typename Equality>
0449 void merge(concurrent_unordered_multimap<Key, T, Hash, Equality, Allocator>&& source)
0450 { this->internal_merge(source); }
0451
0452 #endif
0453
0454 concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a)
0455 : base_type(table, a)
0456 {}
0457 };
0458
0459 #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
0460
0461
0462 template<typename I>
0463 concurrent_unordered_multimap (I, I)
0464 -> internal::cu_map_t<concurrent_unordered_multimap, internal::iterator_key_t<I>, internal::iterator_mapped_t<I>>;
0465
0466
0467 template<typename I, typename... Args>
0468 concurrent_unordered_multimap(I, I, size_t, Args...)
0469 -> internal::cu_map_t<concurrent_unordered_multimap, internal::iterator_key_t<I>, internal::iterator_mapped_t<I>, Args...>;
0470
0471
0472 template<typename Key, typename Element>
0473 concurrent_unordered_multimap(std::initializer_list<std::pair<const Key, Element>>)
0474 -> internal::cu_map_t<concurrent_unordered_multimap, Key, Element>;
0475
0476
0477 template<typename Key, typename Element, typename... Args>
0478 concurrent_unordered_multimap(std::initializer_list<std::pair<const Key, Element>>, size_t, Args...)
0479 -> internal::cu_map_t<concurrent_unordered_multimap, Key, Element, Args...>;
0480
0481 #endif
0482 }
0483
0484 using interface5::concurrent_unordered_map;
0485 using interface5::concurrent_unordered_multimap;
0486
0487 }
0488
0489 #include "internal/_warning_suppress_disable_notice.h"
0490 #undef __TBB_concurrent_unordered_map_H_include_area
0491
0492 #endif