/*** * ==++== * * Copyright (c) Microsoft Corporation. All rights reserved. * * ==--== * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * concurrent_unordered_set.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 set traits template class _Concurrent_unordered_set_traits : public std::_Container_base { public: typedef _Key_type 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_set_traits() : _M_comparator() { } _Concurrent_unordered_set_traits(const _Key_comparator& _Traits) : _M_comparator(_Traits) { } typedef _Key_compare _Value_compare; static const _Key_type& _Key_function(const value_type& _Value) { return _Value; } _Key_comparator _M_comparator; // the comparator predicate for keys }; } // namespace details; /// /// The concurrent_unordered_set class is an concurrency-safe container that controls a varying-length sequence of /// elements of type _Key_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 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 set. This argument is optional and the default value is /// std::allocator<>. /// /// /// For detailed information on the concurrent_unordered_set class, see . /// /// /**/ template , typename _Key_equality = std::equal_to<_Key_type>, typename _Allocator_type = std::allocator<_Key_type> > class concurrent_unordered_set : public details::_Concurrent_hash< details::_Concurrent_unordered_set_traits<_Key_type, details::_Hash_compare<_Key_type, _Hasher, _Key_equality>, _Allocator_type, false> > { public: // Base type definitions typedef concurrent_unordered_set<_Key_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_set_traits<_Key_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 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 set. /// /// /// The initial number of buckets for this unordered set. /// /// /// The hash function for this unordered set. /// /// /// The equality comparison function for this unordered set. /// /// /// The allocator for this unordered set. /// /// /// All constructors store an allocator object and initialize the unordered set. /// The first constructor specifies an empty initial set 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 set. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered set . /// The last constructor specifies a move of the concurrent unordered set . /// /**/ explicit concurrent_unordered_set(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 set. /// /// /// The allocator for this unordered set. /// /// /// All constructors store an allocator object and initialize the unordered set. /// The first constructor specifies an empty initial set 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 set. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered set . /// The last constructor specifies a move of the concurrent unordered set . /// /**/ concurrent_unordered_set(const allocator_type& _Allocator) : _Mybase(8, _Key_compare(), _Allocator) { } /// /// Constructs a concurrent unordered set. /// /// /// 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 set. /// /// /// The hash function for this unordered set. /// /// /// The equality comparison function for this unordered set. /// /// /// The allocator for this unordered set. /// /// /// All constructors store an allocator object and initialize the unordered set. /// The first constructor specifies an empty initial set 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 set. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered set . /// The last constructor specifies a move of the concurrent unordered set . /// /**/ template concurrent_unordered_set(_Iterator _First, _Iterator _Last, 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 (; _First != _Last; ++_First) { _Insert(*_First); } } /// /// Constructs a concurrent unordered set. /// /// /// The source concurrent_unordered_set object to copy or move elements from. /// /// /// All constructors store an allocator object and initialize the unordered set. /// The first constructor specifies an empty initial set 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 set. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered set . /// The last constructor specifies a move of the concurrent unordered set . /// /**/ concurrent_unordered_set(const concurrent_unordered_set& _Uset) : _Mybase(_Uset) { } /// /// Constructs a concurrent unordered set. /// /// /// The source concurrent_unordered_set object to copy or move elements from. /// /// /// The allocator for this unordered set. /// /// /// All constructors store an allocator object and initialize the unordered set. /// The first constructor specifies an empty initial set 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 set. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered set . /// The last constructor specifies a move of the concurrent unordered set . /// /**/ concurrent_unordered_set(const concurrent_unordered_set& _Uset, const allocator_type& _Allocator) : _Mybase(_Uset, _Allocator) { } /// /// Constructs a concurrent unordered set. /// /// /// The source concurrent_unordered_set object to copy or move elements from. /// /// /// All constructors store an allocator object and initialize the unordered set. /// The first constructor specifies an empty initial set 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 set. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered set . /// The last constructor specifies a move of the concurrent unordered set . /// /**/ concurrent_unordered_set(concurrent_unordered_set&& _Uset) : _Mybase(std::move(_Uset)) { } /// /// Assigns the contents of another concurrent_unordered_set object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_set object. /// /// /// A reference to this concurrent_unordered_set object. /// /// /// After erasing any existing elements in a concurrent unordered set, operator= either copies or moves the contents of /// into the concurrent unordered set. /// /**/ concurrent_unordered_set& operator=(const concurrent_unordered_set& _Uset) { _Mybase::operator=(_Uset); return (*this); } /// /// Assigns the contents of another concurrent_unordered_set object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_set object. /// /// /// A reference to this concurrent_unordered_set object. /// /// /// After erasing any existing elements in a concurrent unordered set, operator= either copies or moves the contents of /// into the concurrent unordered set. /// /**/ concurrent_unordered_set& operator=(concurrent_unordered_set&& _Uset) { _Mybase::operator=(std::move(_Uset)); return (*this); } /// /// Adds elements to the concurrent_unordered_set 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_set 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 set 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_set. return _Insert(_Value).first; } /// /// Adds elements to the concurrent_unordered_set 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_set object. /// /// /// The type of the value inserted into the set. /// /// /// 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_set object. /// /// /// The type of the value inserted into the set. /// /// /// 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 set 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_set. return _Insert(std::forward<_Valty>(_Value)).first; } /// /// Removes elements from the concurrent_unordered_set at specified positions. This method is not concurrency-safe. /// /// /// The iterator position to erase from. /// /// /// The first member function removes the element 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 /// (_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or () 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_set at specified positions. This method is not concurrency-safe. /// /// /// The key value to erase. /// /// /// The first member function removes the element 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 /// (_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or () 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_set 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 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 /// (_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or () 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_set objects. This method is not concurrency-safe. /// /// /// The concurrent_unordered_set object to swap with. /// /**/ void swap(concurrent_unordered_set& _Uset) { _Mybase::swap(_Uset); } /// /// 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; } }; /// /// The concurrent_unordered_multiset class is an concurrency-safe container that controls a varying-length sequence of /// elements of type _Key_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 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<>. /// /// /// For detailed information on the concurrent_unordered_multiset class, see . /// /// /**/ template , typename _Key_equality = std::equal_to<_Key_type>, typename _Allocator_type = std::allocator<_Key_type> > class concurrent_unordered_multiset : public details::_Concurrent_hash< details::_Concurrent_unordered_set_traits<_Key_type, details::_Hash_compare<_Key_type, _Hasher, _Key_equality>, _Allocator_type, true> > { public: // Base type definitions typedef concurrent_unordered_multiset<_Key_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_set_traits<_Key_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 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 multiset. /// /// /// The initial number of buckets for this unordered multiset. /// /// /// The hash function for this unordered multiset. /// /// /// The equality comparison function for this unordered multiset. /// /// /// The allocator for this unordered multiset. /// /// /// All constructors store an allocator object and initialize the unordered multiset. /// The first constructor specifies an empty initial multiset 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 multiset. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multiset . /// The last constructor specifies a move of the concurrent unordered multiset . /// /**/ explicit concurrent_unordered_multiset(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 multiset. /// /// /// The allocator for this unordered multiset. /// /// /// All constructors store an allocator object and initialize the unordered multiset. /// The first constructor specifies an empty initial multiset 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 multiset. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multiset . /// The last constructor specifies a move of the concurrent unordered multiset . /// /**/ concurrent_unordered_multiset(const allocator_type& _Allocator) : _Mybase(8, _Key_compare(), _Allocator) { } /// /// Constructs a concurrent unordered multiset. /// /// /// 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 multiset. /// /// /// The hash function for this unordered multiset. /// /// /// The equality comparison function for this unordered multiset. /// /// /// The allocator for this unordered multiset. /// /// /// All constructors store an allocator object and initialize the unordered multiset. /// The first constructor specifies an empty initial multiset 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 multiset. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multiset . /// The last constructor specifies a move of the concurrent unordered multiset . /// /**/ template concurrent_unordered_multiset(_Iterator _First, _Iterator _Last, 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 (; _First != _Last; ++_First) { _Insert(*_First); } } /// /// Constructs a concurrent unordered multiset. /// /// /// The source concurrent_unordered_multiset object to copy elements from. /// /// /// All constructors store an allocator object and initialize the unordered multiset. /// The first constructor specifies an empty initial multiset 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 multiset. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multiset . /// The last constructor specifies a move of the concurrent unordered multiset . /// /**/ concurrent_unordered_multiset(const concurrent_unordered_multiset& _Uset) : _Mybase(_Uset) { } /// /// Constructs a concurrent unordered multiset. /// /// /// The source concurrent_unordered_multiset object to copy elements from. /// /// /// The allocator for this unordered multiset. /// /// /// All constructors store an allocator object and initialize the unordered multiset. /// The first constructor specifies an empty initial multiset 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 multiset. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multiset . /// The last constructor specifies a move of the concurrent unordered multiset . /// /**/ concurrent_unordered_multiset(const concurrent_unordered_multiset& _Uset, const allocator_type& _Allocator) : _Mybase(_Uset, _Allocator) { } /// /// Constructs a concurrent unordered multiset. /// /// /// The source concurrent_unordered_multiset object to move elements from. /// /// /// All constructors store an allocator object and initialize the unordered multiset. /// The first constructor specifies an empty initial multiset 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 multiset. /// The third constructor specifies values supplied by the iterator range [, ). /// The fourth and fifth constructors specify a copy of the concurrent unordered multiset . /// The last constructor specifies a move of the concurrent unordered multiset . /// /**/ concurrent_unordered_multiset(concurrent_unordered_multiset&& _Uset) : _Mybase(std::move(_Uset)) { } /// /// Assigns the contents of another concurrent_unordered_multiset object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_multiset object. /// /// /// A reference to this concurrent_unordered_multiset object. /// /// /// After erasing any existing elements in a concurrent unordered multiset, operator= either copies or moves the contents of /// into the concurrent unordered multiset. /// /**/ concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& _Uset) { _Mybase::operator=(_Uset); return (*this); } /// /// Assigns the contents of another concurrent_unordered_multiset object to this one. This method is not concurrency-safe. /// /// /// The source concurrent_unordered_multiset object. /// /// /// A reference to this concurrent_unordered_multiset object. /// /// /// After erasing any existing elements in a concurrent unordered multiset, operator= either copies or moves the contents of /// into the concurrent unordered multiset. /// /**/ concurrent_unordered_multiset& operator=(concurrent_unordered_multiset&& _Uset) { _Mybase::operator=(std::move(_Uset)); return (*this); } /// /// Adds elements to the concurrent_unordered_multiset 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_multiset 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_multiset. return _Insert(_Value).first; } /// /// Adds elements to the concurrent_unordered_multiset 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_multiset object. /// /// /// The type of the value inserted. /// /// /// 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_multiset object. /// /// /// The type of the value inserted. /// /// /// 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_multiset. return _Insert(std::forward<_Valty>(_Value)).first; } /// /// Removes elements from the concurrent_unordered_multiset at specified positions. This method is not concurrency-safe. /// /// /// The iterator position to erase from. /// /// /// The first member function removes the element 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 /// (_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or () 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_multiset 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 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 /// (_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or () 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); } /// /// Removes elements from the concurrent_unordered_multiset at specified positions. This method is not concurrency-safe. /// /// /// The key value to erase. /// /// /// The first member function removes the element 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 /// (_Keyval). /// /// /// The first two member functions return an iterator that designates the first element remaining beyond any elements removed, /// or () 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_multiset objects. This method is not concurrency-safe. /// /// /// The concurrent_unordered_multiset object to swap with. /// /**/ void swap(concurrent_unordered_multiset& _Uset) { _Mybase::swap(_Uset); } /// /// Returns the stored hash function object. /// /// /// The stored hash function object. /// /**/ hasher hash_function() const { return _M_comparator._M_hash_object; } /// /// 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)