Home | History | Annotate | Line # | Download | only in debug
      1 // Debugging unordered_map/unordered_multimap implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2003-2024 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file debug/unordered_map
     26  *  This file is a GNU debug extension to the Standard C++ Library.
     27  */
     28 
     29 #ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
     30 #define _GLIBCXX_DEBUG_UNORDERED_MAP 1
     31 
     32 #pragma GCC system_header
     33 
     34 #if __cplusplus < 201103L
     35 # include <bits/c++0x_warning.h>
     36 #else
     37 # include <bits/c++config.h>
     38 namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
     39   template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
     40 	   typename _Allocator>
     41     class unordered_map;
     42   template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
     43 	   typename _Allocator>
     44     class unordered_multimap;
     45 } } // namespace std::__debug
     46 
     47 # include <unordered_map>
     48 
     49 #include <debug/safe_unordered_container.h>
     50 #include <debug/safe_container.h>
     51 #include <debug/safe_iterator.h>
     52 #include <debug/safe_local_iterator.h>
     53 
     54 namespace std _GLIBCXX_VISIBILITY(default)
     55 {
     56 namespace __debug
     57 {
     58   /// Class std::unordered_map with safety/checking/debug instrumentation.
     59   template<typename _Key, typename _Tp,
     60 	   typename _Hash = std::hash<_Key>,
     61 	   typename _Pred = std::equal_to<_Key>,
     62 	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
     63     class unordered_map
     64     : public __gnu_debug::_Safe_container<
     65 	unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
     66 	__gnu_debug::_Safe_unordered_container>,
     67       public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
     68     {
     69       typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
     70 					    _Pred, _Alloc>		_Base;
     71       typedef __gnu_debug::_Safe_container<unordered_map,
     72 		   _Alloc, __gnu_debug::_Safe_unordered_container>	_Safe;
     73       typedef typename _Base::const_iterator	_Base_const_iterator;
     74       typedef typename _Base::iterator		_Base_iterator;
     75       typedef typename _Base::const_local_iterator
     76 						_Base_const_local_iterator;
     77       typedef typename _Base::local_iterator	_Base_local_iterator;
     78 
     79       template<typename _ItT, typename _SeqT, typename _CatT>
     80 	friend class ::__gnu_debug::_Safe_iterator;
     81       template<typename _ItT, typename _SeqT>
     82 	friend class ::__gnu_debug::_Safe_local_iterator;
     83 
     84       // Reference wrapper for base class. See PR libstdc++/90102.
     85       struct _Base_ref
     86       {
     87 	_Base_ref(const _Base& __r) : _M_ref(__r) { }
     88 
     89 	const _Base& _M_ref;
     90       };
     91 
     92     public:
     93       typedef typename _Base::size_type			size_type;
     94       typedef typename _Base::hasher			hasher;
     95       typedef typename _Base::key_equal			key_equal;
     96       typedef typename _Base::allocator_type		allocator_type;
     97 
     98       typedef typename _Base::key_type			key_type;
     99       typedef typename _Base::value_type		value_type;
    100       typedef typename _Base::mapped_type		mapped_type;
    101 
    102       typedef typename _Base::pointer			pointer;
    103       typedef typename _Base::const_pointer		const_pointer;
    104       typedef typename _Base::reference			reference;
    105       typedef typename _Base::const_reference		const_reference;
    106       typedef __gnu_debug::_Safe_iterator<
    107 	_Base_iterator, unordered_map>			iterator;
    108       typedef __gnu_debug::_Safe_iterator<
    109 	_Base_const_iterator, unordered_map>		const_iterator;
    110       typedef __gnu_debug::_Safe_local_iterator<
    111 	_Base_local_iterator, unordered_map>		local_iterator;
    112       typedef __gnu_debug::_Safe_local_iterator<
    113 	_Base_const_local_iterator, unordered_map>	const_local_iterator;
    114       typedef typename _Base::difference_type		difference_type;
    115 
    116       unordered_map() = default;
    117 
    118       explicit
    119       unordered_map(size_type __n,
    120 		    const hasher& __hf = hasher(),
    121 		    const key_equal& __eql = key_equal(),
    122 		    const allocator_type& __a = allocator_type())
    123       : _Base(__n, __hf, __eql, __a) { }
    124 
    125       template<typename _InputIterator>
    126 	unordered_map(_InputIterator __first, _InputIterator __last,
    127 		      size_type __n = 0,
    128 		      const hasher& __hf = hasher(),
    129 		      const key_equal& __eql = key_equal(),
    130 		      const allocator_type& __a = allocator_type())
    131 	: _Base(__gnu_debug::__base(
    132 		  __glibcxx_check_valid_constructor_range(__first, __last)),
    133 		__gnu_debug::__base(__last), __n,
    134 		__hf, __eql, __a) { }
    135 
    136       unordered_map(const unordered_map&) = default;
    137 
    138       unordered_map(_Base_ref __x)
    139       : _Base(__x._M_ref) { }
    140 
    141       unordered_map(unordered_map&&) = default;
    142 
    143       explicit
    144       unordered_map(const allocator_type& __a)
    145       : _Base(__a) { }
    146 
    147       unordered_map(const unordered_map& __umap,
    148 		    const allocator_type& __a)
    149       : _Base(__umap, __a) { }
    150 
    151       unordered_map(unordered_map&& __umap,
    152 		    const allocator_type& __a)
    153       noexcept( noexcept(_Base(std::move(__umap), __a)) )
    154       : _Safe(std::move(__umap), __a),
    155 	_Base(std::move(__umap), __a) { }
    156 
    157       unordered_map(initializer_list<value_type> __l,
    158 		    size_type __n = 0,
    159 		    const hasher& __hf = hasher(),
    160 		    const key_equal& __eql = key_equal(),
    161 		    const allocator_type& __a = allocator_type())
    162       : _Base(__l, __n, __hf, __eql, __a) { }
    163 
    164       unordered_map(size_type __n, const allocator_type& __a)
    165       : unordered_map(__n, hasher(), key_equal(), __a)
    166       { }
    167 
    168       unordered_map(size_type __n,
    169 		    const hasher& __hf,
    170 		    const allocator_type& __a)
    171       : unordered_map(__n, __hf, key_equal(), __a)
    172       { }
    173 
    174       template<typename _InputIterator>
    175 	unordered_map(_InputIterator __first, _InputIterator __last,
    176 		      size_type __n,
    177 		      const allocator_type& __a)
    178 	: unordered_map(__first, __last, __n, hasher(), key_equal(), __a)
    179 	{ }
    180 
    181       template<typename _InputIterator>
    182 	unordered_map(_InputIterator __first, _InputIterator __last,
    183 		      size_type __n,
    184 		      const hasher& __hf,
    185 		      const allocator_type& __a)
    186 	: unordered_map(__first, __last, __n, __hf, key_equal(), __a)
    187 	{ }
    188 
    189       unordered_map(initializer_list<value_type> __l,
    190 		    size_type __n,
    191 		    const allocator_type& __a)
    192       : unordered_map(__l, __n, hasher(), key_equal(), __a)
    193       { }
    194 
    195       unordered_map(initializer_list<value_type> __l,
    196 		    size_type __n,
    197 		    const hasher& __hf,
    198 		    const allocator_type& __a)
    199       : unordered_map(__l, __n, __hf, key_equal(), __a)
    200       { }
    201 
    202       ~unordered_map() = default;
    203 
    204       unordered_map&
    205       operator=(const unordered_map&) = default;
    206 
    207       unordered_map&
    208       operator=(unordered_map&&) = default;
    209 
    210       unordered_map&
    211       operator=(initializer_list<value_type> __l)
    212       {
    213 	_Base::operator=(__l);
    214 	this->_M_invalidate_all();
    215 	return *this;
    216       }
    217 
    218       using _Base::get_allocator;
    219       using _Base::empty;
    220       using _Base::size;
    221       using _Base::max_size;
    222 
    223       void
    224       swap(unordered_map& __x)
    225 	noexcept( noexcept(declval<_Base&>().swap(__x)) )
    226       {
    227 	_Safe::_M_swap(__x);
    228 	_Base::swap(__x);
    229       }
    230 
    231       void
    232       clear() noexcept
    233       {
    234 	_Base::clear();
    235 	this->_M_invalidate_all();
    236       }
    237 
    238       iterator
    239       begin() noexcept
    240       { return { _Base::begin(), this }; }
    241 
    242       const_iterator
    243       begin() const noexcept
    244       { return { _Base::begin(), this }; }
    245 
    246       iterator
    247       end() noexcept
    248       { return { _Base::end(), this }; }
    249 
    250       const_iterator
    251       end() const noexcept
    252       { return { _Base::end(), this }; }
    253 
    254       const_iterator
    255       cbegin() const noexcept
    256       { return { _Base::cbegin(), this }; }
    257 
    258       const_iterator
    259       cend() const noexcept
    260       { return { _Base::cend(), this }; }
    261 
    262       // local versions
    263       local_iterator
    264       begin(size_type __b)
    265       {
    266 	__glibcxx_check_bucket_index(__b);
    267 	return { _Base::begin(__b), this };
    268       }
    269 
    270       local_iterator
    271       end(size_type __b)
    272       {
    273 	__glibcxx_check_bucket_index(__b);
    274 	return { _Base::end(__b), this };
    275       }
    276 
    277       const_local_iterator
    278       begin(size_type __b) const
    279       {
    280 	__glibcxx_check_bucket_index(__b);
    281 	return { _Base::begin(__b), this };
    282       }
    283 
    284       const_local_iterator
    285       end(size_type __b) const
    286       {
    287 	__glibcxx_check_bucket_index(__b);
    288 	return { _Base::end(__b), this };
    289       }
    290 
    291       const_local_iterator
    292       cbegin(size_type __b) const
    293       {
    294 	__glibcxx_check_bucket_index(__b);
    295 	return { _Base::cbegin(__b), this };
    296       }
    297 
    298       const_local_iterator
    299       cend(size_type __b) const
    300       {
    301 	__glibcxx_check_bucket_index(__b);
    302 	return { _Base::cend(__b), this };
    303       }
    304 
    305       using _Base::bucket_count;
    306       using _Base::max_bucket_count;
    307       using _Base::bucket;
    308 
    309       size_type
    310       bucket_size(size_type __b) const
    311       {
    312 	__glibcxx_check_bucket_index(__b);
    313 	return _Base::bucket_size(__b);
    314       }
    315 
    316       using _Base::load_factor;
    317 
    318       float
    319       max_load_factor() const noexcept
    320       { return _Base::max_load_factor(); }
    321 
    322       void
    323       max_load_factor(float __f)
    324       {
    325 	__glibcxx_check_max_load_factor(__f);
    326 	_Base::max_load_factor(__f);
    327       }
    328 
    329       template<typename... _Args>
    330 	std::pair<iterator, bool>
    331 	emplace(_Args&&... __args)
    332 	{
    333 	  size_type __bucket_count = this->bucket_count();
    334 	  auto __res = _Base::emplace(std::forward<_Args>(__args)...);
    335 	  _M_check_rehashed(__bucket_count);
    336 	  return { { __res.first, this }, __res.second };
    337 	}
    338 
    339       template<typename... _Args>
    340 	iterator
    341 	emplace_hint(const_iterator __hint, _Args&&... __args)
    342 	{
    343 	  __glibcxx_check_insert(__hint);
    344 	  size_type __bucket_count = this->bucket_count();
    345 	  auto __it = _Base::emplace_hint(__hint.base(),
    346 					  std::forward<_Args>(__args)...);
    347 	  _M_check_rehashed(__bucket_count);
    348 	  return { __it, this };
    349 	}
    350 
    351       std::pair<iterator, bool>
    352       insert(const value_type& __obj)
    353       {
    354 	size_type __bucket_count = this->bucket_count();
    355 	auto __res = _Base::insert(__obj);
    356 	_M_check_rehashed(__bucket_count);
    357 	return { { __res.first, this }, __res.second };
    358       }
    359 
    360       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    361       // 2354. Unnecessary copying when inserting into maps with braced-init
    362       std::pair<iterator, bool>
    363       insert(value_type&& __x)
    364       {
    365 	size_type __bucket_count = this->bucket_count();
    366 	auto __res = _Base::insert(std::move(__x));
    367 	_M_check_rehashed(__bucket_count);
    368 	return { { __res.first, this }, __res.second };
    369       }
    370 
    371       template<typename _Pair, typename = typename
    372 	       std::enable_if<std::is_constructible<value_type,
    373 						    _Pair&&>::value>::type>
    374 	std::pair<iterator, bool>
    375 	insert(_Pair&& __obj)
    376 	{
    377 	  size_type __bucket_count = this->bucket_count();
    378 	  auto __res = _Base::insert(std::forward<_Pair>(__obj));
    379 	  _M_check_rehashed(__bucket_count);
    380 	  return { { __res.first, this }, __res.second };
    381 	}
    382 
    383       iterator
    384       insert(const_iterator __hint, const value_type& __obj)
    385       {
    386 	__glibcxx_check_insert(__hint);
    387 	size_type __bucket_count = this->bucket_count();
    388 	auto __it = _Base::insert(__hint.base(), __obj);
    389 	_M_check_rehashed(__bucket_count);
    390 	return { __it, this };
    391       }
    392 
    393       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    394       // 2354. Unnecessary copying when inserting into maps with braced-init
    395       iterator
    396       insert(const_iterator __hint, value_type&& __x)
    397       {
    398 	__glibcxx_check_insert(__hint);
    399 	size_type __bucket_count = this->bucket_count();
    400 	auto __it = _Base::insert(__hint.base(), std::move(__x));
    401 	_M_check_rehashed(__bucket_count);
    402 	return { __it, this };
    403       }
    404 
    405       template<typename _Pair, typename = typename
    406 	       std::enable_if<std::is_constructible<value_type,
    407 						    _Pair&&>::value>::type>
    408 	iterator
    409 	insert(const_iterator __hint, _Pair&& __obj)
    410 	{
    411 	  __glibcxx_check_insert(__hint);
    412 	  size_type __bucket_count = this->bucket_count();
    413 	  auto __it = _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
    414 	  _M_check_rehashed(__bucket_count);
    415 	  return { __it, this };
    416 	}
    417 
    418       void
    419       insert(std::initializer_list<value_type> __l)
    420       {
    421 	size_type __bucket_count = this->bucket_count();
    422 	_Base::insert(__l);
    423 	_M_check_rehashed(__bucket_count);
    424       }
    425 
    426       template<typename _InputIterator>
    427 	void
    428 	insert(_InputIterator __first, _InputIterator __last)
    429 	{
    430 	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
    431 	  __glibcxx_check_valid_range2(__first, __last, __dist);
    432 	  size_type __bucket_count = this->bucket_count();
    433 
    434 	  if (__dist.second >= __gnu_debug::__dp_sign)
    435 	    _Base::insert(__gnu_debug::__unsafe(__first),
    436 			  __gnu_debug::__unsafe(__last));
    437 	  else
    438 	    _Base::insert(__first, __last);
    439 
    440 	  _M_check_rehashed(__bucket_count);
    441 	}
    442 
    443 #ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED
    444       template <typename... _Args>
    445 	pair<iterator, bool>
    446 	try_emplace(const key_type& __k, _Args&&... __args)
    447 	{
    448 	  auto __res = _Base::try_emplace(__k,
    449 					  std::forward<_Args>(__args)...);
    450 	  return { { __res.first, this }, __res.second };
    451 	}
    452 
    453       template <typename... _Args>
    454 	pair<iterator, bool>
    455 	try_emplace(key_type&& __k, _Args&&... __args)
    456 	{
    457 	  auto __res = _Base::try_emplace(std::move(__k),
    458 					  std::forward<_Args>(__args)...);
    459 	  return { { __res.first, this }, __res.second };
    460 	}
    461 
    462       template <typename... _Args>
    463 	iterator
    464 	try_emplace(const_iterator __hint, const key_type& __k,
    465 		    _Args&&... __args)
    466 	{
    467 	  __glibcxx_check_insert(__hint);
    468 	  return { _Base::try_emplace(__hint.base(), __k,
    469 				      std::forward<_Args>(__args)...),
    470 		   this };
    471 	}
    472 
    473       template <typename... _Args>
    474 	iterator
    475 	try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
    476 	{
    477 	  __glibcxx_check_insert(__hint);
    478 	  return { _Base::try_emplace(__hint.base(), std::move(__k),
    479 				      std::forward<_Args>(__args)...),
    480 		   this };
    481 	}
    482 
    483       template <typename _Obj>
    484 	pair<iterator, bool>
    485 	insert_or_assign(const key_type& __k, _Obj&& __obj)
    486 	{
    487 	  auto __res = _Base::insert_or_assign(__k,
    488 					       std::forward<_Obj>(__obj));
    489 	  return { { __res.first, this }, __res.second };
    490 	}
    491 
    492       template <typename _Obj>
    493 	pair<iterator, bool>
    494 	insert_or_assign(key_type&& __k, _Obj&& __obj)
    495 	{
    496 	  auto __res = _Base::insert_or_assign(std::move(__k),
    497 					       std::forward<_Obj>(__obj));
    498 	  return { { __res.first, this }, __res.second };
    499 	}
    500 
    501       template <typename _Obj>
    502 	iterator
    503 	insert_or_assign(const_iterator __hint, const key_type& __k,
    504 			 _Obj&& __obj)
    505 	{
    506 	  __glibcxx_check_insert(__hint);
    507 	  return { _Base::insert_or_assign(__hint.base(), __k,
    508 					   std::forward<_Obj>(__obj)),
    509 		   this };
    510 	}
    511 
    512       template <typename _Obj>
    513 	iterator
    514 	insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
    515 	{
    516 	  __glibcxx_check_insert(__hint);
    517 	  return { _Base::insert_or_assign(__hint.base(), std::move(__k),
    518 					   std::forward<_Obj>(__obj)),
    519 		   this };
    520 	}
    521 #endif // C++17
    522 
    523 #if __cplusplus > 201402L
    524       using node_type = typename _Base::node_type;
    525       using insert_return_type = _Node_insert_return<iterator, node_type>;
    526 
    527       node_type
    528       extract(const_iterator __position)
    529       {
    530 	__glibcxx_check_erase(__position);
    531 	return _M_extract(__position.base());
    532       }
    533 
    534       node_type
    535       extract(const key_type& __key)
    536       {
    537 	const auto __position = _Base::find(__key);
    538 	if (__position != _Base::end())
    539 	  return _M_extract(__position);
    540 	return {};
    541       }
    542 
    543       insert_return_type
    544       insert(node_type&& __nh)
    545       {
    546 	auto __ret = _Base::insert(std::move(__nh));
    547 	return
    548 	  { { __ret.position, this }, __ret.inserted, std::move(__ret.node) };
    549       }
    550 
    551       iterator
    552       insert(const_iterator __hint, node_type&& __nh)
    553       {
    554 	__glibcxx_check_insert(__hint);
    555 	return { _Base::insert(__hint.base(), std::move(__nh)), this };
    556       }
    557 
    558       template<typename _H2, typename _P2>
    559 	void
    560 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
    561 	{
    562 	  auto __guard
    563 	    = _Safe::_S_uc_guard(std::__detail::_Select1st{}, __source);
    564 	  _Base::merge(__source);
    565 	}
    566 
    567       template<typename _H2, typename _P2>
    568 	void
    569 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
    570 	{ merge(__source); }
    571 
    572       template<typename _H2, typename _P2>
    573 	void
    574 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
    575 	{
    576 	  auto __guard
    577 	    = _Safe::_S_umc_guard(std::__detail::_Select1st{}, __source);
    578 	  _Base::merge(__source);
    579 	}
    580 
    581       template<typename _H2, typename _P2>
    582 	void
    583 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
    584 	{ merge(__source); }
    585 #endif // C++17
    586 
    587       using _Base::hash_function;
    588       using _Base::key_eq;
    589 
    590       iterator
    591       find(const key_type& __key)
    592       { return { _Base::find(__key), this }; }
    593 
    594 #if __cplusplus > 201703L
    595       template<typename _Kt,
    596 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
    597 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
    598 	iterator
    599 	find(const _Kt& __k)
    600 	{ return { _Base::find(__k), this }; }
    601 #endif
    602 
    603       const_iterator
    604       find(const key_type& __key) const
    605       { return { _Base::find(__key), this }; }
    606 
    607 #if __cplusplus > 201703L
    608       template<typename _Kt,
    609 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
    610 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
    611 	const_iterator
    612 	find(const _Kt& __k) const
    613 	{ return { _Base::find(__k), this }; }
    614 #endif
    615 
    616       using _Base::count;
    617 #if __cplusplus > 201703L
    618       using _Base::contains;
    619 #endif
    620 
    621       std::pair<iterator, iterator>
    622       equal_range(const key_type& __key)
    623       {
    624 	auto __res = _Base::equal_range(__key);
    625 	return { { __res.first, this }, { __res.second, this } };
    626       }
    627 
    628 #if __cplusplus > 201703L
    629       template<typename _Kt,
    630 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
    631 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
    632 	std::pair<iterator, iterator>
    633 	equal_range(const _Kt& __k)
    634 	{
    635 	  auto __res = _Base::equal_range(__k);
    636 	  return { { __res.first, this }, { __res.second, this } };
    637 	}
    638 #endif
    639 
    640       std::pair<const_iterator, const_iterator>
    641       equal_range(const key_type& __key) const
    642       {
    643 	auto __res = _Base::equal_range(__key);
    644 	return { { __res.first, this }, { __res.second, this } };
    645       }
    646 
    647 #if __cplusplus > 201703L
    648       template<typename _Kt,
    649 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
    650 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
    651 	std::pair<const_iterator, const_iterator>
    652 	equal_range(const _Kt& __k) const
    653 	{
    654 	  auto __res = _Base::equal_range(__k);
    655 	  return { { __res.first, this }, { __res.second, this } };
    656 	}
    657 #endif
    658 
    659       using _Base::operator[];
    660       using _Base::at;
    661 
    662       size_type
    663       erase(const key_type& __key)
    664       {
    665 	size_type __ret(0);
    666 	auto __victim = _Base::find(__key);
    667 	if (__victim != _Base::end())
    668 	  {
    669 	    _M_erase(__victim);
    670 	    __ret = 1;
    671 	  }
    672 	return __ret;
    673       }
    674 
    675       iterator
    676       erase(const_iterator __it)
    677       {
    678 	__glibcxx_check_erase(__it);
    679 	return { _M_erase(__it.base()), this };
    680       }
    681 
    682       _Base_iterator
    683       erase(_Base_const_iterator __it)
    684       {
    685 	__glibcxx_check_erase2(__it);
    686 	return _M_erase(__it);
    687       }
    688 
    689       iterator
    690       erase(iterator __it)
    691       {
    692 	__glibcxx_check_erase(__it);
    693 	return { _M_erase(__it.base()), this };
    694       }
    695 
    696       iterator
    697       erase(const_iterator __first, const_iterator __last)
    698       {
    699 	__glibcxx_check_erase_range(__first, __last);
    700 	for (auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
    701 	  {
    702 	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
    703 				  _M_message(__gnu_debug::__msg_valid_range)
    704 				  ._M_iterator(__first, "first")
    705 				  ._M_iterator(__last, "last"));
    706 	    _M_invalidate(__tmp);
    707 	  }
    708 
    709 	size_type __bucket_count = this->bucket_count();
    710 	auto __next = _Base::erase(__first.base(), __last.base());
    711 	_M_check_rehashed(__bucket_count);
    712 	return { __next, this };
    713       }
    714 
    715       using _Base::rehash;
    716       using _Base::reserve;
    717 
    718       _Base&
    719       _M_base() noexcept	{ return *this; }
    720 
    721       const _Base&
    722       _M_base() const noexcept	{ return *this; }
    723 
    724     private:
    725       void
    726       _M_check_rehashed(size_type __prev_count)
    727       {
    728 	if (__prev_count != this->bucket_count())
    729 	  this->_M_invalidate_all();
    730       }
    731 
    732       void
    733       _M_invalidate(_Base_const_iterator __victim)
    734       {
    735 	this->_M_invalidate_if(
    736 	  [__victim](_Base_const_iterator __it) { return __it == __victim; });
    737 	this->_M_invalidate_local_if(
    738 	  [__victim](_Base_const_local_iterator __it)
    739 	  { return __it == __victim; });
    740       }
    741 
    742       _Base_iterator
    743       _M_erase(_Base_const_iterator __victim)
    744       {
    745 	_M_invalidate(__victim);
    746 	size_type __bucket_count = this->bucket_count();
    747 	_Base_iterator __next = _Base::erase(__victim);
    748 	_M_check_rehashed(__bucket_count);
    749 	return __next;
    750       }
    751 
    752 #if __cplusplus > 201402L
    753       node_type
    754       _M_extract(_Base_const_iterator __victim)
    755       {
    756 	_M_invalidate(__victim);
    757 	return _Base::extract(__victim);
    758       }
    759 #endif
    760     };
    761 
    762 #if __cpp_deduction_guides >= 201606
    763 
    764   template<typename _InputIterator,
    765 	   typename _Hash = hash<__iter_key_t<_InputIterator>>,
    766 	   typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
    767 	   typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
    768 	   typename = _RequireInputIter<_InputIterator>,
    769 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
    770 	   typename = _RequireNotAllocator<_Pred>,
    771 	   typename = _RequireAllocator<_Allocator>>
    772     unordered_map(_InputIterator, _InputIterator,
    773 		  typename unordered_map<int, int>::size_type = {},
    774 		  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
    775     -> unordered_map<__iter_key_t<_InputIterator>,
    776 		     __iter_val_t<_InputIterator>,
    777 		     _Hash, _Pred, _Allocator>;
    778 
    779   template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
    780 	   typename _Pred = equal_to<_Key>,
    781 	   typename _Allocator = allocator<pair<const _Key, _Tp>>,
    782 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
    783 	   typename = _RequireNotAllocator<_Pred>,
    784 	   typename = _RequireAllocator<_Allocator>>
    785     unordered_map(initializer_list<pair<_Key, _Tp>>,
    786 		  typename unordered_map<int, int>::size_type = {},
    787 		  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
    788     -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>;
    789 
    790   template<typename _InputIterator, typename _Allocator,
    791 	   typename = _RequireInputIter<_InputIterator>,
    792 	   typename = _RequireAllocator<_Allocator>>
    793     unordered_map(_InputIterator, _InputIterator,
    794 		  typename unordered_map<int, int>::size_type, _Allocator)
    795     -> unordered_map<__iter_key_t<_InputIterator>,
    796 		     __iter_val_t<_InputIterator>,
    797 		     hash<__iter_key_t<_InputIterator>>,
    798 		     equal_to<__iter_key_t<_InputIterator>>,
    799 		     _Allocator>;
    800 
    801   template<typename _InputIterator, typename _Allocator,
    802 	   typename = _RequireInputIter<_InputIterator>,
    803 	   typename = _RequireAllocator<_Allocator>>
    804     unordered_map(_InputIterator, _InputIterator, _Allocator)
    805     -> unordered_map<__iter_key_t<_InputIterator>,
    806 		     __iter_val_t<_InputIterator>,
    807 		     hash<__iter_key_t<_InputIterator>>,
    808 		     equal_to<__iter_key_t<_InputIterator>>,
    809 		     _Allocator>;
    810 
    811   template<typename _InputIterator, typename _Hash, typename _Allocator,
    812 	   typename = _RequireInputIter<_InputIterator>,
    813 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
    814 	   typename = _RequireAllocator<_Allocator>>
    815     unordered_map(_InputIterator, _InputIterator,
    816 		  typename unordered_map<int, int>::size_type,
    817 		  _Hash, _Allocator)
    818     -> unordered_map<__iter_key_t<_InputIterator>,
    819 		     __iter_val_t<_InputIterator>, _Hash,
    820 		     equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
    821 
    822   template<typename _Key, typename _Tp, typename _Allocator,
    823 	   typename = _RequireAllocator<_Allocator>>
    824     unordered_map(initializer_list<pair<_Key, _Tp>>,
    825 		  typename unordered_map<int, int>::size_type,
    826 		  _Allocator)
    827     -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
    828 
    829   template<typename _Key, typename _Tp, typename _Allocator,
    830 	   typename = _RequireAllocator<_Allocator>>
    831     unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator)
    832     -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
    833 
    834   template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
    835 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
    836 	   typename = _RequireAllocator<_Allocator>>
    837     unordered_map(initializer_list<pair<_Key, _Tp>>,
    838 		  typename unordered_map<int, int>::size_type,
    839 		  _Hash, _Allocator)
    840     -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
    841 
    842 #endif
    843 
    844   template<typename _Key, typename _Tp, typename _Hash,
    845 	   typename _Pred, typename _Alloc>
    846     inline void
    847     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
    848 	 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    849     noexcept(noexcept(__x.swap(__y)))
    850     { __x.swap(__y); }
    851 
    852   template<typename _Key, typename _Tp, typename _Hash,
    853 	   typename _Pred, typename _Alloc>
    854     inline bool
    855     operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
    856 	       const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    857     { return __x._M_base() == __y._M_base(); }
    858 
    859 #if __cpp_impl_three_way_comparison < 201907L
    860   template<typename _Key, typename _Tp, typename _Hash,
    861 	   typename _Pred, typename _Alloc>
    862     inline bool
    863     operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
    864 	       const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    865     { return !(__x == __y); }
    866 #endif
    867 
    868   /// Class std::unordered_multimap with safety/checking/debug instrumentation.
    869   template<typename _Key, typename _Tp,
    870 	   typename _Hash = std::hash<_Key>,
    871 	   typename _Pred = std::equal_to<_Key>,
    872 	   typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
    873     class unordered_multimap
    874       : public __gnu_debug::_Safe_container<
    875 	unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
    876 	__gnu_debug::_Safe_unordered_container>,
    877 	public _GLIBCXX_STD_C::unordered_multimap<
    878 	_Key, _Tp, _Hash, _Pred, _Alloc>
    879     {
    880       typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
    881 						 _Pred, _Alloc>		_Base;
    882       typedef __gnu_debug::_Safe_container<unordered_multimap,
    883 	_Alloc, __gnu_debug::_Safe_unordered_container>			_Safe;
    884       typedef typename _Base::const_iterator	   _Base_const_iterator;
    885       typedef typename _Base::iterator		   _Base_iterator;
    886       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
    887       typedef typename _Base::local_iterator	   _Base_local_iterator;
    888 
    889       template<typename _ItT, typename _SeqT, typename _CatT>
    890 	friend class ::__gnu_debug::_Safe_iterator;
    891       template<typename _ItT, typename _SeqT>
    892 	friend class ::__gnu_debug::_Safe_local_iterator;
    893 
    894       // Reference wrapper for base class. See PR libstdc++/90102.
    895       struct _Base_ref
    896       {
    897 	_Base_ref(const _Base& __r) : _M_ref(__r) { }
    898 
    899 	const _Base& _M_ref;
    900       };
    901 
    902     public:
    903       typedef typename _Base::size_type			size_type;
    904       typedef typename _Base::hasher			hasher;
    905       typedef typename _Base::key_equal			key_equal;
    906       typedef typename _Base::allocator_type		allocator_type;
    907 
    908       typedef typename _Base::key_type			key_type;
    909       typedef typename _Base::value_type		value_type;
    910       typedef typename _Base::mapped_type		mapped_type;
    911 
    912       typedef typename _Base::pointer			pointer;
    913       typedef typename _Base::const_pointer		const_pointer;
    914       typedef typename _Base::reference			reference;
    915       typedef typename _Base::const_reference		const_reference;
    916       typedef __gnu_debug::_Safe_iterator<
    917 	_Base_iterator, unordered_multimap>		iterator;
    918       typedef __gnu_debug::_Safe_iterator<
    919 	_Base_const_iterator, unordered_multimap>	const_iterator;
    920       typedef __gnu_debug::_Safe_local_iterator<
    921 	_Base_local_iterator, unordered_multimap>	local_iterator;
    922       typedef __gnu_debug::_Safe_local_iterator<
    923 	_Base_const_local_iterator, unordered_multimap>	const_local_iterator;
    924       typedef typename _Base::difference_type		difference_type;
    925 
    926       unordered_multimap() = default;
    927 
    928       explicit
    929       unordered_multimap(size_type __n,
    930 			 const hasher& __hf = hasher(),
    931 			 const key_equal& __eql = key_equal(),
    932 			 const allocator_type& __a = allocator_type())
    933       : _Base(__n, __hf, __eql, __a) { }
    934 
    935       template<typename _InputIterator>
    936 	unordered_multimap(_InputIterator __first, _InputIterator __last,
    937 			   size_type __n = 0,
    938 			   const hasher& __hf = hasher(),
    939 			   const key_equal& __eql = key_equal(),
    940 			   const allocator_type& __a = allocator_type())
    941 	: _Base(__gnu_debug::__base(
    942 		  __glibcxx_check_valid_constructor_range(__first, __last)),
    943 		__gnu_debug::__base(__last), __n,
    944 		__hf, __eql, __a) { }
    945 
    946       unordered_multimap(const unordered_multimap&) = default;
    947 
    948       unordered_multimap(_Base_ref __x)
    949       : _Base(__x._M_ref) { }
    950 
    951       unordered_multimap(unordered_multimap&&) = default;
    952 
    953       explicit
    954       unordered_multimap(const allocator_type& __a)
    955       : _Base(__a) { }
    956 
    957       unordered_multimap(const unordered_multimap& __umap,
    958 			 const allocator_type& __a)
    959       : _Base(__umap, __a) { }
    960 
    961       unordered_multimap(unordered_multimap&& __umap,
    962 			 const allocator_type& __a)
    963       noexcept( noexcept(_Base(std::move(__umap), __a)) )
    964       : _Safe(std::move(__umap), __a),
    965 	_Base(std::move(__umap), __a) { }
    966 
    967       unordered_multimap(initializer_list<value_type> __l,
    968 			 size_type __n = 0,
    969 			 const hasher& __hf = hasher(),
    970 			 const key_equal& __eql = key_equal(),
    971 			 const allocator_type& __a = allocator_type())
    972       : _Base(__l, __n, __hf, __eql, __a) { }
    973 
    974       unordered_multimap(size_type __n, const allocator_type& __a)
    975       : unordered_multimap(__n, hasher(), key_equal(), __a)
    976       { }
    977 
    978       unordered_multimap(size_type __n, const hasher& __hf,
    979 			 const allocator_type& __a)
    980       : unordered_multimap(__n, __hf, key_equal(), __a)
    981       { }
    982 
    983       template<typename _InputIterator>
    984 	unordered_multimap(_InputIterator __first, _InputIterator __last,
    985 			   size_type __n,
    986 			   const allocator_type& __a)
    987 	: unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
    988 	{ }
    989 
    990       template<typename _InputIterator>
    991 	unordered_multimap(_InputIterator __first, _InputIterator __last,
    992 			   size_type __n, const hasher& __hf,
    993 			   const allocator_type& __a)
    994 	: unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
    995 	{ }
    996 
    997       unordered_multimap(initializer_list<value_type> __l,
    998 			 size_type __n,
    999 			 const allocator_type& __a)
   1000       : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
   1001       { }
   1002 
   1003       unordered_multimap(initializer_list<value_type> __l,
   1004 			 size_type __n, const hasher& __hf,
   1005 			 const allocator_type& __a)
   1006       : unordered_multimap(__l, __n, __hf, key_equal(), __a)
   1007       { }
   1008 
   1009       ~unordered_multimap() = default;
   1010 
   1011       unordered_multimap&
   1012       operator=(const unordered_multimap&) = default;
   1013 
   1014       unordered_multimap&
   1015       operator=(unordered_multimap&&) = default;
   1016 
   1017       unordered_multimap&
   1018       operator=(initializer_list<value_type> __l)
   1019       {
   1020 	_Base::operator=(__l);
   1021 	this->_M_invalidate_all();
   1022 	return *this;
   1023       }
   1024 
   1025       using _Base::get_allocator;
   1026       using _Base::empty;
   1027       using _Base::size;
   1028       using _Base::max_size;
   1029 
   1030       void
   1031       swap(unordered_multimap& __x)
   1032 	noexcept( noexcept(declval<_Base&>().swap(__x)) )
   1033       {
   1034 	_Safe::_M_swap(__x);
   1035 	_Base::swap(__x);
   1036       }
   1037 
   1038       void
   1039       clear() noexcept
   1040       {
   1041 	_Base::clear();
   1042 	this->_M_invalidate_all();
   1043       }
   1044 
   1045       iterator
   1046       begin() noexcept
   1047       { return { _Base::begin(), this }; }
   1048 
   1049       const_iterator
   1050       begin() const noexcept
   1051       { return { _Base::begin(), this }; }
   1052 
   1053       iterator
   1054       end() noexcept
   1055       { return { _Base::end(), this }; }
   1056 
   1057       const_iterator
   1058       end() const noexcept
   1059       { return { _Base::end(), this }; }
   1060 
   1061       const_iterator
   1062       cbegin() const noexcept
   1063       { return { _Base::cbegin(), this }; }
   1064 
   1065       const_iterator
   1066       cend() const noexcept
   1067       { return { _Base::cend(), this }; }
   1068 
   1069       // local versions
   1070       local_iterator
   1071       begin(size_type __b)
   1072       {
   1073 	__glibcxx_check_bucket_index(__b);
   1074 	return { _Base::begin(__b), this };
   1075       }
   1076 
   1077       local_iterator
   1078       end(size_type __b)
   1079       {
   1080 	__glibcxx_check_bucket_index(__b);
   1081 	return { _Base::end(__b), this };
   1082       }
   1083 
   1084       const_local_iterator
   1085       begin(size_type __b) const
   1086       {
   1087 	__glibcxx_check_bucket_index(__b);
   1088 	return { _Base::begin(__b), this };
   1089       }
   1090 
   1091       const_local_iterator
   1092       end(size_type __b) const
   1093       {
   1094 	__glibcxx_check_bucket_index(__b);
   1095 	return { _Base::end(__b), this };
   1096       }
   1097 
   1098       const_local_iterator
   1099       cbegin(size_type __b) const
   1100       {
   1101 	__glibcxx_check_bucket_index(__b);
   1102 	return { _Base::cbegin(__b), this };
   1103       }
   1104 
   1105       const_local_iterator
   1106       cend(size_type __b) const
   1107       {
   1108 	__glibcxx_check_bucket_index(__b);
   1109 	return { _Base::cend(__b), this };
   1110       }
   1111 
   1112       using _Base::bucket_count;
   1113       using _Base::max_bucket_count;
   1114       using _Base::bucket;
   1115 
   1116       size_type
   1117       bucket_size(size_type __b) const
   1118       {
   1119 	__glibcxx_check_bucket_index(__b);
   1120 	return _Base::bucket_size(__b);
   1121       }
   1122 
   1123       float
   1124       max_load_factor() const noexcept
   1125       { return _Base::max_load_factor(); }
   1126 
   1127       void
   1128       max_load_factor(float __f)
   1129       {
   1130 	__glibcxx_check_max_load_factor(__f);
   1131 	_Base::max_load_factor(__f);
   1132       }
   1133 
   1134       template<typename... _Args>
   1135 	iterator
   1136 	emplace(_Args&&... __args)
   1137 	{
   1138 	  size_type __bucket_count = this->bucket_count();
   1139 	  auto __it = _Base::emplace(std::forward<_Args>(__args)...);
   1140 	  _M_check_rehashed(__bucket_count);
   1141 	  return { __it, this };
   1142 	}
   1143 
   1144       template<typename... _Args>
   1145 	iterator
   1146 	emplace_hint(const_iterator __hint, _Args&&... __args)
   1147 	{
   1148 	  __glibcxx_check_insert(__hint);
   1149 	  size_type __bucket_count = this->bucket_count();
   1150 	  auto __it = _Base::emplace_hint(__hint.base(),
   1151 					  std::forward<_Args>(__args)...);
   1152 	  _M_check_rehashed(__bucket_count);
   1153 	  return { __it, this };
   1154 	}
   1155 
   1156       iterator
   1157       insert(const value_type& __obj)
   1158       {
   1159 	size_type __bucket_count = this->bucket_count();
   1160 	auto __it = _Base::insert(__obj);
   1161 	_M_check_rehashed(__bucket_count);
   1162 	return { __it, this };
   1163       }
   1164 
   1165       // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1166       // 2354. Unnecessary copying when inserting into maps with braced-init
   1167       iterator
   1168       insert(value_type&& __x)
   1169       {
   1170 	size_type __bucket_count = this->bucket_count();
   1171 	auto __it = _Base::insert(std::move(__x));
   1172 	_M_check_rehashed(__bucket_count);
   1173 	return { __it, this };
   1174       }
   1175 
   1176       iterator
   1177       insert(const_iterator __hint, const value_type& __obj)
   1178       {
   1179 	__glibcxx_check_insert(__hint);
   1180 	size_type __bucket_count = this->bucket_count();
   1181 	auto __it = _Base::insert(__hint.base(), __obj);
   1182 	_M_check_rehashed(__bucket_count);
   1183 	return { __it, this };
   1184       }
   1185 
   1186       // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1187       // 2354. Unnecessary copying when inserting into maps with braced-init
   1188       iterator
   1189       insert(const_iterator __hint, value_type&& __x)
   1190       {
   1191 	__glibcxx_check_insert(__hint);
   1192 	size_type __bucket_count = this->bucket_count();
   1193 	auto __it = _Base::insert(__hint.base(), std::move(__x));
   1194 	_M_check_rehashed(__bucket_count);
   1195 	return { __it, this };
   1196       }
   1197 
   1198       template<typename _Pair, typename = typename
   1199 	       std::enable_if<std::is_constructible<value_type,
   1200 						    _Pair&&>::value>::type>
   1201 	iterator
   1202 	insert(_Pair&& __obj)
   1203 	{
   1204 	  size_type __bucket_count = this->bucket_count();
   1205 	  auto __it = _Base::insert(std::forward<_Pair>(__obj));
   1206 	  _M_check_rehashed(__bucket_count);
   1207 	  return { __it, this };
   1208 	}
   1209 
   1210       template<typename _Pair, typename = typename
   1211 	       std::enable_if<std::is_constructible<value_type,
   1212 						    _Pair&&>::value>::type>
   1213 	iterator
   1214 	insert(const_iterator __hint, _Pair&& __obj)
   1215 	{
   1216 	  __glibcxx_check_insert(__hint);
   1217 	  size_type __bucket_count = this->bucket_count();
   1218 	  auto __it = _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
   1219 	  _M_check_rehashed(__bucket_count);
   1220 	  return { __it, this };
   1221 	}
   1222 
   1223       void
   1224       insert(std::initializer_list<value_type> __l)
   1225       { _Base::insert(__l); }
   1226 
   1227       template<typename _InputIterator>
   1228 	void
   1229 	insert(_InputIterator __first, _InputIterator __last)
   1230 	{
   1231 	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
   1232 	  __glibcxx_check_valid_range2(__first, __last, __dist);
   1233 	  size_type __bucket_count = this->bucket_count();
   1234 
   1235 	  if (__dist.second >= __gnu_debug::__dp_sign)
   1236 	    _Base::insert(__gnu_debug::__unsafe(__first),
   1237 			  __gnu_debug::__unsafe(__last));
   1238 	  else
   1239 	    _Base::insert(__first, __last);
   1240 
   1241 	  _M_check_rehashed(__bucket_count);
   1242 	}
   1243 
   1244 #if __cplusplus > 201402L
   1245       using node_type = typename _Base::node_type;
   1246 
   1247       node_type
   1248       extract(const_iterator __position)
   1249       {
   1250 	__glibcxx_check_erase(__position);
   1251 	return _M_extract(__position.base());
   1252       }
   1253 
   1254       node_type
   1255       extract(const key_type& __key)
   1256       {
   1257 	const auto __position = _Base::find(__key);
   1258 	if (__position != _Base::end())
   1259 	  return _M_extract(__position);
   1260 	return {};
   1261       }
   1262 
   1263       iterator
   1264       insert(node_type&& __nh)
   1265       { return { _Base::insert(std::move(__nh)), this }; }
   1266 
   1267       iterator
   1268       insert(const_iterator __hint, node_type&& __nh)
   1269       {
   1270 	__glibcxx_check_insert(__hint);
   1271 	return { _Base::insert(__hint.base(), std::move(__nh)), this };
   1272       }
   1273 
   1274       template<typename _H2, typename _P2>
   1275 	void
   1276 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
   1277 	{
   1278 	  auto __guard
   1279 	    = _Safe::_S_umc_guard(std::__detail::_Select1st{}, __source);
   1280 	  _Base::merge(__source);
   1281 	}
   1282 
   1283       template<typename _H2, typename _P2>
   1284 	void
   1285 	merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
   1286 	{ merge(__source); }
   1287 
   1288       template<typename _H2, typename _P2>
   1289 	void
   1290 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
   1291 	{
   1292 	  auto __guard
   1293 	    = _Safe::_S_uc_guard(std::__detail::_Select1st{}, __source);
   1294 	  _Base::merge(__source);
   1295 	}
   1296 
   1297       template<typename _H2, typename _P2>
   1298 	void
   1299 	merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
   1300 	{ merge(__source); }
   1301 #endif // C++17
   1302 
   1303       using _Base::hash_function;
   1304       using _Base::key_eq;
   1305 
   1306       iterator
   1307       find(const key_type& __key)
   1308       { return { _Base::find(__key), this }; }
   1309 
   1310 #if __cplusplus > 201703L
   1311       template<typename _Kt,
   1312 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
   1313 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
   1314 	iterator
   1315 	find(const _Kt& __k)
   1316 	{ return { _Base::find(__k), this }; }
   1317 #endif
   1318 
   1319       const_iterator
   1320       find(const key_type& __key) const
   1321       { return { _Base::find(__key), this }; }
   1322 
   1323 #if __cplusplus > 201703L
   1324       template<typename _Kt,
   1325 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
   1326 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
   1327 	const_iterator
   1328 	find(const _Kt& __k) const
   1329 	{ return { _Base::find(__k), this }; }
   1330 #endif
   1331 
   1332       using _Base::count;
   1333 #if __cplusplus > 201703L
   1334       using _Base::contains;
   1335 #endif
   1336 
   1337       std::pair<iterator, iterator>
   1338       equal_range(const key_type& __key)
   1339       {
   1340 	auto __res = _Base::equal_range(__key);
   1341 	return { { __res.first, this }, { __res.second, this } };
   1342       }
   1343 
   1344 #if __cplusplus > 201703L
   1345       template<typename _Kt,
   1346 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
   1347 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
   1348 	std::pair<iterator, iterator>
   1349 	equal_range(const _Kt& __k)
   1350 	{
   1351 	  auto __res = _Base::equal_range(__k);
   1352 	  return { { __res.first, this }, { __res.second, this } };
   1353 	}
   1354 #endif
   1355 
   1356       std::pair<const_iterator, const_iterator>
   1357       equal_range(const key_type& __key) const
   1358       {
   1359 	auto __res = _Base::equal_range(__key);
   1360 	return { { __res.first, this }, { __res.second, this } };
   1361       }
   1362 
   1363 #if __cplusplus > 201703L
   1364       template<typename _Kt,
   1365 	       typename = std::__has_is_transparent_t<_Hash, _Kt>,
   1366 	       typename = std::__has_is_transparent_t<_Pred, _Kt>>
   1367 	std::pair<const_iterator, const_iterator>
   1368 	equal_range(const _Kt& __k) const
   1369 	{
   1370 	  auto __res = _Base::equal_range(__k);
   1371 	  return { { __res.first, this }, { __res.second, this } };
   1372 	}
   1373 #endif
   1374 
   1375       size_type
   1376       erase(const key_type& __key)
   1377       {
   1378 	size_type __ret(0);
   1379 	size_type __bucket_count = this->bucket_count();
   1380 	auto __pair = _Base::equal_range(__key);
   1381 	for (auto __victim = __pair.first; __victim != __pair.second;)
   1382 	  {
   1383 	    _M_invalidate(__victim);
   1384 	    __victim = _Base::erase(__victim);
   1385 	    ++__ret;
   1386 	  }
   1387 
   1388 	_M_check_rehashed(__bucket_count);
   1389 	return __ret;
   1390       }
   1391 
   1392       iterator
   1393       erase(const_iterator __it)
   1394       {
   1395 	__glibcxx_check_erase(__it);
   1396 	return { _M_erase(__it.base()), this };
   1397       }
   1398 
   1399       _Base_iterator
   1400       erase(_Base_const_iterator __it)
   1401       {
   1402 	__glibcxx_check_erase2(__it);
   1403 	return _M_erase(__it);
   1404       }
   1405 
   1406       iterator
   1407       erase(iterator __it)
   1408       {
   1409 	__glibcxx_check_erase(__it);
   1410 	return { _M_erase(__it.base()), this };
   1411       }
   1412 
   1413       iterator
   1414       erase(const_iterator __first, const_iterator __last)
   1415       {
   1416 	__glibcxx_check_erase_range(__first, __last);
   1417 	for (auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
   1418 	  {
   1419 	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
   1420 				  _M_message(__gnu_debug::__msg_valid_range)
   1421 				  ._M_iterator(__first, "first")
   1422 				  ._M_iterator(__last, "last"));
   1423 	    _M_invalidate(__tmp);
   1424 	  }
   1425 
   1426 	size_type __bucket_count = this->bucket_count();
   1427 	auto __next = _Base::erase(__first.base(), __last.base());
   1428 	_M_check_rehashed(__bucket_count);
   1429 	return { __next, this };
   1430       }
   1431 
   1432       using _Base::rehash;
   1433       using _Base::reserve;
   1434 
   1435       _Base&
   1436       _M_base() noexcept { return *this; }
   1437 
   1438       const _Base&
   1439       _M_base() const noexcept { return *this; }
   1440 
   1441     private:
   1442       void
   1443       _M_check_rehashed(size_type __prev_count)
   1444       {
   1445 	if (__prev_count != this->bucket_count())
   1446 	  this->_M_invalidate_all();
   1447       }
   1448 
   1449       void
   1450       _M_invalidate(_Base_const_iterator __victim)
   1451       {
   1452 	this->_M_invalidate_if(
   1453 	  [__victim](_Base_const_iterator __it) { return __it == __victim; });
   1454 	this->_M_invalidate_local_if(
   1455 	  [__victim](_Base_const_local_iterator __it)
   1456 	  { return __it == __victim; });
   1457       }
   1458 
   1459       _Base_iterator
   1460       _M_erase(_Base_const_iterator __victim)
   1461       {
   1462 	_M_invalidate(__victim);
   1463 	size_type __bucket_count = this->bucket_count();
   1464 	_Base_iterator __next = _Base::erase(__victim);
   1465 	_M_check_rehashed(__bucket_count);
   1466 	return __next;
   1467       }
   1468 
   1469 #if __cplusplus > 201402L
   1470       node_type
   1471       _M_extract(_Base_const_iterator __victim)
   1472       {
   1473 	_M_invalidate(__victim);
   1474 	return _Base::extract(__victim);
   1475       }
   1476 #endif
   1477     };
   1478 
   1479 #if __cpp_deduction_guides >= 201606
   1480 
   1481   template<typename _InputIterator,
   1482 	   typename _Hash = hash<__iter_key_t<_InputIterator>>,
   1483 	   typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
   1484 	   typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
   1485 	   typename = _RequireInputIter<_InputIterator>,
   1486 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
   1487 	   typename = _RequireNotAllocator<_Pred>,
   1488 	   typename = _RequireAllocator<_Allocator>>
   1489     unordered_multimap(_InputIterator, _InputIterator,
   1490 		       unordered_multimap<int, int>::size_type = {},
   1491 		       _Hash = _Hash(), _Pred = _Pred(),
   1492 		       _Allocator = _Allocator())
   1493     -> unordered_multimap<__iter_key_t<_InputIterator>,
   1494 			  __iter_val_t<_InputIterator>, _Hash, _Pred,
   1495 			  _Allocator>;
   1496 
   1497   template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
   1498 	   typename _Pred = equal_to<_Key>,
   1499 	   typename _Allocator = allocator<pair<const _Key, _Tp>>,
   1500 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
   1501 	   typename = _RequireNotAllocator<_Pred>,
   1502 	   typename = _RequireAllocator<_Allocator>>
   1503     unordered_multimap(initializer_list<pair<_Key, _Tp>>,
   1504 		       unordered_multimap<int, int>::size_type = {},
   1505 		       _Hash = _Hash(), _Pred = _Pred(),
   1506 		       _Allocator = _Allocator())
   1507     -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>;
   1508 
   1509   template<typename _InputIterator, typename _Allocator,
   1510 	   typename = _RequireInputIter<_InputIterator>,
   1511 	   typename = _RequireAllocator<_Allocator>>
   1512     unordered_multimap(_InputIterator, _InputIterator,
   1513 		       unordered_multimap<int, int>::size_type, _Allocator)
   1514     -> unordered_multimap<__iter_key_t<_InputIterator>,
   1515 			  __iter_val_t<_InputIterator>,
   1516 			  hash<__iter_key_t<_InputIterator>>,
   1517 			  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
   1518 
   1519   template<typename _InputIterator, typename _Allocator,
   1520 	   typename = _RequireInputIter<_InputIterator>,
   1521 	   typename = _RequireAllocator<_Allocator>>
   1522     unordered_multimap(_InputIterator, _InputIterator, _Allocator)
   1523     -> unordered_multimap<__iter_key_t<_InputIterator>,
   1524 			  __iter_val_t<_InputIterator>,
   1525 			  hash<__iter_key_t<_InputIterator>>,
   1526 			  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
   1527 
   1528   template<typename _InputIterator, typename _Hash, typename _Allocator,
   1529 	   typename = _RequireInputIter<_InputIterator>,
   1530 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
   1531 	   typename = _RequireAllocator<_Allocator>>
   1532     unordered_multimap(_InputIterator, _InputIterator,
   1533 		       unordered_multimap<int, int>::size_type, _Hash,
   1534 		       _Allocator)
   1535     -> unordered_multimap<__iter_key_t<_InputIterator>,
   1536 			  __iter_val_t<_InputIterator>, _Hash,
   1537 			  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
   1538 
   1539   template<typename _Key, typename _Tp, typename _Allocator,
   1540 	   typename = _RequireAllocator<_Allocator>>
   1541     unordered_multimap(initializer_list<pair<_Key, _Tp>>,
   1542 		       unordered_multimap<int, int>::size_type,
   1543 		       _Allocator)
   1544     -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
   1545 
   1546   template<typename _Key, typename _Tp, typename _Allocator,
   1547 	   typename = _RequireAllocator<_Allocator>>
   1548     unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
   1549     -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
   1550 
   1551   template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
   1552 	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
   1553 	   typename = _RequireAllocator<_Allocator>>
   1554     unordered_multimap(initializer_list<pair<_Key, _Tp>>,
   1555 		       unordered_multimap<int, int>::size_type,
   1556 		       _Hash, _Allocator)
   1557     -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
   1558 
   1559 #endif
   1560 
   1561   template<typename _Key, typename _Tp, typename _Hash,
   1562 	   typename _Pred, typename _Alloc>
   1563     inline void
   1564     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
   1565 	 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
   1566     noexcept(noexcept(__x.swap(__y)))
   1567     { __x.swap(__y); }
   1568 
   1569   template<typename _Key, typename _Tp, typename _Hash,
   1570 	   typename _Pred, typename _Alloc>
   1571     inline bool
   1572     operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
   1573 	       const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
   1574     { return __x._M_base() == __y._M_base(); }
   1575 
   1576 #if __cpp_impl_three_way_comparison < 201907L
   1577   template<typename _Key, typename _Tp, typename _Hash,
   1578 	   typename _Pred, typename _Alloc>
   1579     inline bool
   1580     operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
   1581 	       const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
   1582     { return !(__x == __y); }
   1583 #endif
   1584 
   1585 } // namespace __debug
   1586 } // namespace std
   1587 
   1588 #endif // C++11
   1589 
   1590 #endif
   1591