// Debugging unordered_set/unordered_multiset implementation -*- C++ -*-

// Copyright (C) 2003-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file debug/unordered_set
 *  This file is a GNU debug extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_DEBUG_UNORDERED_SET
#define _GLIBCXX_DEBUG_UNORDERED_SET 1

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
# include <unordered_set>

#include <debug/safe_unordered_container.h>
#include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
  /// Class std::unordered_set with safety/checking/debug instrumentation.
  template<typename _Value,
	   typename _Hash = std::hash<_Value>,
	   typename _Pred = std::equal_to<_Value>,
	   typename _Alloc = std::allocator<_Value> >
    class unordered_set
    : public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
      public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash,
						       _Pred, _Alloc> >
    {
      typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash,
					    _Pred, _Alloc> _Base;
      typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base;
      typedef typename _Base::const_iterator _Base_const_iterator;
      typedef typename _Base::iterator _Base_iterator;
      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
      typedef typename _Base::local_iterator _Base_local_iterator;

    public:
      typedef typename _Base::size_type       size_type;
      typedef typename _Base::hasher          hasher;
      typedef typename _Base::key_equal       key_equal;
      typedef typename _Base::allocator_type  allocator_type;

      typedef typename _Base::key_type        key_type;
      typedef typename _Base::value_type      value_type;

      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
					  unordered_set> iterator;
      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
					  unordered_set> const_iterator;
      typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
					  unordered_set> local_iterator;
      typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
					  unordered_set> const_local_iterator;

      explicit
      unordered_set(size_type __n = 10,
		    const hasher& __hf = hasher(),
		    const key_equal& __eql = key_equal(),
		    const allocator_type& __a = allocator_type())
      : _Base(__n, __hf, __eql, __a) { }

      template<typename _InputIterator>
        unordered_set(_InputIterator __first, _InputIterator __last, 
		      size_type __n = 0,
		      const hasher& __hf = hasher(), 
		      const key_equal& __eql = key_equal(), 
		      const allocator_type& __a = allocator_type())
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
								     __last)),
		__gnu_debug::__base(__last), __n,
		__hf, __eql, __a) { }

      unordered_set(const unordered_set& __x) = default;

      unordered_set(const _Base& __x) 
      : _Base(__x) { }

      unordered_set(unordered_set&& __x) = default;

      unordered_set(initializer_list<value_type> __l,
		    size_type __n = 0,
		    const hasher& __hf = hasher(),
		    const key_equal& __eql = key_equal(),
		    const allocator_type& __a = allocator_type())
      : _Base(__l, __n, __hf, __eql, __a) { }

      ~unordered_set() noexcept { }

      unordered_set&
      operator=(const unordered_set& __x)
      {
	*static_cast<_Base*>(this) = __x;
	this->_M_invalidate_all();
	return *this;
      }

      unordered_set&
      operator=(unordered_set&& __x)
      {
	// NB: DR 1204.
	// NB: DR 675.
	__glibcxx_check_self_move_assign(__x);
	clear();
	swap(__x);
	return *this;
      }

      unordered_set&
      operator=(initializer_list<value_type> __l)
      {
	this->clear();
	this->insert(__l);
	return *this;
      }

      void
      swap(unordered_set& __x)
      {
	_Base::swap(__x);
	_Safe_base::_M_swap(__x);
      }

      void
      clear() noexcept
      {
	_Base::clear();
	this->_M_invalidate_all();
      }

      iterator 
      begin() noexcept
      { return iterator(_Base::begin(), this); }

      const_iterator
      begin() const noexcept
      { return const_iterator(_Base::begin(), this); }

      iterator
      end() noexcept
      { return iterator(_Base::end(), this); }

      const_iterator
      end() const noexcept
      { return const_iterator(_Base::end(), this); }

      const_iterator
      cbegin() const noexcept
      { return const_iterator(_Base::begin(), this); }

      const_iterator
      cend() const noexcept
      { return const_iterator(_Base::end(), this); }

      // local versions
      local_iterator
      begin(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::begin(__b), __b, this);
      }

      local_iterator
      end(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::end(__b), __b, this);
      }

      const_local_iterator
      begin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::begin(__b), __b, this);
      }

      const_local_iterator
      end(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::end(__b), __b, this);
      }

      const_local_iterator
      cbegin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cbegin(__b), __b, this);
      }

      const_local_iterator
      cend(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cend(__b), __b, this);
      }

      size_type
      bucket_size(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return _Base::bucket_size(__b);
      }

      float
      max_load_factor() const noexcept
      { return _Base::max_load_factor(); }

      void
      max_load_factor(float __f)
      {
	__glibcxx_check_max_load_factor(__f);
	_Base::max_load_factor(__f);
      }

      template<typename... _Args>
	std::pair<iterator, bool>
	emplace(_Args&&... __args)
	{
	  size_type __bucket_count = this->bucket_count();
	  std::pair<_Base_iterator, bool> __res
	    = _Base::emplace(std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return std::make_pair(iterator(__res.first, this), __res.second);
	}

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __hint, _Args&&... __args)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
					std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      std::pair<iterator, bool>
      insert(const value_type& __obj)
      {
	size_type __bucket_count = this->bucket_count();
	typedef std::pair<_Base_iterator, bool> __pair_type;
	  __pair_type __res = _Base::insert(__obj);
	_M_check_rehashed(__bucket_count);
	return std::make_pair(iterator(__res.first, this), __res.second);
      }

      iterator
      insert(const_iterator __hint, const value_type& __obj)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      std::pair<iterator, bool>
      insert(value_type&& __obj)
      {
	size_type __bucket_count = this->bucket_count();
	typedef std::pair<typename _Base::iterator, bool> __pair_type;
	  __pair_type __res = _Base::insert(std::move(__obj));
	_M_check_rehashed(__bucket_count);
	return std::make_pair(iterator(__res.first, this), __res.second);
      }

      iterator
      insert(const_iterator __hint, value_type&& __obj)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      void
      insert(std::initializer_list<value_type> __l)
      {
	size_type __bucket_count = this->bucket_count();
	_Base::insert(__l);
	_M_check_rehashed(__bucket_count);
      }

      template<typename _InputIterator>
	void
	insert(_InputIterator __first, _InputIterator __last)
	{
	  __glibcxx_check_valid_range(__first, __last);
	  size_type __bucket_count = this->bucket_count();
	  _Base::insert(__gnu_debug::__base(__first),
			__gnu_debug::__base(__last));
	  _M_check_rehashed(__bucket_count);
	}

      iterator
      find(const key_type& __key)
      { return iterator(_Base::find(__key), this); }

      const_iterator
      find(const key_type& __key) const
      { return const_iterator(_Base::find(__key), this); }

      std::pair<iterator, iterator>
      equal_range(const key_type& __key)
      {
	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
	__pair_type __res = _Base::equal_range(__key);
	return std::make_pair(iterator(__res.first, this),
			      iterator(__res.second, this));
      }

      std::pair<const_iterator, const_iterator>
      equal_range(const key_type& __key) const
      {
	std::pair<_Base_const_iterator, _Base_const_iterator>
	  __res = _Base::equal_range(__key);
	return std::make_pair(const_iterator(__res.first, this),
			      const_iterator(__res.second, this));
      }

      size_type
      erase(const key_type& __key)
      {
	size_type __ret(0);
	_Base_iterator __victim(_Base::find(__key));
	if (__victim != _Base::end())
	  {
	    this->_M_invalidate_if(
			    [__victim](_Base_const_iterator __it)
			    { return __it == __victim; });
	    this->_M_invalidate_local_if(
			    [__victim](_Base_const_local_iterator __it)
			    { return __it._M_cur == __victim._M_cur; });
	    size_type __bucket_count = this->bucket_count();
	    _Base::erase(__victim);
	    _M_check_rehashed(__bucket_count);
	    __ret = 1;
	  }
	return __ret;
      }

      iterator
      erase(const_iterator __it)
      {
	__glibcxx_check_erase(__it);
	_Base_const_iterator __victim = __it.base();
	this->_M_invalidate_if(
			[__victim](_Base_const_iterator __it)
			{ return __it == __victim; });
	this->_M_invalidate_local_if(
			[__victim](_Base_const_local_iterator __it)
			{ return __it._M_cur == __victim._M_cur; });
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __next = _Base::erase(__it.base());
	_M_check_rehashed(__bucket_count);
	return iterator(__next, this);
      }

      iterator
      erase(iterator __it)
      { return erase(const_iterator(__it)); }

      iterator
      erase(const_iterator __first, const_iterator __last)
      {
	__glibcxx_check_erase_range(__first, __last);
	for (_Base_const_iterator __tmp = __first.base();
	     __tmp != __last.base(); ++__tmp)
	  {
	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
				  _M_message(__gnu_debug::__msg_valid_range)
				  ._M_iterator(__first, "first")
				  ._M_iterator(__last, "last"));
	    this->_M_invalidate_if(
			    [__tmp](_Base_const_iterator __it)
			    { return __it == __tmp; });
	    this->_M_invalidate_local_if(
			    [__tmp](_Base_const_local_iterator __it)
			    { return __it._M_cur == __tmp._M_cur; });
	  }
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __next = _Base::erase(__first.base(),
					     __last.base());
	_M_check_rehashed(__bucket_count);
	return iterator(__next, this);
      }

      _Base&
      _M_base() noexcept       { return *this; }

      const _Base&
      _M_base() const noexcept { return *this; }

    private:
      void
      _M_invalidate_locals()
      {
	_Base_local_iterator __local_end = _Base::end(0);
	this->_M_invalidate_local_if(
			[__local_end](_Base_const_local_iterator __it)
			{ return __it != __local_end; });
      }

      void
      _M_invalidate_all()
      {
	_Base_iterator __end = _Base::end();
	this->_M_invalidate_if(
			[__end](_Base_const_iterator __it)
			{ return __it != __end; });
	_M_invalidate_locals();
      }

      void
      _M_check_rehashed(size_type __prev_count)
      {
	if (__prev_count != this->bucket_count())
	  _M_invalidate_locals();
      }
    };

  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    inline void
    swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
	 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
    { __x.swap(__y); }

  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    inline bool
    operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
    { return __x._M_base() == __y._M_base(); }

  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    inline bool
    operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
    { return !(__x == __y); }


  /// Class std::unordered_multiset with safety/checking/debug instrumentation.
  template<typename _Value,
	   typename _Hash = std::hash<_Value>,
	   typename _Pred = std::equal_to<_Value>,
	   typename _Alloc = std::allocator<_Value> >
    class unordered_multiset
    : public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
      public __gnu_debug::_Safe_unordered_container<
		unordered_multiset<_Value, _Hash, _Pred, _Alloc> >
    {
      typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash,
						 _Pred, _Alloc> _Base;
      typedef __gnu_debug::_Safe_unordered_container<unordered_multiset>
		_Safe_base;
      typedef typename _Base::const_iterator _Base_const_iterator;
      typedef typename _Base::iterator _Base_iterator;
      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
      typedef typename _Base::local_iterator _Base_local_iterator;

    public:
      typedef typename _Base::size_type       size_type;
      typedef typename _Base::hasher          hasher;
      typedef typename _Base::key_equal       key_equal;
      typedef typename _Base::allocator_type  allocator_type;

      typedef typename _Base::key_type        key_type;
      typedef typename _Base::value_type      value_type;

      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
					  unordered_multiset> iterator;
      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
					  unordered_multiset> const_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_local_iterator, unordered_multiset> local_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_const_local_iterator, unordered_multiset> const_local_iterator;

      explicit
      unordered_multiset(size_type __n = 10,
			 const hasher& __hf = hasher(),
			 const key_equal& __eql = key_equal(),
			 const allocator_type& __a = allocator_type())
      : _Base(__n, __hf, __eql, __a) { }

      template<typename _InputIterator>
        unordered_multiset(_InputIterator __first, _InputIterator __last, 
			   size_type __n = 0,
			   const hasher& __hf = hasher(), 
			   const key_equal& __eql = key_equal(), 
			   const allocator_type& __a = allocator_type())
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
								     __last)),
		__gnu_debug::__base(__last), __n,
		__hf, __eql, __a) { }

      unordered_multiset(const unordered_multiset& __x) = default;

      unordered_multiset(const _Base& __x) 
      : _Base(__x) { }

      unordered_multiset(unordered_multiset&& __x) = default;

      unordered_multiset(initializer_list<value_type> __l,
			 size_type __n = 0,
			 const hasher& __hf = hasher(),
			 const key_equal& __eql = key_equal(),
			 const allocator_type& __a = allocator_type())
      : _Base(__l, __n, __hf, __eql, __a) { }

      ~unordered_multiset() noexcept { }

      unordered_multiset&
      operator=(const unordered_multiset& __x)
      {
	*static_cast<_Base*>(this) = __x;
	this->_M_invalidate_all();
	return *this;
      }

      unordered_multiset&
      operator=(unordered_multiset&& __x)
      {
	// NB: DR 1204.
        // NB: DR 675.
	__glibcxx_check_self_move_assign(__x);
	clear();
	swap(__x);
	return *this;
      }

      unordered_multiset&
      operator=(initializer_list<value_type> __l)
      {
	this->clear();
	this->insert(__l);
	return *this;
      }

      void
      swap(unordered_multiset& __x)
      {
	_Base::swap(__x);
	_Safe_base::_M_swap(__x);
      }

      void
      clear() noexcept
      {
	_Base::clear();
	this->_M_invalidate_all();
      }

      iterator
      begin() noexcept
      { return iterator(_Base::begin(), this); }

      const_iterator
      begin() const noexcept
      { return const_iterator(_Base::begin(), this); }

      iterator
      end() noexcept
      { return iterator(_Base::end(), this); }

      const_iterator
      end() const noexcept
      { return const_iterator(_Base::end(), this); }

      const_iterator
      cbegin() const noexcept
      { return const_iterator(_Base::begin(), this); }

      const_iterator
      cend() const noexcept
      { return const_iterator(_Base::end(), this); }

      // local versions
      local_iterator
      begin(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::begin(__b), __b, this);
      }

      local_iterator
      end(size_type __b)
      {
	__glibcxx_check_bucket_index(__b);
	return local_iterator(_Base::end(__b), __b, this);
      }

      const_local_iterator
      begin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::begin(__b), __b, this);
      }

      const_local_iterator
      end(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::end(__b), __b, this);
      }

      const_local_iterator
      cbegin(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cbegin(__b), __b, this);
      }

      const_local_iterator
      cend(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cend(__b), __b, this);
      }

      size_type
      bucket_size(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return _Base::bucket_size(__b);
      }

      float
      max_load_factor() const noexcept
      { return _Base::max_load_factor(); }

      void
      max_load_factor(float __f)
      {
	__glibcxx_check_max_load_factor(__f);
	_Base::max_load_factor(__f);
      }

      template<typename... _Args>
	iterator
	emplace(_Args&&... __args)
	{
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it
	    = _Base::emplace(std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __hint, _Args&&... __args)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
					std::forward<_Args>(__args)...);
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      iterator
      insert(const value_type& __obj)
      {
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__obj);
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      iterator
      insert(const_iterator __hint, const value_type& __obj)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__hint.base(), __obj); 
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      iterator
      insert(value_type&& __obj)
      {
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(std::move(__obj)); 
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      iterator
      insert(const_iterator __hint, value_type&& __obj)
      {
	__glibcxx_check_insert(__hint);
	size_type __bucket_count = this->bucket_count();
	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj)); 
	_M_check_rehashed(__bucket_count);
	return iterator(__it, this);
      }

      void
      insert(std::initializer_list<value_type> __l)
      {
	size_type __bucket_count = this->bucket_count();
	_Base::insert(__l);
	_M_check_rehashed(__bucket_count);
      }

      template<typename _InputIterator>
	void
	insert(_InputIterator __first, _InputIterator __last)
	{
	  __glibcxx_check_valid_range(__first, __last);
	  size_type __bucket_count = this->bucket_count();
	  _Base::insert(__gnu_debug::__base(__first),
			__gnu_debug::__base(__last));
	  _M_check_rehashed(__bucket_count);
	}

      iterator
      find(const key_type& __key)
      { return iterator(_Base::find(__key), this); }

      const_iterator
      find(const key_type& __key) const
      { return const_iterator(_Base::find(__key), this); }

      std::pair<iterator, iterator>
      equal_range(const key_type& __key)
      {
	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
	__pair_type __res = _Base::equal_range(__key);
	return std::make_pair(iterator(__res.first, this),
			      iterator(__res.second, this));
      }

      std::pair<const_iterator, const_iterator>
      equal_range(const key_type& __key) const
      {
	std::pair<_Base_const_iterator, _Base_const_iterator>
	  __res = _Base::equal_range(__key);
	return std::make_pair(const_iterator(__res.first, this),
			      const_iterator(__res.second, this));
      }

      size_type
      erase(const key_type& __key)
      {
	size_type __ret(0);
	std::pair<_Base_iterator, _Base_iterator> __pair =
	  _Base::equal_range(__key);
	for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
	  {
	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
			    { return __it == __victim; });
	    this->_M_invalidate_local_if(
			    [__victim](_Base_const_local_iterator __it)
			    { return __it._M_cur == __victim._M_cur; });
	    _Base::erase(__victim++);
	    ++__ret;
	  }
	return __ret;
      }

      iterator
      erase(const_iterator __it)
      {
	__glibcxx_check_erase(__it);
	_Base_const_iterator __victim = __it.base();
	this->_M_invalidate_if([__victim](_Base_const_iterator __it)
			{ return __it == __victim; });
	this->_M_invalidate_local_if(
			[__victim](_Base_const_local_iterator __it)
			{ return __it._M_cur == __victim._M_cur; });
	return iterator(_Base::erase(__it.base()), this);
      }

      iterator
      erase(iterator __it)
      { return erase(const_iterator(__it)); }

      iterator
      erase(const_iterator __first, const_iterator __last)
      {
	__glibcxx_check_erase_range(__first, __last);
	for (_Base_const_iterator __tmp = __first.base();
	     __tmp != __last.base(); ++__tmp)
	  {
	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
				  _M_message(__gnu_debug::__msg_valid_range)
				  ._M_iterator(__first, "first")
				  ._M_iterator(__last, "last"));
	    this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
			    { return __it == __tmp; });
	    this->_M_invalidate_local_if(
			    [__tmp](_Base_const_local_iterator __it)
			    { return __it._M_cur == __tmp._M_cur; });
	  }
	return iterator(_Base::erase(__first.base(),
				     __last.base()), this);
      }

      _Base&
      _M_base() noexcept       { return *this; }

      const _Base&
      _M_base() const noexcept { return *this; }

    private:
      void
      _M_invalidate_locals()
      {
	_Base_local_iterator __local_end = _Base::end(0);
	this->_M_invalidate_local_if(
			[__local_end](_Base_const_local_iterator __it)
			{ return __it != __local_end; });
      }

      void
      _M_invalidate_all()
      {
	_Base_iterator __end = _Base::end();
	this->_M_invalidate_if([__end](_Base_const_iterator __it)
			{ return __it != __end; });
	_M_invalidate_locals();
      }

      void
      _M_check_rehashed(size_type __prev_count)
      {
	if (__prev_count != this->bucket_count())
	  _M_invalidate_locals();
      }
    };

  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    inline void
    swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
	 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
    { __x.swap(__y); }

  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    inline bool
    operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
    { return __x._M_base() == __y._M_base(); }

  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    inline bool
    operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
    { return !(__x == __y); }

} // namespace __debug
} // namespace std

#endif // C++11

#endif
