// Debugging unordered_map/unordered_multimap implementation -*- C++ -*-

// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
// 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_map
 *  This file is a GNU debug extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
#define _GLIBCXX_DEBUG_UNORDERED_MAP 1

#ifndef __GXX_EXPERIMENTAL_CXX0X__
# include <bits/c++0x_warning.h>
#else
# include <unordered_map>

#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_map with safety/checking/debug instrumentation.
  template<typename _Key, typename _Tp,
	   typename _Hash = std::hash<_Key>,
	   typename _Pred = std::equal_to<_Key>,
	   typename _Alloc = std::allocator<_Key> >
    class unordered_map
    : public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
      public __gnu_debug::_Safe_unordered_container<unordered_map<_Key, _Tp,
							_Hash, _Pred, _Alloc> >
    {
      typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
					    _Pred, _Alloc> _Base;
      typedef __gnu_debug::_Safe_unordered_container<unordered_map> _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_map> iterator;
      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
					  unordered_map> const_iterator;
      typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
					  unordered_map> local_iterator;
      typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
					  unordered_map> const_local_iterator;

      explicit
      unordered_map(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_map(_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_map(const unordered_map& __x) 
      : _Base(__x) { }

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

      unordered_map(unordered_map&& __x)
      : _Base(std::move(__x)) { }

      unordered_map(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_map() noexcept { }

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

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

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

      void
      swap(unordered_map& __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)
      { return local_iterator(_Base::begin(__b), __b, this); }

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

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

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

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

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

      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();
	std::pair<_Base_iterator, bool> __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);
      }

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	std::pair<iterator, bool>
	insert(_Pair&& __obj)
	{
	  size_type __bucket_count = this->bucket_count();
	  std::pair<_Base_iterator, bool> __res =
	    _Base::insert(std::forward<_Pair>(__obj));
	  _M_check_rehashed(__bucket_count);
	  return std::make_pair(iterator(__res.first, this), __res.second);
	}

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(const_iterator __hint, _Pair&& __obj)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it =
	    _Base::insert(__hint.base(), std::forward<_Pair>(__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)
      {
	std::pair<_Base_iterator, _Base_iterator> __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; });
	    _Base_local_iterator __local_victim = _S_to_local(__victim);
	    this->_M_invalidate_local_if(
			    [__local_victim](_Base_const_local_iterator __it)
			    { return __it == __local_victim; });
	    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; });
	_Base_const_local_iterator __local_victim = _S_to_local(__victim);
	this->_M_invalidate_local_if(
			[__local_victim](_Base_const_local_iterator __it)
			{ return __it == __local_victim; });
	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; });
	    _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
	    this->_M_invalidate_local_if(
			    [__local_tmp](_Base_const_local_iterator __it)
			    { return __it == __local_tmp; });
	  }
	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();
      }

      static _Base_local_iterator
      _S_to_local(_Base_iterator __it)
      {
        // The returned local iterator will not be incremented so we don't
	// need to compute __it's node bucket
	return _Base_local_iterator(__it._M_cur, 0, 0);
      }

      static _Base_const_local_iterator
      _S_to_local(_Base_const_iterator __it)
      {
        // The returned local iterator will not be incremented so we don't
	// need to compute __it's node bucket
	return _Base_const_local_iterator(__it._M_cur, 0, 0);
      }
    };

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

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline bool
    operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	       const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { return __x._M_equal(__y); }

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


  /// Class std::unordered_multimap with safety/checking/debug instrumentation.
  template<typename _Key, typename _Tp,
	   typename _Hash = std::hash<_Key>,
	   typename _Pred = std::equal_to<_Key>,
	   typename _Alloc = std::allocator<_Key> >
    class unordered_multimap
    : public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
						_Pred, _Alloc>,
      public __gnu_debug::_Safe_unordered_container<unordered_multimap<_Key,
						_Tp, _Hash, _Pred, _Alloc> >
    {
      typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
						 _Pred, _Alloc> _Base;
      typedef __gnu_debug::_Safe_unordered_container<unordered_multimap>
	_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_multimap> iterator;
      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
					  unordered_multimap> const_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_local_iterator, unordered_multimap> local_iterator;
      typedef __gnu_debug::_Safe_local_iterator<
	_Base_const_local_iterator, unordered_multimap> const_local_iterator;

      explicit
      unordered_multimap(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_multimap(_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_multimap(const unordered_multimap& __x) 
      : _Base(__x) { }

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

      unordered_multimap(unordered_multimap&& __x)
      : _Base(std::move(__x)) { }

      unordered_multimap(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_multimap() noexcept { }

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

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

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

      void
      swap(unordered_multimap& __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)
      { return local_iterator(_Base::begin(__b), __b, this); }

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

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

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

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

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

      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);
      }

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(_Pair&& __obj)
	{
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it = _Base::insert(std::forward<_Pair>(__obj));
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      template<typename _Pair, typename = typename
	       std::enable_if<std::is_constructible<value_type,
						    _Pair&&>::value>::type>
	iterator
	insert(const_iterator __hint, _Pair&& __obj)
	{
	  __glibcxx_check_insert(__hint);
	  size_type __bucket_count = this->bucket_count();
	  _Base_iterator __it =
	    _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
	  _M_check_rehashed(__bucket_count);
	  return iterator(__it, this);
	}

      void
      insert(std::initializer_list<value_type> __l)
      { _Base::insert(__l); }

      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)
      {
	std::pair<_Base_iterator, _Base_iterator> __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);
	size_type __bucket_count = this->bucket_count();
	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; });
	    _Base_local_iterator __local_victim = _S_to_local(__victim);
	    this->_M_invalidate_local_if(
			    [__local_victim](_Base_const_local_iterator __it)
			    { return __it == __local_victim; });
	    _Base::erase(__victim++);
	    ++__ret;
	  }
	_M_check_rehashed(__bucket_count);
	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; });
	_Base_const_local_iterator __local_victim = _S_to_local(__victim);
	this->_M_invalidate_local_if(
			[__local_victim](_Base_const_local_iterator __it)
			{ return __it == __local_victim; });
	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; });
	    _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
	    this->_M_invalidate_local_if(
			    [__local_tmp](_Base_const_local_iterator __it)
			    { return __it == __local_tmp; });
	  }
	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();
      }

      static _Base_local_iterator
      _S_to_local(_Base_iterator __it)
      {
        // The returned local iterator will not be incremented so we don't
	// need to compute __it's node bucket
	return _Base_local_iterator(__it._M_cur, 0, 0);
      }

      static _Base_const_local_iterator
      _S_to_local(_Base_const_iterator __it)
      {
        // The returned local iterator will not be incremented so we don't
	// need to compute __it's node bucket
	return _Base_const_local_iterator(__it._M_cur, 0, 0);
      }
    };

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

  template<typename _Key, typename _Tp, typename _Hash,
	   typename _Pred, typename _Alloc>
    inline bool
    operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
	       const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
    { return __x._M_equal(__y); }

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

} // namespace __debug
} // namespace std

#endif // __GXX_EXPERIMENTAL_CXX0X__

#endif
