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

// Copyright (C) 2003-2014 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;

      typedef __gnu_cxx::__alloc_traits<typename
					_Base::allocator_type> _Alloc_traits;
    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&) = default;

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

      unordered_set(unordered_set&&) = default;

      explicit
      unordered_set(const allocator_type& __a)
	: _Base(__a)
      { }

      unordered_set(const unordered_set& __uset,
		    const allocator_type& __a)
	: _Base(__uset._M_base(), __a)
      { }

      unordered_set(unordered_set&& __uset,
		    const allocator_type& __a)
	: _Base(std::move(__uset._M_base()), __a)
      { }

      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)
      {
	_M_base() = __x._M_base();
	this->_M_invalidate_all();
	return *this;
      }

      unordered_set&
      operator=(unordered_set&& __x)
      noexcept(_Alloc_traits::_S_nothrow_move())
      {
	__glibcxx_check_self_move_assign(__x);
	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
	    || __x.get_allocator() == this->get_allocator();
	_M_base() = std::move(__x._M_base());
	if (__xfer_memory)
	  this->_M_swap(__x);
	else
	  this->_M_invalidate_all();
	__x._M_invalidate_all();
	return *this;
      }

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

      void
      swap(unordered_set& __x)
      noexcept(_Alloc_traits::_S_nothrow_swap())
      {
	if (!_Alloc_traits::_S_propagate_on_swap())
	  __glibcxx_check_equal_allocs(__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), this);
      }

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

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

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

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

      const_local_iterator
      cend(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cend(__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_curr() == __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_curr() == __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_curr() == __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;

      typedef __gnu_cxx::__alloc_traits<typename
					_Base::allocator_type> _Alloc_traits;

    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&) = default;

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

      unordered_multiset(unordered_multiset&&) = default;

      explicit
      unordered_multiset(const allocator_type& __a)
	: _Base(__a)
      { }

      unordered_multiset(const unordered_multiset& __uset,
			 const allocator_type& __a)
	: _Base(__uset._M_base(), __a)
      { }
      
      unordered_multiset(unordered_multiset&& __uset,
			 const allocator_type& __a)
	: _Base(std::move(__uset._M_base()), __a)
      { }

      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)
      {
	_M_base() = __x._M_base();
	this->_M_invalidate_all();
	return *this;
      }

      unordered_multiset&
      operator=(unordered_multiset&& __x)
      noexcept(_Alloc_traits::_S_nothrow_move())
      {
	__glibcxx_check_self_move_assign(__x);
	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
	    || __x.get_allocator() == this->get_allocator();
	_M_base() = std::move(__x._M_base());
	if (__xfer_memory)
	  this->_M_swap(__x);
	else
	  this->_M_invalidate_all();
	__x._M_invalidate_all();
	return *this;
      }

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

      void
      swap(unordered_multiset& __x)
      noexcept(_Alloc_traits::_S_nothrow_swap())
      {
	if (!_Alloc_traits::_S_propagate_on_swap())
	  __glibcxx_check_equal_allocs(__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), this);
      }

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

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

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

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

      const_local_iterator
      cend(size_type __b) const
      {
	__glibcxx_check_bucket_index(__b);
	return const_local_iterator(_Base::cend(__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_curr() == __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_curr() == __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_curr() == __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
