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