1 // Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
 
    3 // Copyright (C) 2003-2014 Free Software Foundation, Inc.
 
    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)
 
   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.
 
   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.
 
   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/>.
 
   25 /** @file debug/unordered_set
 
   26  *  This file is a GNU debug extension to the Standard C++ Library.
 
   29 #ifndef _GLIBCXX_DEBUG_UNORDERED_SET
 
   30 #define _GLIBCXX_DEBUG_UNORDERED_SET 1
 
   32 #if __cplusplus < 201103L
 
   33 # include <bits/c++0x_warning.h>
 
   35 # include <unordered_set>
 
   37 #include <debug/safe_unordered_container.h>
 
   38 #include <debug/safe_iterator.h>
 
   39 #include <debug/safe_local_iterator.h>
 
   41 namespace std _GLIBCXX_VISIBILITY(default)
 
   45   /// Class std::unordered_set with safety/checking/debug instrumentation.
 
   46   template<typename _Value,
 
   47       typename _Hash = std::hash<_Value>,
 
   48       typename _Pred = std::equal_to<_Value>,
 
   49       typename _Alloc = std::allocator<_Value> >
 
   51     : public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
 
   52       public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash,
 
   55       typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash,
 
   57       typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base;
 
   58       typedef typename _Base::const_iterator _Base_const_iterator;
 
   59       typedef typename _Base::iterator _Base_iterator;
 
   60       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
 
   61       typedef typename _Base::local_iterator _Base_local_iterator;
 
   63       typedef __gnu_cxx::__alloc_traits<typename
 
   64                    _Base::allocator_type> _Alloc_traits;
 
   66       typedef typename _Base::size_type       size_type;
 
   67       typedef typename _Base::hasher          hasher;
 
   68       typedef typename _Base::key_equal       key_equal;
 
   69       typedef typename _Base::allocator_type  allocator_type;
 
   71       typedef typename _Base::key_type        key_type;
 
   72       typedef typename _Base::value_type      value_type;
 
   74       typedef __gnu_debug::_Safe_iterator<_Base_iterator,
 
   75                      unordered_set> iterator;
 
   76       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
 
   77                      unordered_set> const_iterator;
 
   78       typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
 
   79                      unordered_set> local_iterator;
 
   80       typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
 
   81                      unordered_set> const_local_iterator;
 
   84       unordered_set(size_type __n = 10,
 
   85            const hasher& __hf = hasher(),
 
   86            const key_equal& __eql = key_equal(),
 
   87            const allocator_type& __a = allocator_type())
 
   88       : _Base(__n, __hf, __eql, __a) { }
 
   90       template<typename _InputIterator>
 
   91         unordered_set(_InputIterator __first, _InputIterator __last, 
 
   93              const hasher& __hf = hasher(), 
 
   94              const key_equal& __eql = key_equal(), 
 
   95              const allocator_type& __a = allocator_type())
 
   96    : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 
   98        __gnu_debug::__base(__last), __n,
 
  101       unordered_set(const unordered_set&) = default;
 
  103       unordered_set(const _Base& __x)
 
  106       unordered_set(unordered_set&&) = default;
 
  109       unordered_set(const allocator_type& __a)
 
  113       unordered_set(const unordered_set& __uset,
 
  114            const allocator_type& __a)
 
  115    : _Base(__uset._M_base(), __a)
 
  118       unordered_set(unordered_set&& __uset,
 
  119            const allocator_type& __a)
 
  120    : _Base(std::move(__uset._M_base()), __a)
 
  123       unordered_set(initializer_list<value_type> __l,
 
  125            const hasher& __hf = hasher(),
 
  126            const key_equal& __eql = key_equal(),
 
  127            const allocator_type& __a = allocator_type())
 
  128       : _Base(__l, __n, __hf, __eql, __a) { }
 
  130       ~unordered_set() noexcept { }
 
  133       operator=(const unordered_set& __x)
 
  135    _M_base() = __x._M_base();
 
  136    this->_M_invalidate_all();
 
  141       operator=(unordered_set&& __x)
 
  142       noexcept(_Alloc_traits::_S_nothrow_move())
 
  144    __glibcxx_check_self_move_assign(__x);
 
  145    bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
 
  146        || __x.get_allocator() == this->get_allocator();
 
  147    _M_base() = std::move(__x._M_base());
 
  151      this->_M_invalidate_all();
 
  152    __x._M_invalidate_all();
 
  157       operator=(initializer_list<value_type> __l)
 
  160    this->_M_invalidate_all();
 
  165       swap(unordered_set& __x)
 
  166       noexcept(_Alloc_traits::_S_nothrow_swap())
 
  168    if (!_Alloc_traits::_S_propagate_on_swap())
 
  169      __glibcxx_check_equal_allocs(__x);
 
  171    _Safe_base::_M_swap(__x);
 
  178    this->_M_invalidate_all();
 
  183       { return iterator(_Base::begin(), this); }
 
  186       begin() const noexcept
 
  187       { return const_iterator(_Base::begin(), this); }
 
  191       { return iterator(_Base::end(), this); }
 
  195       { return const_iterator(_Base::end(), this); }
 
  198       cbegin() const noexcept
 
  199       { return const_iterator(_Base::begin(), this); }
 
  202       cend() const noexcept
 
  203       { return const_iterator(_Base::end(), this); }
 
  209    __glibcxx_check_bucket_index(__b);
 
  210    return local_iterator(_Base::begin(__b), this);
 
  216    __glibcxx_check_bucket_index(__b);
 
  217    return local_iterator(_Base::end(__b), this);
 
  221       begin(size_type __b) const
 
  223    __glibcxx_check_bucket_index(__b);
 
  224    return const_local_iterator(_Base::begin(__b), this);
 
  228       end(size_type __b) const
 
  230    __glibcxx_check_bucket_index(__b);
 
  231    return const_local_iterator(_Base::end(__b), this);
 
  235       cbegin(size_type __b) const
 
  237    __glibcxx_check_bucket_index(__b);
 
  238    return const_local_iterator(_Base::cbegin(__b), this);
 
  242       cend(size_type __b) const
 
  244    __glibcxx_check_bucket_index(__b);
 
  245    return const_local_iterator(_Base::cend(__b), this);
 
  249       bucket_size(size_type __b) const
 
  251    __glibcxx_check_bucket_index(__b);
 
  252    return _Base::bucket_size(__b);
 
  256       max_load_factor() const noexcept
 
  257       { return _Base::max_load_factor(); }
 
  260       max_load_factor(float __f)
 
  262    __glibcxx_check_max_load_factor(__f);
 
  263    _Base::max_load_factor(__f);
 
  266       template<typename... _Args>
 
  267    std::pair<iterator, bool>
 
  268    emplace(_Args&&... __args)
 
  270      size_type __bucket_count = this->bucket_count();
 
  271      std::pair<_Base_iterator, bool> __res
 
  272        = _Base::emplace(std::forward<_Args>(__args)...);
 
  273      _M_check_rehashed(__bucket_count);
 
  274      return std::make_pair(iterator(__res.first, this), __res.second);
 
  277       template<typename... _Args>
 
  279    emplace_hint(const_iterator __hint, _Args&&... __args)
 
  281      __glibcxx_check_insert(__hint);
 
  282      size_type __bucket_count = this->bucket_count();
 
  283      _Base_iterator __it = _Base::emplace_hint(__hint.base(),
 
  284                    std::forward<_Args>(__args)...);
 
  285      _M_check_rehashed(__bucket_count);
 
  286      return iterator(__it, this);
 
  289       std::pair<iterator, bool>
 
  290       insert(const value_type& __obj)
 
  292    size_type __bucket_count = this->bucket_count();
 
  293    typedef std::pair<_Base_iterator, bool> __pair_type;
 
  294      __pair_type __res = _Base::insert(__obj);
 
  295    _M_check_rehashed(__bucket_count);
 
  296    return std::make_pair(iterator(__res.first, this), __res.second);
 
  300       insert(const_iterator __hint, const value_type& __obj)
 
  302    __glibcxx_check_insert(__hint);
 
  303    size_type __bucket_count = this->bucket_count();
 
  304    _Base_iterator __it = _Base::insert(__hint.base(), __obj);
 
  305    _M_check_rehashed(__bucket_count);
 
  306    return iterator(__it, this);
 
  309       std::pair<iterator, bool>
 
  310       insert(value_type&& __obj)
 
  312    size_type __bucket_count = this->bucket_count();
 
  313    typedef std::pair<typename _Base::iterator, bool> __pair_type;
 
  314      __pair_type __res = _Base::insert(std::move(__obj));
 
  315    _M_check_rehashed(__bucket_count);
 
  316    return std::make_pair(iterator(__res.first, this), __res.second);
 
  320       insert(const_iterator __hint, value_type&& __obj)
 
  322    __glibcxx_check_insert(__hint);
 
  323    size_type __bucket_count = this->bucket_count();
 
  324    _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
 
  325    _M_check_rehashed(__bucket_count);
 
  326    return iterator(__it, this);
 
  330       insert(std::initializer_list<value_type> __l)
 
  332    size_type __bucket_count = this->bucket_count();
 
  334    _M_check_rehashed(__bucket_count);
 
  337       template<typename _InputIterator>
 
  339    insert(_InputIterator __first, _InputIterator __last)
 
  341      __glibcxx_check_valid_range(__first, __last);
 
  342      size_type __bucket_count = this->bucket_count();
 
  343      _Base::insert(__gnu_debug::__base(__first),
 
  344            __gnu_debug::__base(__last));
 
  345      _M_check_rehashed(__bucket_count);
 
  349       find(const key_type& __key)
 
  350       { return iterator(_Base::find(__key), this); }
 
  353       find(const key_type& __key) const
 
  354       { return const_iterator(_Base::find(__key), this); }
 
  356       std::pair<iterator, iterator>
 
  357       equal_range(const key_type& __key)
 
  359    typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
 
  360    __pair_type __res = _Base::equal_range(__key);
 
  361    return std::make_pair(iterator(__res.first, this),
 
  362                  iterator(__res.second, this));
 
  365       std::pair<const_iterator, const_iterator>
 
  366       equal_range(const key_type& __key) const
 
  368    std::pair<_Base_const_iterator, _Base_const_iterator>
 
  369      __res = _Base::equal_range(__key);
 
  370    return std::make_pair(const_iterator(__res.first, this),
 
  371                  const_iterator(__res.second, this));
 
  375       erase(const key_type& __key)
 
  378    _Base_iterator __victim(_Base::find(__key));
 
  379    if (__victim != _Base::end())
 
  381        this->_M_invalidate_if(
 
  382                [__victim](_Base_const_iterator __it)
 
  383                { return __it == __victim; });
 
  384        this->_M_invalidate_local_if(
 
  385                [__victim](_Base_const_local_iterator __it)
 
  386                { return __it._M_curr() == __victim._M_cur; });
 
  387        size_type __bucket_count = this->bucket_count();
 
  388        _Base::erase(__victim);
 
  389        _M_check_rehashed(__bucket_count);
 
  396       erase(const_iterator __it)
 
  398    __glibcxx_check_erase(__it);
 
  399    _Base_const_iterator __victim = __it.base();
 
  400    this->_M_invalidate_if(
 
  401            [__victim](_Base_const_iterator __it)
 
  402            { return __it == __victim; });
 
  403    this->_M_invalidate_local_if(
 
  404            [__victim](_Base_const_local_iterator __it)
 
  405            { return __it._M_curr() == __victim._M_cur; });
 
  406    size_type __bucket_count = this->bucket_count();
 
  407    _Base_iterator __next = _Base::erase(__it.base());
 
  408    _M_check_rehashed(__bucket_count);
 
  409    return iterator(__next, this);
 
  414       { return erase(const_iterator(__it)); }
 
  417       erase(const_iterator __first, const_iterator __last)
 
  419    __glibcxx_check_erase_range(__first, __last);
 
  420    for (_Base_const_iterator __tmp = __first.base();
 
  421         __tmp != __last.base(); ++__tmp)
 
  423        _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
 
  424                  _M_message(__gnu_debug::__msg_valid_range)
 
  425                  ._M_iterator(__first, "first")
 
  426                  ._M_iterator(__last, "last"));
 
  427        this->_M_invalidate_if(
 
  428                [__tmp](_Base_const_iterator __it)
 
  429                { return __it == __tmp; });
 
  430        this->_M_invalidate_local_if(
 
  431                [__tmp](_Base_const_local_iterator __it)
 
  432                { return __it._M_curr() == __tmp._M_cur; });
 
  434    size_type __bucket_count = this->bucket_count();
 
  435    _Base_iterator __next = _Base::erase(__first.base(),
 
  437    _M_check_rehashed(__bucket_count);
 
  438    return iterator(__next, this);
 
  442       _M_base() noexcept       { return *this; }
 
  445       _M_base() const noexcept { return *this; }
 
  449       _M_invalidate_locals()
 
  451    _Base_local_iterator __local_end = _Base::end(0);
 
  452    this->_M_invalidate_local_if(
 
  453            [__local_end](_Base_const_local_iterator __it)
 
  454            { return __it != __local_end; });
 
  460    _Base_iterator __end = _Base::end();
 
  461    this->_M_invalidate_if(
 
  462            [__end](_Base_const_iterator __it)
 
  463            { return __it != __end; });
 
  464    _M_invalidate_locals();
 
  468       _M_check_rehashed(size_type __prev_count)
 
  470    if (__prev_count != this->bucket_count())
 
  471      _M_invalidate_locals();
 
  475   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  477     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
 
  478     unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
 
  481   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  483     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
 
  484           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
 
  485     { return __x._M_base() == __y._M_base(); }
 
  487   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  489     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
 
  490           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
 
  491     { return !(__x == __y); }
 
  494   /// Class std::unordered_multiset with safety/checking/debug instrumentation.
 
  495   template<typename _Value,
 
  496       typename _Hash = std::hash<_Value>,
 
  497       typename _Pred = std::equal_to<_Value>,
 
  498       typename _Alloc = std::allocator<_Value> >
 
  499     class unordered_multiset
 
  500     : public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
 
  501       public __gnu_debug::_Safe_unordered_container<
 
  502        unordered_multiset<_Value, _Hash, _Pred, _Alloc> >
 
  504       typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash,
 
  505                         _Pred, _Alloc> _Base;
 
  506       typedef __gnu_debug::_Safe_unordered_container<unordered_multiset>
 
  508       typedef typename _Base::const_iterator _Base_const_iterator;
 
  509       typedef typename _Base::iterator _Base_iterator;
 
  510       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
 
  511       typedef typename _Base::local_iterator _Base_local_iterator;
 
  513       typedef __gnu_cxx::__alloc_traits<typename
 
  514                    _Base::allocator_type> _Alloc_traits;
 
  517       typedef typename _Base::size_type       size_type;
 
  518       typedef typename _Base::hasher          hasher;
 
  519       typedef typename _Base::key_equal       key_equal;
 
  520       typedef typename _Base::allocator_type  allocator_type;
 
  522       typedef typename _Base::key_type        key_type;
 
  523       typedef typename _Base::value_type      value_type;
 
  525       typedef __gnu_debug::_Safe_iterator<_Base_iterator,
 
  526                      unordered_multiset> iterator;
 
  527       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
 
  528                      unordered_multiset> const_iterator;
 
  529       typedef __gnu_debug::_Safe_local_iterator<
 
  530    _Base_local_iterator, unordered_multiset> local_iterator;
 
  531       typedef __gnu_debug::_Safe_local_iterator<
 
  532    _Base_const_local_iterator, unordered_multiset> const_local_iterator;
 
  535       unordered_multiset(size_type __n = 10,
 
  536             const hasher& __hf = hasher(),
 
  537             const key_equal& __eql = key_equal(),
 
  538             const allocator_type& __a = allocator_type())
 
  539       : _Base(__n, __hf, __eql, __a) { }
 
  541       template<typename _InputIterator>
 
  542         unordered_multiset(_InputIterator __first, _InputIterator __last, 
 
  544               const hasher& __hf = hasher(), 
 
  545               const key_equal& __eql = key_equal(), 
 
  546               const allocator_type& __a = allocator_type())
 
  547    : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 
  549        __gnu_debug::__base(__last), __n,
 
  550        __hf, __eql, __a) { }
 
  552       unordered_multiset(const unordered_multiset&) = default;
 
  554       unordered_multiset(const _Base& __x) 
 
  557       unordered_multiset(unordered_multiset&&) = default;
 
  560       unordered_multiset(const allocator_type& __a)
 
  564       unordered_multiset(const unordered_multiset& __uset,
 
  565             const allocator_type& __a)
 
  566    : _Base(__uset._M_base(), __a)
 
  569       unordered_multiset(unordered_multiset&& __uset,
 
  570             const allocator_type& __a)
 
  571    : _Base(std::move(__uset._M_base()), __a)
 
  574       unordered_multiset(initializer_list<value_type> __l,
 
  576             const hasher& __hf = hasher(),
 
  577             const key_equal& __eql = key_equal(),
 
  578             const allocator_type& __a = allocator_type())
 
  579       : _Base(__l, __n, __hf, __eql, __a) { }
 
  581       ~unordered_multiset() noexcept { }
 
  584       operator=(const unordered_multiset& __x)
 
  586    _M_base() = __x._M_base();
 
  587    this->_M_invalidate_all();
 
  592       operator=(unordered_multiset&& __x)
 
  593       noexcept(_Alloc_traits::_S_nothrow_move())
 
  595    __glibcxx_check_self_move_assign(__x);
 
  596    bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
 
  597        || __x.get_allocator() == this->get_allocator();
 
  598    _M_base() = std::move(__x._M_base());
 
  602      this->_M_invalidate_all();
 
  603    __x._M_invalidate_all();
 
  608       operator=(initializer_list<value_type> __l)
 
  611    this->_M_invalidate_all();
 
  616       swap(unordered_multiset& __x)
 
  617       noexcept(_Alloc_traits::_S_nothrow_swap())
 
  619    if (!_Alloc_traits::_S_propagate_on_swap())
 
  620      __glibcxx_check_equal_allocs(__x);
 
  622    _Safe_base::_M_swap(__x);
 
  629    this->_M_invalidate_all();
 
  634       { return iterator(_Base::begin(), this); }
 
  637       begin() const noexcept
 
  638       { return const_iterator(_Base::begin(), this); }
 
  642       { return iterator(_Base::end(), this); }
 
  646       { return const_iterator(_Base::end(), this); }
 
  649       cbegin() const noexcept
 
  650       { return const_iterator(_Base::begin(), this); }
 
  653       cend() const noexcept
 
  654       { return const_iterator(_Base::end(), this); }
 
  660    __glibcxx_check_bucket_index(__b);
 
  661    return local_iterator(_Base::begin(__b), this);
 
  667    __glibcxx_check_bucket_index(__b);
 
  668    return local_iterator(_Base::end(__b), this);
 
  672       begin(size_type __b) const
 
  674    __glibcxx_check_bucket_index(__b);
 
  675    return const_local_iterator(_Base::begin(__b), this);
 
  679       end(size_type __b) const
 
  681    __glibcxx_check_bucket_index(__b);
 
  682    return const_local_iterator(_Base::end(__b), this);
 
  686       cbegin(size_type __b) const
 
  688    __glibcxx_check_bucket_index(__b);
 
  689    return const_local_iterator(_Base::cbegin(__b), this);
 
  693       cend(size_type __b) const
 
  695    __glibcxx_check_bucket_index(__b);
 
  696    return const_local_iterator(_Base::cend(__b), this);
 
  700       bucket_size(size_type __b) const
 
  702    __glibcxx_check_bucket_index(__b);
 
  703    return _Base::bucket_size(__b);
 
  707       max_load_factor() const noexcept
 
  708       { return _Base::max_load_factor(); }
 
  711       max_load_factor(float __f)
 
  713    __glibcxx_check_max_load_factor(__f);
 
  714    _Base::max_load_factor(__f);
 
  717       template<typename... _Args>
 
  719    emplace(_Args&&... __args)
 
  721      size_type __bucket_count = this->bucket_count();
 
  723        = _Base::emplace(std::forward<_Args>(__args)...);
 
  724      _M_check_rehashed(__bucket_count);
 
  725      return iterator(__it, this);
 
  728       template<typename... _Args>
 
  730    emplace_hint(const_iterator __hint, _Args&&... __args)
 
  732      __glibcxx_check_insert(__hint);
 
  733      size_type __bucket_count = this->bucket_count();
 
  734      _Base_iterator __it = _Base::emplace_hint(__hint.base(),
 
  735                    std::forward<_Args>(__args)...);
 
  736      _M_check_rehashed(__bucket_count);
 
  737      return iterator(__it, this);
 
  741       insert(const value_type& __obj)
 
  743    size_type __bucket_count = this->bucket_count();
 
  744    _Base_iterator __it = _Base::insert(__obj);
 
  745    _M_check_rehashed(__bucket_count);
 
  746    return iterator(__it, this);
 
  750       insert(const_iterator __hint, const value_type& __obj)
 
  752    __glibcxx_check_insert(__hint);
 
  753    size_type __bucket_count = this->bucket_count();
 
  754    _Base_iterator __it = _Base::insert(__hint.base(), __obj); 
 
  755    _M_check_rehashed(__bucket_count);
 
  756    return iterator(__it, this);
 
  760       insert(value_type&& __obj)
 
  762    size_type __bucket_count = this->bucket_count();
 
  763    _Base_iterator __it = _Base::insert(std::move(__obj)); 
 
  764    _M_check_rehashed(__bucket_count);
 
  765    return iterator(__it, this);
 
  769       insert(const_iterator __hint, value_type&& __obj)
 
  771    __glibcxx_check_insert(__hint);
 
  772    size_type __bucket_count = this->bucket_count();
 
  773    _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj)); 
 
  774    _M_check_rehashed(__bucket_count);
 
  775    return iterator(__it, this);
 
  779       insert(std::initializer_list<value_type> __l)
 
  781    size_type __bucket_count = this->bucket_count();
 
  783    _M_check_rehashed(__bucket_count);
 
  786       template<typename _InputIterator>
 
  788    insert(_InputIterator __first, _InputIterator __last)
 
  790      __glibcxx_check_valid_range(__first, __last);
 
  791      size_type __bucket_count = this->bucket_count();
 
  792      _Base::insert(__gnu_debug::__base(__first),
 
  793            __gnu_debug::__base(__last));
 
  794      _M_check_rehashed(__bucket_count);
 
  798       find(const key_type& __key)
 
  799       { return iterator(_Base::find(__key), this); }
 
  802       find(const key_type& __key) const
 
  803       { return const_iterator(_Base::find(__key), this); }
 
  805       std::pair<iterator, iterator>
 
  806       equal_range(const key_type& __key)
 
  808    typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
 
  809    __pair_type __res = _Base::equal_range(__key);
 
  810    return std::make_pair(iterator(__res.first, this),
 
  811                  iterator(__res.second, this));
 
  814       std::pair<const_iterator, const_iterator>
 
  815       equal_range(const key_type& __key) const
 
  817    std::pair<_Base_const_iterator, _Base_const_iterator>
 
  818      __res = _Base::equal_range(__key);
 
  819    return std::make_pair(const_iterator(__res.first, this),
 
  820                  const_iterator(__res.second, this));
 
  824       erase(const key_type& __key)
 
  827    std::pair<_Base_iterator, _Base_iterator> __pair =
 
  828      _Base::equal_range(__key);
 
  829    for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
 
  831        this->_M_invalidate_if([__victim](_Base_const_iterator __it)
 
  832                { return __it == __victim; });
 
  833        this->_M_invalidate_local_if(
 
  834                [__victim](_Base_const_local_iterator __it)
 
  835                { return __it._M_curr() == __victim._M_cur; });
 
  836        _Base::erase(__victim++);
 
  843       erase(const_iterator __it)
 
  845    __glibcxx_check_erase(__it);
 
  846    _Base_const_iterator __victim = __it.base();
 
  847    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
 
  848            { return __it == __victim; });
 
  849    this->_M_invalidate_local_if(
 
  850            [__victim](_Base_const_local_iterator __it)
 
  851            { return __it._M_curr() == __victim._M_cur; });
 
  852    return iterator(_Base::erase(__it.base()), this);
 
  857       { return erase(const_iterator(__it)); }
 
  860       erase(const_iterator __first, const_iterator __last)
 
  862    __glibcxx_check_erase_range(__first, __last);
 
  863    for (_Base_const_iterator __tmp = __first.base();
 
  864         __tmp != __last.base(); ++__tmp)
 
  866        _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
 
  867                  _M_message(__gnu_debug::__msg_valid_range)
 
  868                  ._M_iterator(__first, "first")
 
  869                  ._M_iterator(__last, "last"));
 
  870        this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
 
  871                { return __it == __tmp; });
 
  872        this->_M_invalidate_local_if(
 
  873                [__tmp](_Base_const_local_iterator __it)
 
  874                { return __it._M_curr() == __tmp._M_cur; });
 
  876    return iterator(_Base::erase(__first.base(),
 
  877                     __last.base()), this);
 
  881       _M_base() noexcept       { return *this; }
 
  884       _M_base() const noexcept { return *this; }
 
  888       _M_invalidate_locals()
 
  890    _Base_local_iterator __local_end = _Base::end(0);
 
  891    this->_M_invalidate_local_if(
 
  892            [__local_end](_Base_const_local_iterator __it)
 
  893            { return __it != __local_end; });
 
  899    _Base_iterator __end = _Base::end();
 
  900    this->_M_invalidate_if([__end](_Base_const_iterator __it)
 
  901            { return __it != __end; });
 
  902    _M_invalidate_locals();
 
  906       _M_check_rehashed(size_type __prev_count)
 
  908    if (__prev_count != this->bucket_count())
 
  909      _M_invalidate_locals();
 
  913   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  915     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 
  916     unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 
  919   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  921     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 
  922           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 
  923     { return __x._M_base() == __y._M_base(); }
 
  925   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  927     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 
  928           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 
  929     { return !(__x == __y); }
 
  931 } // namespace __debug