1*38fd1498Szrj // unordered_map implementation -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2010-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file bits/unordered_map.h 26*38fd1498Szrj * This is an internal header file, included by other library headers. 27*38fd1498Szrj * Do not attempt to use it directly. @headername{unordered_map} 28*38fd1498Szrj */ 29*38fd1498Szrj 30*38fd1498Szrj #ifndef _UNORDERED_MAP_H 31*38fd1498Szrj #define _UNORDERED_MAP_H 32*38fd1498Szrj 33*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 34*38fd1498Szrj { 35*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 36*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 37*38fd1498Szrj 38*38fd1498Szrj /// Base types for unordered_map. 39*38fd1498Szrj template<bool _Cache> 40*38fd1498Szrj using __umap_traits = __detail::_Hashtable_traits<_Cache, false, true>; 41*38fd1498Szrj 42*38fd1498Szrj template<typename _Key, 43*38fd1498Szrj typename _Tp, 44*38fd1498Szrj typename _Hash = hash<_Key>, 45*38fd1498Szrj typename _Pred = std::equal_to<_Key>, 46*38fd1498Szrj typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >, 47*38fd1498Szrj typename _Tr = __umap_traits<__cache_default<_Key, _Hash>::value>> 48*38fd1498Szrj using __umap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>, 49*38fd1498Szrj _Alloc, __detail::_Select1st, 50*38fd1498Szrj _Pred, _Hash, 51*38fd1498Szrj __detail::_Mod_range_hashing, 52*38fd1498Szrj __detail::_Default_ranged_hash, 53*38fd1498Szrj __detail::_Prime_rehash_policy, _Tr>; 54*38fd1498Szrj 55*38fd1498Szrj /// Base types for unordered_multimap. 56*38fd1498Szrj template<bool _Cache> 57*38fd1498Szrj using __ummap_traits = __detail::_Hashtable_traits<_Cache, false, false>; 58*38fd1498Szrj 59*38fd1498Szrj template<typename _Key, 60*38fd1498Szrj typename _Tp, 61*38fd1498Szrj typename _Hash = hash<_Key>, 62*38fd1498Szrj typename _Pred = std::equal_to<_Key>, 63*38fd1498Szrj typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >, 64*38fd1498Szrj typename _Tr = __ummap_traits<__cache_default<_Key, _Hash>::value>> 65*38fd1498Szrj using __ummap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>, 66*38fd1498Szrj _Alloc, __detail::_Select1st, 67*38fd1498Szrj _Pred, _Hash, 68*38fd1498Szrj __detail::_Mod_range_hashing, 69*38fd1498Szrj __detail::_Default_ranged_hash, 70*38fd1498Szrj __detail::_Prime_rehash_policy, _Tr>; 71*38fd1498Szrj 72*38fd1498Szrj template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 73*38fd1498Szrj class unordered_multimap; 74*38fd1498Szrj 75*38fd1498Szrj /** 76*38fd1498Szrj * @brief A standard container composed of unique keys (containing 77*38fd1498Szrj * at most one of each key value) that associates values of another type 78*38fd1498Szrj * with the keys. 79*38fd1498Szrj * 80*38fd1498Szrj * @ingroup unordered_associative_containers 81*38fd1498Szrj * 82*38fd1498Szrj * @tparam _Key Type of key objects. 83*38fd1498Szrj * @tparam _Tp Type of mapped objects. 84*38fd1498Szrj * @tparam _Hash Hashing function object type, defaults to hash<_Value>. 85*38fd1498Szrj * @tparam _Pred Predicate function object type, defaults 86*38fd1498Szrj * to equal_to<_Value>. 87*38fd1498Szrj * @tparam _Alloc Allocator type, defaults to 88*38fd1498Szrj * std::allocator<std::pair<const _Key, _Tp>>. 89*38fd1498Szrj * 90*38fd1498Szrj * Meets the requirements of a <a href="tables.html#65">container</a>, and 91*38fd1498Szrj * <a href="tables.html#xx">unordered associative container</a> 92*38fd1498Szrj * 93*38fd1498Szrj * The resulting value type of the container is std::pair<const _Key, _Tp>. 94*38fd1498Szrj * 95*38fd1498Szrj * Base is _Hashtable, dispatched at compile time via template 96*38fd1498Szrj * alias __umap_hashtable. 97*38fd1498Szrj */ 98*38fd1498Szrj template<typename _Key, typename _Tp, 99*38fd1498Szrj typename _Hash = hash<_Key>, 100*38fd1498Szrj typename _Pred = equal_to<_Key>, 101*38fd1498Szrj typename _Alloc = allocator<std::pair<const _Key, _Tp>>> 102*38fd1498Szrj class unordered_map 103*38fd1498Szrj { 104*38fd1498Szrj typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; 105*38fd1498Szrj _Hashtable _M_h; 106*38fd1498Szrj 107*38fd1498Szrj public: 108*38fd1498Szrj // typedefs: 109*38fd1498Szrj //@{ 110*38fd1498Szrj /// Public typedefs. 111*38fd1498Szrj typedef typename _Hashtable::key_type key_type; 112*38fd1498Szrj typedef typename _Hashtable::value_type value_type; 113*38fd1498Szrj typedef typename _Hashtable::mapped_type mapped_type; 114*38fd1498Szrj typedef typename _Hashtable::hasher hasher; 115*38fd1498Szrj typedef typename _Hashtable::key_equal key_equal; 116*38fd1498Szrj typedef typename _Hashtable::allocator_type allocator_type; 117*38fd1498Szrj //@} 118*38fd1498Szrj 119*38fd1498Szrj //@{ 120*38fd1498Szrj /// Iterator-related typedefs. 121*38fd1498Szrj typedef typename _Hashtable::pointer pointer; 122*38fd1498Szrj typedef typename _Hashtable::const_pointer const_pointer; 123*38fd1498Szrj typedef typename _Hashtable::reference reference; 124*38fd1498Szrj typedef typename _Hashtable::const_reference const_reference; 125*38fd1498Szrj typedef typename _Hashtable::iterator iterator; 126*38fd1498Szrj typedef typename _Hashtable::const_iterator const_iterator; 127*38fd1498Szrj typedef typename _Hashtable::local_iterator local_iterator; 128*38fd1498Szrj typedef typename _Hashtable::const_local_iterator const_local_iterator; 129*38fd1498Szrj typedef typename _Hashtable::size_type size_type; 130*38fd1498Szrj typedef typename _Hashtable::difference_type difference_type; 131*38fd1498Szrj //@} 132*38fd1498Szrj 133*38fd1498Szrj #if __cplusplus > 201402L 134*38fd1498Szrj using node_type = typename _Hashtable::node_type; 135*38fd1498Szrj using insert_return_type = typename _Hashtable::insert_return_type; 136*38fd1498Szrj #endif 137*38fd1498Szrj 138*38fd1498Szrj //construct/destroy/copy 139*38fd1498Szrj 140*38fd1498Szrj /// Default constructor. 141*38fd1498Szrj unordered_map() = default; 142*38fd1498Szrj 143*38fd1498Szrj /** 144*38fd1498Szrj * @brief Default constructor creates no elements. 145*38fd1498Szrj * @param __n Minimal initial number of buckets. 146*38fd1498Szrj * @param __hf A hash functor. 147*38fd1498Szrj * @param __eql A key equality functor. 148*38fd1498Szrj * @param __a An allocator object. 149*38fd1498Szrj */ 150*38fd1498Szrj explicit 151*38fd1498Szrj unordered_map(size_type __n, 152*38fd1498Szrj const hasher& __hf = hasher(), 153*38fd1498Szrj const key_equal& __eql = key_equal(), 154*38fd1498Szrj const allocator_type& __a = allocator_type()) 155*38fd1498Szrj : _M_h(__n, __hf, __eql, __a) 156*38fd1498Szrj { } 157*38fd1498Szrj 158*38fd1498Szrj /** 159*38fd1498Szrj * @brief Builds an %unordered_map from a range. 160*38fd1498Szrj * @param __first An input iterator. 161*38fd1498Szrj * @param __last An input iterator. 162*38fd1498Szrj * @param __n Minimal initial number of buckets. 163*38fd1498Szrj * @param __hf A hash functor. 164*38fd1498Szrj * @param __eql A key equality functor. 165*38fd1498Szrj * @param __a An allocator object. 166*38fd1498Szrj * 167*38fd1498Szrj * Create an %unordered_map consisting of copies of the elements from 168*38fd1498Szrj * [__first,__last). This is linear in N (where N is 169*38fd1498Szrj * distance(__first,__last)). 170*38fd1498Szrj */ 171*38fd1498Szrj template<typename _InputIterator> 172*38fd1498Szrj unordered_map(_InputIterator __first, _InputIterator __last, 173*38fd1498Szrj size_type __n = 0, 174*38fd1498Szrj const hasher& __hf = hasher(), 175*38fd1498Szrj const key_equal& __eql = key_equal(), 176*38fd1498Szrj const allocator_type& __a = allocator_type()) 177*38fd1498Szrj : _M_h(__first, __last, __n, __hf, __eql, __a) 178*38fd1498Szrj { } 179*38fd1498Szrj 180*38fd1498Szrj /// Copy constructor. 181*38fd1498Szrj unordered_map(const unordered_map&) = default; 182*38fd1498Szrj 183*38fd1498Szrj /// Move constructor. 184*38fd1498Szrj unordered_map(unordered_map&&) = default; 185*38fd1498Szrj 186*38fd1498Szrj /** 187*38fd1498Szrj * @brief Creates an %unordered_map with no elements. 188*38fd1498Szrj * @param __a An allocator object. 189*38fd1498Szrj */ 190*38fd1498Szrj explicit 191*38fd1498Szrj unordered_map(const allocator_type& __a) 192*38fd1498Szrj : _M_h(__a) 193*38fd1498Szrj { } 194*38fd1498Szrj 195*38fd1498Szrj /* 196*38fd1498Szrj * @brief Copy constructor with allocator argument. 197*38fd1498Szrj * @param __uset Input %unordered_map to copy. 198*38fd1498Szrj * @param __a An allocator object. 199*38fd1498Szrj */ 200*38fd1498Szrj unordered_map(const unordered_map& __umap, 201*38fd1498Szrj const allocator_type& __a) 202*38fd1498Szrj : _M_h(__umap._M_h, __a) 203*38fd1498Szrj { } 204*38fd1498Szrj 205*38fd1498Szrj /* 206*38fd1498Szrj * @brief Move constructor with allocator argument. 207*38fd1498Szrj * @param __uset Input %unordered_map to move. 208*38fd1498Szrj * @param __a An allocator object. 209*38fd1498Szrj */ 210*38fd1498Szrj unordered_map(unordered_map&& __umap, 211*38fd1498Szrj const allocator_type& __a) 212*38fd1498Szrj : _M_h(std::move(__umap._M_h), __a) 213*38fd1498Szrj { } 214*38fd1498Szrj 215*38fd1498Szrj /** 216*38fd1498Szrj * @brief Builds an %unordered_map from an initializer_list. 217*38fd1498Szrj * @param __l An initializer_list. 218*38fd1498Szrj * @param __n Minimal initial number of buckets. 219*38fd1498Szrj * @param __hf A hash functor. 220*38fd1498Szrj * @param __eql A key equality functor. 221*38fd1498Szrj * @param __a An allocator object. 222*38fd1498Szrj * 223*38fd1498Szrj * Create an %unordered_map consisting of copies of the elements in the 224*38fd1498Szrj * list. This is linear in N (where N is @a __l.size()). 225*38fd1498Szrj */ 226*38fd1498Szrj unordered_map(initializer_list<value_type> __l, 227*38fd1498Szrj size_type __n = 0, 228*38fd1498Szrj const hasher& __hf = hasher(), 229*38fd1498Szrj const key_equal& __eql = key_equal(), 230*38fd1498Szrj const allocator_type& __a = allocator_type()) 231*38fd1498Szrj : _M_h(__l, __n, __hf, __eql, __a) 232*38fd1498Szrj { } 233*38fd1498Szrj 234*38fd1498Szrj unordered_map(size_type __n, const allocator_type& __a) 235*38fd1498Szrj : unordered_map(__n, hasher(), key_equal(), __a) 236*38fd1498Szrj { } 237*38fd1498Szrj 238*38fd1498Szrj unordered_map(size_type __n, const hasher& __hf, 239*38fd1498Szrj const allocator_type& __a) 240*38fd1498Szrj : unordered_map(__n, __hf, key_equal(), __a) 241*38fd1498Szrj { } 242*38fd1498Szrj 243*38fd1498Szrj template<typename _InputIterator> 244*38fd1498Szrj unordered_map(_InputIterator __first, _InputIterator __last, 245*38fd1498Szrj size_type __n, 246*38fd1498Szrj const allocator_type& __a) 247*38fd1498Szrj : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) 248*38fd1498Szrj { } 249*38fd1498Szrj 250*38fd1498Szrj template<typename _InputIterator> 251*38fd1498Szrj unordered_map(_InputIterator __first, _InputIterator __last, 252*38fd1498Szrj size_type __n, const hasher& __hf, 253*38fd1498Szrj const allocator_type& __a) 254*38fd1498Szrj : unordered_map(__first, __last, __n, __hf, key_equal(), __a) 255*38fd1498Szrj { } 256*38fd1498Szrj 257*38fd1498Szrj unordered_map(initializer_list<value_type> __l, 258*38fd1498Szrj size_type __n, 259*38fd1498Szrj const allocator_type& __a) 260*38fd1498Szrj : unordered_map(__l, __n, hasher(), key_equal(), __a) 261*38fd1498Szrj { } 262*38fd1498Szrj 263*38fd1498Szrj unordered_map(initializer_list<value_type> __l, 264*38fd1498Szrj size_type __n, const hasher& __hf, 265*38fd1498Szrj const allocator_type& __a) 266*38fd1498Szrj : unordered_map(__l, __n, __hf, key_equal(), __a) 267*38fd1498Szrj { } 268*38fd1498Szrj 269*38fd1498Szrj /// Copy assignment operator. 270*38fd1498Szrj unordered_map& 271*38fd1498Szrj operator=(const unordered_map&) = default; 272*38fd1498Szrj 273*38fd1498Szrj /// Move assignment operator. 274*38fd1498Szrj unordered_map& 275*38fd1498Szrj operator=(unordered_map&&) = default; 276*38fd1498Szrj 277*38fd1498Szrj /** 278*38fd1498Szrj * @brief %Unordered_map list assignment operator. 279*38fd1498Szrj * @param __l An initializer_list. 280*38fd1498Szrj * 281*38fd1498Szrj * This function fills an %unordered_map with copies of the elements in 282*38fd1498Szrj * the initializer list @a __l. 283*38fd1498Szrj * 284*38fd1498Szrj * Note that the assignment completely changes the %unordered_map and 285*38fd1498Szrj * that the resulting %unordered_map's size is the same as the number 286*38fd1498Szrj * of elements assigned. 287*38fd1498Szrj */ 288*38fd1498Szrj unordered_map& 289*38fd1498Szrj operator=(initializer_list<value_type> __l) 290*38fd1498Szrj { 291*38fd1498Szrj _M_h = __l; 292*38fd1498Szrj return *this; 293*38fd1498Szrj } 294*38fd1498Szrj 295*38fd1498Szrj /// Returns the allocator object used by the %unordered_map. 296*38fd1498Szrj allocator_type 297*38fd1498Szrj get_allocator() const noexcept 298*38fd1498Szrj { return _M_h.get_allocator(); } 299*38fd1498Szrj 300*38fd1498Szrj // size and capacity: 301*38fd1498Szrj 302*38fd1498Szrj /// Returns true if the %unordered_map is empty. 303*38fd1498Szrj bool 304*38fd1498Szrj empty() const noexcept 305*38fd1498Szrj { return _M_h.empty(); } 306*38fd1498Szrj 307*38fd1498Szrj /// Returns the size of the %unordered_map. 308*38fd1498Szrj size_type 309*38fd1498Szrj size() const noexcept 310*38fd1498Szrj { return _M_h.size(); } 311*38fd1498Szrj 312*38fd1498Szrj /// Returns the maximum size of the %unordered_map. 313*38fd1498Szrj size_type 314*38fd1498Szrj max_size() const noexcept 315*38fd1498Szrj { return _M_h.max_size(); } 316*38fd1498Szrj 317*38fd1498Szrj // iterators. 318*38fd1498Szrj 319*38fd1498Szrj /** 320*38fd1498Szrj * Returns a read/write iterator that points to the first element in the 321*38fd1498Szrj * %unordered_map. 322*38fd1498Szrj */ 323*38fd1498Szrj iterator 324*38fd1498Szrj begin() noexcept 325*38fd1498Szrj { return _M_h.begin(); } 326*38fd1498Szrj 327*38fd1498Szrj //@{ 328*38fd1498Szrj /** 329*38fd1498Szrj * Returns a read-only (constant) iterator that points to the first 330*38fd1498Szrj * element in the %unordered_map. 331*38fd1498Szrj */ 332*38fd1498Szrj const_iterator 333*38fd1498Szrj begin() const noexcept 334*38fd1498Szrj { return _M_h.begin(); } 335*38fd1498Szrj 336*38fd1498Szrj const_iterator 337*38fd1498Szrj cbegin() const noexcept 338*38fd1498Szrj { return _M_h.begin(); } 339*38fd1498Szrj //@} 340*38fd1498Szrj 341*38fd1498Szrj /** 342*38fd1498Szrj * Returns a read/write iterator that points one past the last element in 343*38fd1498Szrj * the %unordered_map. 344*38fd1498Szrj */ 345*38fd1498Szrj iterator 346*38fd1498Szrj end() noexcept 347*38fd1498Szrj { return _M_h.end(); } 348*38fd1498Szrj 349*38fd1498Szrj //@{ 350*38fd1498Szrj /** 351*38fd1498Szrj * Returns a read-only (constant) iterator that points one past the last 352*38fd1498Szrj * element in the %unordered_map. 353*38fd1498Szrj */ 354*38fd1498Szrj const_iterator 355*38fd1498Szrj end() const noexcept 356*38fd1498Szrj { return _M_h.end(); } 357*38fd1498Szrj 358*38fd1498Szrj const_iterator 359*38fd1498Szrj cend() const noexcept 360*38fd1498Szrj { return _M_h.end(); } 361*38fd1498Szrj //@} 362*38fd1498Szrj 363*38fd1498Szrj // modifiers. 364*38fd1498Szrj 365*38fd1498Szrj /** 366*38fd1498Szrj * @brief Attempts to build and insert a std::pair into the 367*38fd1498Szrj * %unordered_map. 368*38fd1498Szrj * 369*38fd1498Szrj * @param __args Arguments used to generate a new pair instance (see 370*38fd1498Szrj * std::piecewise_contruct for passing arguments to each 371*38fd1498Szrj * part of the pair constructor). 372*38fd1498Szrj * 373*38fd1498Szrj * @return A pair, of which the first element is an iterator that points 374*38fd1498Szrj * to the possibly inserted pair, and the second is a bool that 375*38fd1498Szrj * is true if the pair was actually inserted. 376*38fd1498Szrj * 377*38fd1498Szrj * This function attempts to build and insert a (key, value) %pair into 378*38fd1498Szrj * the %unordered_map. 379*38fd1498Szrj * An %unordered_map relies on unique keys and thus a %pair is only 380*38fd1498Szrj * inserted if its first element (the key) is not already present in the 381*38fd1498Szrj * %unordered_map. 382*38fd1498Szrj * 383*38fd1498Szrj * Insertion requires amortized constant time. 384*38fd1498Szrj */ 385*38fd1498Szrj template<typename... _Args> 386*38fd1498Szrj std::pair<iterator, bool> 387*38fd1498Szrj emplace(_Args&&... __args) 388*38fd1498Szrj { return _M_h.emplace(std::forward<_Args>(__args)...); } 389*38fd1498Szrj 390*38fd1498Szrj /** 391*38fd1498Szrj * @brief Attempts to build and insert a std::pair into the 392*38fd1498Szrj * %unordered_map. 393*38fd1498Szrj * 394*38fd1498Szrj * @param __pos An iterator that serves as a hint as to where the pair 395*38fd1498Szrj * should be inserted. 396*38fd1498Szrj * @param __args Arguments used to generate a new pair instance (see 397*38fd1498Szrj * std::piecewise_contruct for passing arguments to each 398*38fd1498Szrj * part of the pair constructor). 399*38fd1498Szrj * @return An iterator that points to the element with key of the 400*38fd1498Szrj * std::pair built from @a __args (may or may not be that 401*38fd1498Szrj * std::pair). 402*38fd1498Szrj * 403*38fd1498Szrj * This function is not concerned about whether the insertion took place, 404*38fd1498Szrj * and thus does not return a boolean like the single-argument emplace() 405*38fd1498Szrj * does. 406*38fd1498Szrj * Note that the first parameter is only a hint and can potentially 407*38fd1498Szrj * improve the performance of the insertion process. A bad hint would 408*38fd1498Szrj * cause no gains in efficiency. 409*38fd1498Szrj * 410*38fd1498Szrj * See 411*38fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 412*38fd1498Szrj * for more on @a hinting. 413*38fd1498Szrj * 414*38fd1498Szrj * Insertion requires amortized constant time. 415*38fd1498Szrj */ 416*38fd1498Szrj template<typename... _Args> 417*38fd1498Szrj iterator 418*38fd1498Szrj emplace_hint(const_iterator __pos, _Args&&... __args) 419*38fd1498Szrj { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } 420*38fd1498Szrj 421*38fd1498Szrj #if __cplusplus > 201402L 422*38fd1498Szrj /// Extract a node. 423*38fd1498Szrj node_type 424*38fd1498Szrj extract(const_iterator __pos) 425*38fd1498Szrj { 426*38fd1498Szrj __glibcxx_assert(__pos != end()); 427*38fd1498Szrj return _M_h.extract(__pos); 428*38fd1498Szrj } 429*38fd1498Szrj 430*38fd1498Szrj /// Extract a node. 431*38fd1498Szrj node_type 432*38fd1498Szrj extract(const key_type& __key) 433*38fd1498Szrj { return _M_h.extract(__key); } 434*38fd1498Szrj 435*38fd1498Szrj /// Re-insert an extracted node. 436*38fd1498Szrj insert_return_type 437*38fd1498Szrj insert(node_type&& __nh) 438*38fd1498Szrj { return _M_h._M_reinsert_node(std::move(__nh)); } 439*38fd1498Szrj 440*38fd1498Szrj /// Re-insert an extracted node. 441*38fd1498Szrj iterator 442*38fd1498Szrj insert(const_iterator, node_type&& __nh) 443*38fd1498Szrj { return _M_h._M_reinsert_node(std::move(__nh)).position; } 444*38fd1498Szrj 445*38fd1498Szrj #define __cpp_lib_unordered_map_try_emplace 201411 446*38fd1498Szrj /** 447*38fd1498Szrj * @brief Attempts to build and insert a std::pair into the 448*38fd1498Szrj * %unordered_map. 449*38fd1498Szrj * 450*38fd1498Szrj * @param __k Key to use for finding a possibly existing pair in 451*38fd1498Szrj * the unordered_map. 452*38fd1498Szrj * @param __args Arguments used to generate the .second for a 453*38fd1498Szrj * new pair instance. 454*38fd1498Szrj * 455*38fd1498Szrj * @return A pair, of which the first element is an iterator that points 456*38fd1498Szrj * to the possibly inserted pair, and the second is a bool that 457*38fd1498Szrj * is true if the pair was actually inserted. 458*38fd1498Szrj * 459*38fd1498Szrj * This function attempts to build and insert a (key, value) %pair into 460*38fd1498Szrj * the %unordered_map. 461*38fd1498Szrj * An %unordered_map relies on unique keys and thus a %pair is only 462*38fd1498Szrj * inserted if its first element (the key) is not already present in the 463*38fd1498Szrj * %unordered_map. 464*38fd1498Szrj * If a %pair is not inserted, this function has no effect. 465*38fd1498Szrj * 466*38fd1498Szrj * Insertion requires amortized constant time. 467*38fd1498Szrj */ 468*38fd1498Szrj template <typename... _Args> 469*38fd1498Szrj pair<iterator, bool> 470*38fd1498Szrj try_emplace(const key_type& __k, _Args&&... __args) 471*38fd1498Szrj { 472*38fd1498Szrj iterator __i = find(__k); 473*38fd1498Szrj if (__i == end()) 474*38fd1498Szrj { 475*38fd1498Szrj __i = emplace(std::piecewise_construct, 476*38fd1498Szrj std::forward_as_tuple(__k), 477*38fd1498Szrj std::forward_as_tuple( 478*38fd1498Szrj std::forward<_Args>(__args)...)) 479*38fd1498Szrj .first; 480*38fd1498Szrj return {__i, true}; 481*38fd1498Szrj } 482*38fd1498Szrj return {__i, false}; 483*38fd1498Szrj } 484*38fd1498Szrj 485*38fd1498Szrj // move-capable overload 486*38fd1498Szrj template <typename... _Args> 487*38fd1498Szrj pair<iterator, bool> 488*38fd1498Szrj try_emplace(key_type&& __k, _Args&&... __args) 489*38fd1498Szrj { 490*38fd1498Szrj iterator __i = find(__k); 491*38fd1498Szrj if (__i == end()) 492*38fd1498Szrj { 493*38fd1498Szrj __i = emplace(std::piecewise_construct, 494*38fd1498Szrj std::forward_as_tuple(std::move(__k)), 495*38fd1498Szrj std::forward_as_tuple( 496*38fd1498Szrj std::forward<_Args>(__args)...)) 497*38fd1498Szrj .first; 498*38fd1498Szrj return {__i, true}; 499*38fd1498Szrj } 500*38fd1498Szrj return {__i, false}; 501*38fd1498Szrj } 502*38fd1498Szrj 503*38fd1498Szrj /** 504*38fd1498Szrj * @brief Attempts to build and insert a std::pair into the 505*38fd1498Szrj * %unordered_map. 506*38fd1498Szrj * 507*38fd1498Szrj * @param __hint An iterator that serves as a hint as to where the pair 508*38fd1498Szrj * should be inserted. 509*38fd1498Szrj * @param __k Key to use for finding a possibly existing pair in 510*38fd1498Szrj * the unordered_map. 511*38fd1498Szrj * @param __args Arguments used to generate the .second for a 512*38fd1498Szrj * new pair instance. 513*38fd1498Szrj * @return An iterator that points to the element with key of the 514*38fd1498Szrj * std::pair built from @a __args (may or may not be that 515*38fd1498Szrj * std::pair). 516*38fd1498Szrj * 517*38fd1498Szrj * This function is not concerned about whether the insertion took place, 518*38fd1498Szrj * and thus does not return a boolean like the single-argument emplace() 519*38fd1498Szrj * does. However, if insertion did not take place, 520*38fd1498Szrj * this function has no effect. 521*38fd1498Szrj * Note that the first parameter is only a hint and can potentially 522*38fd1498Szrj * improve the performance of the insertion process. A bad hint would 523*38fd1498Szrj * cause no gains in efficiency. 524*38fd1498Szrj * 525*38fd1498Szrj * See 526*38fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 527*38fd1498Szrj * for more on @a hinting. 528*38fd1498Szrj * 529*38fd1498Szrj * Insertion requires amortized constant time. 530*38fd1498Szrj */ 531*38fd1498Szrj template <typename... _Args> 532*38fd1498Szrj iterator 533*38fd1498Szrj try_emplace(const_iterator __hint, const key_type& __k, 534*38fd1498Szrj _Args&&... __args) 535*38fd1498Szrj { 536*38fd1498Szrj iterator __i = find(__k); 537*38fd1498Szrj if (__i == end()) 538*38fd1498Szrj __i = emplace_hint(__hint, std::piecewise_construct, 539*38fd1498Szrj std::forward_as_tuple(__k), 540*38fd1498Szrj std::forward_as_tuple( 541*38fd1498Szrj std::forward<_Args>(__args)...)); 542*38fd1498Szrj return __i; 543*38fd1498Szrj } 544*38fd1498Szrj 545*38fd1498Szrj // move-capable overload 546*38fd1498Szrj template <typename... _Args> 547*38fd1498Szrj iterator 548*38fd1498Szrj try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args) 549*38fd1498Szrj { 550*38fd1498Szrj iterator __i = find(__k); 551*38fd1498Szrj if (__i == end()) 552*38fd1498Szrj __i = emplace_hint(__hint, std::piecewise_construct, 553*38fd1498Szrj std::forward_as_tuple(std::move(__k)), 554*38fd1498Szrj std::forward_as_tuple( 555*38fd1498Szrj std::forward<_Args>(__args)...)); 556*38fd1498Szrj return __i; 557*38fd1498Szrj } 558*38fd1498Szrj #endif // C++17 559*38fd1498Szrj 560*38fd1498Szrj //@{ 561*38fd1498Szrj /** 562*38fd1498Szrj * @brief Attempts to insert a std::pair into the %unordered_map. 563*38fd1498Szrj 564*38fd1498Szrj * @param __x Pair to be inserted (see std::make_pair for easy 565*38fd1498Szrj * creation of pairs). 566*38fd1498Szrj * 567*38fd1498Szrj * @return A pair, of which the first element is an iterator that 568*38fd1498Szrj * points to the possibly inserted pair, and the second is 569*38fd1498Szrj * a bool that is true if the pair was actually inserted. 570*38fd1498Szrj * 571*38fd1498Szrj * This function attempts to insert a (key, value) %pair into the 572*38fd1498Szrj * %unordered_map. An %unordered_map relies on unique keys and thus a 573*38fd1498Szrj * %pair is only inserted if its first element (the key) is not already 574*38fd1498Szrj * present in the %unordered_map. 575*38fd1498Szrj * 576*38fd1498Szrj * Insertion requires amortized constant time. 577*38fd1498Szrj */ 578*38fd1498Szrj std::pair<iterator, bool> 579*38fd1498Szrj insert(const value_type& __x) 580*38fd1498Szrj { return _M_h.insert(__x); } 581*38fd1498Szrj 582*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 583*38fd1498Szrj // 2354. Unnecessary copying when inserting into maps with braced-init 584*38fd1498Szrj std::pair<iterator, bool> 585*38fd1498Szrj insert(value_type&& __x) 586*38fd1498Szrj { return _M_h.insert(std::move(__x)); } 587*38fd1498Szrj 588*38fd1498Szrj template<typename _Pair, typename = typename 589*38fd1498Szrj std::enable_if<std::is_constructible<value_type, 590*38fd1498Szrj _Pair&&>::value>::type> 591*38fd1498Szrj std::pair<iterator, bool> 592*38fd1498Szrj insert(_Pair&& __x) 593*38fd1498Szrj { return _M_h.insert(std::forward<_Pair>(__x)); } 594*38fd1498Szrj //@} 595*38fd1498Szrj 596*38fd1498Szrj //@{ 597*38fd1498Szrj /** 598*38fd1498Szrj * @brief Attempts to insert a std::pair into the %unordered_map. 599*38fd1498Szrj * @param __hint An iterator that serves as a hint as to where the 600*38fd1498Szrj * pair should be inserted. 601*38fd1498Szrj * @param __x Pair to be inserted (see std::make_pair for easy creation 602*38fd1498Szrj * of pairs). 603*38fd1498Szrj * @return An iterator that points to the element with key of 604*38fd1498Szrj * @a __x (may or may not be the %pair passed in). 605*38fd1498Szrj * 606*38fd1498Szrj * This function is not concerned about whether the insertion took place, 607*38fd1498Szrj * and thus does not return a boolean like the single-argument insert() 608*38fd1498Szrj * does. Note that the first parameter is only a hint and can 609*38fd1498Szrj * potentially improve the performance of the insertion process. A bad 610*38fd1498Szrj * hint would cause no gains in efficiency. 611*38fd1498Szrj * 612*38fd1498Szrj * See 613*38fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 614*38fd1498Szrj * for more on @a hinting. 615*38fd1498Szrj * 616*38fd1498Szrj * Insertion requires amortized constant time. 617*38fd1498Szrj */ 618*38fd1498Szrj iterator 619*38fd1498Szrj insert(const_iterator __hint, const value_type& __x) 620*38fd1498Szrj { return _M_h.insert(__hint, __x); } 621*38fd1498Szrj 622*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 623*38fd1498Szrj // 2354. Unnecessary copying when inserting into maps with braced-init 624*38fd1498Szrj iterator 625*38fd1498Szrj insert(const_iterator __hint, value_type&& __x) 626*38fd1498Szrj { return _M_h.insert(__hint, std::move(__x)); } 627*38fd1498Szrj 628*38fd1498Szrj template<typename _Pair, typename = typename 629*38fd1498Szrj std::enable_if<std::is_constructible<value_type, 630*38fd1498Szrj _Pair&&>::value>::type> 631*38fd1498Szrj iterator 632*38fd1498Szrj insert(const_iterator __hint, _Pair&& __x) 633*38fd1498Szrj { return _M_h.insert(__hint, std::forward<_Pair>(__x)); } 634*38fd1498Szrj //@} 635*38fd1498Szrj 636*38fd1498Szrj /** 637*38fd1498Szrj * @brief A template function that attempts to insert a range of 638*38fd1498Szrj * elements. 639*38fd1498Szrj * @param __first Iterator pointing to the start of the range to be 640*38fd1498Szrj * inserted. 641*38fd1498Szrj * @param __last Iterator pointing to the end of the range. 642*38fd1498Szrj * 643*38fd1498Szrj * Complexity similar to that of the range constructor. 644*38fd1498Szrj */ 645*38fd1498Szrj template<typename _InputIterator> 646*38fd1498Szrj void 647*38fd1498Szrj insert(_InputIterator __first, _InputIterator __last) 648*38fd1498Szrj { _M_h.insert(__first, __last); } 649*38fd1498Szrj 650*38fd1498Szrj /** 651*38fd1498Szrj * @brief Attempts to insert a list of elements into the %unordered_map. 652*38fd1498Szrj * @param __l A std::initializer_list<value_type> of elements 653*38fd1498Szrj * to be inserted. 654*38fd1498Szrj * 655*38fd1498Szrj * Complexity similar to that of the range constructor. 656*38fd1498Szrj */ 657*38fd1498Szrj void 658*38fd1498Szrj insert(initializer_list<value_type> __l) 659*38fd1498Szrj { _M_h.insert(__l); } 660*38fd1498Szrj 661*38fd1498Szrj 662*38fd1498Szrj #if __cplusplus > 201402L 663*38fd1498Szrj #define __cpp_lib_unordered_map_insertion 201411 664*38fd1498Szrj /** 665*38fd1498Szrj * @brief Attempts to insert a std::pair into the %unordered_map. 666*38fd1498Szrj * @param __k Key to use for finding a possibly existing pair in 667*38fd1498Szrj * the map. 668*38fd1498Szrj * @param __obj Argument used to generate the .second for a pair 669*38fd1498Szrj * instance. 670*38fd1498Szrj * 671*38fd1498Szrj * @return A pair, of which the first element is an iterator that 672*38fd1498Szrj * points to the possibly inserted pair, and the second is 673*38fd1498Szrj * a bool that is true if the pair was actually inserted. 674*38fd1498Szrj * 675*38fd1498Szrj * This function attempts to insert a (key, value) %pair into the 676*38fd1498Szrj * %unordered_map. An %unordered_map relies on unique keys and thus a 677*38fd1498Szrj * %pair is only inserted if its first element (the key) is not already 678*38fd1498Szrj * present in the %unordered_map. 679*38fd1498Szrj * If the %pair was already in the %unordered_map, the .second of 680*38fd1498Szrj * the %pair is assigned from __obj. 681*38fd1498Szrj * 682*38fd1498Szrj * Insertion requires amortized constant time. 683*38fd1498Szrj */ 684*38fd1498Szrj template <typename _Obj> 685*38fd1498Szrj pair<iterator, bool> 686*38fd1498Szrj insert_or_assign(const key_type& __k, _Obj&& __obj) 687*38fd1498Szrj { 688*38fd1498Szrj iterator __i = find(__k); 689*38fd1498Szrj if (__i == end()) 690*38fd1498Szrj { 691*38fd1498Szrj __i = emplace(std::piecewise_construct, 692*38fd1498Szrj std::forward_as_tuple(__k), 693*38fd1498Szrj std::forward_as_tuple(std::forward<_Obj>(__obj))) 694*38fd1498Szrj .first; 695*38fd1498Szrj return {__i, true}; 696*38fd1498Szrj } 697*38fd1498Szrj (*__i).second = std::forward<_Obj>(__obj); 698*38fd1498Szrj return {__i, false}; 699*38fd1498Szrj } 700*38fd1498Szrj 701*38fd1498Szrj // move-capable overload 702*38fd1498Szrj template <typename _Obj> 703*38fd1498Szrj pair<iterator, bool> 704*38fd1498Szrj insert_or_assign(key_type&& __k, _Obj&& __obj) 705*38fd1498Szrj { 706*38fd1498Szrj iterator __i = find(__k); 707*38fd1498Szrj if (__i == end()) 708*38fd1498Szrj { 709*38fd1498Szrj __i = emplace(std::piecewise_construct, 710*38fd1498Szrj std::forward_as_tuple(std::move(__k)), 711*38fd1498Szrj std::forward_as_tuple(std::forward<_Obj>(__obj))) 712*38fd1498Szrj .first; 713*38fd1498Szrj return {__i, true}; 714*38fd1498Szrj } 715*38fd1498Szrj (*__i).second = std::forward<_Obj>(__obj); 716*38fd1498Szrj return {__i, false}; 717*38fd1498Szrj } 718*38fd1498Szrj 719*38fd1498Szrj /** 720*38fd1498Szrj * @brief Attempts to insert a std::pair into the %unordered_map. 721*38fd1498Szrj * @param __hint An iterator that serves as a hint as to where the 722*38fd1498Szrj * pair should be inserted. 723*38fd1498Szrj * @param __k Key to use for finding a possibly existing pair in 724*38fd1498Szrj * the unordered_map. 725*38fd1498Szrj * @param __obj Argument used to generate the .second for a pair 726*38fd1498Szrj * instance. 727*38fd1498Szrj * @return An iterator that points to the element with key of 728*38fd1498Szrj * @a __x (may or may not be the %pair passed in). 729*38fd1498Szrj * 730*38fd1498Szrj * This function is not concerned about whether the insertion took place, 731*38fd1498Szrj * and thus does not return a boolean like the single-argument insert() 732*38fd1498Szrj * does. 733*38fd1498Szrj * If the %pair was already in the %unordered map, the .second of 734*38fd1498Szrj * the %pair is assigned from __obj. 735*38fd1498Szrj * Note that the first parameter is only a hint and can 736*38fd1498Szrj * potentially improve the performance of the insertion process. A bad 737*38fd1498Szrj * hint would cause no gains in efficiency. 738*38fd1498Szrj * 739*38fd1498Szrj * See 740*38fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 741*38fd1498Szrj * for more on @a hinting. 742*38fd1498Szrj * 743*38fd1498Szrj * Insertion requires amortized constant time. 744*38fd1498Szrj */ 745*38fd1498Szrj template <typename _Obj> 746*38fd1498Szrj iterator 747*38fd1498Szrj insert_or_assign(const_iterator __hint, const key_type& __k, 748*38fd1498Szrj _Obj&& __obj) 749*38fd1498Szrj { 750*38fd1498Szrj iterator __i = find(__k); 751*38fd1498Szrj if (__i == end()) 752*38fd1498Szrj { 753*38fd1498Szrj return emplace_hint(__hint, std::piecewise_construct, 754*38fd1498Szrj std::forward_as_tuple(__k), 755*38fd1498Szrj std::forward_as_tuple( 756*38fd1498Szrj std::forward<_Obj>(__obj))); 757*38fd1498Szrj } 758*38fd1498Szrj (*__i).second = std::forward<_Obj>(__obj); 759*38fd1498Szrj return __i; 760*38fd1498Szrj } 761*38fd1498Szrj 762*38fd1498Szrj // move-capable overload 763*38fd1498Szrj template <typename _Obj> 764*38fd1498Szrj iterator 765*38fd1498Szrj insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj) 766*38fd1498Szrj { 767*38fd1498Szrj iterator __i = find(__k); 768*38fd1498Szrj if (__i == end()) 769*38fd1498Szrj { 770*38fd1498Szrj return emplace_hint(__hint, std::piecewise_construct, 771*38fd1498Szrj std::forward_as_tuple(std::move(__k)), 772*38fd1498Szrj std::forward_as_tuple( 773*38fd1498Szrj std::forward<_Obj>(__obj))); 774*38fd1498Szrj } 775*38fd1498Szrj (*__i).second = std::forward<_Obj>(__obj); 776*38fd1498Szrj return __i; 777*38fd1498Szrj } 778*38fd1498Szrj #endif 779*38fd1498Szrj 780*38fd1498Szrj //@{ 781*38fd1498Szrj /** 782*38fd1498Szrj * @brief Erases an element from an %unordered_map. 783*38fd1498Szrj * @param __position An iterator pointing to the element to be erased. 784*38fd1498Szrj * @return An iterator pointing to the element immediately following 785*38fd1498Szrj * @a __position prior to the element being erased. If no such 786*38fd1498Szrj * element exists, end() is returned. 787*38fd1498Szrj * 788*38fd1498Szrj * This function erases an element, pointed to by the given iterator, 789*38fd1498Szrj * from an %unordered_map. 790*38fd1498Szrj * Note that this function only erases the element, and that if the 791*38fd1498Szrj * element is itself a pointer, the pointed-to memory is not touched in 792*38fd1498Szrj * any way. Managing the pointer is the user's responsibility. 793*38fd1498Szrj */ 794*38fd1498Szrj iterator 795*38fd1498Szrj erase(const_iterator __position) 796*38fd1498Szrj { return _M_h.erase(__position); } 797*38fd1498Szrj 798*38fd1498Szrj // LWG 2059. 799*38fd1498Szrj iterator 800*38fd1498Szrj erase(iterator __position) 801*38fd1498Szrj { return _M_h.erase(__position); } 802*38fd1498Szrj //@} 803*38fd1498Szrj 804*38fd1498Szrj /** 805*38fd1498Szrj * @brief Erases elements according to the provided key. 806*38fd1498Szrj * @param __x Key of element to be erased. 807*38fd1498Szrj * @return The number of elements erased. 808*38fd1498Szrj * 809*38fd1498Szrj * This function erases all the elements located by the given key from 810*38fd1498Szrj * an %unordered_map. For an %unordered_map the result of this function 811*38fd1498Szrj * can only be 0 (not present) or 1 (present). 812*38fd1498Szrj * Note that this function only erases the element, and that if the 813*38fd1498Szrj * element is itself a pointer, the pointed-to memory is not touched in 814*38fd1498Szrj * any way. Managing the pointer is the user's responsibility. 815*38fd1498Szrj */ 816*38fd1498Szrj size_type 817*38fd1498Szrj erase(const key_type& __x) 818*38fd1498Szrj { return _M_h.erase(__x); } 819*38fd1498Szrj 820*38fd1498Szrj /** 821*38fd1498Szrj * @brief Erases a [__first,__last) range of elements from an 822*38fd1498Szrj * %unordered_map. 823*38fd1498Szrj * @param __first Iterator pointing to the start of the range to be 824*38fd1498Szrj * erased. 825*38fd1498Szrj * @param __last Iterator pointing to the end of the range to 826*38fd1498Szrj * be erased. 827*38fd1498Szrj * @return The iterator @a __last. 828*38fd1498Szrj * 829*38fd1498Szrj * This function erases a sequence of elements from an %unordered_map. 830*38fd1498Szrj * Note that this function only erases the elements, and that if 831*38fd1498Szrj * the element is itself a pointer, the pointed-to memory is not touched 832*38fd1498Szrj * in any way. Managing the pointer is the user's responsibility. 833*38fd1498Szrj */ 834*38fd1498Szrj iterator 835*38fd1498Szrj erase(const_iterator __first, const_iterator __last) 836*38fd1498Szrj { return _M_h.erase(__first, __last); } 837*38fd1498Szrj 838*38fd1498Szrj /** 839*38fd1498Szrj * Erases all elements in an %unordered_map. 840*38fd1498Szrj * Note that this function only erases the elements, and that if the 841*38fd1498Szrj * elements themselves are pointers, the pointed-to memory is not touched 842*38fd1498Szrj * in any way. Managing the pointer is the user's responsibility. 843*38fd1498Szrj */ 844*38fd1498Szrj void 845*38fd1498Szrj clear() noexcept 846*38fd1498Szrj { _M_h.clear(); } 847*38fd1498Szrj 848*38fd1498Szrj /** 849*38fd1498Szrj * @brief Swaps data with another %unordered_map. 850*38fd1498Szrj * @param __x An %unordered_map of the same element and allocator 851*38fd1498Szrj * types. 852*38fd1498Szrj * 853*38fd1498Szrj * This exchanges the elements between two %unordered_map in constant 854*38fd1498Szrj * time. 855*38fd1498Szrj * Note that the global std::swap() function is specialized such that 856*38fd1498Szrj * std::swap(m1,m2) will feed to this function. 857*38fd1498Szrj */ 858*38fd1498Szrj void 859*38fd1498Szrj swap(unordered_map& __x) 860*38fd1498Szrj noexcept( noexcept(_M_h.swap(__x._M_h)) ) 861*38fd1498Szrj { _M_h.swap(__x._M_h); } 862*38fd1498Szrj 863*38fd1498Szrj #if __cplusplus > 201402L 864*38fd1498Szrj template<typename, typename, typename> 865*38fd1498Szrj friend class std::_Hash_merge_helper; 866*38fd1498Szrj 867*38fd1498Szrj template<typename _H2, typename _P2> 868*38fd1498Szrj void 869*38fd1498Szrj merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source) 870*38fd1498Szrj { 871*38fd1498Szrj using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>; 872*38fd1498Szrj _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source)); 873*38fd1498Szrj } 874*38fd1498Szrj 875*38fd1498Szrj template<typename _H2, typename _P2> 876*38fd1498Szrj void 877*38fd1498Szrj merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source) 878*38fd1498Szrj { merge(__source); } 879*38fd1498Szrj 880*38fd1498Szrj template<typename _H2, typename _P2> 881*38fd1498Szrj void 882*38fd1498Szrj merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source) 883*38fd1498Szrj { 884*38fd1498Szrj using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>; 885*38fd1498Szrj _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source)); 886*38fd1498Szrj } 887*38fd1498Szrj 888*38fd1498Szrj template<typename _H2, typename _P2> 889*38fd1498Szrj void 890*38fd1498Szrj merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source) 891*38fd1498Szrj { merge(__source); } 892*38fd1498Szrj #endif // C++17 893*38fd1498Szrj 894*38fd1498Szrj // observers. 895*38fd1498Szrj 896*38fd1498Szrj /// Returns the hash functor object with which the %unordered_map was 897*38fd1498Szrj /// constructed. 898*38fd1498Szrj hasher 899*38fd1498Szrj hash_function() const 900*38fd1498Szrj { return _M_h.hash_function(); } 901*38fd1498Szrj 902*38fd1498Szrj /// Returns the key comparison object with which the %unordered_map was 903*38fd1498Szrj /// constructed. 904*38fd1498Szrj key_equal 905*38fd1498Szrj key_eq() const 906*38fd1498Szrj { return _M_h.key_eq(); } 907*38fd1498Szrj 908*38fd1498Szrj // lookup. 909*38fd1498Szrj 910*38fd1498Szrj //@{ 911*38fd1498Szrj /** 912*38fd1498Szrj * @brief Tries to locate an element in an %unordered_map. 913*38fd1498Szrj * @param __x Key to be located. 914*38fd1498Szrj * @return Iterator pointing to sought-after element, or end() if not 915*38fd1498Szrj * found. 916*38fd1498Szrj * 917*38fd1498Szrj * This function takes a key and tries to locate the element with which 918*38fd1498Szrj * the key matches. If successful the function returns an iterator 919*38fd1498Szrj * pointing to the sought after element. If unsuccessful it returns the 920*38fd1498Szrj * past-the-end ( @c end() ) iterator. 921*38fd1498Szrj */ 922*38fd1498Szrj iterator 923*38fd1498Szrj find(const key_type& __x) 924*38fd1498Szrj { return _M_h.find(__x); } 925*38fd1498Szrj 926*38fd1498Szrj const_iterator 927*38fd1498Szrj find(const key_type& __x) const 928*38fd1498Szrj { return _M_h.find(__x); } 929*38fd1498Szrj //@} 930*38fd1498Szrj 931*38fd1498Szrj /** 932*38fd1498Szrj * @brief Finds the number of elements. 933*38fd1498Szrj * @param __x Key to count. 934*38fd1498Szrj * @return Number of elements with specified key. 935*38fd1498Szrj * 936*38fd1498Szrj * This function only makes sense for %unordered_multimap; for 937*38fd1498Szrj * %unordered_map the result will either be 0 (not present) or 1 938*38fd1498Szrj * (present). 939*38fd1498Szrj */ 940*38fd1498Szrj size_type 941*38fd1498Szrj count(const key_type& __x) const 942*38fd1498Szrj { return _M_h.count(__x); } 943*38fd1498Szrj 944*38fd1498Szrj //@{ 945*38fd1498Szrj /** 946*38fd1498Szrj * @brief Finds a subsequence matching given key. 947*38fd1498Szrj * @param __x Key to be located. 948*38fd1498Szrj * @return Pair of iterators that possibly points to the subsequence 949*38fd1498Szrj * matching given key. 950*38fd1498Szrj * 951*38fd1498Szrj * This function probably only makes sense for %unordered_multimap. 952*38fd1498Szrj */ 953*38fd1498Szrj std::pair<iterator, iterator> 954*38fd1498Szrj equal_range(const key_type& __x) 955*38fd1498Szrj { return _M_h.equal_range(__x); } 956*38fd1498Szrj 957*38fd1498Szrj std::pair<const_iterator, const_iterator> 958*38fd1498Szrj equal_range(const key_type& __x) const 959*38fd1498Szrj { return _M_h.equal_range(__x); } 960*38fd1498Szrj //@} 961*38fd1498Szrj 962*38fd1498Szrj //@{ 963*38fd1498Szrj /** 964*38fd1498Szrj * @brief Subscript ( @c [] ) access to %unordered_map data. 965*38fd1498Szrj * @param __k The key for which data should be retrieved. 966*38fd1498Szrj * @return A reference to the data of the (key,data) %pair. 967*38fd1498Szrj * 968*38fd1498Szrj * Allows for easy lookup with the subscript ( @c [] )operator. Returns 969*38fd1498Szrj * data associated with the key specified in subscript. If the key does 970*38fd1498Szrj * not exist, a pair with that key is created using default values, which 971*38fd1498Szrj * is then returned. 972*38fd1498Szrj * 973*38fd1498Szrj * Lookup requires constant time. 974*38fd1498Szrj */ 975*38fd1498Szrj mapped_type& 976*38fd1498Szrj operator[](const key_type& __k) 977*38fd1498Szrj { return _M_h[__k]; } 978*38fd1498Szrj 979*38fd1498Szrj mapped_type& 980*38fd1498Szrj operator[](key_type&& __k) 981*38fd1498Szrj { return _M_h[std::move(__k)]; } 982*38fd1498Szrj //@} 983*38fd1498Szrj 984*38fd1498Szrj //@{ 985*38fd1498Szrj /** 986*38fd1498Szrj * @brief Access to %unordered_map data. 987*38fd1498Szrj * @param __k The key for which data should be retrieved. 988*38fd1498Szrj * @return A reference to the data whose key is equal to @a __k, if 989*38fd1498Szrj * such a data is present in the %unordered_map. 990*38fd1498Szrj * @throw std::out_of_range If no such data is present. 991*38fd1498Szrj */ 992*38fd1498Szrj mapped_type& 993*38fd1498Szrj at(const key_type& __k) 994*38fd1498Szrj { return _M_h.at(__k); } 995*38fd1498Szrj 996*38fd1498Szrj const mapped_type& 997*38fd1498Szrj at(const key_type& __k) const 998*38fd1498Szrj { return _M_h.at(__k); } 999*38fd1498Szrj //@} 1000*38fd1498Szrj 1001*38fd1498Szrj // bucket interface. 1002*38fd1498Szrj 1003*38fd1498Szrj /// Returns the number of buckets of the %unordered_map. 1004*38fd1498Szrj size_type 1005*38fd1498Szrj bucket_count() const noexcept 1006*38fd1498Szrj { return _M_h.bucket_count(); } 1007*38fd1498Szrj 1008*38fd1498Szrj /// Returns the maximum number of buckets of the %unordered_map. 1009*38fd1498Szrj size_type 1010*38fd1498Szrj max_bucket_count() const noexcept 1011*38fd1498Szrj { return _M_h.max_bucket_count(); } 1012*38fd1498Szrj 1013*38fd1498Szrj /* 1014*38fd1498Szrj * @brief Returns the number of elements in a given bucket. 1015*38fd1498Szrj * @param __n A bucket index. 1016*38fd1498Szrj * @return The number of elements in the bucket. 1017*38fd1498Szrj */ 1018*38fd1498Szrj size_type 1019*38fd1498Szrj bucket_size(size_type __n) const 1020*38fd1498Szrj { return _M_h.bucket_size(__n); } 1021*38fd1498Szrj 1022*38fd1498Szrj /* 1023*38fd1498Szrj * @brief Returns the bucket index of a given element. 1024*38fd1498Szrj * @param __key A key instance. 1025*38fd1498Szrj * @return The key bucket index. 1026*38fd1498Szrj */ 1027*38fd1498Szrj size_type 1028*38fd1498Szrj bucket(const key_type& __key) const 1029*38fd1498Szrj { return _M_h.bucket(__key); } 1030*38fd1498Szrj 1031*38fd1498Szrj /** 1032*38fd1498Szrj * @brief Returns a read/write iterator pointing to the first bucket 1033*38fd1498Szrj * element. 1034*38fd1498Szrj * @param __n The bucket index. 1035*38fd1498Szrj * @return A read/write local iterator. 1036*38fd1498Szrj */ 1037*38fd1498Szrj local_iterator 1038*38fd1498Szrj begin(size_type __n) 1039*38fd1498Szrj { return _M_h.begin(__n); } 1040*38fd1498Szrj 1041*38fd1498Szrj //@{ 1042*38fd1498Szrj /** 1043*38fd1498Szrj * @brief Returns a read-only (constant) iterator pointing to the first 1044*38fd1498Szrj * bucket element. 1045*38fd1498Szrj * @param __n The bucket index. 1046*38fd1498Szrj * @return A read-only local iterator. 1047*38fd1498Szrj */ 1048*38fd1498Szrj const_local_iterator 1049*38fd1498Szrj begin(size_type __n) const 1050*38fd1498Szrj { return _M_h.begin(__n); } 1051*38fd1498Szrj 1052*38fd1498Szrj const_local_iterator 1053*38fd1498Szrj cbegin(size_type __n) const 1054*38fd1498Szrj { return _M_h.cbegin(__n); } 1055*38fd1498Szrj //@} 1056*38fd1498Szrj 1057*38fd1498Szrj /** 1058*38fd1498Szrj * @brief Returns a read/write iterator pointing to one past the last 1059*38fd1498Szrj * bucket elements. 1060*38fd1498Szrj * @param __n The bucket index. 1061*38fd1498Szrj * @return A read/write local iterator. 1062*38fd1498Szrj */ 1063*38fd1498Szrj local_iterator 1064*38fd1498Szrj end(size_type __n) 1065*38fd1498Szrj { return _M_h.end(__n); } 1066*38fd1498Szrj 1067*38fd1498Szrj //@{ 1068*38fd1498Szrj /** 1069*38fd1498Szrj * @brief Returns a read-only (constant) iterator pointing to one past 1070*38fd1498Szrj * the last bucket elements. 1071*38fd1498Szrj * @param __n The bucket index. 1072*38fd1498Szrj * @return A read-only local iterator. 1073*38fd1498Szrj */ 1074*38fd1498Szrj const_local_iterator 1075*38fd1498Szrj end(size_type __n) const 1076*38fd1498Szrj { return _M_h.end(__n); } 1077*38fd1498Szrj 1078*38fd1498Szrj const_local_iterator 1079*38fd1498Szrj cend(size_type __n) const 1080*38fd1498Szrj { return _M_h.cend(__n); } 1081*38fd1498Szrj //@} 1082*38fd1498Szrj 1083*38fd1498Szrj // hash policy. 1084*38fd1498Szrj 1085*38fd1498Szrj /// Returns the average number of elements per bucket. 1086*38fd1498Szrj float 1087*38fd1498Szrj load_factor() const noexcept 1088*38fd1498Szrj { return _M_h.load_factor(); } 1089*38fd1498Szrj 1090*38fd1498Szrj /// Returns a positive number that the %unordered_map tries to keep the 1091*38fd1498Szrj /// load factor less than or equal to. 1092*38fd1498Szrj float 1093*38fd1498Szrj max_load_factor() const noexcept 1094*38fd1498Szrj { return _M_h.max_load_factor(); } 1095*38fd1498Szrj 1096*38fd1498Szrj /** 1097*38fd1498Szrj * @brief Change the %unordered_map maximum load factor. 1098*38fd1498Szrj * @param __z The new maximum load factor. 1099*38fd1498Szrj */ 1100*38fd1498Szrj void 1101*38fd1498Szrj max_load_factor(float __z) 1102*38fd1498Szrj { _M_h.max_load_factor(__z); } 1103*38fd1498Szrj 1104*38fd1498Szrj /** 1105*38fd1498Szrj * @brief May rehash the %unordered_map. 1106*38fd1498Szrj * @param __n The new number of buckets. 1107*38fd1498Szrj * 1108*38fd1498Szrj * Rehash will occur only if the new number of buckets respect the 1109*38fd1498Szrj * %unordered_map maximum load factor. 1110*38fd1498Szrj */ 1111*38fd1498Szrj void 1112*38fd1498Szrj rehash(size_type __n) 1113*38fd1498Szrj { _M_h.rehash(__n); } 1114*38fd1498Szrj 1115*38fd1498Szrj /** 1116*38fd1498Szrj * @brief Prepare the %unordered_map for a specified number of 1117*38fd1498Szrj * elements. 1118*38fd1498Szrj * @param __n Number of elements required. 1119*38fd1498Szrj * 1120*38fd1498Szrj * Same as rehash(ceil(n / max_load_factor())). 1121*38fd1498Szrj */ 1122*38fd1498Szrj void 1123*38fd1498Szrj reserve(size_type __n) 1124*38fd1498Szrj { _M_h.reserve(__n); } 1125*38fd1498Szrj 1126*38fd1498Szrj template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1, 1127*38fd1498Szrj typename _Alloc1> 1128*38fd1498Szrj friend bool 1129*38fd1498Szrj operator==(const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&, 1130*38fd1498Szrj const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&); 1131*38fd1498Szrj }; 1132*38fd1498Szrj 1133*38fd1498Szrj #if __cpp_deduction_guides >= 201606 1134*38fd1498Szrj 1135*38fd1498Szrj template<typename _InputIterator, 1136*38fd1498Szrj typename _Hash = hash<__iter_key_t<_InputIterator>>, 1137*38fd1498Szrj typename _Pred = equal_to<__iter_key_t<_InputIterator>>, 1138*38fd1498Szrj typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>, 1139*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 1140*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1141*38fd1498Szrj unordered_map(_InputIterator, _InputIterator, 1142*38fd1498Szrj typename unordered_map<int, int>::size_type = {}, 1143*38fd1498Szrj _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) 1144*38fd1498Szrj -> unordered_map<__iter_key_t<_InputIterator>, 1145*38fd1498Szrj __iter_val_t<_InputIterator>, 1146*38fd1498Szrj _Hash, _Pred, _Allocator>; 1147*38fd1498Szrj 1148*38fd1498Szrj template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, 1149*38fd1498Szrj typename _Pred = equal_to<_Key>, 1150*38fd1498Szrj typename _Allocator = allocator<pair<const _Key, _Tp>>, 1151*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1152*38fd1498Szrj unordered_map(initializer_list<pair<_Key, _Tp>>, 1153*38fd1498Szrj typename unordered_map<int, int>::size_type = {}, 1154*38fd1498Szrj _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) 1155*38fd1498Szrj -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>; 1156*38fd1498Szrj 1157*38fd1498Szrj template<typename _InputIterator, typename _Allocator, 1158*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 1159*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1160*38fd1498Szrj unordered_map(_InputIterator, _InputIterator, 1161*38fd1498Szrj typename unordered_map<int, int>::size_type, _Allocator) 1162*38fd1498Szrj -> unordered_map<__iter_key_t<_InputIterator>, 1163*38fd1498Szrj __iter_val_t<_InputIterator>, 1164*38fd1498Szrj hash<__iter_key_t<_InputIterator>>, 1165*38fd1498Szrj equal_to<__iter_key_t<_InputIterator>>, 1166*38fd1498Szrj _Allocator>; 1167*38fd1498Szrj 1168*38fd1498Szrj template<typename _InputIterator, typename _Allocator, 1169*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 1170*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1171*38fd1498Szrj unordered_map(_InputIterator, _InputIterator, _Allocator) 1172*38fd1498Szrj -> unordered_map<__iter_key_t<_InputIterator>, 1173*38fd1498Szrj __iter_val_t<_InputIterator>, 1174*38fd1498Szrj hash<__iter_key_t<_InputIterator>>, 1175*38fd1498Szrj equal_to<__iter_key_t<_InputIterator>>, 1176*38fd1498Szrj _Allocator>; 1177*38fd1498Szrj 1178*38fd1498Szrj template<typename _InputIterator, typename _Hash, typename _Allocator, 1179*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 1180*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1181*38fd1498Szrj unordered_map(_InputIterator, _InputIterator, 1182*38fd1498Szrj typename unordered_map<int, int>::size_type, 1183*38fd1498Szrj _Hash, _Allocator) 1184*38fd1498Szrj -> unordered_map<__iter_key_t<_InputIterator>, 1185*38fd1498Szrj __iter_val_t<_InputIterator>, _Hash, 1186*38fd1498Szrj equal_to<__iter_key_t<_InputIterator>>, _Allocator>; 1187*38fd1498Szrj 1188*38fd1498Szrj template<typename _Key, typename _Tp, typename _Allocator, 1189*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1190*38fd1498Szrj unordered_map(initializer_list<pair<_Key, _Tp>>, 1191*38fd1498Szrj typename unordered_map<int, int>::size_type, 1192*38fd1498Szrj _Allocator) 1193*38fd1498Szrj -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; 1194*38fd1498Szrj 1195*38fd1498Szrj template<typename _Key, typename _Tp, typename _Allocator, 1196*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1197*38fd1498Szrj unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator) 1198*38fd1498Szrj -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; 1199*38fd1498Szrj 1200*38fd1498Szrj template<typename _Key, typename _Tp, typename _Hash, typename _Allocator, 1201*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1202*38fd1498Szrj unordered_map(initializer_list<pair<_Key, _Tp>>, 1203*38fd1498Szrj typename unordered_map<int, int>::size_type, 1204*38fd1498Szrj _Hash, _Allocator) 1205*38fd1498Szrj -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; 1206*38fd1498Szrj 1207*38fd1498Szrj #endif 1208*38fd1498Szrj 1209*38fd1498Szrj /** 1210*38fd1498Szrj * @brief A standard container composed of equivalent keys 1211*38fd1498Szrj * (possibly containing multiple of each key value) that associates 1212*38fd1498Szrj * values of another type with the keys. 1213*38fd1498Szrj * 1214*38fd1498Szrj * @ingroup unordered_associative_containers 1215*38fd1498Szrj * 1216*38fd1498Szrj * @tparam _Key Type of key objects. 1217*38fd1498Szrj * @tparam _Tp Type of mapped objects. 1218*38fd1498Szrj * @tparam _Hash Hashing function object type, defaults to hash<_Value>. 1219*38fd1498Szrj * @tparam _Pred Predicate function object type, defaults 1220*38fd1498Szrj * to equal_to<_Value>. 1221*38fd1498Szrj * @tparam _Alloc Allocator type, defaults to 1222*38fd1498Szrj * std::allocator<std::pair<const _Key, _Tp>>. 1223*38fd1498Szrj * 1224*38fd1498Szrj * Meets the requirements of a <a href="tables.html#65">container</a>, and 1225*38fd1498Szrj * <a href="tables.html#xx">unordered associative container</a> 1226*38fd1498Szrj * 1227*38fd1498Szrj * The resulting value type of the container is std::pair<const _Key, _Tp>. 1228*38fd1498Szrj * 1229*38fd1498Szrj * Base is _Hashtable, dispatched at compile time via template 1230*38fd1498Szrj * alias __ummap_hashtable. 1231*38fd1498Szrj */ 1232*38fd1498Szrj template<typename _Key, typename _Tp, 1233*38fd1498Szrj typename _Hash = hash<_Key>, 1234*38fd1498Szrj typename _Pred = equal_to<_Key>, 1235*38fd1498Szrj typename _Alloc = allocator<std::pair<const _Key, _Tp>>> 1236*38fd1498Szrj class unordered_multimap 1237*38fd1498Szrj { 1238*38fd1498Szrj typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; 1239*38fd1498Szrj _Hashtable _M_h; 1240*38fd1498Szrj 1241*38fd1498Szrj public: 1242*38fd1498Szrj // typedefs: 1243*38fd1498Szrj //@{ 1244*38fd1498Szrj /// Public typedefs. 1245*38fd1498Szrj typedef typename _Hashtable::key_type key_type; 1246*38fd1498Szrj typedef typename _Hashtable::value_type value_type; 1247*38fd1498Szrj typedef typename _Hashtable::mapped_type mapped_type; 1248*38fd1498Szrj typedef typename _Hashtable::hasher hasher; 1249*38fd1498Szrj typedef typename _Hashtable::key_equal key_equal; 1250*38fd1498Szrj typedef typename _Hashtable::allocator_type allocator_type; 1251*38fd1498Szrj //@} 1252*38fd1498Szrj 1253*38fd1498Szrj //@{ 1254*38fd1498Szrj /// Iterator-related typedefs. 1255*38fd1498Szrj typedef typename _Hashtable::pointer pointer; 1256*38fd1498Szrj typedef typename _Hashtable::const_pointer const_pointer; 1257*38fd1498Szrj typedef typename _Hashtable::reference reference; 1258*38fd1498Szrj typedef typename _Hashtable::const_reference const_reference; 1259*38fd1498Szrj typedef typename _Hashtable::iterator iterator; 1260*38fd1498Szrj typedef typename _Hashtable::const_iterator const_iterator; 1261*38fd1498Szrj typedef typename _Hashtable::local_iterator local_iterator; 1262*38fd1498Szrj typedef typename _Hashtable::const_local_iterator const_local_iterator; 1263*38fd1498Szrj typedef typename _Hashtable::size_type size_type; 1264*38fd1498Szrj typedef typename _Hashtable::difference_type difference_type; 1265*38fd1498Szrj //@} 1266*38fd1498Szrj 1267*38fd1498Szrj #if __cplusplus > 201402L 1268*38fd1498Szrj using node_type = typename _Hashtable::node_type; 1269*38fd1498Szrj #endif 1270*38fd1498Szrj 1271*38fd1498Szrj //construct/destroy/copy 1272*38fd1498Szrj 1273*38fd1498Szrj /// Default constructor. 1274*38fd1498Szrj unordered_multimap() = default; 1275*38fd1498Szrj 1276*38fd1498Szrj /** 1277*38fd1498Szrj * @brief Default constructor creates no elements. 1278*38fd1498Szrj * @param __n Mnimal initial number of buckets. 1279*38fd1498Szrj * @param __hf A hash functor. 1280*38fd1498Szrj * @param __eql A key equality functor. 1281*38fd1498Szrj * @param __a An allocator object. 1282*38fd1498Szrj */ 1283*38fd1498Szrj explicit 1284*38fd1498Szrj unordered_multimap(size_type __n, 1285*38fd1498Szrj const hasher& __hf = hasher(), 1286*38fd1498Szrj const key_equal& __eql = key_equal(), 1287*38fd1498Szrj const allocator_type& __a = allocator_type()) 1288*38fd1498Szrj : _M_h(__n, __hf, __eql, __a) 1289*38fd1498Szrj { } 1290*38fd1498Szrj 1291*38fd1498Szrj /** 1292*38fd1498Szrj * @brief Builds an %unordered_multimap from a range. 1293*38fd1498Szrj * @param __first An input iterator. 1294*38fd1498Szrj * @param __last An input iterator. 1295*38fd1498Szrj * @param __n Minimal initial number of buckets. 1296*38fd1498Szrj * @param __hf A hash functor. 1297*38fd1498Szrj * @param __eql A key equality functor. 1298*38fd1498Szrj * @param __a An allocator object. 1299*38fd1498Szrj * 1300*38fd1498Szrj * Create an %unordered_multimap consisting of copies of the elements 1301*38fd1498Szrj * from [__first,__last). This is linear in N (where N is 1302*38fd1498Szrj * distance(__first,__last)). 1303*38fd1498Szrj */ 1304*38fd1498Szrj template<typename _InputIterator> 1305*38fd1498Szrj unordered_multimap(_InputIterator __first, _InputIterator __last, 1306*38fd1498Szrj size_type __n = 0, 1307*38fd1498Szrj const hasher& __hf = hasher(), 1308*38fd1498Szrj const key_equal& __eql = key_equal(), 1309*38fd1498Szrj const allocator_type& __a = allocator_type()) 1310*38fd1498Szrj : _M_h(__first, __last, __n, __hf, __eql, __a) 1311*38fd1498Szrj { } 1312*38fd1498Szrj 1313*38fd1498Szrj /// Copy constructor. 1314*38fd1498Szrj unordered_multimap(const unordered_multimap&) = default; 1315*38fd1498Szrj 1316*38fd1498Szrj /// Move constructor. 1317*38fd1498Szrj unordered_multimap(unordered_multimap&&) = default; 1318*38fd1498Szrj 1319*38fd1498Szrj /** 1320*38fd1498Szrj * @brief Creates an %unordered_multimap with no elements. 1321*38fd1498Szrj * @param __a An allocator object. 1322*38fd1498Szrj */ 1323*38fd1498Szrj explicit 1324*38fd1498Szrj unordered_multimap(const allocator_type& __a) 1325*38fd1498Szrj : _M_h(__a) 1326*38fd1498Szrj { } 1327*38fd1498Szrj 1328*38fd1498Szrj /* 1329*38fd1498Szrj * @brief Copy constructor with allocator argument. 1330*38fd1498Szrj * @param __uset Input %unordered_multimap to copy. 1331*38fd1498Szrj * @param __a An allocator object. 1332*38fd1498Szrj */ 1333*38fd1498Szrj unordered_multimap(const unordered_multimap& __ummap, 1334*38fd1498Szrj const allocator_type& __a) 1335*38fd1498Szrj : _M_h(__ummap._M_h, __a) 1336*38fd1498Szrj { } 1337*38fd1498Szrj 1338*38fd1498Szrj /* 1339*38fd1498Szrj * @brief Move constructor with allocator argument. 1340*38fd1498Szrj * @param __uset Input %unordered_multimap to move. 1341*38fd1498Szrj * @param __a An allocator object. 1342*38fd1498Szrj */ 1343*38fd1498Szrj unordered_multimap(unordered_multimap&& __ummap, 1344*38fd1498Szrj const allocator_type& __a) 1345*38fd1498Szrj : _M_h(std::move(__ummap._M_h), __a) 1346*38fd1498Szrj { } 1347*38fd1498Szrj 1348*38fd1498Szrj /** 1349*38fd1498Szrj * @brief Builds an %unordered_multimap from an initializer_list. 1350*38fd1498Szrj * @param __l An initializer_list. 1351*38fd1498Szrj * @param __n Minimal initial number of buckets. 1352*38fd1498Szrj * @param __hf A hash functor. 1353*38fd1498Szrj * @param __eql A key equality functor. 1354*38fd1498Szrj * @param __a An allocator object. 1355*38fd1498Szrj * 1356*38fd1498Szrj * Create an %unordered_multimap consisting of copies of the elements in 1357*38fd1498Szrj * the list. This is linear in N (where N is @a __l.size()). 1358*38fd1498Szrj */ 1359*38fd1498Szrj unordered_multimap(initializer_list<value_type> __l, 1360*38fd1498Szrj size_type __n = 0, 1361*38fd1498Szrj const hasher& __hf = hasher(), 1362*38fd1498Szrj const key_equal& __eql = key_equal(), 1363*38fd1498Szrj const allocator_type& __a = allocator_type()) 1364*38fd1498Szrj : _M_h(__l, __n, __hf, __eql, __a) 1365*38fd1498Szrj { } 1366*38fd1498Szrj 1367*38fd1498Szrj unordered_multimap(size_type __n, const allocator_type& __a) 1368*38fd1498Szrj : unordered_multimap(__n, hasher(), key_equal(), __a) 1369*38fd1498Szrj { } 1370*38fd1498Szrj 1371*38fd1498Szrj unordered_multimap(size_type __n, const hasher& __hf, 1372*38fd1498Szrj const allocator_type& __a) 1373*38fd1498Szrj : unordered_multimap(__n, __hf, key_equal(), __a) 1374*38fd1498Szrj { } 1375*38fd1498Szrj 1376*38fd1498Szrj template<typename _InputIterator> 1377*38fd1498Szrj unordered_multimap(_InputIterator __first, _InputIterator __last, 1378*38fd1498Szrj size_type __n, 1379*38fd1498Szrj const allocator_type& __a) 1380*38fd1498Szrj : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) 1381*38fd1498Szrj { } 1382*38fd1498Szrj 1383*38fd1498Szrj template<typename _InputIterator> 1384*38fd1498Szrj unordered_multimap(_InputIterator __first, _InputIterator __last, 1385*38fd1498Szrj size_type __n, const hasher& __hf, 1386*38fd1498Szrj const allocator_type& __a) 1387*38fd1498Szrj : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) 1388*38fd1498Szrj { } 1389*38fd1498Szrj 1390*38fd1498Szrj unordered_multimap(initializer_list<value_type> __l, 1391*38fd1498Szrj size_type __n, 1392*38fd1498Szrj const allocator_type& __a) 1393*38fd1498Szrj : unordered_multimap(__l, __n, hasher(), key_equal(), __a) 1394*38fd1498Szrj { } 1395*38fd1498Szrj 1396*38fd1498Szrj unordered_multimap(initializer_list<value_type> __l, 1397*38fd1498Szrj size_type __n, const hasher& __hf, 1398*38fd1498Szrj const allocator_type& __a) 1399*38fd1498Szrj : unordered_multimap(__l, __n, __hf, key_equal(), __a) 1400*38fd1498Szrj { } 1401*38fd1498Szrj 1402*38fd1498Szrj /// Copy assignment operator. 1403*38fd1498Szrj unordered_multimap& 1404*38fd1498Szrj operator=(const unordered_multimap&) = default; 1405*38fd1498Szrj 1406*38fd1498Szrj /// Move assignment operator. 1407*38fd1498Szrj unordered_multimap& 1408*38fd1498Szrj operator=(unordered_multimap&&) = default; 1409*38fd1498Szrj 1410*38fd1498Szrj /** 1411*38fd1498Szrj * @brief %Unordered_multimap list assignment operator. 1412*38fd1498Szrj * @param __l An initializer_list. 1413*38fd1498Szrj * 1414*38fd1498Szrj * This function fills an %unordered_multimap with copies of the 1415*38fd1498Szrj * elements in the initializer list @a __l. 1416*38fd1498Szrj * 1417*38fd1498Szrj * Note that the assignment completely changes the %unordered_multimap 1418*38fd1498Szrj * and that the resulting %unordered_multimap's size is the same as the 1419*38fd1498Szrj * number of elements assigned. 1420*38fd1498Szrj */ 1421*38fd1498Szrj unordered_multimap& 1422*38fd1498Szrj operator=(initializer_list<value_type> __l) 1423*38fd1498Szrj { 1424*38fd1498Szrj _M_h = __l; 1425*38fd1498Szrj return *this; 1426*38fd1498Szrj } 1427*38fd1498Szrj 1428*38fd1498Szrj /// Returns the allocator object used by the %unordered_multimap. 1429*38fd1498Szrj allocator_type 1430*38fd1498Szrj get_allocator() const noexcept 1431*38fd1498Szrj { return _M_h.get_allocator(); } 1432*38fd1498Szrj 1433*38fd1498Szrj // size and capacity: 1434*38fd1498Szrj 1435*38fd1498Szrj /// Returns true if the %unordered_multimap is empty. 1436*38fd1498Szrj bool 1437*38fd1498Szrj empty() const noexcept 1438*38fd1498Szrj { return _M_h.empty(); } 1439*38fd1498Szrj 1440*38fd1498Szrj /// Returns the size of the %unordered_multimap. 1441*38fd1498Szrj size_type 1442*38fd1498Szrj size() const noexcept 1443*38fd1498Szrj { return _M_h.size(); } 1444*38fd1498Szrj 1445*38fd1498Szrj /// Returns the maximum size of the %unordered_multimap. 1446*38fd1498Szrj size_type 1447*38fd1498Szrj max_size() const noexcept 1448*38fd1498Szrj { return _M_h.max_size(); } 1449*38fd1498Szrj 1450*38fd1498Szrj // iterators. 1451*38fd1498Szrj 1452*38fd1498Szrj /** 1453*38fd1498Szrj * Returns a read/write iterator that points to the first element in the 1454*38fd1498Szrj * %unordered_multimap. 1455*38fd1498Szrj */ 1456*38fd1498Szrj iterator 1457*38fd1498Szrj begin() noexcept 1458*38fd1498Szrj { return _M_h.begin(); } 1459*38fd1498Szrj 1460*38fd1498Szrj //@{ 1461*38fd1498Szrj /** 1462*38fd1498Szrj * Returns a read-only (constant) iterator that points to the first 1463*38fd1498Szrj * element in the %unordered_multimap. 1464*38fd1498Szrj */ 1465*38fd1498Szrj const_iterator 1466*38fd1498Szrj begin() const noexcept 1467*38fd1498Szrj { return _M_h.begin(); } 1468*38fd1498Szrj 1469*38fd1498Szrj const_iterator 1470*38fd1498Szrj cbegin() const noexcept 1471*38fd1498Szrj { return _M_h.begin(); } 1472*38fd1498Szrj //@} 1473*38fd1498Szrj 1474*38fd1498Szrj /** 1475*38fd1498Szrj * Returns a read/write iterator that points one past the last element in 1476*38fd1498Szrj * the %unordered_multimap. 1477*38fd1498Szrj */ 1478*38fd1498Szrj iterator 1479*38fd1498Szrj end() noexcept 1480*38fd1498Szrj { return _M_h.end(); } 1481*38fd1498Szrj 1482*38fd1498Szrj //@{ 1483*38fd1498Szrj /** 1484*38fd1498Szrj * Returns a read-only (constant) iterator that points one past the last 1485*38fd1498Szrj * element in the %unordered_multimap. 1486*38fd1498Szrj */ 1487*38fd1498Szrj const_iterator 1488*38fd1498Szrj end() const noexcept 1489*38fd1498Szrj { return _M_h.end(); } 1490*38fd1498Szrj 1491*38fd1498Szrj const_iterator 1492*38fd1498Szrj cend() const noexcept 1493*38fd1498Szrj { return _M_h.end(); } 1494*38fd1498Szrj //@} 1495*38fd1498Szrj 1496*38fd1498Szrj // modifiers. 1497*38fd1498Szrj 1498*38fd1498Szrj /** 1499*38fd1498Szrj * @brief Attempts to build and insert a std::pair into the 1500*38fd1498Szrj * %unordered_multimap. 1501*38fd1498Szrj * 1502*38fd1498Szrj * @param __args Arguments used to generate a new pair instance (see 1503*38fd1498Szrj * std::piecewise_contruct for passing arguments to each 1504*38fd1498Szrj * part of the pair constructor). 1505*38fd1498Szrj * 1506*38fd1498Szrj * @return An iterator that points to the inserted pair. 1507*38fd1498Szrj * 1508*38fd1498Szrj * This function attempts to build and insert a (key, value) %pair into 1509*38fd1498Szrj * the %unordered_multimap. 1510*38fd1498Szrj * 1511*38fd1498Szrj * Insertion requires amortized constant time. 1512*38fd1498Szrj */ 1513*38fd1498Szrj template<typename... _Args> 1514*38fd1498Szrj iterator 1515*38fd1498Szrj emplace(_Args&&... __args) 1516*38fd1498Szrj { return _M_h.emplace(std::forward<_Args>(__args)...); } 1517*38fd1498Szrj 1518*38fd1498Szrj /** 1519*38fd1498Szrj * @brief Attempts to build and insert a std::pair into the 1520*38fd1498Szrj * %unordered_multimap. 1521*38fd1498Szrj * 1522*38fd1498Szrj * @param __pos An iterator that serves as a hint as to where the pair 1523*38fd1498Szrj * should be inserted. 1524*38fd1498Szrj * @param __args Arguments used to generate a new pair instance (see 1525*38fd1498Szrj * std::piecewise_contruct for passing arguments to each 1526*38fd1498Szrj * part of the pair constructor). 1527*38fd1498Szrj * @return An iterator that points to the element with key of the 1528*38fd1498Szrj * std::pair built from @a __args. 1529*38fd1498Szrj * 1530*38fd1498Szrj * Note that the first parameter is only a hint and can potentially 1531*38fd1498Szrj * improve the performance of the insertion process. A bad hint would 1532*38fd1498Szrj * cause no gains in efficiency. 1533*38fd1498Szrj * 1534*38fd1498Szrj * See 1535*38fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 1536*38fd1498Szrj * for more on @a hinting. 1537*38fd1498Szrj * 1538*38fd1498Szrj * Insertion requires amortized constant time. 1539*38fd1498Szrj */ 1540*38fd1498Szrj template<typename... _Args> 1541*38fd1498Szrj iterator 1542*38fd1498Szrj emplace_hint(const_iterator __pos, _Args&&... __args) 1543*38fd1498Szrj { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } 1544*38fd1498Szrj 1545*38fd1498Szrj //@{ 1546*38fd1498Szrj /** 1547*38fd1498Szrj * @brief Inserts a std::pair into the %unordered_multimap. 1548*38fd1498Szrj * @param __x Pair to be inserted (see std::make_pair for easy 1549*38fd1498Szrj * creation of pairs). 1550*38fd1498Szrj * 1551*38fd1498Szrj * @return An iterator that points to the inserted pair. 1552*38fd1498Szrj * 1553*38fd1498Szrj * Insertion requires amortized constant time. 1554*38fd1498Szrj */ 1555*38fd1498Szrj iterator 1556*38fd1498Szrj insert(const value_type& __x) 1557*38fd1498Szrj { return _M_h.insert(__x); } 1558*38fd1498Szrj 1559*38fd1498Szrj iterator 1560*38fd1498Szrj insert(value_type&& __x) 1561*38fd1498Szrj { return _M_h.insert(std::move(__x)); } 1562*38fd1498Szrj 1563*38fd1498Szrj template<typename _Pair, typename = typename 1564*38fd1498Szrj std::enable_if<std::is_constructible<value_type, 1565*38fd1498Szrj _Pair&&>::value>::type> 1566*38fd1498Szrj iterator 1567*38fd1498Szrj insert(_Pair&& __x) 1568*38fd1498Szrj { return _M_h.insert(std::forward<_Pair>(__x)); } 1569*38fd1498Szrj //@} 1570*38fd1498Szrj 1571*38fd1498Szrj //@{ 1572*38fd1498Szrj /** 1573*38fd1498Szrj * @brief Inserts a std::pair into the %unordered_multimap. 1574*38fd1498Szrj * @param __hint An iterator that serves as a hint as to where the 1575*38fd1498Szrj * pair should be inserted. 1576*38fd1498Szrj * @param __x Pair to be inserted (see std::make_pair for easy creation 1577*38fd1498Szrj * of pairs). 1578*38fd1498Szrj * @return An iterator that points to the element with key of 1579*38fd1498Szrj * @a __x (may or may not be the %pair passed in). 1580*38fd1498Szrj * 1581*38fd1498Szrj * Note that the first parameter is only a hint and can potentially 1582*38fd1498Szrj * improve the performance of the insertion process. A bad hint would 1583*38fd1498Szrj * cause no gains in efficiency. 1584*38fd1498Szrj * 1585*38fd1498Szrj * See 1586*38fd1498Szrj * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints 1587*38fd1498Szrj * for more on @a hinting. 1588*38fd1498Szrj * 1589*38fd1498Szrj * Insertion requires amortized constant time. 1590*38fd1498Szrj */ 1591*38fd1498Szrj iterator 1592*38fd1498Szrj insert(const_iterator __hint, const value_type& __x) 1593*38fd1498Szrj { return _M_h.insert(__hint, __x); } 1594*38fd1498Szrj 1595*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 1596*38fd1498Szrj // 2354. Unnecessary copying when inserting into maps with braced-init 1597*38fd1498Szrj iterator 1598*38fd1498Szrj insert(const_iterator __hint, value_type&& __x) 1599*38fd1498Szrj { return _M_h.insert(__hint, std::move(__x)); } 1600*38fd1498Szrj 1601*38fd1498Szrj template<typename _Pair, typename = typename 1602*38fd1498Szrj std::enable_if<std::is_constructible<value_type, 1603*38fd1498Szrj _Pair&&>::value>::type> 1604*38fd1498Szrj iterator 1605*38fd1498Szrj insert(const_iterator __hint, _Pair&& __x) 1606*38fd1498Szrj { return _M_h.insert(__hint, std::forward<_Pair>(__x)); } 1607*38fd1498Szrj //@} 1608*38fd1498Szrj 1609*38fd1498Szrj /** 1610*38fd1498Szrj * @brief A template function that attempts to insert a range of 1611*38fd1498Szrj * elements. 1612*38fd1498Szrj * @param __first Iterator pointing to the start of the range to be 1613*38fd1498Szrj * inserted. 1614*38fd1498Szrj * @param __last Iterator pointing to the end of the range. 1615*38fd1498Szrj * 1616*38fd1498Szrj * Complexity similar to that of the range constructor. 1617*38fd1498Szrj */ 1618*38fd1498Szrj template<typename _InputIterator> 1619*38fd1498Szrj void 1620*38fd1498Szrj insert(_InputIterator __first, _InputIterator __last) 1621*38fd1498Szrj { _M_h.insert(__first, __last); } 1622*38fd1498Szrj 1623*38fd1498Szrj /** 1624*38fd1498Szrj * @brief Attempts to insert a list of elements into the 1625*38fd1498Szrj * %unordered_multimap. 1626*38fd1498Szrj * @param __l A std::initializer_list<value_type> of elements 1627*38fd1498Szrj * to be inserted. 1628*38fd1498Szrj * 1629*38fd1498Szrj * Complexity similar to that of the range constructor. 1630*38fd1498Szrj */ 1631*38fd1498Szrj void 1632*38fd1498Szrj insert(initializer_list<value_type> __l) 1633*38fd1498Szrj { _M_h.insert(__l); } 1634*38fd1498Szrj 1635*38fd1498Szrj #if __cplusplus > 201402L 1636*38fd1498Szrj /// Extract a node. 1637*38fd1498Szrj node_type 1638*38fd1498Szrj extract(const_iterator __pos) 1639*38fd1498Szrj { 1640*38fd1498Szrj __glibcxx_assert(__pos != end()); 1641*38fd1498Szrj return _M_h.extract(__pos); 1642*38fd1498Szrj } 1643*38fd1498Szrj 1644*38fd1498Szrj /// Extract a node. 1645*38fd1498Szrj node_type 1646*38fd1498Szrj extract(const key_type& __key) 1647*38fd1498Szrj { return _M_h.extract(__key); } 1648*38fd1498Szrj 1649*38fd1498Szrj /// Re-insert an extracted node. 1650*38fd1498Szrj iterator 1651*38fd1498Szrj insert(node_type&& __nh) 1652*38fd1498Szrj { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); } 1653*38fd1498Szrj 1654*38fd1498Szrj /// Re-insert an extracted node. 1655*38fd1498Szrj iterator 1656*38fd1498Szrj insert(const_iterator __hint, node_type&& __nh) 1657*38fd1498Szrj { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); } 1658*38fd1498Szrj #endif // C++17 1659*38fd1498Szrj 1660*38fd1498Szrj //@{ 1661*38fd1498Szrj /** 1662*38fd1498Szrj * @brief Erases an element from an %unordered_multimap. 1663*38fd1498Szrj * @param __position An iterator pointing to the element to be erased. 1664*38fd1498Szrj * @return An iterator pointing to the element immediately following 1665*38fd1498Szrj * @a __position prior to the element being erased. If no such 1666*38fd1498Szrj * element exists, end() is returned. 1667*38fd1498Szrj * 1668*38fd1498Szrj * This function erases an element, pointed to by the given iterator, 1669*38fd1498Szrj * from an %unordered_multimap. 1670*38fd1498Szrj * Note that this function only erases the element, and that if the 1671*38fd1498Szrj * element is itself a pointer, the pointed-to memory is not touched in 1672*38fd1498Szrj * any way. Managing the pointer is the user's responsibility. 1673*38fd1498Szrj */ 1674*38fd1498Szrj iterator 1675*38fd1498Szrj erase(const_iterator __position) 1676*38fd1498Szrj { return _M_h.erase(__position); } 1677*38fd1498Szrj 1678*38fd1498Szrj // LWG 2059. 1679*38fd1498Szrj iterator 1680*38fd1498Szrj erase(iterator __position) 1681*38fd1498Szrj { return _M_h.erase(__position); } 1682*38fd1498Szrj //@} 1683*38fd1498Szrj 1684*38fd1498Szrj /** 1685*38fd1498Szrj * @brief Erases elements according to the provided key. 1686*38fd1498Szrj * @param __x Key of elements to be erased. 1687*38fd1498Szrj * @return The number of elements erased. 1688*38fd1498Szrj * 1689*38fd1498Szrj * This function erases all the elements located by the given key from 1690*38fd1498Szrj * an %unordered_multimap. 1691*38fd1498Szrj * Note that this function only erases the element, and that if the 1692*38fd1498Szrj * element is itself a pointer, the pointed-to memory is not touched in 1693*38fd1498Szrj * any way. Managing the pointer is the user's responsibility. 1694*38fd1498Szrj */ 1695*38fd1498Szrj size_type 1696*38fd1498Szrj erase(const key_type& __x) 1697*38fd1498Szrj { return _M_h.erase(__x); } 1698*38fd1498Szrj 1699*38fd1498Szrj /** 1700*38fd1498Szrj * @brief Erases a [__first,__last) range of elements from an 1701*38fd1498Szrj * %unordered_multimap. 1702*38fd1498Szrj * @param __first Iterator pointing to the start of the range to be 1703*38fd1498Szrj * erased. 1704*38fd1498Szrj * @param __last Iterator pointing to the end of the range to 1705*38fd1498Szrj * be erased. 1706*38fd1498Szrj * @return The iterator @a __last. 1707*38fd1498Szrj * 1708*38fd1498Szrj * This function erases a sequence of elements from an 1709*38fd1498Szrj * %unordered_multimap. 1710*38fd1498Szrj * Note that this function only erases the elements, and that if 1711*38fd1498Szrj * the element is itself a pointer, the pointed-to memory is not touched 1712*38fd1498Szrj * in any way. Managing the pointer is the user's responsibility. 1713*38fd1498Szrj */ 1714*38fd1498Szrj iterator 1715*38fd1498Szrj erase(const_iterator __first, const_iterator __last) 1716*38fd1498Szrj { return _M_h.erase(__first, __last); } 1717*38fd1498Szrj 1718*38fd1498Szrj /** 1719*38fd1498Szrj * Erases all elements in an %unordered_multimap. 1720*38fd1498Szrj * Note that this function only erases the elements, and that if the 1721*38fd1498Szrj * elements themselves are pointers, the pointed-to memory is not touched 1722*38fd1498Szrj * in any way. Managing the pointer is the user's responsibility. 1723*38fd1498Szrj */ 1724*38fd1498Szrj void 1725*38fd1498Szrj clear() noexcept 1726*38fd1498Szrj { _M_h.clear(); } 1727*38fd1498Szrj 1728*38fd1498Szrj /** 1729*38fd1498Szrj * @brief Swaps data with another %unordered_multimap. 1730*38fd1498Szrj * @param __x An %unordered_multimap of the same element and allocator 1731*38fd1498Szrj * types. 1732*38fd1498Szrj * 1733*38fd1498Szrj * This exchanges the elements between two %unordered_multimap in 1734*38fd1498Szrj * constant time. 1735*38fd1498Szrj * Note that the global std::swap() function is specialized such that 1736*38fd1498Szrj * std::swap(m1,m2) will feed to this function. 1737*38fd1498Szrj */ 1738*38fd1498Szrj void 1739*38fd1498Szrj swap(unordered_multimap& __x) 1740*38fd1498Szrj noexcept( noexcept(_M_h.swap(__x._M_h)) ) 1741*38fd1498Szrj { _M_h.swap(__x._M_h); } 1742*38fd1498Szrj 1743*38fd1498Szrj #if __cplusplus > 201402L 1744*38fd1498Szrj template<typename, typename, typename> 1745*38fd1498Szrj friend class std::_Hash_merge_helper; 1746*38fd1498Szrj 1747*38fd1498Szrj template<typename _H2, typename _P2> 1748*38fd1498Szrj void 1749*38fd1498Szrj merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source) 1750*38fd1498Szrj { 1751*38fd1498Szrj using _Merge_helper 1752*38fd1498Szrj = _Hash_merge_helper<unordered_multimap, _H2, _P2>; 1753*38fd1498Szrj _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source)); 1754*38fd1498Szrj } 1755*38fd1498Szrj 1756*38fd1498Szrj template<typename _H2, typename _P2> 1757*38fd1498Szrj void 1758*38fd1498Szrj merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source) 1759*38fd1498Szrj { merge(__source); } 1760*38fd1498Szrj 1761*38fd1498Szrj template<typename _H2, typename _P2> 1762*38fd1498Szrj void 1763*38fd1498Szrj merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source) 1764*38fd1498Szrj { 1765*38fd1498Szrj using _Merge_helper 1766*38fd1498Szrj = _Hash_merge_helper<unordered_multimap, _H2, _P2>; 1767*38fd1498Szrj _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source)); 1768*38fd1498Szrj } 1769*38fd1498Szrj 1770*38fd1498Szrj template<typename _H2, typename _P2> 1771*38fd1498Szrj void 1772*38fd1498Szrj merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source) 1773*38fd1498Szrj { merge(__source); } 1774*38fd1498Szrj #endif // C++17 1775*38fd1498Szrj 1776*38fd1498Szrj // observers. 1777*38fd1498Szrj 1778*38fd1498Szrj /// Returns the hash functor object with which the %unordered_multimap 1779*38fd1498Szrj /// was constructed. 1780*38fd1498Szrj hasher 1781*38fd1498Szrj hash_function() const 1782*38fd1498Szrj { return _M_h.hash_function(); } 1783*38fd1498Szrj 1784*38fd1498Szrj /// Returns the key comparison object with which the %unordered_multimap 1785*38fd1498Szrj /// was constructed. 1786*38fd1498Szrj key_equal 1787*38fd1498Szrj key_eq() const 1788*38fd1498Szrj { return _M_h.key_eq(); } 1789*38fd1498Szrj 1790*38fd1498Szrj // lookup. 1791*38fd1498Szrj 1792*38fd1498Szrj //@{ 1793*38fd1498Szrj /** 1794*38fd1498Szrj * @brief Tries to locate an element in an %unordered_multimap. 1795*38fd1498Szrj * @param __x Key to be located. 1796*38fd1498Szrj * @return Iterator pointing to sought-after element, or end() if not 1797*38fd1498Szrj * found. 1798*38fd1498Szrj * 1799*38fd1498Szrj * This function takes a key and tries to locate the element with which 1800*38fd1498Szrj * the key matches. If successful the function returns an iterator 1801*38fd1498Szrj * pointing to the sought after element. If unsuccessful it returns the 1802*38fd1498Szrj * past-the-end ( @c end() ) iterator. 1803*38fd1498Szrj */ 1804*38fd1498Szrj iterator 1805*38fd1498Szrj find(const key_type& __x) 1806*38fd1498Szrj { return _M_h.find(__x); } 1807*38fd1498Szrj 1808*38fd1498Szrj const_iterator 1809*38fd1498Szrj find(const key_type& __x) const 1810*38fd1498Szrj { return _M_h.find(__x); } 1811*38fd1498Szrj //@} 1812*38fd1498Szrj 1813*38fd1498Szrj /** 1814*38fd1498Szrj * @brief Finds the number of elements. 1815*38fd1498Szrj * @param __x Key to count. 1816*38fd1498Szrj * @return Number of elements with specified key. 1817*38fd1498Szrj */ 1818*38fd1498Szrj size_type 1819*38fd1498Szrj count(const key_type& __x) const 1820*38fd1498Szrj { return _M_h.count(__x); } 1821*38fd1498Szrj 1822*38fd1498Szrj //@{ 1823*38fd1498Szrj /** 1824*38fd1498Szrj * @brief Finds a subsequence matching given key. 1825*38fd1498Szrj * @param __x Key to be located. 1826*38fd1498Szrj * @return Pair of iterators that possibly points to the subsequence 1827*38fd1498Szrj * matching given key. 1828*38fd1498Szrj */ 1829*38fd1498Szrj std::pair<iterator, iterator> 1830*38fd1498Szrj equal_range(const key_type& __x) 1831*38fd1498Szrj { return _M_h.equal_range(__x); } 1832*38fd1498Szrj 1833*38fd1498Szrj std::pair<const_iterator, const_iterator> 1834*38fd1498Szrj equal_range(const key_type& __x) const 1835*38fd1498Szrj { return _M_h.equal_range(__x); } 1836*38fd1498Szrj //@} 1837*38fd1498Szrj 1838*38fd1498Szrj // bucket interface. 1839*38fd1498Szrj 1840*38fd1498Szrj /// Returns the number of buckets of the %unordered_multimap. 1841*38fd1498Szrj size_type 1842*38fd1498Szrj bucket_count() const noexcept 1843*38fd1498Szrj { return _M_h.bucket_count(); } 1844*38fd1498Szrj 1845*38fd1498Szrj /// Returns the maximum number of buckets of the %unordered_multimap. 1846*38fd1498Szrj size_type 1847*38fd1498Szrj max_bucket_count() const noexcept 1848*38fd1498Szrj { return _M_h.max_bucket_count(); } 1849*38fd1498Szrj 1850*38fd1498Szrj /* 1851*38fd1498Szrj * @brief Returns the number of elements in a given bucket. 1852*38fd1498Szrj * @param __n A bucket index. 1853*38fd1498Szrj * @return The number of elements in the bucket. 1854*38fd1498Szrj */ 1855*38fd1498Szrj size_type 1856*38fd1498Szrj bucket_size(size_type __n) const 1857*38fd1498Szrj { return _M_h.bucket_size(__n); } 1858*38fd1498Szrj 1859*38fd1498Szrj /* 1860*38fd1498Szrj * @brief Returns the bucket index of a given element. 1861*38fd1498Szrj * @param __key A key instance. 1862*38fd1498Szrj * @return The key bucket index. 1863*38fd1498Szrj */ 1864*38fd1498Szrj size_type 1865*38fd1498Szrj bucket(const key_type& __key) const 1866*38fd1498Szrj { return _M_h.bucket(__key); } 1867*38fd1498Szrj 1868*38fd1498Szrj /** 1869*38fd1498Szrj * @brief Returns a read/write iterator pointing to the first bucket 1870*38fd1498Szrj * element. 1871*38fd1498Szrj * @param __n The bucket index. 1872*38fd1498Szrj * @return A read/write local iterator. 1873*38fd1498Szrj */ 1874*38fd1498Szrj local_iterator 1875*38fd1498Szrj begin(size_type __n) 1876*38fd1498Szrj { return _M_h.begin(__n); } 1877*38fd1498Szrj 1878*38fd1498Szrj //@{ 1879*38fd1498Szrj /** 1880*38fd1498Szrj * @brief Returns a read-only (constant) iterator pointing to the first 1881*38fd1498Szrj * bucket element. 1882*38fd1498Szrj * @param __n The bucket index. 1883*38fd1498Szrj * @return A read-only local iterator. 1884*38fd1498Szrj */ 1885*38fd1498Szrj const_local_iterator 1886*38fd1498Szrj begin(size_type __n) const 1887*38fd1498Szrj { return _M_h.begin(__n); } 1888*38fd1498Szrj 1889*38fd1498Szrj const_local_iterator 1890*38fd1498Szrj cbegin(size_type __n) const 1891*38fd1498Szrj { return _M_h.cbegin(__n); } 1892*38fd1498Szrj //@} 1893*38fd1498Szrj 1894*38fd1498Szrj /** 1895*38fd1498Szrj * @brief Returns a read/write iterator pointing to one past the last 1896*38fd1498Szrj * bucket elements. 1897*38fd1498Szrj * @param __n The bucket index. 1898*38fd1498Szrj * @return A read/write local iterator. 1899*38fd1498Szrj */ 1900*38fd1498Szrj local_iterator 1901*38fd1498Szrj end(size_type __n) 1902*38fd1498Szrj { return _M_h.end(__n); } 1903*38fd1498Szrj 1904*38fd1498Szrj //@{ 1905*38fd1498Szrj /** 1906*38fd1498Szrj * @brief Returns a read-only (constant) iterator pointing to one past 1907*38fd1498Szrj * the last bucket elements. 1908*38fd1498Szrj * @param __n The bucket index. 1909*38fd1498Szrj * @return A read-only local iterator. 1910*38fd1498Szrj */ 1911*38fd1498Szrj const_local_iterator 1912*38fd1498Szrj end(size_type __n) const 1913*38fd1498Szrj { return _M_h.end(__n); } 1914*38fd1498Szrj 1915*38fd1498Szrj const_local_iterator 1916*38fd1498Szrj cend(size_type __n) const 1917*38fd1498Szrj { return _M_h.cend(__n); } 1918*38fd1498Szrj //@} 1919*38fd1498Szrj 1920*38fd1498Szrj // hash policy. 1921*38fd1498Szrj 1922*38fd1498Szrj /// Returns the average number of elements per bucket. 1923*38fd1498Szrj float 1924*38fd1498Szrj load_factor() const noexcept 1925*38fd1498Szrj { return _M_h.load_factor(); } 1926*38fd1498Szrj 1927*38fd1498Szrj /// Returns a positive number that the %unordered_multimap tries to keep 1928*38fd1498Szrj /// the load factor less than or equal to. 1929*38fd1498Szrj float 1930*38fd1498Szrj max_load_factor() const noexcept 1931*38fd1498Szrj { return _M_h.max_load_factor(); } 1932*38fd1498Szrj 1933*38fd1498Szrj /** 1934*38fd1498Szrj * @brief Change the %unordered_multimap maximum load factor. 1935*38fd1498Szrj * @param __z The new maximum load factor. 1936*38fd1498Szrj */ 1937*38fd1498Szrj void 1938*38fd1498Szrj max_load_factor(float __z) 1939*38fd1498Szrj { _M_h.max_load_factor(__z); } 1940*38fd1498Szrj 1941*38fd1498Szrj /** 1942*38fd1498Szrj * @brief May rehash the %unordered_multimap. 1943*38fd1498Szrj * @param __n The new number of buckets. 1944*38fd1498Szrj * 1945*38fd1498Szrj * Rehash will occur only if the new number of buckets respect the 1946*38fd1498Szrj * %unordered_multimap maximum load factor. 1947*38fd1498Szrj */ 1948*38fd1498Szrj void 1949*38fd1498Szrj rehash(size_type __n) 1950*38fd1498Szrj { _M_h.rehash(__n); } 1951*38fd1498Szrj 1952*38fd1498Szrj /** 1953*38fd1498Szrj * @brief Prepare the %unordered_multimap for a specified number of 1954*38fd1498Szrj * elements. 1955*38fd1498Szrj * @param __n Number of elements required. 1956*38fd1498Szrj * 1957*38fd1498Szrj * Same as rehash(ceil(n / max_load_factor())). 1958*38fd1498Szrj */ 1959*38fd1498Szrj void 1960*38fd1498Szrj reserve(size_type __n) 1961*38fd1498Szrj { _M_h.reserve(__n); } 1962*38fd1498Szrj 1963*38fd1498Szrj template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1, 1964*38fd1498Szrj typename _Alloc1> 1965*38fd1498Szrj friend bool 1966*38fd1498Szrj operator==(const unordered_multimap<_Key1, _Tp1, 1967*38fd1498Szrj _Hash1, _Pred1, _Alloc1>&, 1968*38fd1498Szrj const unordered_multimap<_Key1, _Tp1, 1969*38fd1498Szrj _Hash1, _Pred1, _Alloc1>&); 1970*38fd1498Szrj }; 1971*38fd1498Szrj 1972*38fd1498Szrj #if __cpp_deduction_guides >= 201606 1973*38fd1498Szrj 1974*38fd1498Szrj template<typename _InputIterator, 1975*38fd1498Szrj typename _Hash = hash<__iter_key_t<_InputIterator>>, 1976*38fd1498Szrj typename _Pred = equal_to<__iter_key_t<_InputIterator>>, 1977*38fd1498Szrj typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>, 1978*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 1979*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1980*38fd1498Szrj unordered_multimap(_InputIterator, _InputIterator, 1981*38fd1498Szrj unordered_multimap<int, int>::size_type = {}, 1982*38fd1498Szrj _Hash = _Hash(), _Pred = _Pred(), 1983*38fd1498Szrj _Allocator = _Allocator()) 1984*38fd1498Szrj -> unordered_multimap<__iter_key_t<_InputIterator>, 1985*38fd1498Szrj __iter_val_t<_InputIterator>, _Hash, _Pred, 1986*38fd1498Szrj _Allocator>; 1987*38fd1498Szrj 1988*38fd1498Szrj template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, 1989*38fd1498Szrj typename _Pred = equal_to<_Key>, 1990*38fd1498Szrj typename _Allocator = allocator<pair<const _Key, _Tp>>, 1991*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 1992*38fd1498Szrj unordered_multimap(initializer_list<pair<_Key, _Tp>>, 1993*38fd1498Szrj unordered_multimap<int, int>::size_type = {}, 1994*38fd1498Szrj _Hash = _Hash(), _Pred = _Pred(), 1995*38fd1498Szrj _Allocator = _Allocator()) 1996*38fd1498Szrj -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>; 1997*38fd1498Szrj 1998*38fd1498Szrj template<typename _InputIterator, typename _Allocator, 1999*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 2000*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 2001*38fd1498Szrj unordered_multimap(_InputIterator, _InputIterator, 2002*38fd1498Szrj unordered_multimap<int, int>::size_type, _Allocator) 2003*38fd1498Szrj -> unordered_multimap<__iter_key_t<_InputIterator>, 2004*38fd1498Szrj __iter_val_t<_InputIterator>, 2005*38fd1498Szrj hash<__iter_key_t<_InputIterator>>, 2006*38fd1498Szrj equal_to<__iter_key_t<_InputIterator>>, _Allocator>; 2007*38fd1498Szrj 2008*38fd1498Szrj template<typename _InputIterator, typename _Allocator, 2009*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 2010*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 2011*38fd1498Szrj unordered_multimap(_InputIterator, _InputIterator, _Allocator) 2012*38fd1498Szrj -> unordered_multimap<__iter_key_t<_InputIterator>, 2013*38fd1498Szrj __iter_val_t<_InputIterator>, 2014*38fd1498Szrj hash<__iter_key_t<_InputIterator>>, 2015*38fd1498Szrj equal_to<__iter_key_t<_InputIterator>>, _Allocator>; 2016*38fd1498Szrj 2017*38fd1498Szrj template<typename _InputIterator, typename _Hash, typename _Allocator, 2018*38fd1498Szrj typename = _RequireInputIter<_InputIterator>, 2019*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 2020*38fd1498Szrj unordered_multimap(_InputIterator, _InputIterator, 2021*38fd1498Szrj unordered_multimap<int, int>::size_type, _Hash, 2022*38fd1498Szrj _Allocator) 2023*38fd1498Szrj -> unordered_multimap<__iter_key_t<_InputIterator>, 2024*38fd1498Szrj __iter_val_t<_InputIterator>, _Hash, 2025*38fd1498Szrj equal_to<__iter_key_t<_InputIterator>>, _Allocator>; 2026*38fd1498Szrj 2027*38fd1498Szrj template<typename _Key, typename _Tp, typename _Allocator, 2028*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 2029*38fd1498Szrj unordered_multimap(initializer_list<pair<_Key, _Tp>>, 2030*38fd1498Szrj unordered_multimap<int, int>::size_type, 2031*38fd1498Szrj _Allocator) 2032*38fd1498Szrj -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; 2033*38fd1498Szrj 2034*38fd1498Szrj template<typename _Key, typename _Tp, typename _Allocator, 2035*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 2036*38fd1498Szrj unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) 2037*38fd1498Szrj -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; 2038*38fd1498Szrj 2039*38fd1498Szrj template<typename _Key, typename _Tp, typename _Hash, typename _Allocator, 2040*38fd1498Szrj typename = _RequireAllocator<_Allocator>> 2041*38fd1498Szrj unordered_multimap(initializer_list<pair<_Key, _Tp>>, 2042*38fd1498Szrj unordered_multimap<int, int>::size_type, 2043*38fd1498Szrj _Hash, _Allocator) 2044*38fd1498Szrj -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; 2045*38fd1498Szrj 2046*38fd1498Szrj #endif 2047*38fd1498Szrj 2048*38fd1498Szrj template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 2049*38fd1498Szrj inline void 2050*38fd1498Szrj swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 2051*38fd1498Szrj unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 2052*38fd1498Szrj noexcept(noexcept(__x.swap(__y))) 2053*38fd1498Szrj { __x.swap(__y); } 2054*38fd1498Szrj 2055*38fd1498Szrj template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 2056*38fd1498Szrj inline void 2057*38fd1498Szrj swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 2058*38fd1498Szrj unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 2059*38fd1498Szrj noexcept(noexcept(__x.swap(__y))) 2060*38fd1498Szrj { __x.swap(__y); } 2061*38fd1498Szrj 2062*38fd1498Szrj template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 2063*38fd1498Szrj inline bool 2064*38fd1498Szrj operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 2065*38fd1498Szrj const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 2066*38fd1498Szrj { return __x._M_h._M_equal(__y._M_h); } 2067*38fd1498Szrj 2068*38fd1498Szrj template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 2069*38fd1498Szrj inline bool 2070*38fd1498Szrj operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 2071*38fd1498Szrj const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 2072*38fd1498Szrj { return !(__x == __y); } 2073*38fd1498Szrj 2074*38fd1498Szrj template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 2075*38fd1498Szrj inline bool 2076*38fd1498Szrj operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 2077*38fd1498Szrj const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 2078*38fd1498Szrj { return __x._M_h._M_equal(__y._M_h); } 2079*38fd1498Szrj 2080*38fd1498Szrj template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 2081*38fd1498Szrj inline bool 2082*38fd1498Szrj operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 2083*38fd1498Szrj const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 2084*38fd1498Szrj { return !(__x == __y); } 2085*38fd1498Szrj 2086*38fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER 2087*38fd1498Szrj 2088*38fd1498Szrj #if __cplusplus > 201402L 2089*38fd1498Szrj // Allow std::unordered_map access to internals of compatible maps. 2090*38fd1498Szrj template<typename _Key, typename _Val, typename _Hash1, typename _Eq1, 2091*38fd1498Szrj typename _Alloc, typename _Hash2, typename _Eq2> 2092*38fd1498Szrj struct _Hash_merge_helper< 2093*38fd1498Szrj _GLIBCXX_STD_C::unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>, 2094*38fd1498Szrj _Hash2, _Eq2> 2095*38fd1498Szrj { 2096*38fd1498Szrj private: 2097*38fd1498Szrj template<typename... _Tp> 2098*38fd1498Szrj using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>; 2099*38fd1498Szrj template<typename... _Tp> 2100*38fd1498Szrj using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>; 2101*38fd1498Szrj 2102*38fd1498Szrj friend unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>; 2103*38fd1498Szrj 2104*38fd1498Szrj static auto& 2105*38fd1498Szrj _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) 2106*38fd1498Szrj { return __map._M_h; } 2107*38fd1498Szrj 2108*38fd1498Szrj static auto& 2109*38fd1498Szrj _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) 2110*38fd1498Szrj { return __map._M_h; } 2111*38fd1498Szrj }; 2112*38fd1498Szrj 2113*38fd1498Szrj // Allow std::unordered_multimap access to internals of compatible maps. 2114*38fd1498Szrj template<typename _Key, typename _Val, typename _Hash1, typename _Eq1, 2115*38fd1498Szrj typename _Alloc, typename _Hash2, typename _Eq2> 2116*38fd1498Szrj struct _Hash_merge_helper< 2117*38fd1498Szrj _GLIBCXX_STD_C::unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>, 2118*38fd1498Szrj _Hash2, _Eq2> 2119*38fd1498Szrj { 2120*38fd1498Szrj private: 2121*38fd1498Szrj template<typename... _Tp> 2122*38fd1498Szrj using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>; 2123*38fd1498Szrj template<typename... _Tp> 2124*38fd1498Szrj using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>; 2125*38fd1498Szrj 2126*38fd1498Szrj friend unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>; 2127*38fd1498Szrj 2128*38fd1498Szrj static auto& 2129*38fd1498Szrj _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) 2130*38fd1498Szrj { return __map._M_h; } 2131*38fd1498Szrj 2132*38fd1498Szrj static auto& 2133*38fd1498Szrj _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) 2134*38fd1498Szrj { return __map._M_h; } 2135*38fd1498Szrj }; 2136*38fd1498Szrj #endif // C++17 2137*38fd1498Szrj 2138*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 2139*38fd1498Szrj } // namespace std 2140*38fd1498Szrj 2141*38fd1498Szrj #endif /* _UNORDERED_MAP_H */ 2142