xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/unordered_map.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // unordered_map implementation -*- C++ -*-
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2010-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /** @file bits/unordered_map.h
261debfc3dSmrg  *  This is an internal header file, included by other library headers.
271debfc3dSmrg  *  Do not attempt to use it directly. @headername{unordered_map}
281debfc3dSmrg  */
291debfc3dSmrg 
301debfc3dSmrg #ifndef _UNORDERED_MAP_H
311debfc3dSmrg #define _UNORDERED_MAP_H
321debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)331debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
341debfc3dSmrg {
35a2dc1f3fSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
361debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
371debfc3dSmrg 
381debfc3dSmrg   /// Base types for unordered_map.
391debfc3dSmrg   template<bool _Cache>
401debfc3dSmrg     using __umap_traits = __detail::_Hashtable_traits<_Cache, false, true>;
411debfc3dSmrg 
421debfc3dSmrg   template<typename _Key,
431debfc3dSmrg 	   typename _Tp,
441debfc3dSmrg 	   typename _Hash = hash<_Key>,
451debfc3dSmrg 	   typename _Pred = std::equal_to<_Key>,
461debfc3dSmrg 	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >,
471debfc3dSmrg 	   typename _Tr = __umap_traits<__cache_default<_Key, _Hash>::value>>
481debfc3dSmrg     using __umap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>,
491debfc3dSmrg                                         _Alloc, __detail::_Select1st,
501debfc3dSmrg 				        _Pred, _Hash,
511debfc3dSmrg 				        __detail::_Mod_range_hashing,
521debfc3dSmrg 				        __detail::_Default_ranged_hash,
531debfc3dSmrg 				        __detail::_Prime_rehash_policy, _Tr>;
541debfc3dSmrg 
551debfc3dSmrg   /// Base types for unordered_multimap.
561debfc3dSmrg   template<bool _Cache>
571debfc3dSmrg     using __ummap_traits = __detail::_Hashtable_traits<_Cache, false, false>;
581debfc3dSmrg 
591debfc3dSmrg   template<typename _Key,
601debfc3dSmrg 	   typename _Tp,
611debfc3dSmrg 	   typename _Hash = hash<_Key>,
621debfc3dSmrg 	   typename _Pred = std::equal_to<_Key>,
631debfc3dSmrg 	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >,
641debfc3dSmrg 	   typename _Tr = __ummap_traits<__cache_default<_Key, _Hash>::value>>
651debfc3dSmrg     using __ummap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>,
661debfc3dSmrg 					 _Alloc, __detail::_Select1st,
671debfc3dSmrg 					 _Pred, _Hash,
681debfc3dSmrg 					 __detail::_Mod_range_hashing,
691debfc3dSmrg 					 __detail::_Default_ranged_hash,
701debfc3dSmrg 					 __detail::_Prime_rehash_policy, _Tr>;
711debfc3dSmrg 
721debfc3dSmrg   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
731debfc3dSmrg     class unordered_multimap;
741debfc3dSmrg 
751debfc3dSmrg   /**
761debfc3dSmrg    *  @brief A standard container composed of unique keys (containing
771debfc3dSmrg    *  at most one of each key value) that associates values of another type
781debfc3dSmrg    *  with the keys.
791debfc3dSmrg    *
801debfc3dSmrg    *  @ingroup unordered_associative_containers
811debfc3dSmrg    *
821debfc3dSmrg    *  @tparam  _Key    Type of key objects.
831debfc3dSmrg    *  @tparam  _Tp     Type of mapped objects.
841debfc3dSmrg    *  @tparam  _Hash   Hashing function object type, defaults to hash<_Value>.
851debfc3dSmrg    *  @tparam  _Pred   Predicate function object type, defaults
861debfc3dSmrg    *                   to equal_to<_Value>.
871debfc3dSmrg    *  @tparam  _Alloc  Allocator type, defaults to
881debfc3dSmrg    *                   std::allocator<std::pair<const _Key, _Tp>>.
891debfc3dSmrg    *
901debfc3dSmrg    *  Meets the requirements of a <a href="tables.html#65">container</a>, and
911debfc3dSmrg    *  <a href="tables.html#xx">unordered associative container</a>
921debfc3dSmrg    *
931debfc3dSmrg    * The resulting value type of the container is std::pair<const _Key, _Tp>.
941debfc3dSmrg    *
951debfc3dSmrg    *  Base is _Hashtable, dispatched at compile time via template
961debfc3dSmrg    *  alias __umap_hashtable.
971debfc3dSmrg    */
98a2dc1f3fSmrg   template<typename _Key, typename _Tp,
99a2dc1f3fSmrg 	   typename _Hash = hash<_Key>,
100a2dc1f3fSmrg 	   typename _Pred = equal_to<_Key>,
101a2dc1f3fSmrg 	   typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
1021debfc3dSmrg     class unordered_map
1031debfc3dSmrg     {
1041debfc3dSmrg       typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
1051debfc3dSmrg       _Hashtable _M_h;
1061debfc3dSmrg 
1071debfc3dSmrg     public:
1081debfc3dSmrg       // typedefs:
109*8feb0f0bSmrg       ///@{
1101debfc3dSmrg       /// Public typedefs.
1111debfc3dSmrg       typedef typename _Hashtable::key_type	key_type;
1121debfc3dSmrg       typedef typename _Hashtable::value_type	value_type;
1131debfc3dSmrg       typedef typename _Hashtable::mapped_type	mapped_type;
1141debfc3dSmrg       typedef typename _Hashtable::hasher	hasher;
1151debfc3dSmrg       typedef typename _Hashtable::key_equal	key_equal;
1161debfc3dSmrg       typedef typename _Hashtable::allocator_type allocator_type;
117*8feb0f0bSmrg       ///@}
1181debfc3dSmrg 
119*8feb0f0bSmrg       ///@{
1201debfc3dSmrg       ///  Iterator-related typedefs.
1211debfc3dSmrg       typedef typename _Hashtable::pointer		pointer;
1221debfc3dSmrg       typedef typename _Hashtable::const_pointer	const_pointer;
1231debfc3dSmrg       typedef typename _Hashtable::reference		reference;
1241debfc3dSmrg       typedef typename _Hashtable::const_reference	const_reference;
1251debfc3dSmrg       typedef typename _Hashtable::iterator		iterator;
1261debfc3dSmrg       typedef typename _Hashtable::const_iterator	const_iterator;
1271debfc3dSmrg       typedef typename _Hashtable::local_iterator	local_iterator;
1281debfc3dSmrg       typedef typename _Hashtable::const_local_iterator	const_local_iterator;
1291debfc3dSmrg       typedef typename _Hashtable::size_type		size_type;
1301debfc3dSmrg       typedef typename _Hashtable::difference_type	difference_type;
131*8feb0f0bSmrg       ///@}
1321debfc3dSmrg 
1331debfc3dSmrg #if __cplusplus > 201402L
1341debfc3dSmrg       using node_type = typename _Hashtable::node_type;
1351debfc3dSmrg       using insert_return_type = typename _Hashtable::insert_return_type;
1361debfc3dSmrg #endif
1371debfc3dSmrg 
1381debfc3dSmrg       //construct/destroy/copy
1391debfc3dSmrg 
1401debfc3dSmrg       /// Default constructor.
1411debfc3dSmrg       unordered_map() = default;
1421debfc3dSmrg 
1431debfc3dSmrg       /**
1441debfc3dSmrg        *  @brief  Default constructor creates no elements.
1451debfc3dSmrg        *  @param __n  Minimal initial number of buckets.
1461debfc3dSmrg        *  @param __hf  A hash functor.
1471debfc3dSmrg        *  @param __eql  A key equality functor.
1481debfc3dSmrg        *  @param __a  An allocator object.
1491debfc3dSmrg        */
1501debfc3dSmrg       explicit
1511debfc3dSmrg       unordered_map(size_type __n,
1521debfc3dSmrg 		    const hasher& __hf = hasher(),
1531debfc3dSmrg 		    const key_equal& __eql = key_equal(),
1541debfc3dSmrg 		    const allocator_type& __a = allocator_type())
1551debfc3dSmrg       : _M_h(__n, __hf, __eql, __a)
1561debfc3dSmrg       { }
1571debfc3dSmrg 
1581debfc3dSmrg       /**
1591debfc3dSmrg        *  @brief  Builds an %unordered_map from a range.
1601debfc3dSmrg        *  @param  __first  An input iterator.
1611debfc3dSmrg        *  @param  __last  An input iterator.
1621debfc3dSmrg        *  @param __n  Minimal initial number of buckets.
1631debfc3dSmrg        *  @param __hf  A hash functor.
1641debfc3dSmrg        *  @param __eql  A key equality functor.
1651debfc3dSmrg        *  @param __a  An allocator object.
1661debfc3dSmrg        *
1671debfc3dSmrg        *  Create an %unordered_map consisting of copies of the elements from
1681debfc3dSmrg        *  [__first,__last).  This is linear in N (where N is
1691debfc3dSmrg        *  distance(__first,__last)).
1701debfc3dSmrg        */
1711debfc3dSmrg       template<typename _InputIterator>
1721debfc3dSmrg 	unordered_map(_InputIterator __first, _InputIterator __last,
1731debfc3dSmrg 		      size_type __n = 0,
1741debfc3dSmrg 		      const hasher& __hf = hasher(),
1751debfc3dSmrg 		      const key_equal& __eql = key_equal(),
1761debfc3dSmrg 		      const allocator_type& __a = allocator_type())
1771debfc3dSmrg 	: _M_h(__first, __last, __n, __hf, __eql, __a)
1781debfc3dSmrg 	{ }
1791debfc3dSmrg 
1801debfc3dSmrg       /// Copy constructor.
1811debfc3dSmrg       unordered_map(const unordered_map&) = default;
1821debfc3dSmrg 
1831debfc3dSmrg       /// Move constructor.
1841debfc3dSmrg       unordered_map(unordered_map&&) = default;
1851debfc3dSmrg 
1861debfc3dSmrg       /**
1871debfc3dSmrg        *  @brief Creates an %unordered_map with no elements.
1881debfc3dSmrg        *  @param __a An allocator object.
1891debfc3dSmrg        */
1901debfc3dSmrg       explicit
1911debfc3dSmrg       unordered_map(const allocator_type& __a)
1921debfc3dSmrg 	: _M_h(__a)
1931debfc3dSmrg       { }
1941debfc3dSmrg 
1951debfc3dSmrg       /*
1961debfc3dSmrg        *  @brief Copy constructor with allocator argument.
1971debfc3dSmrg        * @param  __uset  Input %unordered_map to copy.
1981debfc3dSmrg        * @param  __a  An allocator object.
1991debfc3dSmrg        */
2001debfc3dSmrg       unordered_map(const unordered_map& __umap,
2011debfc3dSmrg 		    const allocator_type& __a)
2021debfc3dSmrg       : _M_h(__umap._M_h, __a)
2031debfc3dSmrg       { }
2041debfc3dSmrg 
2051debfc3dSmrg       /*
2061debfc3dSmrg        *  @brief  Move constructor with allocator argument.
2071debfc3dSmrg        *  @param  __uset Input %unordered_map to move.
2081debfc3dSmrg        *  @param  __a    An allocator object.
2091debfc3dSmrg        */
2101debfc3dSmrg       unordered_map(unordered_map&& __umap,
2111debfc3dSmrg 		    const allocator_type& __a)
212*8feb0f0bSmrg 	noexcept( noexcept(_Hashtable(std::move(__umap._M_h), __a)) )
2131debfc3dSmrg       : _M_h(std::move(__umap._M_h), __a)
2141debfc3dSmrg       { }
2151debfc3dSmrg 
2161debfc3dSmrg       /**
2171debfc3dSmrg        *  @brief  Builds an %unordered_map from an initializer_list.
2181debfc3dSmrg        *  @param  __l  An initializer_list.
2191debfc3dSmrg        *  @param __n  Minimal initial number of buckets.
2201debfc3dSmrg        *  @param __hf  A hash functor.
2211debfc3dSmrg        *  @param __eql  A key equality functor.
2221debfc3dSmrg        *  @param  __a  An allocator object.
2231debfc3dSmrg        *
2241debfc3dSmrg        *  Create an %unordered_map consisting of copies of the elements in the
2251debfc3dSmrg        *  list. This is linear in N (where N is @a __l.size()).
2261debfc3dSmrg        */
2271debfc3dSmrg       unordered_map(initializer_list<value_type> __l,
2281debfc3dSmrg 		    size_type __n = 0,
2291debfc3dSmrg 		    const hasher& __hf = hasher(),
2301debfc3dSmrg 		    const key_equal& __eql = key_equal(),
2311debfc3dSmrg 		    const allocator_type& __a = allocator_type())
2321debfc3dSmrg       : _M_h(__l, __n, __hf, __eql, __a)
2331debfc3dSmrg       { }
2341debfc3dSmrg 
2351debfc3dSmrg       unordered_map(size_type __n, const allocator_type& __a)
2361debfc3dSmrg       : unordered_map(__n, hasher(), key_equal(), __a)
2371debfc3dSmrg       { }
2381debfc3dSmrg 
2391debfc3dSmrg       unordered_map(size_type __n, const hasher& __hf,
2401debfc3dSmrg 		    const allocator_type& __a)
2411debfc3dSmrg       : unordered_map(__n, __hf, key_equal(), __a)
2421debfc3dSmrg       { }
2431debfc3dSmrg 
2441debfc3dSmrg       template<typename _InputIterator>
2451debfc3dSmrg 	unordered_map(_InputIterator __first, _InputIterator __last,
2461debfc3dSmrg 		      size_type __n,
2471debfc3dSmrg 		      const allocator_type& __a)
2481debfc3dSmrg 	: unordered_map(__first, __last, __n, hasher(), key_equal(), __a)
2491debfc3dSmrg 	{ }
2501debfc3dSmrg 
2511debfc3dSmrg       template<typename _InputIterator>
2521debfc3dSmrg 	unordered_map(_InputIterator __first, _InputIterator __last,
2531debfc3dSmrg 		      size_type __n, const hasher& __hf,
2541debfc3dSmrg 		      const allocator_type& __a)
2551debfc3dSmrg 	  : unordered_map(__first, __last, __n, __hf, key_equal(), __a)
2561debfc3dSmrg 	{ }
2571debfc3dSmrg 
2581debfc3dSmrg       unordered_map(initializer_list<value_type> __l,
2591debfc3dSmrg 		    size_type __n,
2601debfc3dSmrg 		    const allocator_type& __a)
2611debfc3dSmrg       : unordered_map(__l, __n, hasher(), key_equal(), __a)
2621debfc3dSmrg       { }
2631debfc3dSmrg 
2641debfc3dSmrg       unordered_map(initializer_list<value_type> __l,
2651debfc3dSmrg 		    size_type __n, const hasher& __hf,
2661debfc3dSmrg 		    const allocator_type& __a)
2671debfc3dSmrg       : unordered_map(__l, __n, __hf, key_equal(), __a)
2681debfc3dSmrg       { }
2691debfc3dSmrg 
2701debfc3dSmrg       /// Copy assignment operator.
2711debfc3dSmrg       unordered_map&
2721debfc3dSmrg       operator=(const unordered_map&) = default;
2731debfc3dSmrg 
2741debfc3dSmrg       /// Move assignment operator.
2751debfc3dSmrg       unordered_map&
2761debfc3dSmrg       operator=(unordered_map&&) = default;
2771debfc3dSmrg 
2781debfc3dSmrg       /**
2791debfc3dSmrg        *  @brief  %Unordered_map list assignment operator.
2801debfc3dSmrg        *  @param  __l  An initializer_list.
2811debfc3dSmrg        *
2821debfc3dSmrg        *  This function fills an %unordered_map with copies of the elements in
2831debfc3dSmrg        *  the initializer list @a __l.
2841debfc3dSmrg        *
2851debfc3dSmrg        *  Note that the assignment completely changes the %unordered_map and
2861debfc3dSmrg        *  that the resulting %unordered_map's size is the same as the number
2871debfc3dSmrg        *  of elements assigned.
2881debfc3dSmrg        */
2891debfc3dSmrg       unordered_map&
2901debfc3dSmrg       operator=(initializer_list<value_type> __l)
2911debfc3dSmrg       {
2921debfc3dSmrg 	_M_h = __l;
2931debfc3dSmrg 	return *this;
2941debfc3dSmrg       }
2951debfc3dSmrg 
2961debfc3dSmrg       ///  Returns the allocator object used by the %unordered_map.
2971debfc3dSmrg       allocator_type
2981debfc3dSmrg       get_allocator() const noexcept
2991debfc3dSmrg       { return _M_h.get_allocator(); }
3001debfc3dSmrg 
3011debfc3dSmrg       // size and capacity:
3021debfc3dSmrg 
3031debfc3dSmrg       ///  Returns true if the %unordered_map is empty.
304c0a68be4Smrg       _GLIBCXX_NODISCARD bool
3051debfc3dSmrg       empty() const noexcept
3061debfc3dSmrg       { return _M_h.empty(); }
3071debfc3dSmrg 
3081debfc3dSmrg       ///  Returns the size of the %unordered_map.
3091debfc3dSmrg       size_type
3101debfc3dSmrg       size() const noexcept
3111debfc3dSmrg       { return _M_h.size(); }
3121debfc3dSmrg 
3131debfc3dSmrg       ///  Returns the maximum size of the %unordered_map.
3141debfc3dSmrg       size_type
3151debfc3dSmrg       max_size() const noexcept
3161debfc3dSmrg       { return _M_h.max_size(); }
3171debfc3dSmrg 
3181debfc3dSmrg       // iterators.
3191debfc3dSmrg 
3201debfc3dSmrg       /**
3211debfc3dSmrg        *  Returns a read/write iterator that points to the first element in the
3221debfc3dSmrg        *  %unordered_map.
3231debfc3dSmrg        */
3241debfc3dSmrg       iterator
3251debfc3dSmrg       begin() noexcept
3261debfc3dSmrg       { return _M_h.begin(); }
3271debfc3dSmrg 
328*8feb0f0bSmrg       ///@{
3291debfc3dSmrg       /**
3301debfc3dSmrg        *  Returns a read-only (constant) iterator that points to the first
3311debfc3dSmrg        *  element in the %unordered_map.
3321debfc3dSmrg        */
3331debfc3dSmrg       const_iterator
3341debfc3dSmrg       begin() const noexcept
3351debfc3dSmrg       { return _M_h.begin(); }
3361debfc3dSmrg 
3371debfc3dSmrg       const_iterator
3381debfc3dSmrg       cbegin() const noexcept
3391debfc3dSmrg       { return _M_h.begin(); }
340*8feb0f0bSmrg       ///@}
3411debfc3dSmrg 
3421debfc3dSmrg       /**
3431debfc3dSmrg        *  Returns a read/write iterator that points one past the last element in
3441debfc3dSmrg        *  the %unordered_map.
3451debfc3dSmrg        */
3461debfc3dSmrg       iterator
3471debfc3dSmrg       end() noexcept
3481debfc3dSmrg       { return _M_h.end(); }
3491debfc3dSmrg 
350*8feb0f0bSmrg       ///@{
3511debfc3dSmrg       /**
3521debfc3dSmrg        *  Returns a read-only (constant) iterator that points one past the last
3531debfc3dSmrg        *  element in the %unordered_map.
3541debfc3dSmrg        */
3551debfc3dSmrg       const_iterator
3561debfc3dSmrg       end() const noexcept
3571debfc3dSmrg       { return _M_h.end(); }
3581debfc3dSmrg 
3591debfc3dSmrg       const_iterator
3601debfc3dSmrg       cend() const noexcept
3611debfc3dSmrg       { return _M_h.end(); }
362*8feb0f0bSmrg       ///@}
3631debfc3dSmrg 
3641debfc3dSmrg       // modifiers.
3651debfc3dSmrg 
3661debfc3dSmrg       /**
3671debfc3dSmrg        *  @brief Attempts to build and insert a std::pair into the
3681debfc3dSmrg        *  %unordered_map.
3691debfc3dSmrg        *
3701debfc3dSmrg        *  @param __args  Arguments used to generate a new pair instance (see
3711debfc3dSmrg        *	        std::piecewise_contruct for passing arguments to each
3721debfc3dSmrg        *	        part of the pair constructor).
3731debfc3dSmrg        *
3741debfc3dSmrg        *  @return  A pair, of which the first element is an iterator that points
3751debfc3dSmrg        *           to the possibly inserted pair, and the second is a bool that
3761debfc3dSmrg        *           is true if the pair was actually inserted.
3771debfc3dSmrg        *
3781debfc3dSmrg        *  This function attempts to build and insert a (key, value) %pair into
3791debfc3dSmrg        *  the %unordered_map.
3801debfc3dSmrg        *  An %unordered_map relies on unique keys and thus a %pair is only
3811debfc3dSmrg        *  inserted if its first element (the key) is not already present in the
3821debfc3dSmrg        *  %unordered_map.
3831debfc3dSmrg        *
3841debfc3dSmrg        *  Insertion requires amortized constant time.
3851debfc3dSmrg        */
3861debfc3dSmrg       template<typename... _Args>
3871debfc3dSmrg 	std::pair<iterator, bool>
3881debfc3dSmrg 	emplace(_Args&&... __args)
3891debfc3dSmrg 	{ return _M_h.emplace(std::forward<_Args>(__args)...); }
3901debfc3dSmrg 
3911debfc3dSmrg       /**
3921debfc3dSmrg        *  @brief Attempts to build and insert a std::pair into the
3931debfc3dSmrg        *  %unordered_map.
3941debfc3dSmrg        *
3951debfc3dSmrg        *  @param  __pos  An iterator that serves as a hint as to where the pair
3961debfc3dSmrg        *                should be inserted.
3971debfc3dSmrg        *  @param  __args  Arguments used to generate a new pair instance (see
3981debfc3dSmrg        *	         std::piecewise_contruct for passing arguments to each
3991debfc3dSmrg        *	         part of the pair constructor).
4001debfc3dSmrg        *  @return An iterator that points to the element with key of the
4011debfc3dSmrg        *          std::pair built from @a __args (may or may not be that
4021debfc3dSmrg        *          std::pair).
4031debfc3dSmrg        *
4041debfc3dSmrg        *  This function is not concerned about whether the insertion took place,
4051debfc3dSmrg        *  and thus does not return a boolean like the single-argument emplace()
4061debfc3dSmrg        *  does.
4071debfc3dSmrg        *  Note that the first parameter is only a hint and can potentially
4081debfc3dSmrg        *  improve the performance of the insertion process. A bad hint would
4091debfc3dSmrg        *  cause no gains in efficiency.
4101debfc3dSmrg        *
4111debfc3dSmrg        *  See
4121debfc3dSmrg        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
4131debfc3dSmrg        *  for more on @a hinting.
4141debfc3dSmrg        *
4151debfc3dSmrg        *  Insertion requires amortized constant time.
4161debfc3dSmrg        */
4171debfc3dSmrg       template<typename... _Args>
4181debfc3dSmrg 	iterator
4191debfc3dSmrg 	emplace_hint(const_iterator __pos, _Args&&... __args)
4201debfc3dSmrg 	{ return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
4211debfc3dSmrg 
4221debfc3dSmrg #if __cplusplus > 201402L
4231debfc3dSmrg       /// Extract a node.
4241debfc3dSmrg       node_type
4251debfc3dSmrg       extract(const_iterator __pos)
4261debfc3dSmrg       {
4271debfc3dSmrg 	__glibcxx_assert(__pos != end());
4281debfc3dSmrg 	return _M_h.extract(__pos);
4291debfc3dSmrg       }
4301debfc3dSmrg 
4311debfc3dSmrg       /// Extract a node.
4321debfc3dSmrg       node_type
4331debfc3dSmrg       extract(const key_type& __key)
4341debfc3dSmrg       { return _M_h.extract(__key); }
4351debfc3dSmrg 
4361debfc3dSmrg       /// Re-insert an extracted node.
4371debfc3dSmrg       insert_return_type
4381debfc3dSmrg       insert(node_type&& __nh)
4391debfc3dSmrg       { return _M_h._M_reinsert_node(std::move(__nh)); }
4401debfc3dSmrg 
4411debfc3dSmrg       /// Re-insert an extracted node.
4421debfc3dSmrg       iterator
4431debfc3dSmrg       insert(const_iterator, node_type&& __nh)
4441debfc3dSmrg       { return _M_h._M_reinsert_node(std::move(__nh)).position; }
4451debfc3dSmrg 
4461debfc3dSmrg #define __cpp_lib_unordered_map_try_emplace 201411
4471debfc3dSmrg       /**
4481debfc3dSmrg        *  @brief Attempts to build and insert a std::pair into the
4491debfc3dSmrg        *  %unordered_map.
4501debfc3dSmrg        *
4511debfc3dSmrg        *  @param __k    Key to use for finding a possibly existing pair in
4521debfc3dSmrg        *                the unordered_map.
4531debfc3dSmrg        *  @param __args  Arguments used to generate the .second for a
4541debfc3dSmrg        *                new pair instance.
4551debfc3dSmrg        *
4561debfc3dSmrg        *  @return  A pair, of which the first element is an iterator that points
4571debfc3dSmrg        *           to the possibly inserted pair, and the second is a bool that
4581debfc3dSmrg        *           is true if the pair was actually inserted.
4591debfc3dSmrg        *
4601debfc3dSmrg        *  This function attempts to build and insert a (key, value) %pair into
4611debfc3dSmrg        *  the %unordered_map.
4621debfc3dSmrg        *  An %unordered_map relies on unique keys and thus a %pair is only
4631debfc3dSmrg        *  inserted if its first element (the key) is not already present in the
4641debfc3dSmrg        *  %unordered_map.
4651debfc3dSmrg        *  If a %pair is not inserted, this function has no effect.
4661debfc3dSmrg        *
4671debfc3dSmrg        *  Insertion requires amortized constant time.
4681debfc3dSmrg        */
4691debfc3dSmrg       template <typename... _Args>
4701debfc3dSmrg         pair<iterator, bool>
4711debfc3dSmrg         try_emplace(const key_type& __k, _Args&&... __args)
4721debfc3dSmrg         {
4731debfc3dSmrg           iterator __i = find(__k);
4741debfc3dSmrg           if (__i == end())
4751debfc3dSmrg             {
4761debfc3dSmrg               __i = emplace(std::piecewise_construct,
4771debfc3dSmrg                             std::forward_as_tuple(__k),
4781debfc3dSmrg                             std::forward_as_tuple(
4791debfc3dSmrg                               std::forward<_Args>(__args)...))
4801debfc3dSmrg                 .first;
4811debfc3dSmrg               return {__i, true};
4821debfc3dSmrg             }
4831debfc3dSmrg           return {__i, false};
4841debfc3dSmrg         }
4851debfc3dSmrg 
4861debfc3dSmrg       // move-capable overload
4871debfc3dSmrg       template <typename... _Args>
4881debfc3dSmrg         pair<iterator, bool>
4891debfc3dSmrg         try_emplace(key_type&& __k, _Args&&... __args)
4901debfc3dSmrg         {
4911debfc3dSmrg           iterator __i = find(__k);
4921debfc3dSmrg           if (__i == end())
4931debfc3dSmrg             {
4941debfc3dSmrg               __i = emplace(std::piecewise_construct,
4951debfc3dSmrg                             std::forward_as_tuple(std::move(__k)),
4961debfc3dSmrg                             std::forward_as_tuple(
4971debfc3dSmrg                               std::forward<_Args>(__args)...))
4981debfc3dSmrg                 .first;
4991debfc3dSmrg               return {__i, true};
5001debfc3dSmrg             }
5011debfc3dSmrg           return {__i, false};
5021debfc3dSmrg         }
5031debfc3dSmrg 
5041debfc3dSmrg       /**
5051debfc3dSmrg        *  @brief Attempts to build and insert a std::pair into the
5061debfc3dSmrg        *  %unordered_map.
5071debfc3dSmrg        *
5081debfc3dSmrg        *  @param  __hint  An iterator that serves as a hint as to where the pair
5091debfc3dSmrg        *                should be inserted.
5101debfc3dSmrg        *  @param __k    Key to use for finding a possibly existing pair in
5111debfc3dSmrg        *                the unordered_map.
5121debfc3dSmrg        *  @param __args  Arguments used to generate the .second for a
5131debfc3dSmrg        *                new pair instance.
5141debfc3dSmrg        *  @return An iterator that points to the element with key of the
5151debfc3dSmrg        *          std::pair built from @a __args (may or may not be that
5161debfc3dSmrg        *          std::pair).
5171debfc3dSmrg        *
5181debfc3dSmrg        *  This function is not concerned about whether the insertion took place,
5191debfc3dSmrg        *  and thus does not return a boolean like the single-argument emplace()
5201debfc3dSmrg        *  does. However, if insertion did not take place,
5211debfc3dSmrg        *  this function has no effect.
5221debfc3dSmrg        *  Note that the first parameter is only a hint and can potentially
5231debfc3dSmrg        *  improve the performance of the insertion process. A bad hint would
5241debfc3dSmrg        *  cause no gains in efficiency.
5251debfc3dSmrg        *
5261debfc3dSmrg        *  See
5271debfc3dSmrg        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
5281debfc3dSmrg        *  for more on @a hinting.
5291debfc3dSmrg        *
5301debfc3dSmrg        *  Insertion requires amortized constant time.
5311debfc3dSmrg        */
5321debfc3dSmrg       template <typename... _Args>
5331debfc3dSmrg         iterator
5341debfc3dSmrg         try_emplace(const_iterator __hint, const key_type& __k,
5351debfc3dSmrg                     _Args&&... __args)
5361debfc3dSmrg         {
5371debfc3dSmrg           iterator __i = find(__k);
5381debfc3dSmrg           if (__i == end())
5391debfc3dSmrg             __i = emplace_hint(__hint, std::piecewise_construct,
5401debfc3dSmrg                                std::forward_as_tuple(__k),
5411debfc3dSmrg                                std::forward_as_tuple(
5421debfc3dSmrg                                  std::forward<_Args>(__args)...));
5431debfc3dSmrg           return __i;
5441debfc3dSmrg         }
5451debfc3dSmrg 
5461debfc3dSmrg       // move-capable overload
5471debfc3dSmrg       template <typename... _Args>
5481debfc3dSmrg         iterator
5491debfc3dSmrg         try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
5501debfc3dSmrg         {
5511debfc3dSmrg           iterator __i = find(__k);
5521debfc3dSmrg           if (__i == end())
5531debfc3dSmrg             __i = emplace_hint(__hint, std::piecewise_construct,
5541debfc3dSmrg                                std::forward_as_tuple(std::move(__k)),
5551debfc3dSmrg                                std::forward_as_tuple(
5561debfc3dSmrg                                  std::forward<_Args>(__args)...));
5571debfc3dSmrg           return __i;
5581debfc3dSmrg         }
5591debfc3dSmrg #endif // C++17
5601debfc3dSmrg 
561*8feb0f0bSmrg       ///@{
5621debfc3dSmrg       /**
5631debfc3dSmrg        *  @brief Attempts to insert a std::pair into the %unordered_map.
5641debfc3dSmrg 
5651debfc3dSmrg        *  @param __x Pair to be inserted (see std::make_pair for easy
5661debfc3dSmrg        *	     creation of pairs).
5671debfc3dSmrg        *
5681debfc3dSmrg        *  @return  A pair, of which the first element is an iterator that
5691debfc3dSmrg        *           points to the possibly inserted pair, and the second is
5701debfc3dSmrg        *           a bool that is true if the pair was actually inserted.
5711debfc3dSmrg        *
5721debfc3dSmrg        *  This function attempts to insert a (key, value) %pair into the
5731debfc3dSmrg        *  %unordered_map. An %unordered_map relies on unique keys and thus a
5741debfc3dSmrg        *  %pair is only inserted if its first element (the key) is not already
5751debfc3dSmrg        *  present in the %unordered_map.
5761debfc3dSmrg        *
5771debfc3dSmrg        *  Insertion requires amortized constant time.
5781debfc3dSmrg        */
5791debfc3dSmrg       std::pair<iterator, bool>
5801debfc3dSmrg       insert(const value_type& __x)
5811debfc3dSmrg       { return _M_h.insert(__x); }
5821debfc3dSmrg 
5831debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
5841debfc3dSmrg       // 2354. Unnecessary copying when inserting into maps with braced-init
5851debfc3dSmrg       std::pair<iterator, bool>
5861debfc3dSmrg       insert(value_type&& __x)
5871debfc3dSmrg       { return _M_h.insert(std::move(__x)); }
5881debfc3dSmrg 
5891debfc3dSmrg       template<typename _Pair>
5901debfc3dSmrg 	__enable_if_t<is_constructible<value_type, _Pair&&>::value,
5911debfc3dSmrg 		      pair<iterator, bool>>
5921debfc3dSmrg 	insert(_Pair&& __x)
5931debfc3dSmrg         { return _M_h.emplace(std::forward<_Pair>(__x)); }
594*8feb0f0bSmrg       ///@}
5951debfc3dSmrg 
596*8feb0f0bSmrg       ///@{
5971debfc3dSmrg       /**
5981debfc3dSmrg        *  @brief Attempts to insert a std::pair into the %unordered_map.
5991debfc3dSmrg        *  @param  __hint  An iterator that serves as a hint as to where the
6001debfc3dSmrg        *                 pair should be inserted.
6011debfc3dSmrg        *  @param  __x  Pair to be inserted (see std::make_pair for easy creation
6021debfc3dSmrg        *               of pairs).
6031debfc3dSmrg        *  @return An iterator that points to the element with key of
6041debfc3dSmrg        *           @a __x (may or may not be the %pair passed in).
6051debfc3dSmrg        *
6061debfc3dSmrg        *  This function is not concerned about whether the insertion took place,
6071debfc3dSmrg        *  and thus does not return a boolean like the single-argument insert()
6081debfc3dSmrg        *  does.  Note that the first parameter is only a hint and can
6091debfc3dSmrg        *  potentially improve the performance of the insertion process.  A bad
6101debfc3dSmrg        *  hint would cause no gains in efficiency.
6111debfc3dSmrg        *
6121debfc3dSmrg        *  See
6131debfc3dSmrg        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
6141debfc3dSmrg        *  for more on @a hinting.
6151debfc3dSmrg        *
6161debfc3dSmrg        *  Insertion requires amortized constant time.
6171debfc3dSmrg        */
6181debfc3dSmrg       iterator
6191debfc3dSmrg       insert(const_iterator __hint, const value_type& __x)
6201debfc3dSmrg       { return _M_h.insert(__hint, __x); }
6211debfc3dSmrg 
6221debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
6231debfc3dSmrg       // 2354. Unnecessary copying when inserting into maps with braced-init
6241debfc3dSmrg       iterator
6251debfc3dSmrg       insert(const_iterator __hint, value_type&& __x)
6261debfc3dSmrg       { return _M_h.insert(__hint, std::move(__x)); }
6271debfc3dSmrg 
6281debfc3dSmrg       template<typename _Pair>
6291debfc3dSmrg 	__enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
6301debfc3dSmrg 	insert(const_iterator __hint, _Pair&& __x)
6311debfc3dSmrg 	{ return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); }
632*8feb0f0bSmrg       ///@}
6331debfc3dSmrg 
6341debfc3dSmrg       /**
6351debfc3dSmrg        *  @brief A template function that attempts to insert a range of
6361debfc3dSmrg        *  elements.
6371debfc3dSmrg        *  @param  __first  Iterator pointing to the start of the range to be
6381debfc3dSmrg        *                   inserted.
6391debfc3dSmrg        *  @param  __last  Iterator pointing to the end of the range.
6401debfc3dSmrg        *
6411debfc3dSmrg        *  Complexity similar to that of the range constructor.
6421debfc3dSmrg        */
6431debfc3dSmrg       template<typename _InputIterator>
6441debfc3dSmrg 	void
6451debfc3dSmrg 	insert(_InputIterator __first, _InputIterator __last)
6461debfc3dSmrg 	{ _M_h.insert(__first, __last); }
6471debfc3dSmrg 
6481debfc3dSmrg       /**
6491debfc3dSmrg        *  @brief Attempts to insert a list of elements into the %unordered_map.
6501debfc3dSmrg        *  @param  __l  A std::initializer_list<value_type> of elements
6511debfc3dSmrg        *               to be inserted.
6521debfc3dSmrg        *
6531debfc3dSmrg        *  Complexity similar to that of the range constructor.
6541debfc3dSmrg        */
6551debfc3dSmrg       void
6561debfc3dSmrg       insert(initializer_list<value_type> __l)
6571debfc3dSmrg       { _M_h.insert(__l); }
6581debfc3dSmrg 
6591debfc3dSmrg 
6601debfc3dSmrg #if __cplusplus > 201402L
6611debfc3dSmrg       /**
6621debfc3dSmrg        *  @brief Attempts to insert a std::pair into the %unordered_map.
6631debfc3dSmrg        *  @param __k    Key to use for finding a possibly existing pair in
6641debfc3dSmrg        *                the map.
6651debfc3dSmrg        *  @param __obj  Argument used to generate the .second for a pair
6661debfc3dSmrg        *                instance.
6671debfc3dSmrg        *
6681debfc3dSmrg        *  @return  A pair, of which the first element is an iterator that
6691debfc3dSmrg        *           points to the possibly inserted pair, and the second is
6701debfc3dSmrg        *           a bool that is true if the pair was actually inserted.
6711debfc3dSmrg        *
6721debfc3dSmrg        *  This function attempts to insert a (key, value) %pair into the
6731debfc3dSmrg        *  %unordered_map. An %unordered_map relies on unique keys and thus a
6741debfc3dSmrg        *  %pair is only inserted if its first element (the key) is not already
6751debfc3dSmrg        *  present in the %unordered_map.
6761debfc3dSmrg        *  If the %pair was already in the %unordered_map, the .second of
6771debfc3dSmrg        *  the %pair is assigned from __obj.
6781debfc3dSmrg        *
6791debfc3dSmrg        *  Insertion requires amortized constant time.
6801debfc3dSmrg        */
6811debfc3dSmrg       template <typename _Obj>
6821debfc3dSmrg         pair<iterator, bool>
6831debfc3dSmrg         insert_or_assign(const key_type& __k, _Obj&& __obj)
6841debfc3dSmrg         {
6851debfc3dSmrg           iterator __i = find(__k);
6861debfc3dSmrg           if (__i == end())
6871debfc3dSmrg             {
6881debfc3dSmrg               __i = emplace(std::piecewise_construct,
6891debfc3dSmrg                             std::forward_as_tuple(__k),
6901debfc3dSmrg                             std::forward_as_tuple(std::forward<_Obj>(__obj)))
6911debfc3dSmrg                 .first;
6921debfc3dSmrg               return {__i, true};
6931debfc3dSmrg             }
6941debfc3dSmrg           (*__i).second = std::forward<_Obj>(__obj);
6951debfc3dSmrg           return {__i, false};
6961debfc3dSmrg         }
6971debfc3dSmrg 
6981debfc3dSmrg       // move-capable overload
6991debfc3dSmrg       template <typename _Obj>
7001debfc3dSmrg         pair<iterator, bool>
7011debfc3dSmrg         insert_or_assign(key_type&& __k, _Obj&& __obj)
7021debfc3dSmrg         {
7031debfc3dSmrg           iterator __i = find(__k);
7041debfc3dSmrg           if (__i == end())
7051debfc3dSmrg             {
7061debfc3dSmrg               __i = emplace(std::piecewise_construct,
7071debfc3dSmrg                             std::forward_as_tuple(std::move(__k)),
7081debfc3dSmrg                             std::forward_as_tuple(std::forward<_Obj>(__obj)))
7091debfc3dSmrg                 .first;
7101debfc3dSmrg               return {__i, true};
7111debfc3dSmrg             }
7121debfc3dSmrg           (*__i).second = std::forward<_Obj>(__obj);
7131debfc3dSmrg           return {__i, false};
7141debfc3dSmrg         }
7151debfc3dSmrg 
7161debfc3dSmrg       /**
7171debfc3dSmrg        *  @brief Attempts to insert a std::pair into the %unordered_map.
7181debfc3dSmrg        *  @param  __hint  An iterator that serves as a hint as to where the
7191debfc3dSmrg        *                  pair should be inserted.
7201debfc3dSmrg        *  @param __k    Key to use for finding a possibly existing pair in
7211debfc3dSmrg        *                the unordered_map.
7221debfc3dSmrg        *  @param __obj  Argument used to generate the .second for a pair
7231debfc3dSmrg        *                instance.
7241debfc3dSmrg        *  @return An iterator that points to the element with key of
7251debfc3dSmrg        *           @a __x (may or may not be the %pair passed in).
7261debfc3dSmrg        *
7271debfc3dSmrg        *  This function is not concerned about whether the insertion took place,
7281debfc3dSmrg        *  and thus does not return a boolean like the single-argument insert()
7291debfc3dSmrg        *  does.
7301debfc3dSmrg        *  If the %pair was already in the %unordered map, the .second of
7311debfc3dSmrg        *  the %pair is assigned from __obj.
7321debfc3dSmrg        *  Note that the first parameter is only a hint and can
7331debfc3dSmrg        *  potentially improve the performance of the insertion process.  A bad
7341debfc3dSmrg        *  hint would cause no gains in efficiency.
7351debfc3dSmrg        *
7361debfc3dSmrg        *  See
7371debfc3dSmrg        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
7381debfc3dSmrg        *  for more on @a hinting.
7391debfc3dSmrg        *
7401debfc3dSmrg        *  Insertion requires amortized constant time.
7411debfc3dSmrg        */
7421debfc3dSmrg       template <typename _Obj>
7431debfc3dSmrg         iterator
7441debfc3dSmrg         insert_or_assign(const_iterator __hint, const key_type& __k,
7451debfc3dSmrg                          _Obj&& __obj)
7461debfc3dSmrg         {
7471debfc3dSmrg           iterator __i = find(__k);
7481debfc3dSmrg           if (__i == end())
7491debfc3dSmrg             {
7501debfc3dSmrg               return emplace_hint(__hint, std::piecewise_construct,
7511debfc3dSmrg                                   std::forward_as_tuple(__k),
7521debfc3dSmrg                                   std::forward_as_tuple(
7531debfc3dSmrg                                     std::forward<_Obj>(__obj)));
7541debfc3dSmrg             }
7551debfc3dSmrg           (*__i).second = std::forward<_Obj>(__obj);
7561debfc3dSmrg           return __i;
7571debfc3dSmrg         }
7581debfc3dSmrg 
7591debfc3dSmrg       // move-capable overload
7601debfc3dSmrg       template <typename _Obj>
7611debfc3dSmrg         iterator
7621debfc3dSmrg         insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
7631debfc3dSmrg         {
7641debfc3dSmrg           iterator __i = find(__k);
7651debfc3dSmrg           if (__i == end())
7661debfc3dSmrg             {
7671debfc3dSmrg               return emplace_hint(__hint, std::piecewise_construct,
7681debfc3dSmrg                                   std::forward_as_tuple(std::move(__k)),
7691debfc3dSmrg                                   std::forward_as_tuple(
7701debfc3dSmrg                                     std::forward<_Obj>(__obj)));
7711debfc3dSmrg             }
7721debfc3dSmrg           (*__i).second = std::forward<_Obj>(__obj);
7731debfc3dSmrg           return __i;
7741debfc3dSmrg         }
7751debfc3dSmrg #endif
7761debfc3dSmrg 
777*8feb0f0bSmrg       ///@{
7781debfc3dSmrg       /**
7791debfc3dSmrg        *  @brief Erases an element from an %unordered_map.
7801debfc3dSmrg        *  @param  __position  An iterator pointing to the element to be erased.
7811debfc3dSmrg        *  @return An iterator pointing to the element immediately following
7821debfc3dSmrg        *          @a __position prior to the element being erased. If no such
7831debfc3dSmrg        *          element exists, end() is returned.
7841debfc3dSmrg        *
7851debfc3dSmrg        *  This function erases an element, pointed to by the given iterator,
7861debfc3dSmrg        *  from an %unordered_map.
7871debfc3dSmrg        *  Note that this function only erases the element, and that if the
7881debfc3dSmrg        *  element is itself a pointer, the pointed-to memory is not touched in
7891debfc3dSmrg        *  any way.  Managing the pointer is the user's responsibility.
7901debfc3dSmrg        */
7911debfc3dSmrg       iterator
7921debfc3dSmrg       erase(const_iterator __position)
7931debfc3dSmrg       { return _M_h.erase(__position); }
7941debfc3dSmrg 
7951debfc3dSmrg       // LWG 2059.
7961debfc3dSmrg       iterator
7971debfc3dSmrg       erase(iterator __position)
7981debfc3dSmrg       { return _M_h.erase(__position); }
799*8feb0f0bSmrg       ///@}
8001debfc3dSmrg 
8011debfc3dSmrg       /**
8021debfc3dSmrg        *  @brief Erases elements according to the provided key.
8031debfc3dSmrg        *  @param  __x  Key of element to be erased.
8041debfc3dSmrg        *  @return  The number of elements erased.
8051debfc3dSmrg        *
8061debfc3dSmrg        *  This function erases all the elements located by the given key from
8071debfc3dSmrg        *  an %unordered_map. For an %unordered_map the result of this function
8081debfc3dSmrg        *  can only be 0 (not present) or 1 (present).
8091debfc3dSmrg        *  Note that this function only erases the element, and that if the
8101debfc3dSmrg        *  element is itself a pointer, the pointed-to memory is not touched in
8111debfc3dSmrg        *  any way.  Managing the pointer is the user's responsibility.
8121debfc3dSmrg        */
8131debfc3dSmrg       size_type
8141debfc3dSmrg       erase(const key_type& __x)
8151debfc3dSmrg       { return _M_h.erase(__x); }
8161debfc3dSmrg 
8171debfc3dSmrg       /**
8181debfc3dSmrg        *  @brief Erases a [__first,__last) range of elements from an
8191debfc3dSmrg        *  %unordered_map.
8201debfc3dSmrg        *  @param  __first  Iterator pointing to the start of the range to be
8211debfc3dSmrg        *                  erased.
8221debfc3dSmrg        *  @param __last  Iterator pointing to the end of the range to
8231debfc3dSmrg        *                be erased.
8241debfc3dSmrg        *  @return The iterator @a __last.
8251debfc3dSmrg        *
8261debfc3dSmrg        *  This function erases a sequence of elements from an %unordered_map.
8271debfc3dSmrg        *  Note that this function only erases the elements, and that if
8281debfc3dSmrg        *  the element is itself a pointer, the pointed-to memory is not touched
8291debfc3dSmrg        *  in any way.  Managing the pointer is the user's responsibility.
8301debfc3dSmrg        */
8311debfc3dSmrg       iterator
8321debfc3dSmrg       erase(const_iterator __first, const_iterator __last)
8331debfc3dSmrg       { return _M_h.erase(__first, __last); }
8341debfc3dSmrg 
8351debfc3dSmrg       /**
8361debfc3dSmrg        *  Erases all elements in an %unordered_map.
8371debfc3dSmrg        *  Note that this function only erases the elements, and that if the
8381debfc3dSmrg        *  elements themselves are pointers, the pointed-to memory is not touched
8391debfc3dSmrg        *  in any way.  Managing the pointer is the user's responsibility.
8401debfc3dSmrg        */
8411debfc3dSmrg       void
8421debfc3dSmrg       clear() noexcept
8431debfc3dSmrg       { _M_h.clear(); }
8441debfc3dSmrg 
8451debfc3dSmrg       /**
8461debfc3dSmrg        *  @brief  Swaps data with another %unordered_map.
8471debfc3dSmrg        *  @param  __x  An %unordered_map of the same element and allocator
8481debfc3dSmrg        *  types.
8491debfc3dSmrg        *
8501debfc3dSmrg        *  This exchanges the elements between two %unordered_map in constant
8511debfc3dSmrg        *  time.
8521debfc3dSmrg        *  Note that the global std::swap() function is specialized such that
8531debfc3dSmrg        *  std::swap(m1,m2) will feed to this function.
8541debfc3dSmrg        */
8551debfc3dSmrg       void
8561debfc3dSmrg       swap(unordered_map& __x)
8571debfc3dSmrg       noexcept( noexcept(_M_h.swap(__x._M_h)) )
8581debfc3dSmrg       { _M_h.swap(__x._M_h); }
8591debfc3dSmrg 
8601debfc3dSmrg #if __cplusplus > 201402L
8611debfc3dSmrg       template<typename, typename, typename>
862a2dc1f3fSmrg 	friend class std::_Hash_merge_helper;
8631debfc3dSmrg 
8641debfc3dSmrg       template<typename _H2, typename _P2>
8651debfc3dSmrg 	void
8661debfc3dSmrg 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
8671debfc3dSmrg 	{
8681debfc3dSmrg 	  using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
8691debfc3dSmrg 	  _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
8701debfc3dSmrg 	}
8711debfc3dSmrg 
8721debfc3dSmrg       template<typename _H2, typename _P2>
8731debfc3dSmrg 	void
8741debfc3dSmrg 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
8751debfc3dSmrg 	{ merge(__source); }
8761debfc3dSmrg 
8771debfc3dSmrg       template<typename _H2, typename _P2>
8781debfc3dSmrg 	void
8791debfc3dSmrg 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
8801debfc3dSmrg 	{
8811debfc3dSmrg 	  using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
8821debfc3dSmrg 	  _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
8831debfc3dSmrg 	}
8841debfc3dSmrg 
8851debfc3dSmrg       template<typename _H2, typename _P2>
8861debfc3dSmrg 	void
8871debfc3dSmrg 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
8881debfc3dSmrg 	{ merge(__source); }
8891debfc3dSmrg #endif // C++17
8901debfc3dSmrg 
8911debfc3dSmrg       // observers.
8921debfc3dSmrg 
8931debfc3dSmrg       ///  Returns the hash functor object with which the %unordered_map was
8941debfc3dSmrg       ///  constructed.
8951debfc3dSmrg       hasher
8961debfc3dSmrg       hash_function() const
8971debfc3dSmrg       { return _M_h.hash_function(); }
8981debfc3dSmrg 
8991debfc3dSmrg       ///  Returns the key comparison object with which the %unordered_map was
9001debfc3dSmrg       ///  constructed.
9011debfc3dSmrg       key_equal
9021debfc3dSmrg       key_eq() const
9031debfc3dSmrg       { return _M_h.key_eq(); }
9041debfc3dSmrg 
9051debfc3dSmrg       // lookup.
9061debfc3dSmrg 
907*8feb0f0bSmrg       ///@{
9081debfc3dSmrg       /**
9091debfc3dSmrg        *  @brief Tries to locate an element in an %unordered_map.
9101debfc3dSmrg        *  @param  __x  Key to be located.
9111debfc3dSmrg        *  @return  Iterator pointing to sought-after element, or end() if not
9121debfc3dSmrg        *           found.
9131debfc3dSmrg        *
9141debfc3dSmrg        *  This function takes a key and tries to locate the element with which
9151debfc3dSmrg        *  the key matches.  If successful the function returns an iterator
9161debfc3dSmrg        *  pointing to the sought after element.  If unsuccessful it returns the
9171debfc3dSmrg        *  past-the-end ( @c end() ) iterator.
9181debfc3dSmrg        */
9191debfc3dSmrg       iterator
9201debfc3dSmrg       find(const key_type& __x)
9211debfc3dSmrg       { return _M_h.find(__x); }
9221debfc3dSmrg 
9231debfc3dSmrg       const_iterator
9241debfc3dSmrg       find(const key_type& __x) const
9251debfc3dSmrg       { return _M_h.find(__x); }
926*8feb0f0bSmrg       ///@}
9271debfc3dSmrg 
9281debfc3dSmrg       /**
9291debfc3dSmrg        *  @brief  Finds the number of elements.
9301debfc3dSmrg        *  @param  __x  Key to count.
9311debfc3dSmrg        *  @return  Number of elements with specified key.
9321debfc3dSmrg        *
9331debfc3dSmrg        *  This function only makes sense for %unordered_multimap; for
9341debfc3dSmrg        *  %unordered_map the result will either be 0 (not present) or 1
9351debfc3dSmrg        *  (present).
9361debfc3dSmrg        */
9371debfc3dSmrg       size_type
9381debfc3dSmrg       count(const key_type& __x) const
9391debfc3dSmrg       { return _M_h.count(__x); }
9401debfc3dSmrg 
941c0a68be4Smrg #if __cplusplus > 201703L
942c0a68be4Smrg       /**
943c0a68be4Smrg        *  @brief  Finds whether an element with the given key exists.
944c0a68be4Smrg        *  @param  __x  Key of elements to be located.
945c0a68be4Smrg        *  @return  True if there is any element with the specified key.
946c0a68be4Smrg        */
947c0a68be4Smrg       bool
948c0a68be4Smrg       contains(const key_type& __x) const
949c0a68be4Smrg       { return _M_h.find(__x) != _M_h.end(); }
950c0a68be4Smrg #endif
951c0a68be4Smrg 
952*8feb0f0bSmrg       ///@{
9531debfc3dSmrg       /**
9541debfc3dSmrg        *  @brief Finds a subsequence matching given key.
9551debfc3dSmrg        *  @param  __x  Key to be located.
9561debfc3dSmrg        *  @return  Pair of iterators that possibly points to the subsequence
9571debfc3dSmrg        *           matching given key.
9581debfc3dSmrg        *
9591debfc3dSmrg        *  This function probably only makes sense for %unordered_multimap.
9601debfc3dSmrg        */
9611debfc3dSmrg       std::pair<iterator, iterator>
9621debfc3dSmrg       equal_range(const key_type& __x)
9631debfc3dSmrg       { return _M_h.equal_range(__x); }
9641debfc3dSmrg 
9651debfc3dSmrg       std::pair<const_iterator, const_iterator>
9661debfc3dSmrg       equal_range(const key_type& __x) const
9671debfc3dSmrg       { return _M_h.equal_range(__x); }
968*8feb0f0bSmrg       ///@}
9691debfc3dSmrg 
970*8feb0f0bSmrg       ///@{
9711debfc3dSmrg       /**
9721debfc3dSmrg        *  @brief  Subscript ( @c [] ) access to %unordered_map data.
9731debfc3dSmrg        *  @param  __k  The key for which data should be retrieved.
9741debfc3dSmrg        *  @return  A reference to the data of the (key,data) %pair.
9751debfc3dSmrg        *
9761debfc3dSmrg        *  Allows for easy lookup with the subscript ( @c [] )operator.  Returns
9771debfc3dSmrg        *  data associated with the key specified in subscript.  If the key does
9781debfc3dSmrg        *  not exist, a pair with that key is created using default values, which
9791debfc3dSmrg        *  is then returned.
9801debfc3dSmrg        *
9811debfc3dSmrg        *  Lookup requires constant time.
9821debfc3dSmrg        */
9831debfc3dSmrg       mapped_type&
9841debfc3dSmrg       operator[](const key_type& __k)
9851debfc3dSmrg       { return _M_h[__k]; }
9861debfc3dSmrg 
9871debfc3dSmrg       mapped_type&
9881debfc3dSmrg       operator[](key_type&& __k)
9891debfc3dSmrg       { return _M_h[std::move(__k)]; }
990*8feb0f0bSmrg       ///@}
9911debfc3dSmrg 
992*8feb0f0bSmrg       ///@{
9931debfc3dSmrg       /**
9941debfc3dSmrg        *  @brief  Access to %unordered_map data.
9951debfc3dSmrg        *  @param  __k  The key for which data should be retrieved.
9961debfc3dSmrg        *  @return  A reference to the data whose key is equal to @a __k, if
9971debfc3dSmrg        *           such a data is present in the %unordered_map.
9981debfc3dSmrg        *  @throw  std::out_of_range  If no such data is present.
9991debfc3dSmrg        */
10001debfc3dSmrg       mapped_type&
10011debfc3dSmrg       at(const key_type& __k)
10021debfc3dSmrg       { return _M_h.at(__k); }
10031debfc3dSmrg 
10041debfc3dSmrg       const mapped_type&
10051debfc3dSmrg       at(const key_type& __k) const
10061debfc3dSmrg       { return _M_h.at(__k); }
1007*8feb0f0bSmrg       ///@}
10081debfc3dSmrg 
10091debfc3dSmrg       // bucket interface.
10101debfc3dSmrg 
10111debfc3dSmrg       /// Returns the number of buckets of the %unordered_map.
10121debfc3dSmrg       size_type
10131debfc3dSmrg       bucket_count() const noexcept
10141debfc3dSmrg       { return _M_h.bucket_count(); }
10151debfc3dSmrg 
10161debfc3dSmrg       /// Returns the maximum number of buckets of the %unordered_map.
10171debfc3dSmrg       size_type
10181debfc3dSmrg       max_bucket_count() const noexcept
10191debfc3dSmrg       { return _M_h.max_bucket_count(); }
10201debfc3dSmrg 
10211debfc3dSmrg       /*
10221debfc3dSmrg        * @brief  Returns the number of elements in a given bucket.
10231debfc3dSmrg        * @param  __n  A bucket index.
10241debfc3dSmrg        * @return  The number of elements in the bucket.
10251debfc3dSmrg        */
10261debfc3dSmrg       size_type
10271debfc3dSmrg       bucket_size(size_type __n) const
10281debfc3dSmrg       { return _M_h.bucket_size(__n); }
10291debfc3dSmrg 
10301debfc3dSmrg       /*
10311debfc3dSmrg        * @brief  Returns the bucket index of a given element.
10321debfc3dSmrg        * @param  __key  A key instance.
10331debfc3dSmrg        * @return  The key bucket index.
10341debfc3dSmrg        */
10351debfc3dSmrg       size_type
10361debfc3dSmrg       bucket(const key_type& __key) const
10371debfc3dSmrg       { return _M_h.bucket(__key); }
10381debfc3dSmrg 
10391debfc3dSmrg       /**
10401debfc3dSmrg        *  @brief  Returns a read/write iterator pointing to the first bucket
10411debfc3dSmrg        *         element.
10421debfc3dSmrg        *  @param  __n The bucket index.
10431debfc3dSmrg        *  @return  A read/write local iterator.
10441debfc3dSmrg        */
10451debfc3dSmrg       local_iterator
10461debfc3dSmrg       begin(size_type __n)
10471debfc3dSmrg       { return _M_h.begin(__n); }
10481debfc3dSmrg 
1049*8feb0f0bSmrg       ///@{
10501debfc3dSmrg       /**
10511debfc3dSmrg        *  @brief  Returns a read-only (constant) iterator pointing to the first
10521debfc3dSmrg        *         bucket element.
10531debfc3dSmrg        *  @param  __n The bucket index.
10541debfc3dSmrg        *  @return  A read-only local iterator.
10551debfc3dSmrg        */
10561debfc3dSmrg       const_local_iterator
10571debfc3dSmrg       begin(size_type __n) const
10581debfc3dSmrg       { return _M_h.begin(__n); }
10591debfc3dSmrg 
10601debfc3dSmrg       const_local_iterator
10611debfc3dSmrg       cbegin(size_type __n) const
10621debfc3dSmrg       { return _M_h.cbegin(__n); }
1063*8feb0f0bSmrg       ///@}
10641debfc3dSmrg 
10651debfc3dSmrg       /**
10661debfc3dSmrg        *  @brief  Returns a read/write iterator pointing to one past the last
10671debfc3dSmrg        *         bucket elements.
10681debfc3dSmrg        *  @param  __n The bucket index.
10691debfc3dSmrg        *  @return  A read/write local iterator.
10701debfc3dSmrg        */
10711debfc3dSmrg       local_iterator
10721debfc3dSmrg       end(size_type __n)
10731debfc3dSmrg       { return _M_h.end(__n); }
10741debfc3dSmrg 
1075*8feb0f0bSmrg       ///@{
10761debfc3dSmrg       /**
10771debfc3dSmrg        *  @brief  Returns a read-only (constant) iterator pointing to one past
10781debfc3dSmrg        *         the last bucket elements.
10791debfc3dSmrg        *  @param  __n The bucket index.
10801debfc3dSmrg        *  @return  A read-only local iterator.
10811debfc3dSmrg        */
10821debfc3dSmrg       const_local_iterator
10831debfc3dSmrg       end(size_type __n) const
10841debfc3dSmrg       { return _M_h.end(__n); }
10851debfc3dSmrg 
10861debfc3dSmrg       const_local_iterator
10871debfc3dSmrg       cend(size_type __n) const
10881debfc3dSmrg       { return _M_h.cend(__n); }
1089*8feb0f0bSmrg       ///@}
10901debfc3dSmrg 
10911debfc3dSmrg       // hash policy.
10921debfc3dSmrg 
10931debfc3dSmrg       /// Returns the average number of elements per bucket.
10941debfc3dSmrg       float
10951debfc3dSmrg       load_factor() const noexcept
10961debfc3dSmrg       { return _M_h.load_factor(); }
10971debfc3dSmrg 
10981debfc3dSmrg       /// Returns a positive number that the %unordered_map tries to keep the
10991debfc3dSmrg       /// load factor less than or equal to.
11001debfc3dSmrg       float
11011debfc3dSmrg       max_load_factor() const noexcept
11021debfc3dSmrg       { return _M_h.max_load_factor(); }
11031debfc3dSmrg 
11041debfc3dSmrg       /**
11051debfc3dSmrg        *  @brief  Change the %unordered_map maximum load factor.
11061debfc3dSmrg        *  @param  __z The new maximum load factor.
11071debfc3dSmrg        */
11081debfc3dSmrg       void
11091debfc3dSmrg       max_load_factor(float __z)
11101debfc3dSmrg       { _M_h.max_load_factor(__z); }
11111debfc3dSmrg 
11121debfc3dSmrg       /**
11131debfc3dSmrg        *  @brief  May rehash the %unordered_map.
11141debfc3dSmrg        *  @param  __n The new number of buckets.
11151debfc3dSmrg        *
11161debfc3dSmrg        *  Rehash will occur only if the new number of buckets respect the
11171debfc3dSmrg        *  %unordered_map maximum load factor.
11181debfc3dSmrg        */
11191debfc3dSmrg       void
11201debfc3dSmrg       rehash(size_type __n)
11211debfc3dSmrg       { _M_h.rehash(__n); }
11221debfc3dSmrg 
11231debfc3dSmrg       /**
11241debfc3dSmrg        *  @brief  Prepare the %unordered_map for a specified number of
11251debfc3dSmrg        *          elements.
11261debfc3dSmrg        *  @param  __n Number of elements required.
11271debfc3dSmrg        *
11281debfc3dSmrg        *  Same as rehash(ceil(n / max_load_factor())).
11291debfc3dSmrg        */
11301debfc3dSmrg       void
11311debfc3dSmrg       reserve(size_type __n)
11321debfc3dSmrg       { _M_h.reserve(__n); }
11331debfc3dSmrg 
11341debfc3dSmrg       template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1,
11351debfc3dSmrg 	       typename _Alloc1>
11361debfc3dSmrg         friend bool
11371debfc3dSmrg 	operator==(const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&,
11381debfc3dSmrg 		   const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&);
11391debfc3dSmrg     };
11401debfc3dSmrg 
1141a2dc1f3fSmrg #if __cpp_deduction_guides >= 201606
1142a2dc1f3fSmrg 
1143a2dc1f3fSmrg   template<typename _InputIterator,
1144a2dc1f3fSmrg 	   typename _Hash = hash<__iter_key_t<_InputIterator>>,
1145a2dc1f3fSmrg 	   typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
1146a2dc1f3fSmrg 	   typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
1147a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
1148c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1149c0a68be4Smrg 	   typename = _RequireNotAllocator<_Pred>,
1150a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1151a2dc1f3fSmrg     unordered_map(_InputIterator, _InputIterator,
1152a2dc1f3fSmrg 		  typename unordered_map<int, int>::size_type = {},
1153a2dc1f3fSmrg 		  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1154a2dc1f3fSmrg     -> unordered_map<__iter_key_t<_InputIterator>,
1155a2dc1f3fSmrg 		     __iter_val_t<_InputIterator>,
1156a2dc1f3fSmrg 		     _Hash, _Pred, _Allocator>;
1157a2dc1f3fSmrg 
1158a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
1159a2dc1f3fSmrg 	   typename _Pred = equal_to<_Key>,
1160a2dc1f3fSmrg 	   typename _Allocator = allocator<pair<const _Key, _Tp>>,
1161c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1162c0a68be4Smrg 	   typename = _RequireNotAllocator<_Pred>,
1163a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1164a2dc1f3fSmrg     unordered_map(initializer_list<pair<_Key, _Tp>>,
1165a2dc1f3fSmrg 		  typename unordered_map<int, int>::size_type = {},
1166a2dc1f3fSmrg 		  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1167a2dc1f3fSmrg     -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>;
1168a2dc1f3fSmrg 
1169a2dc1f3fSmrg   template<typename _InputIterator, typename _Allocator,
1170a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
1171a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1172a2dc1f3fSmrg     unordered_map(_InputIterator, _InputIterator,
1173a2dc1f3fSmrg 		  typename unordered_map<int, int>::size_type, _Allocator)
1174a2dc1f3fSmrg     -> unordered_map<__iter_key_t<_InputIterator>,
1175a2dc1f3fSmrg 		     __iter_val_t<_InputIterator>,
1176a2dc1f3fSmrg 		     hash<__iter_key_t<_InputIterator>>,
1177a2dc1f3fSmrg 		     equal_to<__iter_key_t<_InputIterator>>,
1178a2dc1f3fSmrg 		     _Allocator>;
1179a2dc1f3fSmrg 
1180a2dc1f3fSmrg   template<typename _InputIterator, typename _Allocator,
1181a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
1182a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1183a2dc1f3fSmrg     unordered_map(_InputIterator, _InputIterator, _Allocator)
1184a2dc1f3fSmrg     -> unordered_map<__iter_key_t<_InputIterator>,
1185a2dc1f3fSmrg 		     __iter_val_t<_InputIterator>,
1186a2dc1f3fSmrg 		     hash<__iter_key_t<_InputIterator>>,
1187a2dc1f3fSmrg 		     equal_to<__iter_key_t<_InputIterator>>,
1188a2dc1f3fSmrg 		     _Allocator>;
1189a2dc1f3fSmrg 
1190a2dc1f3fSmrg   template<typename _InputIterator, typename _Hash, typename _Allocator,
1191a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
1192c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1193a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1194a2dc1f3fSmrg     unordered_map(_InputIterator, _InputIterator,
1195a2dc1f3fSmrg 		  typename unordered_map<int, int>::size_type,
1196a2dc1f3fSmrg 		  _Hash, _Allocator)
1197a2dc1f3fSmrg     -> unordered_map<__iter_key_t<_InputIterator>,
1198a2dc1f3fSmrg 		     __iter_val_t<_InputIterator>, _Hash,
1199a2dc1f3fSmrg 		     equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1200a2dc1f3fSmrg 
1201a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Allocator,
1202a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1203a2dc1f3fSmrg     unordered_map(initializer_list<pair<_Key, _Tp>>,
1204a2dc1f3fSmrg 		  typename unordered_map<int, int>::size_type,
1205a2dc1f3fSmrg 		  _Allocator)
1206a2dc1f3fSmrg     -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1207a2dc1f3fSmrg 
1208a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Allocator,
1209a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1210a2dc1f3fSmrg     unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator)
1211a2dc1f3fSmrg     -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1212a2dc1f3fSmrg 
1213a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
1214c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1215a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
1216a2dc1f3fSmrg     unordered_map(initializer_list<pair<_Key, _Tp>>,
1217a2dc1f3fSmrg 		  typename unordered_map<int, int>::size_type,
1218a2dc1f3fSmrg 		  _Hash, _Allocator)
1219a2dc1f3fSmrg     -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
1220a2dc1f3fSmrg 
1221a2dc1f3fSmrg #endif
1222a2dc1f3fSmrg 
12231debfc3dSmrg   /**
12241debfc3dSmrg    *  @brief A standard container composed of equivalent keys
12251debfc3dSmrg    *  (possibly containing multiple of each key value) that associates
12261debfc3dSmrg    *  values of another type with the keys.
12271debfc3dSmrg    *
12281debfc3dSmrg    *  @ingroup unordered_associative_containers
12291debfc3dSmrg    *
12301debfc3dSmrg    *  @tparam  _Key    Type of key objects.
12311debfc3dSmrg    *  @tparam  _Tp     Type of mapped objects.
12321debfc3dSmrg    *  @tparam  _Hash   Hashing function object type, defaults to hash<_Value>.
12331debfc3dSmrg    *  @tparam  _Pred   Predicate function object type, defaults
12341debfc3dSmrg    *                   to equal_to<_Value>.
12351debfc3dSmrg    *  @tparam  _Alloc  Allocator type, defaults to
12361debfc3dSmrg    *                   std::allocator<std::pair<const _Key, _Tp>>.
12371debfc3dSmrg    *
12381debfc3dSmrg    *  Meets the requirements of a <a href="tables.html#65">container</a>, and
12391debfc3dSmrg    *  <a href="tables.html#xx">unordered associative container</a>
12401debfc3dSmrg    *
12411debfc3dSmrg    * The resulting value type of the container is std::pair<const _Key, _Tp>.
12421debfc3dSmrg    *
12431debfc3dSmrg    *  Base is _Hashtable, dispatched at compile time via template
12441debfc3dSmrg    *  alias __ummap_hashtable.
12451debfc3dSmrg    */
1246a2dc1f3fSmrg   template<typename _Key, typename _Tp,
1247a2dc1f3fSmrg 	   typename _Hash = hash<_Key>,
1248a2dc1f3fSmrg 	   typename _Pred = equal_to<_Key>,
1249a2dc1f3fSmrg 	   typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
12501debfc3dSmrg     class unordered_multimap
12511debfc3dSmrg     {
12521debfc3dSmrg       typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
12531debfc3dSmrg       _Hashtable _M_h;
12541debfc3dSmrg 
12551debfc3dSmrg     public:
12561debfc3dSmrg       // typedefs:
1257*8feb0f0bSmrg       ///@{
12581debfc3dSmrg       /// Public typedefs.
12591debfc3dSmrg       typedef typename _Hashtable::key_type	key_type;
12601debfc3dSmrg       typedef typename _Hashtable::value_type	value_type;
12611debfc3dSmrg       typedef typename _Hashtable::mapped_type	mapped_type;
12621debfc3dSmrg       typedef typename _Hashtable::hasher	hasher;
12631debfc3dSmrg       typedef typename _Hashtable::key_equal	key_equal;
12641debfc3dSmrg       typedef typename _Hashtable::allocator_type allocator_type;
1265*8feb0f0bSmrg       ///@}
12661debfc3dSmrg 
1267*8feb0f0bSmrg       ///@{
12681debfc3dSmrg       ///  Iterator-related typedefs.
12691debfc3dSmrg       typedef typename _Hashtable::pointer		pointer;
12701debfc3dSmrg       typedef typename _Hashtable::const_pointer	const_pointer;
12711debfc3dSmrg       typedef typename _Hashtable::reference		reference;
12721debfc3dSmrg       typedef typename _Hashtable::const_reference	const_reference;
12731debfc3dSmrg       typedef typename _Hashtable::iterator		iterator;
12741debfc3dSmrg       typedef typename _Hashtable::const_iterator	const_iterator;
12751debfc3dSmrg       typedef typename _Hashtable::local_iterator	local_iterator;
12761debfc3dSmrg       typedef typename _Hashtable::const_local_iterator	const_local_iterator;
12771debfc3dSmrg       typedef typename _Hashtable::size_type		size_type;
12781debfc3dSmrg       typedef typename _Hashtable::difference_type	difference_type;
1279*8feb0f0bSmrg       ///@}
12801debfc3dSmrg 
12811debfc3dSmrg #if __cplusplus > 201402L
12821debfc3dSmrg       using node_type = typename _Hashtable::node_type;
12831debfc3dSmrg #endif
12841debfc3dSmrg 
12851debfc3dSmrg       //construct/destroy/copy
12861debfc3dSmrg 
12871debfc3dSmrg       /// Default constructor.
12881debfc3dSmrg       unordered_multimap() = default;
12891debfc3dSmrg 
12901debfc3dSmrg       /**
12911debfc3dSmrg        *  @brief  Default constructor creates no elements.
12921debfc3dSmrg        *  @param __n  Mnimal initial number of buckets.
12931debfc3dSmrg        *  @param __hf  A hash functor.
12941debfc3dSmrg        *  @param __eql  A key equality functor.
12951debfc3dSmrg        *  @param __a  An allocator object.
12961debfc3dSmrg        */
12971debfc3dSmrg       explicit
12981debfc3dSmrg       unordered_multimap(size_type __n,
12991debfc3dSmrg 			 const hasher& __hf = hasher(),
13001debfc3dSmrg 			 const key_equal& __eql = key_equal(),
13011debfc3dSmrg 			 const allocator_type& __a = allocator_type())
13021debfc3dSmrg       : _M_h(__n, __hf, __eql, __a)
13031debfc3dSmrg       { }
13041debfc3dSmrg 
13051debfc3dSmrg       /**
13061debfc3dSmrg        *  @brief  Builds an %unordered_multimap from a range.
13071debfc3dSmrg        *  @param  __first An input iterator.
13081debfc3dSmrg        *  @param  __last  An input iterator.
13091debfc3dSmrg        *  @param __n      Minimal initial number of buckets.
13101debfc3dSmrg        *  @param __hf     A hash functor.
13111debfc3dSmrg        *  @param __eql    A key equality functor.
13121debfc3dSmrg        *  @param __a      An allocator object.
13131debfc3dSmrg        *
13141debfc3dSmrg        *  Create an %unordered_multimap consisting of copies of the elements
13151debfc3dSmrg        *  from [__first,__last).  This is linear in N (where N is
13161debfc3dSmrg        *  distance(__first,__last)).
13171debfc3dSmrg        */
13181debfc3dSmrg       template<typename _InputIterator>
13191debfc3dSmrg 	unordered_multimap(_InputIterator __first, _InputIterator __last,
13201debfc3dSmrg 			   size_type __n = 0,
13211debfc3dSmrg 			   const hasher& __hf = hasher(),
13221debfc3dSmrg 			   const key_equal& __eql = key_equal(),
13231debfc3dSmrg 			   const allocator_type& __a = allocator_type())
13241debfc3dSmrg 	: _M_h(__first, __last, __n, __hf, __eql, __a)
13251debfc3dSmrg 	{ }
13261debfc3dSmrg 
13271debfc3dSmrg       /// Copy constructor.
13281debfc3dSmrg       unordered_multimap(const unordered_multimap&) = default;
13291debfc3dSmrg 
13301debfc3dSmrg       /// Move constructor.
13311debfc3dSmrg       unordered_multimap(unordered_multimap&&) = default;
13321debfc3dSmrg 
13331debfc3dSmrg       /**
13341debfc3dSmrg        *  @brief Creates an %unordered_multimap with no elements.
13351debfc3dSmrg        *  @param __a An allocator object.
13361debfc3dSmrg        */
13371debfc3dSmrg       explicit
13381debfc3dSmrg       unordered_multimap(const allocator_type& __a)
13391debfc3dSmrg       : _M_h(__a)
13401debfc3dSmrg       { }
13411debfc3dSmrg 
13421debfc3dSmrg       /*
13431debfc3dSmrg        *  @brief Copy constructor with allocator argument.
13441debfc3dSmrg        * @param  __uset  Input %unordered_multimap to copy.
13451debfc3dSmrg        * @param  __a  An allocator object.
13461debfc3dSmrg        */
13471debfc3dSmrg       unordered_multimap(const unordered_multimap& __ummap,
13481debfc3dSmrg 			 const allocator_type& __a)
13491debfc3dSmrg       : _M_h(__ummap._M_h, __a)
13501debfc3dSmrg       { }
13511debfc3dSmrg 
13521debfc3dSmrg       /*
13531debfc3dSmrg        *  @brief  Move constructor with allocator argument.
13541debfc3dSmrg        *  @param  __uset Input %unordered_multimap to move.
13551debfc3dSmrg        *  @param  __a    An allocator object.
13561debfc3dSmrg        */
13571debfc3dSmrg       unordered_multimap(unordered_multimap&& __ummap,
13581debfc3dSmrg 			 const allocator_type& __a)
1359*8feb0f0bSmrg 	noexcept( noexcept(_Hashtable(std::move(__ummap._M_h), __a)) )
13601debfc3dSmrg       : _M_h(std::move(__ummap._M_h), __a)
13611debfc3dSmrg       { }
13621debfc3dSmrg 
13631debfc3dSmrg       /**
13641debfc3dSmrg        *  @brief  Builds an %unordered_multimap from an initializer_list.
13651debfc3dSmrg        *  @param  __l  An initializer_list.
13661debfc3dSmrg        *  @param __n  Minimal initial number of buckets.
13671debfc3dSmrg        *  @param __hf  A hash functor.
13681debfc3dSmrg        *  @param __eql  A key equality functor.
13691debfc3dSmrg        *  @param  __a  An allocator object.
13701debfc3dSmrg        *
13711debfc3dSmrg        *  Create an %unordered_multimap consisting of copies of the elements in
13721debfc3dSmrg        *  the list. This is linear in N (where N is @a __l.size()).
13731debfc3dSmrg        */
13741debfc3dSmrg       unordered_multimap(initializer_list<value_type> __l,
13751debfc3dSmrg 			 size_type __n = 0,
13761debfc3dSmrg 			 const hasher& __hf = hasher(),
13771debfc3dSmrg 			 const key_equal& __eql = key_equal(),
13781debfc3dSmrg 			 const allocator_type& __a = allocator_type())
13791debfc3dSmrg       : _M_h(__l, __n, __hf, __eql, __a)
13801debfc3dSmrg       { }
13811debfc3dSmrg 
13821debfc3dSmrg       unordered_multimap(size_type __n, const allocator_type& __a)
13831debfc3dSmrg       : unordered_multimap(__n, hasher(), key_equal(), __a)
13841debfc3dSmrg       { }
13851debfc3dSmrg 
13861debfc3dSmrg       unordered_multimap(size_type __n, const hasher& __hf,
13871debfc3dSmrg 			 const allocator_type& __a)
13881debfc3dSmrg       : unordered_multimap(__n, __hf, key_equal(), __a)
13891debfc3dSmrg       { }
13901debfc3dSmrg 
13911debfc3dSmrg       template<typename _InputIterator>
13921debfc3dSmrg 	unordered_multimap(_InputIterator __first, _InputIterator __last,
13931debfc3dSmrg 			   size_type __n,
13941debfc3dSmrg 			   const allocator_type& __a)
13951debfc3dSmrg 	: unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
13961debfc3dSmrg 	{ }
13971debfc3dSmrg 
13981debfc3dSmrg       template<typename _InputIterator>
13991debfc3dSmrg 	unordered_multimap(_InputIterator __first, _InputIterator __last,
14001debfc3dSmrg 			   size_type __n, const hasher& __hf,
14011debfc3dSmrg 			   const allocator_type& __a)
14021debfc3dSmrg 	: unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
14031debfc3dSmrg 	{ }
14041debfc3dSmrg 
14051debfc3dSmrg       unordered_multimap(initializer_list<value_type> __l,
14061debfc3dSmrg 			 size_type __n,
14071debfc3dSmrg 			 const allocator_type& __a)
14081debfc3dSmrg       : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
14091debfc3dSmrg       { }
14101debfc3dSmrg 
14111debfc3dSmrg       unordered_multimap(initializer_list<value_type> __l,
14121debfc3dSmrg 			 size_type __n, const hasher& __hf,
14131debfc3dSmrg 			 const allocator_type& __a)
14141debfc3dSmrg       : unordered_multimap(__l, __n, __hf, key_equal(), __a)
14151debfc3dSmrg       { }
14161debfc3dSmrg 
14171debfc3dSmrg       /// Copy assignment operator.
14181debfc3dSmrg       unordered_multimap&
14191debfc3dSmrg       operator=(const unordered_multimap&) = default;
14201debfc3dSmrg 
14211debfc3dSmrg       /// Move assignment operator.
14221debfc3dSmrg       unordered_multimap&
14231debfc3dSmrg       operator=(unordered_multimap&&) = default;
14241debfc3dSmrg 
14251debfc3dSmrg       /**
14261debfc3dSmrg        *  @brief  %Unordered_multimap list assignment operator.
14271debfc3dSmrg        *  @param  __l  An initializer_list.
14281debfc3dSmrg        *
14291debfc3dSmrg        *  This function fills an %unordered_multimap with copies of the
14301debfc3dSmrg        *  elements in the initializer list @a __l.
14311debfc3dSmrg        *
14321debfc3dSmrg        *  Note that the assignment completely changes the %unordered_multimap
14331debfc3dSmrg        *  and that the resulting %unordered_multimap's size is the same as the
14341debfc3dSmrg        *  number of elements assigned.
14351debfc3dSmrg        */
14361debfc3dSmrg       unordered_multimap&
14371debfc3dSmrg       operator=(initializer_list<value_type> __l)
14381debfc3dSmrg       {
14391debfc3dSmrg 	_M_h = __l;
14401debfc3dSmrg 	return *this;
14411debfc3dSmrg       }
14421debfc3dSmrg 
14431debfc3dSmrg       ///  Returns the allocator object used by the %unordered_multimap.
14441debfc3dSmrg       allocator_type
14451debfc3dSmrg       get_allocator() const noexcept
14461debfc3dSmrg       { return _M_h.get_allocator(); }
14471debfc3dSmrg 
14481debfc3dSmrg       // size and capacity:
14491debfc3dSmrg 
14501debfc3dSmrg       ///  Returns true if the %unordered_multimap is empty.
1451c0a68be4Smrg       _GLIBCXX_NODISCARD bool
14521debfc3dSmrg       empty() const noexcept
14531debfc3dSmrg       { return _M_h.empty(); }
14541debfc3dSmrg 
14551debfc3dSmrg       ///  Returns the size of the %unordered_multimap.
14561debfc3dSmrg       size_type
14571debfc3dSmrg       size() const noexcept
14581debfc3dSmrg       { return _M_h.size(); }
14591debfc3dSmrg 
14601debfc3dSmrg       ///  Returns the maximum size of the %unordered_multimap.
14611debfc3dSmrg       size_type
14621debfc3dSmrg       max_size() const noexcept
14631debfc3dSmrg       { return _M_h.max_size(); }
14641debfc3dSmrg 
14651debfc3dSmrg       // iterators.
14661debfc3dSmrg 
14671debfc3dSmrg       /**
14681debfc3dSmrg        *  Returns a read/write iterator that points to the first element in the
14691debfc3dSmrg        *  %unordered_multimap.
14701debfc3dSmrg        */
14711debfc3dSmrg       iterator
14721debfc3dSmrg       begin() noexcept
14731debfc3dSmrg       { return _M_h.begin(); }
14741debfc3dSmrg 
1475*8feb0f0bSmrg       ///@{
14761debfc3dSmrg       /**
14771debfc3dSmrg        *  Returns a read-only (constant) iterator that points to the first
14781debfc3dSmrg        *  element in the %unordered_multimap.
14791debfc3dSmrg        */
14801debfc3dSmrg       const_iterator
14811debfc3dSmrg       begin() const noexcept
14821debfc3dSmrg       { return _M_h.begin(); }
14831debfc3dSmrg 
14841debfc3dSmrg       const_iterator
14851debfc3dSmrg       cbegin() const noexcept
14861debfc3dSmrg       { return _M_h.begin(); }
1487*8feb0f0bSmrg       ///@}
14881debfc3dSmrg 
14891debfc3dSmrg       /**
14901debfc3dSmrg        *  Returns a read/write iterator that points one past the last element in
14911debfc3dSmrg        *  the %unordered_multimap.
14921debfc3dSmrg        */
14931debfc3dSmrg       iterator
14941debfc3dSmrg       end() noexcept
14951debfc3dSmrg       { return _M_h.end(); }
14961debfc3dSmrg 
1497*8feb0f0bSmrg       ///@{
14981debfc3dSmrg       /**
14991debfc3dSmrg        *  Returns a read-only (constant) iterator that points one past the last
15001debfc3dSmrg        *  element in the %unordered_multimap.
15011debfc3dSmrg        */
15021debfc3dSmrg       const_iterator
15031debfc3dSmrg       end() const noexcept
15041debfc3dSmrg       { return _M_h.end(); }
15051debfc3dSmrg 
15061debfc3dSmrg       const_iterator
15071debfc3dSmrg       cend() const noexcept
15081debfc3dSmrg       { return _M_h.end(); }
1509*8feb0f0bSmrg       ///@}
15101debfc3dSmrg 
15111debfc3dSmrg       // modifiers.
15121debfc3dSmrg 
15131debfc3dSmrg       /**
15141debfc3dSmrg        *  @brief Attempts to build and insert a std::pair into the
15151debfc3dSmrg        *  %unordered_multimap.
15161debfc3dSmrg        *
15171debfc3dSmrg        *  @param __args  Arguments used to generate a new pair instance (see
15181debfc3dSmrg        *	        std::piecewise_contruct for passing arguments to each
15191debfc3dSmrg        *	        part of the pair constructor).
15201debfc3dSmrg        *
15211debfc3dSmrg        *  @return  An iterator that points to the inserted pair.
15221debfc3dSmrg        *
15231debfc3dSmrg        *  This function attempts to build and insert a (key, value) %pair into
15241debfc3dSmrg        *  the %unordered_multimap.
15251debfc3dSmrg        *
15261debfc3dSmrg        *  Insertion requires amortized constant time.
15271debfc3dSmrg        */
15281debfc3dSmrg       template<typename... _Args>
15291debfc3dSmrg 	iterator
15301debfc3dSmrg 	emplace(_Args&&... __args)
15311debfc3dSmrg 	{ return _M_h.emplace(std::forward<_Args>(__args)...); }
15321debfc3dSmrg 
15331debfc3dSmrg       /**
15341debfc3dSmrg        *  @brief Attempts to build and insert a std::pair into the
15351debfc3dSmrg        *  %unordered_multimap.
15361debfc3dSmrg        *
15371debfc3dSmrg        *  @param  __pos  An iterator that serves as a hint as to where the pair
15381debfc3dSmrg        *                should be inserted.
15391debfc3dSmrg        *  @param  __args  Arguments used to generate a new pair instance (see
15401debfc3dSmrg        *	         std::piecewise_contruct for passing arguments to each
15411debfc3dSmrg        *	         part of the pair constructor).
15421debfc3dSmrg        *  @return An iterator that points to the element with key of the
15431debfc3dSmrg        *          std::pair built from @a __args.
15441debfc3dSmrg        *
15451debfc3dSmrg        *  Note that the first parameter is only a hint and can potentially
15461debfc3dSmrg        *  improve the performance of the insertion process. A bad hint would
15471debfc3dSmrg        *  cause no gains in efficiency.
15481debfc3dSmrg        *
15491debfc3dSmrg        *  See
15501debfc3dSmrg        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
15511debfc3dSmrg        *  for more on @a hinting.
15521debfc3dSmrg        *
15531debfc3dSmrg        *  Insertion requires amortized constant time.
15541debfc3dSmrg        */
15551debfc3dSmrg       template<typename... _Args>
15561debfc3dSmrg 	iterator
15571debfc3dSmrg 	emplace_hint(const_iterator __pos, _Args&&... __args)
15581debfc3dSmrg 	{ return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
15591debfc3dSmrg 
1560*8feb0f0bSmrg       ///@{
15611debfc3dSmrg       /**
15621debfc3dSmrg        *  @brief Inserts a std::pair into the %unordered_multimap.
15631debfc3dSmrg        *  @param __x Pair to be inserted (see std::make_pair for easy
15641debfc3dSmrg        *	     creation of pairs).
15651debfc3dSmrg        *
15661debfc3dSmrg        *  @return  An iterator that points to the inserted pair.
15671debfc3dSmrg        *
15681debfc3dSmrg        *  Insertion requires amortized constant time.
15691debfc3dSmrg        */
15701debfc3dSmrg       iterator
15711debfc3dSmrg       insert(const value_type& __x)
15721debfc3dSmrg       { return _M_h.insert(__x); }
15731debfc3dSmrg 
15741debfc3dSmrg       iterator
15751debfc3dSmrg       insert(value_type&& __x)
15761debfc3dSmrg       { return _M_h.insert(std::move(__x)); }
15771debfc3dSmrg 
15781debfc3dSmrg       template<typename _Pair>
15791debfc3dSmrg 	__enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
15801debfc3dSmrg 	insert(_Pair&& __x)
15811debfc3dSmrg         { return _M_h.emplace(std::forward<_Pair>(__x)); }
1582*8feb0f0bSmrg       ///@}
15831debfc3dSmrg 
1584*8feb0f0bSmrg       ///@{
15851debfc3dSmrg       /**
15861debfc3dSmrg        *  @brief Inserts a std::pair into the %unordered_multimap.
15871debfc3dSmrg        *  @param  __hint  An iterator that serves as a hint as to where the
15881debfc3dSmrg        *                 pair should be inserted.
15891debfc3dSmrg        *  @param  __x  Pair to be inserted (see std::make_pair for easy creation
15901debfc3dSmrg        *               of pairs).
15911debfc3dSmrg        *  @return An iterator that points to the element with key of
15921debfc3dSmrg        *           @a __x (may or may not be the %pair passed in).
15931debfc3dSmrg        *
15941debfc3dSmrg        *  Note that the first parameter is only a hint and can potentially
15951debfc3dSmrg        *  improve the performance of the insertion process.  A bad hint would
15961debfc3dSmrg        *  cause no gains in efficiency.
15971debfc3dSmrg        *
15981debfc3dSmrg        *  See
15991debfc3dSmrg        *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
16001debfc3dSmrg        *  for more on @a hinting.
16011debfc3dSmrg        *
16021debfc3dSmrg        *  Insertion requires amortized constant time.
16031debfc3dSmrg        */
16041debfc3dSmrg       iterator
16051debfc3dSmrg       insert(const_iterator __hint, const value_type& __x)
16061debfc3dSmrg       { return _M_h.insert(__hint, __x); }
16071debfc3dSmrg 
16081debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
16091debfc3dSmrg       // 2354. Unnecessary copying when inserting into maps with braced-init
16101debfc3dSmrg       iterator
16111debfc3dSmrg       insert(const_iterator __hint, value_type&& __x)
16121debfc3dSmrg       { return _M_h.insert(__hint, std::move(__x)); }
16131debfc3dSmrg 
16141debfc3dSmrg       template<typename _Pair>
16151debfc3dSmrg 	__enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
16161debfc3dSmrg 	insert(const_iterator __hint, _Pair&& __x)
16171debfc3dSmrg         { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); }
1618*8feb0f0bSmrg       ///@}
16191debfc3dSmrg 
16201debfc3dSmrg       /**
16211debfc3dSmrg        *  @brief A template function that attempts to insert a range of
16221debfc3dSmrg        *  elements.
16231debfc3dSmrg        *  @param  __first  Iterator pointing to the start of the range to be
16241debfc3dSmrg        *                   inserted.
16251debfc3dSmrg        *  @param  __last  Iterator pointing to the end of the range.
16261debfc3dSmrg        *
16271debfc3dSmrg        *  Complexity similar to that of the range constructor.
16281debfc3dSmrg        */
16291debfc3dSmrg       template<typename _InputIterator>
16301debfc3dSmrg 	void
16311debfc3dSmrg 	insert(_InputIterator __first, _InputIterator __last)
16321debfc3dSmrg 	{ _M_h.insert(__first, __last); }
16331debfc3dSmrg 
16341debfc3dSmrg       /**
16351debfc3dSmrg        *  @brief Attempts to insert a list of elements into the
16361debfc3dSmrg        *  %unordered_multimap.
16371debfc3dSmrg        *  @param  __l  A std::initializer_list<value_type> of elements
16381debfc3dSmrg        *               to be inserted.
16391debfc3dSmrg        *
16401debfc3dSmrg        *  Complexity similar to that of the range constructor.
16411debfc3dSmrg        */
16421debfc3dSmrg       void
16431debfc3dSmrg       insert(initializer_list<value_type> __l)
16441debfc3dSmrg       { _M_h.insert(__l); }
16451debfc3dSmrg 
16461debfc3dSmrg #if __cplusplus > 201402L
16471debfc3dSmrg       /// Extract a node.
16481debfc3dSmrg       node_type
16491debfc3dSmrg       extract(const_iterator __pos)
16501debfc3dSmrg       {
16511debfc3dSmrg 	__glibcxx_assert(__pos != end());
16521debfc3dSmrg 	return _M_h.extract(__pos);
16531debfc3dSmrg       }
16541debfc3dSmrg 
16551debfc3dSmrg       /// Extract a node.
16561debfc3dSmrg       node_type
16571debfc3dSmrg       extract(const key_type& __key)
16581debfc3dSmrg       { return _M_h.extract(__key); }
16591debfc3dSmrg 
16601debfc3dSmrg       /// Re-insert an extracted node.
16611debfc3dSmrg       iterator
16621debfc3dSmrg       insert(node_type&& __nh)
16631debfc3dSmrg       { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
16641debfc3dSmrg 
16651debfc3dSmrg       /// Re-insert an extracted node.
16661debfc3dSmrg       iterator
16671debfc3dSmrg       insert(const_iterator __hint, node_type&& __nh)
16681debfc3dSmrg       { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
16691debfc3dSmrg #endif // C++17
16701debfc3dSmrg 
1671*8feb0f0bSmrg       ///@{
16721debfc3dSmrg       /**
16731debfc3dSmrg        *  @brief Erases an element from an %unordered_multimap.
16741debfc3dSmrg        *  @param  __position  An iterator pointing to the element to be erased.
16751debfc3dSmrg        *  @return An iterator pointing to the element immediately following
16761debfc3dSmrg        *          @a __position prior to the element being erased. If no such
16771debfc3dSmrg        *          element exists, end() is returned.
16781debfc3dSmrg        *
16791debfc3dSmrg        *  This function erases an element, pointed to by the given iterator,
16801debfc3dSmrg        *  from an %unordered_multimap.
16811debfc3dSmrg        *  Note that this function only erases the element, and that if the
16821debfc3dSmrg        *  element is itself a pointer, the pointed-to memory is not touched in
16831debfc3dSmrg        *  any way.  Managing the pointer is the user's responsibility.
16841debfc3dSmrg        */
16851debfc3dSmrg       iterator
16861debfc3dSmrg       erase(const_iterator __position)
16871debfc3dSmrg       { return _M_h.erase(__position); }
16881debfc3dSmrg 
16891debfc3dSmrg       // LWG 2059.
16901debfc3dSmrg       iterator
16911debfc3dSmrg       erase(iterator __position)
16921debfc3dSmrg       { return _M_h.erase(__position); }
1693*8feb0f0bSmrg       ///@}
16941debfc3dSmrg 
16951debfc3dSmrg       /**
16961debfc3dSmrg        *  @brief Erases elements according to the provided key.
16971debfc3dSmrg        *  @param  __x  Key of elements to be erased.
16981debfc3dSmrg        *  @return  The number of elements erased.
16991debfc3dSmrg        *
17001debfc3dSmrg        *  This function erases all the elements located by the given key from
17011debfc3dSmrg        *  an %unordered_multimap.
17021debfc3dSmrg        *  Note that this function only erases the element, and that if the
17031debfc3dSmrg        *  element is itself a pointer, the pointed-to memory is not touched in
17041debfc3dSmrg        *  any way.  Managing the pointer is the user's responsibility.
17051debfc3dSmrg        */
17061debfc3dSmrg       size_type
17071debfc3dSmrg       erase(const key_type& __x)
17081debfc3dSmrg       { return _M_h.erase(__x); }
17091debfc3dSmrg 
17101debfc3dSmrg       /**
17111debfc3dSmrg        *  @brief Erases a [__first,__last) range of elements from an
17121debfc3dSmrg        *  %unordered_multimap.
17131debfc3dSmrg        *  @param  __first  Iterator pointing to the start of the range to be
17141debfc3dSmrg        *                  erased.
17151debfc3dSmrg        *  @param __last  Iterator pointing to the end of the range to
17161debfc3dSmrg        *                be erased.
17171debfc3dSmrg        *  @return The iterator @a __last.
17181debfc3dSmrg        *
17191debfc3dSmrg        *  This function erases a sequence of elements from an
17201debfc3dSmrg        *  %unordered_multimap.
17211debfc3dSmrg        *  Note that this function only erases the elements, and that if
17221debfc3dSmrg        *  the element is itself a pointer, the pointed-to memory is not touched
17231debfc3dSmrg        *  in any way.  Managing the pointer is the user's responsibility.
17241debfc3dSmrg        */
17251debfc3dSmrg       iterator
17261debfc3dSmrg       erase(const_iterator __first, const_iterator __last)
17271debfc3dSmrg       { return _M_h.erase(__first, __last); }
17281debfc3dSmrg 
17291debfc3dSmrg       /**
17301debfc3dSmrg        *  Erases all elements in an %unordered_multimap.
17311debfc3dSmrg        *  Note that this function only erases the elements, and that if the
17321debfc3dSmrg        *  elements themselves are pointers, the pointed-to memory is not touched
17331debfc3dSmrg        *  in any way.  Managing the pointer is the user's responsibility.
17341debfc3dSmrg        */
17351debfc3dSmrg       void
17361debfc3dSmrg       clear() noexcept
17371debfc3dSmrg       { _M_h.clear(); }
17381debfc3dSmrg 
17391debfc3dSmrg       /**
17401debfc3dSmrg        *  @brief  Swaps data with another %unordered_multimap.
17411debfc3dSmrg        *  @param  __x  An %unordered_multimap of the same element and allocator
17421debfc3dSmrg        *  types.
17431debfc3dSmrg        *
17441debfc3dSmrg        *  This exchanges the elements between two %unordered_multimap in
17451debfc3dSmrg        *  constant time.
17461debfc3dSmrg        *  Note that the global std::swap() function is specialized such that
17471debfc3dSmrg        *  std::swap(m1,m2) will feed to this function.
17481debfc3dSmrg        */
17491debfc3dSmrg       void
17501debfc3dSmrg       swap(unordered_multimap& __x)
17511debfc3dSmrg       noexcept( noexcept(_M_h.swap(__x._M_h)) )
17521debfc3dSmrg       { _M_h.swap(__x._M_h); }
17531debfc3dSmrg 
17541debfc3dSmrg #if __cplusplus > 201402L
17551debfc3dSmrg       template<typename, typename, typename>
1756a2dc1f3fSmrg 	friend class std::_Hash_merge_helper;
17571debfc3dSmrg 
17581debfc3dSmrg       template<typename _H2, typename _P2>
17591debfc3dSmrg 	void
17601debfc3dSmrg 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
17611debfc3dSmrg 	{
17621debfc3dSmrg 	  using _Merge_helper
17631debfc3dSmrg 	    = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
17641debfc3dSmrg 	  _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
17651debfc3dSmrg 	}
17661debfc3dSmrg 
17671debfc3dSmrg       template<typename _H2, typename _P2>
17681debfc3dSmrg 	void
17691debfc3dSmrg 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
17701debfc3dSmrg 	{ merge(__source); }
17711debfc3dSmrg 
17721debfc3dSmrg       template<typename _H2, typename _P2>
17731debfc3dSmrg 	void
17741debfc3dSmrg 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
17751debfc3dSmrg 	{
17761debfc3dSmrg 	  using _Merge_helper
17771debfc3dSmrg 	    = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
17781debfc3dSmrg 	  _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
17791debfc3dSmrg 	}
17801debfc3dSmrg 
17811debfc3dSmrg       template<typename _H2, typename _P2>
17821debfc3dSmrg 	void
17831debfc3dSmrg 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
17841debfc3dSmrg 	{ merge(__source); }
17851debfc3dSmrg #endif // C++17
17861debfc3dSmrg 
17871debfc3dSmrg       // observers.
17881debfc3dSmrg 
17891debfc3dSmrg       ///  Returns the hash functor object with which the %unordered_multimap
17901debfc3dSmrg       ///  was constructed.
17911debfc3dSmrg       hasher
17921debfc3dSmrg       hash_function() const
17931debfc3dSmrg       { return _M_h.hash_function(); }
17941debfc3dSmrg 
17951debfc3dSmrg       ///  Returns the key comparison object with which the %unordered_multimap
17961debfc3dSmrg       ///  was constructed.
17971debfc3dSmrg       key_equal
17981debfc3dSmrg       key_eq() const
17991debfc3dSmrg       { return _M_h.key_eq(); }
18001debfc3dSmrg 
18011debfc3dSmrg       // lookup.
18021debfc3dSmrg 
1803*8feb0f0bSmrg       ///@{
18041debfc3dSmrg       /**
18051debfc3dSmrg        *  @brief Tries to locate an element in an %unordered_multimap.
18061debfc3dSmrg        *  @param  __x  Key to be located.
18071debfc3dSmrg        *  @return  Iterator pointing to sought-after element, or end() if not
18081debfc3dSmrg        *           found.
18091debfc3dSmrg        *
18101debfc3dSmrg        *  This function takes a key and tries to locate the element with which
18111debfc3dSmrg        *  the key matches.  If successful the function returns an iterator
18121debfc3dSmrg        *  pointing to the sought after element.  If unsuccessful it returns the
18131debfc3dSmrg        *  past-the-end ( @c end() ) iterator.
18141debfc3dSmrg        */
18151debfc3dSmrg       iterator
18161debfc3dSmrg       find(const key_type& __x)
18171debfc3dSmrg       { return _M_h.find(__x); }
18181debfc3dSmrg 
18191debfc3dSmrg       const_iterator
18201debfc3dSmrg       find(const key_type& __x) const
18211debfc3dSmrg       { return _M_h.find(__x); }
1822*8feb0f0bSmrg       ///@}
18231debfc3dSmrg 
18241debfc3dSmrg       /**
18251debfc3dSmrg        *  @brief  Finds the number of elements.
18261debfc3dSmrg        *  @param  __x  Key to count.
18271debfc3dSmrg        *  @return  Number of elements with specified key.
18281debfc3dSmrg        */
18291debfc3dSmrg       size_type
18301debfc3dSmrg       count(const key_type& __x) const
18311debfc3dSmrg       { return _M_h.count(__x); }
18321debfc3dSmrg 
1833c0a68be4Smrg #if __cplusplus > 201703L
1834c0a68be4Smrg       /**
1835c0a68be4Smrg        *  @brief  Finds whether an element with the given key exists.
1836c0a68be4Smrg        *  @param  __x  Key of elements to be located.
1837c0a68be4Smrg        *  @return  True if there is any element with the specified key.
1838c0a68be4Smrg        */
1839c0a68be4Smrg       bool
1840c0a68be4Smrg       contains(const key_type& __x) const
1841c0a68be4Smrg       { return _M_h.find(__x) != _M_h.end(); }
1842c0a68be4Smrg #endif
1843c0a68be4Smrg 
1844*8feb0f0bSmrg       ///@{
18451debfc3dSmrg       /**
18461debfc3dSmrg        *  @brief Finds a subsequence matching given key.
18471debfc3dSmrg        *  @param  __x  Key to be located.
18481debfc3dSmrg        *  @return  Pair of iterators that possibly points to the subsequence
18491debfc3dSmrg        *           matching given key.
18501debfc3dSmrg        */
18511debfc3dSmrg       std::pair<iterator, iterator>
18521debfc3dSmrg       equal_range(const key_type& __x)
18531debfc3dSmrg       { return _M_h.equal_range(__x); }
18541debfc3dSmrg 
18551debfc3dSmrg       std::pair<const_iterator, const_iterator>
18561debfc3dSmrg       equal_range(const key_type& __x) const
18571debfc3dSmrg       { return _M_h.equal_range(__x); }
1858*8feb0f0bSmrg       ///@}
18591debfc3dSmrg 
18601debfc3dSmrg       // bucket interface.
18611debfc3dSmrg 
18621debfc3dSmrg       /// Returns the number of buckets of the %unordered_multimap.
18631debfc3dSmrg       size_type
18641debfc3dSmrg       bucket_count() const noexcept
18651debfc3dSmrg       { return _M_h.bucket_count(); }
18661debfc3dSmrg 
18671debfc3dSmrg       /// Returns the maximum number of buckets of the %unordered_multimap.
18681debfc3dSmrg       size_type
18691debfc3dSmrg       max_bucket_count() const noexcept
18701debfc3dSmrg       { return _M_h.max_bucket_count(); }
18711debfc3dSmrg 
18721debfc3dSmrg       /*
18731debfc3dSmrg        * @brief  Returns the number of elements in a given bucket.
18741debfc3dSmrg        * @param  __n  A bucket index.
18751debfc3dSmrg        * @return  The number of elements in the bucket.
18761debfc3dSmrg        */
18771debfc3dSmrg       size_type
18781debfc3dSmrg       bucket_size(size_type __n) const
18791debfc3dSmrg       { return _M_h.bucket_size(__n); }
18801debfc3dSmrg 
18811debfc3dSmrg       /*
18821debfc3dSmrg        * @brief  Returns the bucket index of a given element.
18831debfc3dSmrg        * @param  __key  A key instance.
18841debfc3dSmrg        * @return  The key bucket index.
18851debfc3dSmrg        */
18861debfc3dSmrg       size_type
18871debfc3dSmrg       bucket(const key_type& __key) const
18881debfc3dSmrg       { return _M_h.bucket(__key); }
18891debfc3dSmrg 
18901debfc3dSmrg       /**
18911debfc3dSmrg        *  @brief  Returns a read/write iterator pointing to the first bucket
18921debfc3dSmrg        *         element.
18931debfc3dSmrg        *  @param  __n The bucket index.
18941debfc3dSmrg        *  @return  A read/write local iterator.
18951debfc3dSmrg        */
18961debfc3dSmrg       local_iterator
18971debfc3dSmrg       begin(size_type __n)
18981debfc3dSmrg       { return _M_h.begin(__n); }
18991debfc3dSmrg 
1900*8feb0f0bSmrg       ///@{
19011debfc3dSmrg       /**
19021debfc3dSmrg        *  @brief  Returns a read-only (constant) iterator pointing to the first
19031debfc3dSmrg        *         bucket element.
19041debfc3dSmrg        *  @param  __n The bucket index.
19051debfc3dSmrg        *  @return  A read-only local iterator.
19061debfc3dSmrg        */
19071debfc3dSmrg       const_local_iterator
19081debfc3dSmrg       begin(size_type __n) const
19091debfc3dSmrg       { return _M_h.begin(__n); }
19101debfc3dSmrg 
19111debfc3dSmrg       const_local_iterator
19121debfc3dSmrg       cbegin(size_type __n) const
19131debfc3dSmrg       { return _M_h.cbegin(__n); }
1914*8feb0f0bSmrg       ///@}
19151debfc3dSmrg 
19161debfc3dSmrg       /**
19171debfc3dSmrg        *  @brief  Returns a read/write iterator pointing to one past the last
19181debfc3dSmrg        *         bucket elements.
19191debfc3dSmrg        *  @param  __n The bucket index.
19201debfc3dSmrg        *  @return  A read/write local iterator.
19211debfc3dSmrg        */
19221debfc3dSmrg       local_iterator
19231debfc3dSmrg       end(size_type __n)
19241debfc3dSmrg       { return _M_h.end(__n); }
19251debfc3dSmrg 
1926*8feb0f0bSmrg       ///@{
19271debfc3dSmrg       /**
19281debfc3dSmrg        *  @brief  Returns a read-only (constant) iterator pointing to one past
19291debfc3dSmrg        *         the last bucket elements.
19301debfc3dSmrg        *  @param  __n The bucket index.
19311debfc3dSmrg        *  @return  A read-only local iterator.
19321debfc3dSmrg        */
19331debfc3dSmrg       const_local_iterator
19341debfc3dSmrg       end(size_type __n) const
19351debfc3dSmrg       { return _M_h.end(__n); }
19361debfc3dSmrg 
19371debfc3dSmrg       const_local_iterator
19381debfc3dSmrg       cend(size_type __n) const
19391debfc3dSmrg       { return _M_h.cend(__n); }
1940*8feb0f0bSmrg       ///@}
19411debfc3dSmrg 
19421debfc3dSmrg       // hash policy.
19431debfc3dSmrg 
19441debfc3dSmrg       /// Returns the average number of elements per bucket.
19451debfc3dSmrg       float
19461debfc3dSmrg       load_factor() const noexcept
19471debfc3dSmrg       { return _M_h.load_factor(); }
19481debfc3dSmrg 
19491debfc3dSmrg       /// Returns a positive number that the %unordered_multimap tries to keep
19501debfc3dSmrg       /// the load factor less than or equal to.
19511debfc3dSmrg       float
19521debfc3dSmrg       max_load_factor() const noexcept
19531debfc3dSmrg       { return _M_h.max_load_factor(); }
19541debfc3dSmrg 
19551debfc3dSmrg       /**
19561debfc3dSmrg        *  @brief  Change the %unordered_multimap maximum load factor.
19571debfc3dSmrg        *  @param  __z The new maximum load factor.
19581debfc3dSmrg        */
19591debfc3dSmrg       void
19601debfc3dSmrg       max_load_factor(float __z)
19611debfc3dSmrg       { _M_h.max_load_factor(__z); }
19621debfc3dSmrg 
19631debfc3dSmrg       /**
19641debfc3dSmrg        *  @brief  May rehash the %unordered_multimap.
19651debfc3dSmrg        *  @param  __n The new number of buckets.
19661debfc3dSmrg        *
19671debfc3dSmrg        *  Rehash will occur only if the new number of buckets respect the
19681debfc3dSmrg        *  %unordered_multimap maximum load factor.
19691debfc3dSmrg        */
19701debfc3dSmrg       void
19711debfc3dSmrg       rehash(size_type __n)
19721debfc3dSmrg       { _M_h.rehash(__n); }
19731debfc3dSmrg 
19741debfc3dSmrg       /**
19751debfc3dSmrg        *  @brief  Prepare the %unordered_multimap for a specified number of
19761debfc3dSmrg        *          elements.
19771debfc3dSmrg        *  @param  __n Number of elements required.
19781debfc3dSmrg        *
19791debfc3dSmrg        *  Same as rehash(ceil(n / max_load_factor())).
19801debfc3dSmrg        */
19811debfc3dSmrg       void
19821debfc3dSmrg       reserve(size_type __n)
19831debfc3dSmrg       { _M_h.reserve(__n); }
19841debfc3dSmrg 
19851debfc3dSmrg       template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1,
19861debfc3dSmrg 	       typename _Alloc1>
19871debfc3dSmrg         friend bool
19881debfc3dSmrg 	operator==(const unordered_multimap<_Key1, _Tp1,
19891debfc3dSmrg 					    _Hash1, _Pred1, _Alloc1>&,
19901debfc3dSmrg 		   const unordered_multimap<_Key1, _Tp1,
19911debfc3dSmrg 					    _Hash1, _Pred1, _Alloc1>&);
19921debfc3dSmrg     };
19931debfc3dSmrg 
1994a2dc1f3fSmrg #if __cpp_deduction_guides >= 201606
1995a2dc1f3fSmrg 
1996a2dc1f3fSmrg   template<typename _InputIterator,
1997a2dc1f3fSmrg 	   typename _Hash = hash<__iter_key_t<_InputIterator>>,
1998a2dc1f3fSmrg 	   typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
1999a2dc1f3fSmrg 	   typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
2000a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
2001c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
2002c0a68be4Smrg 	   typename = _RequireNotAllocator<_Pred>,
2003a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2004a2dc1f3fSmrg     unordered_multimap(_InputIterator, _InputIterator,
2005a2dc1f3fSmrg 		       unordered_multimap<int, int>::size_type = {},
2006a2dc1f3fSmrg 		       _Hash = _Hash(), _Pred = _Pred(),
2007a2dc1f3fSmrg 		       _Allocator = _Allocator())
2008a2dc1f3fSmrg     -> unordered_multimap<__iter_key_t<_InputIterator>,
2009a2dc1f3fSmrg 			  __iter_val_t<_InputIterator>, _Hash, _Pred,
2010a2dc1f3fSmrg 			  _Allocator>;
2011a2dc1f3fSmrg 
2012a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
2013a2dc1f3fSmrg 	   typename _Pred = equal_to<_Key>,
2014a2dc1f3fSmrg 	   typename _Allocator = allocator<pair<const _Key, _Tp>>,
2015c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
2016c0a68be4Smrg 	   typename = _RequireNotAllocator<_Pred>,
2017a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2018a2dc1f3fSmrg     unordered_multimap(initializer_list<pair<_Key, _Tp>>,
2019a2dc1f3fSmrg 		       unordered_multimap<int, int>::size_type = {},
2020a2dc1f3fSmrg 		       _Hash = _Hash(), _Pred = _Pred(),
2021a2dc1f3fSmrg 		       _Allocator = _Allocator())
2022a2dc1f3fSmrg     -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>;
2023a2dc1f3fSmrg 
2024a2dc1f3fSmrg   template<typename _InputIterator, typename _Allocator,
2025a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
2026a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2027a2dc1f3fSmrg     unordered_multimap(_InputIterator, _InputIterator,
2028a2dc1f3fSmrg 		       unordered_multimap<int, int>::size_type, _Allocator)
2029a2dc1f3fSmrg     -> unordered_multimap<__iter_key_t<_InputIterator>,
2030a2dc1f3fSmrg 			  __iter_val_t<_InputIterator>,
2031a2dc1f3fSmrg 			  hash<__iter_key_t<_InputIterator>>,
2032a2dc1f3fSmrg 			  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
2033a2dc1f3fSmrg 
2034a2dc1f3fSmrg   template<typename _InputIterator, typename _Allocator,
2035a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
2036a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2037a2dc1f3fSmrg     unordered_multimap(_InputIterator, _InputIterator, _Allocator)
2038a2dc1f3fSmrg     -> unordered_multimap<__iter_key_t<_InputIterator>,
2039a2dc1f3fSmrg 			  __iter_val_t<_InputIterator>,
2040a2dc1f3fSmrg 			  hash<__iter_key_t<_InputIterator>>,
2041a2dc1f3fSmrg 			  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
2042a2dc1f3fSmrg 
2043a2dc1f3fSmrg   template<typename _InputIterator, typename _Hash, typename _Allocator,
2044a2dc1f3fSmrg 	   typename = _RequireInputIter<_InputIterator>,
2045c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
2046a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2047a2dc1f3fSmrg     unordered_multimap(_InputIterator, _InputIterator,
2048a2dc1f3fSmrg 		       unordered_multimap<int, int>::size_type, _Hash,
2049a2dc1f3fSmrg 		       _Allocator)
2050a2dc1f3fSmrg     -> unordered_multimap<__iter_key_t<_InputIterator>,
2051a2dc1f3fSmrg 			  __iter_val_t<_InputIterator>, _Hash,
2052a2dc1f3fSmrg 			  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
2053a2dc1f3fSmrg 
2054a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Allocator,
2055a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2056a2dc1f3fSmrg     unordered_multimap(initializer_list<pair<_Key, _Tp>>,
2057a2dc1f3fSmrg 		       unordered_multimap<int, int>::size_type,
2058a2dc1f3fSmrg 		       _Allocator)
2059a2dc1f3fSmrg     -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
2060a2dc1f3fSmrg 
2061a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Allocator,
2062a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2063a2dc1f3fSmrg     unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
2064a2dc1f3fSmrg     -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
2065a2dc1f3fSmrg 
2066a2dc1f3fSmrg   template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
2067c0a68be4Smrg 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
2068a2dc1f3fSmrg 	   typename = _RequireAllocator<_Allocator>>
2069a2dc1f3fSmrg     unordered_multimap(initializer_list<pair<_Key, _Tp>>,
2070a2dc1f3fSmrg 		       unordered_multimap<int, int>::size_type,
2071a2dc1f3fSmrg 		       _Hash, _Allocator)
2072a2dc1f3fSmrg     -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
2073a2dc1f3fSmrg 
2074a2dc1f3fSmrg #endif
2075a2dc1f3fSmrg 
20761debfc3dSmrg   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
20771debfc3dSmrg     inline void
20781debfc3dSmrg     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
20791debfc3dSmrg 	 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
20801debfc3dSmrg     noexcept(noexcept(__x.swap(__y)))
20811debfc3dSmrg     { __x.swap(__y); }
20821debfc3dSmrg 
20831debfc3dSmrg   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
20841debfc3dSmrg     inline void
20851debfc3dSmrg     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
20861debfc3dSmrg 	 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
20871debfc3dSmrg     noexcept(noexcept(__x.swap(__y)))
20881debfc3dSmrg     { __x.swap(__y); }
20891debfc3dSmrg 
20901debfc3dSmrg   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
20911debfc3dSmrg     inline bool
20921debfc3dSmrg     operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
20931debfc3dSmrg 	       const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
20941debfc3dSmrg     { return __x._M_h._M_equal(__y._M_h); }
20951debfc3dSmrg 
2096*8feb0f0bSmrg #if __cpp_impl_three_way_comparison < 201907L
20971debfc3dSmrg   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
20981debfc3dSmrg     inline bool
20991debfc3dSmrg     operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
21001debfc3dSmrg 	       const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
21011debfc3dSmrg     { return !(__x == __y); }
2102*8feb0f0bSmrg #endif
21031debfc3dSmrg 
21041debfc3dSmrg   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
21051debfc3dSmrg     inline bool
21061debfc3dSmrg     operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
21071debfc3dSmrg 	       const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
21081debfc3dSmrg     { return __x._M_h._M_equal(__y._M_h); }
21091debfc3dSmrg 
2110*8feb0f0bSmrg #if __cpp_impl_three_way_comparison < 201907L
21111debfc3dSmrg   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
21121debfc3dSmrg     inline bool
21131debfc3dSmrg     operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
21141debfc3dSmrg 	       const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
21151debfc3dSmrg     { return !(__x == __y); }
2116*8feb0f0bSmrg #endif
21171debfc3dSmrg 
21181debfc3dSmrg _GLIBCXX_END_NAMESPACE_CONTAINER
21191debfc3dSmrg 
21201debfc3dSmrg #if __cplusplus > 201402L
21211debfc3dSmrg   // Allow std::unordered_map access to internals of compatible maps.
21221debfc3dSmrg   template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
21231debfc3dSmrg 	   typename _Alloc, typename _Hash2, typename _Eq2>
21241debfc3dSmrg     struct _Hash_merge_helper<
21251debfc3dSmrg       _GLIBCXX_STD_C::unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>,
21261debfc3dSmrg       _Hash2, _Eq2>
21271debfc3dSmrg     {
21281debfc3dSmrg     private:
21291debfc3dSmrg       template<typename... _Tp>
21301debfc3dSmrg 	using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
21311debfc3dSmrg       template<typename... _Tp>
21321debfc3dSmrg 	using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
21331debfc3dSmrg 
21341debfc3dSmrg       friend unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>;
21351debfc3dSmrg 
21361debfc3dSmrg       static auto&
21371debfc3dSmrg       _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
21381debfc3dSmrg       { return __map._M_h; }
21391debfc3dSmrg 
21401debfc3dSmrg       static auto&
21411debfc3dSmrg       _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
21421debfc3dSmrg       { return __map._M_h; }
21431debfc3dSmrg     };
21441debfc3dSmrg 
21451debfc3dSmrg   // Allow std::unordered_multimap access to internals of compatible maps.
21461debfc3dSmrg   template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
21471debfc3dSmrg 	   typename _Alloc, typename _Hash2, typename _Eq2>
21481debfc3dSmrg     struct _Hash_merge_helper<
21491debfc3dSmrg       _GLIBCXX_STD_C::unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>,
21501debfc3dSmrg       _Hash2, _Eq2>
21511debfc3dSmrg     {
21521debfc3dSmrg     private:
21531debfc3dSmrg       template<typename... _Tp>
21541debfc3dSmrg 	using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
21551debfc3dSmrg       template<typename... _Tp>
21561debfc3dSmrg 	using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
21571debfc3dSmrg 
21581debfc3dSmrg       friend unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>;
21591debfc3dSmrg 
21601debfc3dSmrg       static auto&
21611debfc3dSmrg       _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
21621debfc3dSmrg       { return __map._M_h; }
21631debfc3dSmrg 
21641debfc3dSmrg       static auto&
21651debfc3dSmrg       _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
21661debfc3dSmrg       { return __map._M_h; }
21671debfc3dSmrg     };
21681debfc3dSmrg #endif // C++17
21691debfc3dSmrg 
2170a2dc1f3fSmrg _GLIBCXX_END_NAMESPACE_VERSION
21711debfc3dSmrg } // namespace std
21721debfc3dSmrg 
21731debfc3dSmrg #endif /* _UNORDERED_MAP_H */
2174