Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:53

0001 /*
0002     Copyright (c) 2005-2020 Intel Corporation
0003 
0004     Licensed under the Apache License, Version 2.0 (the "License");
0005     you may not use this file except in compliance with the License.
0006     You may obtain a copy of the License at
0007 
0008         http://www.apache.org/licenses/LICENSE-2.0
0009 
0010     Unless required by applicable law or agreed to in writing, software
0011     distributed under the License is distributed on an "AS IS" BASIS,
0012     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013     See the License for the specific language governing permissions and
0014     limitations under the License.
0015 */
0016 
0017 /* Container implementations in this header are based on PPL implementations
0018    provided by Microsoft. */
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 // Template class for hash map traits
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 // __TBB_UNORDERED_NODE_HANDLE_PRESENT
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; // the comparator predicate for keys
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     // Base type definitions
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     // Type definitions
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 // __TBB_UNORDERED_NODE_HANDLE_PRESENT
0107 
0108     // Construction/destruction/copying
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     //! Constructor from initializer_list
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 //# __TBB_INITIALIZER_LISTS_PRESENT
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 //__TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT
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 /*__TBB_CPP11_RVALUE_REF_PRESENT*/
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 //__TBB_UNORDERED_NODE_HANDLE_PRESENT
0219 
0220     concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
0221         : base_type(table, a)
0222     {}
0223 
0224     // Observers
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 // Deduction guide for the constructor from two iterators
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 // Deduction guide for the constructor from two iterators and hasher/equality/allocator
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 // Deduction guide for the constructor from an initializer_list
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 // Deduction guide for the constructor from an initializer_list and hasher/equality/allocator
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 /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */
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     // Base type definitions
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     // Type definitions
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 //__TBB_UNORDERED_NODE_HANDLE_PRESENT
0342 
0343     // Construction/destruction/copying
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     //! Constructor from initializer_list
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 //# __TBB_INITIALIZER_LISTS_PRESENT
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 //__TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT
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 /*__TBB_CPP11_RVALUE_REF_PRESENT*/
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 //__TBB_UNORDERED_NODE_HANDLE_PRESENT
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 // Deduction guide for the constructor from two iterators
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 // Deduction guide for the constructor from two iterators and hasher/equality/allocator
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 // Deduction guide for the constructor from an initializer_list
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 // Deduction guide for the constructor from an initializer_list and hasher/equality/allocator
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 /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */
0482 } // namespace interface5
0483 
0484 using interface5::concurrent_unordered_map;
0485 using interface5::concurrent_unordered_multimap;
0486 
0487 } // namespace tbb
0488 
0489 #include "internal/_warning_suppress_disable_notice.h"
0490 #undef __TBB_concurrent_unordered_map_H_include_area
0491 
0492 #endif// __TBB_concurrent_unordered_map_H