/*** * ==++== * * Copyright (c) Microsoft Corporation. All rights reserved. * * ==--== * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * concurrent_unordered_map.h * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #pragma once #include #include "internal_concurrent_hash.h" #define _PPL_CONTAINER #if !(defined (_M_X64) || defined (_M_IX86) || defined (_M_ARM)) #error ERROR: Concurrency Runtime is supported only on X64, X86, and ARM architectures. #endif /* !(defined (_M_X64) || defined (_M_IX86) || defined (_M_ARM)) */ #if defined (_M_CEE) #error ERROR: Concurrency Runtime is not supported when compiling /clr. #endif /* defined (_M_CEE) */ #pragma pack(push,_CRT_PACKING) #pragma warning(push) #pragma warning(disable: 4100) // Unreferenced formal parameter - needed for document generation namespace Concurrency { namespace details { // Template class for hash map traits template class _Concurrent_unordered_map_traits : public std::_Container_base { public: typedef std::pair value_type; typedef _Key_type key_type; typedef _Key_comparator _Key_compare; typedef typename _Allocator_type::template rebind::other allocator_type; enum { _M_allow_multimapping = _Allow_multimapping }; _Concurrent_unordered_map_traits() : _M_comparator() { } _Concurrent_unordered_map_traits(const _Key_compare& _Traits) : _M_comparator(_Traits) { } class _Value_compare : public std::binary_function { friend class _Concurrent_unordered_map_traits<_Key_type, _Element_type, _Key_comparator, _Allocator_type, _Allow_multimapping>; public: bool operator()(const value_type& _Left, const value_type& _Right) const { return (_M_comparator(_Left.first, _Right.first)); } _Value_compare(const _Key_compare& _Traits) : _M_comparator(_Traits) { } protected: _Key_compare _M_comparator; // the comparator predicate for keys }; template static const _Type1& _Key_function(const std::pair<_Type1, _Type2>& _Value) { return (_Value.first); } _Key_compare _M_comparator; // the comparator predicate for keys }; } // namespace details; /// /// The concurrent_unordered_map class is a concurrency-safe container that controls a varying-length sequence of /// elements of type std::pair<const _Key_type, _Element_type>. The sequence is represented in a way that enables concurrency-safe /// append, element access, iterator access, and iterator traversal operations. /// /// /// The key type. /// /// /// The mapped type. /// /// /// The hash function object type. This argument is optional and the default value is /// std::tr1::hash<>. /// /// /// The equality comparison function object type. This argument is optional and the default value is /// std::equal_to<>. /// /// /// The type that represents the stored allocator object that encapsulates details about the allocation and /// deallocation of memory for the concurrent unordered map. This argument is optional and the default value is /// std::allocator<std::pair<, >>. /// /// /// For detailed information on the concurrent_unordered_map class, see . /// /// /**/ template , typename _Key_equality = std::equal_to<_Key_type>, typename _Allocator_type = std::allocator > > class concurrent_unordered_map : public details::_Concurrent_hash< details::_Concurrent_unordered_map_traits<_Key_type, _Element_type, details::_Hash_compare<_Key_type, _Hasher, _Key_equality>, _Allocator_type, false> > { public: // Base type definitions typedef concurrent_unordered_map<_Key_type, _Element_type, _Hasher, _Key_equality, _Allocator_type> _Mytype; typedef details::_Hash_compare<_Key_type, _Hasher, _Key_equality> _Key_compare; typedef details::_Concurrent_hash< details::_Concurrent_unordered_map_traits<_Key_type, _Element_type, _Key_compare, _Allocator_type, false> > _Mybase; /// /// The type of an ordering key. /// /**/ typedef _Key_type key_type; /// /// The type of an element. /// /**/ typedef typename _Mybase::value_type value_type; /// /// The type of a mapped value associated with each key. /// /**/ typedef _Element_type mapped_type; /// /// The type of the hash function. /// /**/ typedef _Hasher hasher; /// /// The type of the comparison function. /// /**/ typedef _Key_equality key_equal; /// /// The type of an allocator for managing storage. /// /**/ typedef typename _Mybase::allocator_type allocator_type; /// /// The type of a pointer to an element. /// /**/ typedef typename _Mybase::pointer pointer; /// /// The type of a constant pointer to an element. /// /**/ typedef typename _Mybase::const_pointer const_pointer; /// /// The type of a reference to an element. /// /**/ typedef typename _Mybase::reference reference; /// /// The type of a constant reference to an element. /// /**/ typedef typename _Mybase::const_reference const_reference; /// /// The type of an unsigned distance between two elements. /// /**/ typedef typename _Mybase::size_type size_type; /// /// The type of a signed distance between two elements. /// /**/ typedef typename _Mybase::difference_type difference_type; /// /// The type of an iterator for the controlled sequence. /// /**/ typedef typename _Mybase::iterator iterator; /// /// The type of a constant iterator for the controlled sequence. /// /**/ typedef typename _Mybase::const_iterator const_iterator; /// /// The type of a bucket iterator for the controlled sequence. /// /**/ typedef typename _Mybase::iterator local_iterator; /// /// The type of a constant bucket iterator for the controlled sequence. /// /**/ typedef typename _Mybase::const_iterator const_local_iterator; /// /// Constructs a concurrent unordered map. /// /// /// The initial number of buckets for this unordered map. /// /// /// The hash function for this unordered map. /// /// /// The equality comparison function for this unordered map. /// /// /// The allocator for this unordered map. /// /// /// All constructors store an allocator object and initialize the unordered map. /// The first constructor specifies an empty initial map and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered map. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered map . /// The last constructor specifies a move of the concurrent unordered map . /// /**/ explicit concurrent_unordered_map(size_type _Number_of_buckets = 8, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& _Allocator = allocator_type()) : _Mybase(_Number_of_buckets, _Key_compare(_Hasher, _Key_equality), _Allocator) { this->rehash(_Number_of_buckets); } /// /// Constructs a concurrent unordered map. /// /// /// The allocator for this unordered map. /// /// /// All constructors store an allocator object and initialize the unordered map. /// The first constructor specifies an empty initial map and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered map. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered map . /// The last constructor specifies a move of the concurrent unordered map . /// /**/ concurrent_unordered_map(const allocator_type& _Allocator) : _Mybase(8, _Key_compare(), _Allocator) { } /// /// Constructs a concurrent unordered map. /// /// /// The type of the input iterator. /// /// /// The position of the first element in the range of elements to be copied. /// /// /// The position of the first element beyond the range of elements to be copied. /// /// /// The initial number of buckets for this unordered map. /// /// /// The hash function for this unordered map. /// /// /// The equality comparison function for this unordered map. /// /// /// The allocator for this unordered map. /// /// /// All constructors store an allocator object and initialize the unordered map. /// The first constructor specifies an empty initial map and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered map. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered map . /// The last constructor specifies a move of the concurrent unordered map . /// /**/ template concurrent_unordered_map(_Iterator _Begin, _Iterator _End, size_type _Number_of_buckets = 8, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& _Allocator = allocator_type()) : _Mybase(_Number_of_buckets, _Key_compare(), allocator_type()) { this->rehash(_Number_of_buckets); for (; _Begin != _End; ++_Begin) { _Insert(*_Begin); } } /// /// Constructs a concurrent unordered map. /// /// /// The source concurrent_unordered_map object to copy or move elements from. /// /// /// All constructors store an allocator object and initialize the unordered map. /// The first constructor specifies an empty initial map and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered map. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered map . /// The last constructor specifies a move of the concurrent unordered map . /// /**/ concurrent_unordered_map(const concurrent_unordered_map& _Umap) : _Mybase(_Umap) { } /// /// Constructs a concurrent unordered map. /// /// /// The source concurrent_unordered_map object to copy or move elements from. /// /// /// The allocator for this unordered map. /// /// /// All constructors store an allocator object and initialize the unordered map. /// The first constructor specifies an empty initial map and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered map. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered map . /// The last constructor specifies a move of the concurrent unordered map . /// /**/ concurrent_unordered_map(const concurrent_unordered_map& _Umap, const allocator_type& _Allocator) : _Mybase(_Umap, _Allocator) { } /// /// Constructs a concurrent unordered map. /// /// /// The source concurrent_unordered_map object to copy or move elements from. /// /// /// All constructors store an allocator object and initialize the unordered map. /// The first constructor specifies an empty initial map and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered map. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered map . /// The last constructor specifies a move of the concurrent unordered map . /// /**/ concurrent_unordered_map(concurrent_unordered_map&& _Umap) : _Mybase(std::move(_Umap)) { } /// /// Assigns the contents of another concurrent_unordered_map object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_map object. /// /// /// A reference to this concurrent_unordered_map object. /// /// /// After erasing any existing elements a concurrent vector, operator= either copies or moves the contents of into /// the concurrent vector. /// /**/ concurrent_unordered_map& operator=(const concurrent_unordered_map& _Umap) { _Mybase::operator=(_Umap); return (*this); } /// /// Assigns the contents of another concurrent_unordered_map object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_map object. /// /// /// A reference to this concurrent_unordered_map object. /// /// /// After erasing any existing elements in a concurrent vector, operator= either copies or moves the contents of into /// the concurrent vector. /// /**/ concurrent_unordered_map& operator=(concurrent_unordered_map&& _Umap) { _Mybase::operator=(std::move(_Umap)); return (*this); } /// /// Adds elements to the concurrent_unordered_map object. /// /// /// The value to be inserted. /// /// /// A pair that contains an iterator and a boolean value. See the Remarks section for more details. /// /// /// The first member function determines whether an element X exists in the sequence whose key has equivalent ordering to /// that of . If not, it creates such an element X and initializes it with . /// The function then determines the iterator where that designates X. If an insertion occurred, the function returns /// std::pair(where, true). Otherwise, it returns std::pair(where, false). /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ std::pair insert(const value_type& _Value) { return _Insert(_Value); } /// /// Adds elements to the concurrent_unordered_map object. /// /// /// The starting location to search for an insertion point. /// /// /// The value to be inserted. /// /// /// An iterator pointing to the insertion location of the object. If the key already exists in the container /// an iterator pointing to the duplicate key location in the map is returned. /// /// /// The first member function determines whether an element X exists in the sequence whose key has equivalent ordering to /// that of . If not, it creates such an element X and initializes it with . /// The function then determines the iterator where that designates X. If an insertion occurred, the function returns /// std::pair(where, true). Otherwise, it returns std::pair(where, false). /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ iterator insert(const_iterator _Where, const value_type& _Value) { // Current implementation ignores the hint. The method is provided for compatibility with unordered_map. return _Insert(_Value).first; } /// /// Adds elements to the concurrent_unordered_map object. /// /// /// The iterator type used for insertion. /// /// /// The beginning of the range to insert. /// /// /// The end of the range to insert. /// /// /// The first member function determines whether an element X exists in the sequence whose key has equivalent ordering to /// that of . If not, it creates such an element X and initializes it with . /// The function then determines the iterator where that designates X. If an insertion occurred, the function returns /// std::pair(where, true). Otherwise, it returns std::pair(where, false). /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ template void insert(_Iterator _First, _Iterator _Last) { _Insert(_First, _Last); } /// /// Adds elements to the concurrent_unordered_map object. /// /// /// The type of the value inserted into the map. /// /// /// The value to be inserted. /// /// /// A pair that contains an iterator and a boolean value. See the Remarks section for more details. /// /// /// The first member function determines whether an element X exists in the sequence whose key has equivalent ordering to /// that of . If not, it creates such an element X and initializes it with . /// The function then determines the iterator where that designates X. If an insertion occurred, the function returns /// std::pair(where, true). Otherwise, it returns std::pair(where, false). /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ template std::pair insert(_Valty&& _Value) { return _Insert(std::forward<_Valty>(_Value)); } /// /// Adds elements to the concurrent_unordered_map object. /// /// /// The type of the value inserted into the map. /// /// /// The starting location to search for an insertion point. /// /// /// The value to be inserted. /// /// /// An iterator pointing to the insertion location of the object. If the key already exists in the container /// an iterator pointing to the duplicate key location in the map is returned. /// /// /// The first member function determines whether an element X exists in the sequence whose key has equivalent ordering to /// that of . If not, it creates such an element X and initializes it with . /// The function then determines the iterator where that designates X. If an insertion occurred, the function returns /// std::pair(where, true). Otherwise, it returns std::pair(where, false). /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ template typename std::tr1::enable_if::type>::value, iterator>::type insert(const_iterator _Where, _Valty&& _Value) { // Current implementation ignores the hint. The method is provided for compatibility with unordered_map. return _Insert(std::forward<_Valty>(_Value)).first; } /// /// Removes elements from the concurrent_unordered_map at specified positions. This method is not concurrency-safe. /// /// /// The iterator position to erase from. /// /// /// The first member function removes the element of the controlled sequence pointed to by . The second /// member function removes the elements in the range [, ). /// The third member function removes the elements in the range delimited by /// concurrent_unordered_map::equal_range(_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or concurrent_unordered_map::end() if no such element exists. The third /// member function returns the number of elements it removes. /// /**/ iterator unsafe_erase(const_iterator _Where) { return _Mybase::unsafe_erase(_Where); } /// /// Removes elements from the concurrent_unordered_map at specified positions. This method is not concurrency-safe. /// /// /// The position of the first element in the range of elements to be erased. /// /// /// The position of the first element beyond the range of elements to be erased. /// /// /// The first member function removes the element of the controlled sequence pointed to by . The second /// member function removes the elements in the range [, ). /// The third member function removes the elements in the range delimited by /// concurrent_unordered_map::equal_range(_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or concurrent_unordered_map::end() if no such element exists. The third /// member function returns the number of elements it removes. /// /**/ iterator unsafe_erase(const_iterator _Begin, const_iterator _End) { return _Mybase::unsafe_erase(_Begin, _End); } /// /// Removes elements from the concurrent_unordered_map at specified positions. This method is not concurrency-safe. /// /// /// The key value to erase. /// /// /// The first member function removes the element of the controlled sequence pointed to by . The second /// member function removes the elements in the range [, ). /// The third member function removes the elements in the range delimited by /// concurrent_unordered_map::equal_range(_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or concurrent_unordered_map::end() if no such element exists. The third /// member function returns the number of elements it removes. /// /**/ size_type unsafe_erase(const key_type& _Keyval) { return _Mybase::unsafe_erase(_Keyval); } /// /// Swaps the contents of two concurrent_unordered_map objects. This method is not concurrency-safe. /// /// /// The concurrent_unordered_map object to swap with. /// /**/ void swap(concurrent_unordered_map& _Umap) { _Mybase::swap(_Umap); } /// /// Gets the stored hash function object. /// /// /// The stored hash function object. /// /**/ hasher hash_function() const { return _M_comparator._M_hash_object; } /// /// Gets the stored equality comparison function object. /// /// /// The stored equality comparison function object. /// /**/ key_equal key_eq() const { return _M_comparator._M_key_compare_object; } /// /// Finds or inserts an element with the specified key. This method is concurrency-safe. /// /// /// The key value to find or insert. /// /// /// A reference to the data value of the found or inserted element. /// /// /// If the argument key value is not found, then it is inserted along with the default value of the data type. /// operator[] may be used to insert elements into a map m using m[_Key] = DataValue;, where /// DataValue is the value of the mapped_type of the element with a key value of _Key. /// When using operator[] to insert elements, the returned reference does not indicate whether an insertion /// is changing a pre-existing element or creating a new one. The member functions /// find and insert can be used to determine whether an element /// with a specified key is already present before an insertion. /// /**/ mapped_type& operator[](const key_type& _Keyval) { iterator _Where = find(_Keyval); if (_Where == end()) { _Where = _Insert(std::make_pair(_Keyval, mapped_type())).first; } return ((*_Where).second); } /// /// Finds or inserts an element with the specified key. This method is concurrency-safe. /// /// /// The key value to find or insert. /// /// /// A reference to the data value of the found or inserted element. /// /// /// If the argument key value is not found, then it is inserted along with the default value of the data type. /// operator[] may be used to insert elements into a map m using m[_Key] = DataValue;, where /// DataValue is the value of the mapped_type of the element with a key value of _Key. /// When using operator[] to insert elements, the returned reference does not indicate whether an insertion /// is changing a pre-existing element or creating a new one. The member functions /// find and insert can be used to determine whether an element /// with a specified key is already present before an insertion. /// /**/ mapped_type& operator[](key_type && _Keyval) { iterator _Where = find(_Keyval); if (_Where == end()) { _Where = _Insert(std::make_pair(std::forward(_Keyval), mapped_type())).first; } return ((*_Where).second); } /// /// Finds an element in a concurrent_unordered_map with a specified key value.. This method is concurrency-safe. /// /// /// The key value to find. /// /// /// A reference to the data value of the element found. /// /// /// If the argument key value is not found, the function throws an object of class out_of_range. /// /**/ mapped_type& at(const key_type& _Keyval) { iterator _Where = find(_Keyval); if (_Where == end()) { throw std::out_of_range("invalid concurrent_unordered_map key"); } return ((*_Where).second); } /// /// Finds an element in a concurrent_unordered_map with a specified key value.. This method is concurrency-safe. /// /// /// The key value to find. /// /// /// A reference to the data value of the element found. /// /// /// If the argument key value is not found, the function throws an object of class out_of_range. /// /**/ const mapped_type& at(const key_type& _Keyval) const { const_iterator _Where = find(_Keyval); if (_Where == end()) { throw std::out_of_range("invalid concurrent_unordered_map key"); } return ((*_Where).second); } }; /// /// The concurrent_unordered_multimap class is an concurrency-safe container that controls a varying-length sequence of /// elements of type std::pair<const _Key_type, _Element_type>. The sequence is represented in a way that enables /// concurrency-safe append, element access, iterator access and iterator traversal operations. /// /// /// The key type. /// /// /// The mapped type. /// /// /// The hash function object type. This argument is optional and the default value is /// std::tr1::hash<>. /// /// /// The equality comparison function object type. This argument is optional and the default value is /// std::equal_to<>. /// /// /// The type that represents the stored allocator object that encapsulates details about the allocation and /// deallocation of memory for the concurrent vector. This argument is optional and the default value is /// std::allocator<std::pair<, >>. /// /// /// For detailed information on the concurrent_unordered_multimap class, see . /// /// /**/ template , typename _Key_equality = std::equal_to<_Key_type>, typename _Allocator_type = std::allocator > > class concurrent_unordered_multimap : public details::_Concurrent_hash< details::_Concurrent_unordered_map_traits<_Key_type, _Element_type, details::_Hash_compare<_Key_type, _Hasher, _Key_equality>, _Allocator_type, true> > { public: // Base type definitions typedef concurrent_unordered_multimap<_Key_type, _Element_type, _Hasher, _Key_equality, _Allocator_type> _Mytype; typedef details::_Hash_compare<_Key_type, _Hasher, _Key_equality> _Key_compare; typedef details::_Concurrent_hash< details::_Concurrent_unordered_map_traits<_Key_type, _Element_type, _Key_compare, _Allocator_type, true> > _Mybase; /// /// The type of an ordering key. /// /**/ typedef _Key_type key_type; /// /// The type of an element. /// /**/ typedef typename _Mybase::value_type value_type; /// /// The type of a mapped value associated with each key. /// /**/ typedef _Element_type mapped_type; /// /// The type of the hash function. /// /**/ typedef _Hasher hasher; /// /// The type of the comparison function. /// /**/ typedef _Key_equality key_equal; /// /// The type of an allocator for managing storage. /// /**/ typedef typename _Mybase::allocator_type allocator_type; /// /// The type of a pointer to an element. /// /**/ typedef typename _Mybase::pointer pointer; /// /// The type of a constant pointer to an element. /// /**/ typedef typename _Mybase::const_pointer const_pointer; /// /// The type of a reference to an element. /// /**/ typedef typename _Mybase::reference reference; /// /// The type of a constant reference to an element. /// /**/ typedef typename _Mybase::const_reference const_reference; /// /// The type of an unsigned distance between two elements. /// /**/ typedef typename _Mybase::size_type size_type; /// /// The type of a signed distance between two elements. /// /**/ typedef typename _Mybase::difference_type difference_type; /// /// The type of an iterator for the controlled sequence. /// /**/ typedef typename _Mybase::iterator iterator; /// /// The type of a constant iterator for the controlled sequence. /// /**/ typedef typename _Mybase::const_iterator const_iterator; /// /// The type of a bucket iterator for the controlled sequence. /// /**/ typedef typename _Mybase::iterator local_iterator; /// /// The type of a constant bucket iterator for the controlled sequence. /// /**/ typedef typename _Mybase::const_iterator const_local_iterator; /// /// Constructs a concurrent unordered multimap. /// /// /// The initial number of buckets for this unordered multimap. /// /// /// The hash function for this unordered multimap. /// /// /// The equality comparison function for this unordered multimap. /// /// /// The allocator for this unordered multimap. /// /// /// All constructors store an allocator object and initialize the unordered multimap. /// The first constructor specifies an empty initial multimap and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered multimap. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multimap . /// The last constructor specifies a move of the concurrent unordered multimap . /// /**/ explicit concurrent_unordered_multimap(size_type _Number_of_buckets = 8, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& _Allocator = allocator_type()) : _Mybase(_Number_of_buckets, _Key_compare(_Hasher, _Key_equality), _Allocator) { this->rehash(_Number_of_buckets); } /// /// Constructs a concurrent unordered multimap. /// /// /// The allocator for this unordered multimap. /// /// /// All constructors store an allocator object and initialize the unordered multimap. /// The first constructor specifies an empty initial multimap and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered multimap. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multimap . /// The last constructor specifies a move of the concurrent unordered multimap . /// /**/ concurrent_unordered_multimap(const allocator_type& _Allocator) : _Mybase(8, _Key_compare(), _Allocator) { } /// /// Constructs a concurrent unordered multimap. /// /// /// The type of the input iterator. /// /// /// The position of the first element in the range of elements to be copied. /// /// /// The position of the first element beyond the range of elements to be copied. /// /// /// The initial number of buckets for this unordered multimap. /// /// /// The hash function for this unordered multimap. /// /// /// The equality comparison function for this unordered multimap. /// /// /// The allocator for this unordered multimap. /// /// /// All constructors store an allocator object and initialize the unordered multimap. /// The first constructor specifies an empty initial multimap and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered multimap. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multimap . /// The last constructor specifies a move of the concurrent unordered multimap . /// /**/ template concurrent_unordered_multimap(_Iterator _Begin, _Iterator _End, size_type _Number_of_buckets = 8, const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& _Allocator = allocator_type()) : _Mybase(_Number_of_buckets, _Key_compare(), allocator_type()) { this->rehash(_Number_of_buckets); for (; _Begin != _End; ++_Begin) { _Insert(*_Begin); } } /// /// Constructs a concurrent unordered multimap. /// /// /// The source concurrent_unordered_multimap object to copy elements from. /// /// /// All constructors store an allocator object and initialize the unordered multimap. /// The first constructor specifies an empty initial multimap and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered multimap. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multimap . /// The last constructor specifies a move of the concurrent unordered multimap . /// /**/ concurrent_unordered_multimap(const concurrent_unordered_multimap& _Umap) : _Mybase(_Umap) { } /// /// Constructs a concurrent unordered multimap. /// /// /// The source concurrent_unordered_multimap object to copy elements from. /// /// /// The allocator for this unordered multimap. /// /// /// All constructors store an allocator object and initialize the unordered multimap. /// The first constructor specifies an empty initial multimap and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered multimap. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multimap . /// The last constructor specifies a move of the concurrent unordered multimap . /// /**/ concurrent_unordered_multimap(const concurrent_unordered_multimap& _Umap, const allocator_type& _Allocator) : _Mybase(_Umap, _Allocator) { } /// /// Constructs a concurrent unordered multimap. /// /// /// The source concurrent_unordered_multimap object to copy elements from. /// /// /// All constructors store an allocator object and initialize the unordered multimap. /// The first constructor specifies an empty initial multimap and explicitly specifies the number of buckets, /// hash function, equality function and allocator type to be used. /// The second constructor specifies an allocator for the unordered multimap. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multimap . /// The last constructor specifies a move of the concurrent unordered multimap . /// /**/ concurrent_unordered_multimap(concurrent_unordered_multimap&& _Umap) : _Mybase(std::move(_Umap)) { } /// /// Assigns the contents of another concurrent_unordered_multimap object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_multimap object. /// /// /// A reference to this concurrent_unordered_multimap object. /// /// /// After erasing any existing elements in a concurrent unordered multimap, operator= either copies or moves the contents of /// into the concurrent unordered multimap. /// /**/ concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& _Umap) { _Mybase::operator=(_Umap); return (*this); } /// /// Assigns the contents of another concurrent_unordered_multimap object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_multimap object. /// /// /// A reference to this concurrent_unordered_multimap object. /// /// /// After erasing any existing elements in a concurrent unordered multimap, operator= either copies or moves the contents of /// into the concurrent unordered multimap. /// /**/ concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& _Umap) { _Mybase::operator=(std::move(_Umap)); return (*this); } /// /// Adds elements to the concurrent_unordered_multimap object. /// /// /// The value to be inserted. /// /// /// An iterator pointing to the insertion location. /// /// /// The first member function inserts the element in the controlled sequence, then returns the iterator /// that designates the inserted element. /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ iterator insert(const value_type& _Value) { return _Insert(_Value).first; } /// /// Adds elements to the concurrent_unordered_multimap object. /// /// /// The starting location to search for an insertion point. /// /// /// The value to be inserted. /// /// /// An iterator pointing to the insertion location. /// /// /// The first member function inserts the element in the controlled sequence, then returns the iterator /// that designates the inserted element. /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ iterator insert(const_iterator _Where, const value_type& _Value) { // Current implementation ignores the hint. The method is provided for compatibility with unordered_multimap. return _Insert(_Value).first; } /// /// Adds elements to the concurrent_unordered_multimap object. /// /// /// The iterator type used for insertion. /// /// /// The beginning of the range to insert. /// /// /// The end of the range to insert. /// /// /// The first member function inserts the element in the controlled sequence, then returns the iterator /// that designates the inserted element. /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ template void insert(_Iterator _First, _Iterator _Last) { _Insert(_First, _Last); } /// /// Adds elements to the concurrent_unordered_multimap object. /// /// /// The type of the value inserted into the map. /// /// /// The value to be inserted. /// /// /// An iterator pointing to the insertion location. /// /// /// The first member function inserts the element in the controlled sequence, then returns the iterator /// that designates the inserted element. /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ template iterator insert(_Valty&& _Value) { return _Insert(std::forward<_Valty>(_Value)).first; } /// /// Adds elements to the concurrent_unordered_multimap object. /// /// /// The type of the value inserted into the map. /// /// /// The starting location to search for an insertion point. /// /// /// The value to be inserted. /// /// /// An iterator pointing to the insertion location. /// /// /// The first member function inserts the element in the controlled sequence, then returns the iterator /// that designates the inserted element. /// The second member function returns insert(), using as a starting /// place within the controlled sequence to search for the insertion point. /// The third member function inserts the sequence of element values from the range [, /// ). /// The last two member functions behave the same as the first two, except that is used to /// construct the inserted value. /// /**/ template typename std::tr1::enable_if::type>::value, iterator>::type insert(const_iterator _Where, _Valty&& _Value) { // Current implementation ignores the hint. The method is provided for compatibility with unordered_multimap. return _Insert(std::forward<_Valty>(_Value)).first; } /// /// Removes elements from the concurrent_unordered_multimap at specified positions. This method is not concurrency-safe. /// /// /// The iterator position to erase from. /// /// /// The first member function removes the element of the controlled sequence pointed to by . The second /// member function removes the elements in the range [, ). /// The third member function removes the elements in the range delimited by /// concurrent_unordered_multimap::equal_range(_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or concurrent_unordered_multimap::end() if no such element exists. The third /// member function returns the number of elements it removes. /// /**/ iterator unsafe_erase(const_iterator _Where) { return _Mybase::unsafe_erase(_Where); } /// /// Removes elements from the concurrent_unordered_multimap at specified positions. This method is not concurrency-safe. /// /// /// The key value to erase. /// /// /// The first member function removes the element of the controlled sequence pointed to by . The second /// member function removes the elements in the range [, ). /// The third member function removes the elements in the range delimited by /// concurrent_unordered_multimap::equal_range(_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or concurrent_unordered_multimap::end() if no such element exists. The third /// member function returns the number of elements it removes. /// /**/ size_type unsafe_erase(const key_type& _Keyval) { return _Mybase::unsafe_erase(_Keyval); } /// /// Removes elements from the concurrent_unordered_multimap at specified positions. This method is not concurrency-safe. /// /// /// Position of the first element in the range of elements to be erased. /// /// /// Position of the first element beyond the range of elements to be erased. /// /// /// The first member function removes the element of the controlled sequence pointed to by . The second /// member function removes the elements in the range [, ). /// The third member function removes the elements in the range delimited by /// concurrent_unordered_multimap::equal_range(_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or concurrent_unordered_multimap::end() if no such element exists. The third /// member function returns the number of elements it removes. /// /**/ iterator unsafe_erase(const_iterator _First, const_iterator _Last) { return _Mybase::unsafe_erase(_First, _Last); } /// /// Swaps the contents of two concurrent_unordered_multimap objects. This method is not concurrency-safe. /// /// /// The concurrent_unordered_multimap object to swap with. /// /**/ void swap(concurrent_unordered_multimap& _Umap) { _Mybase::swap(_Umap); } /// /// Returns the stored hash function object. /// /// /// The stored hash function object. /// /**/ hasher hash_function() const { return _M_comparator._M_hash_object; } /// /// Returns the stored equality comparison function object. /// /// /// The stored equality comparison function object. /// /**/ key_equal key_eq() const { return _M_comparator._M_key_compare_object; } }; } // namespace Concurrency namespace concurrency = Concurrency; #pragma warning(pop) #pragma pack(pop)