// Hashtable implementation used by containers -*- C++ -*-

// Copyright (C) 2001-2021 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/>.

/*
 * Copyright (c) 1996,1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 */

/** @file backward/hashtable.h
 *  This file is a GNU extension to the Standard C++ Library (possibly
 *  containing extensions from the HP/SGI STL subset).
 */

#ifndef _BACKWARD_HASHTABLE_H
#define _BACKWARD_HASHTABLE_H 1

// Hashtable class, used to implement the hashed associative containers
// hash_set, hash_map, hash_multiset, and hash_multimap.

#include <vector>
#include <iterator>
#include <algorithm>
#include <bits/stl_function.h>
#include <ext/alloc_traits.h>
#include <backward/hash_fun.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<class _Val>
    struct _Hashtable_node
    {
      _Hashtable_node* _M_next;
      _Val _M_val;
    };

  template<class _Val, class _Key, class _HashFcn, class _ExtractKey, 
	   class _EqualKey, class _Alloc = std::allocator<_Val> >
    class hashtable;

  template<class _Val, class _Key, class _HashFcn,
	   class _ExtractKey, class _EqualKey, class _Alloc>
    struct _Hashtable_iterator;

  template<class _Val, class _Key, class _HashFcn,
	   class _ExtractKey, class _EqualKey, class _Alloc>
    struct _Hashtable_const_iterator;

  template<class _Val, class _Key, class _HashFcn,
	   class _ExtractKey, class _EqualKey, class _Alloc>
    struct _Hashtable_iterator
    {
      typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
        _Hashtable;
      typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
				  _ExtractKey, _EqualKey, _Alloc>
        iterator;
      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
					_ExtractKey, _EqualKey, _Alloc>
        const_iterator;
      typedef _Hashtable_node<_Val> _Node;
      typedef std::forward_iterator_tag iterator_category;
      typedef _Val value_type;
      typedef std::ptrdiff_t difference_type;
      typedef std::size_t size_type;
      typedef _Val& reference;
      typedef _Val* pointer;
      
      _Node* _M_cur;
      _Hashtable* _M_ht;

      _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
      : _M_cur(__n), _M_ht(__tab) { }

      _Hashtable_iterator() { }

      reference
      operator*() const
      { return _M_cur->_M_val; }

      pointer
      operator->() const
      { return &(operator*()); }

      iterator&
      operator++();

      iterator
      operator++(int);

      bool
      operator==(const iterator& __it) const
      { return _M_cur == __it._M_cur; }

      bool
      operator!=(const iterator& __it) const
      { return _M_cur != __it._M_cur; }
    };

  template<class _Val, class _Key, class _HashFcn,
	   class _ExtractKey, class _EqualKey, class _Alloc>
    struct _Hashtable_const_iterator
    {
      typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
        _Hashtable;
      typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
				  _ExtractKey,_EqualKey,_Alloc>
        iterator;
      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
					_ExtractKey, _EqualKey, _Alloc>
        const_iterator;
      typedef _Hashtable_node<_Val> _Node;

      typedef std::forward_iterator_tag iterator_category;
      typedef _Val value_type;
      typedef std::ptrdiff_t difference_type;
      typedef std::size_t size_type;
      typedef const _Val& reference;
      typedef const _Val* pointer;
      
      const _Node* _M_cur;
      const _Hashtable* _M_ht;

      _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
      : _M_cur(__n), _M_ht(__tab) { }

      _Hashtable_const_iterator() { }

      _Hashtable_const_iterator(const iterator& __it)
      : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { }

      reference
      operator*() const
      { return _M_cur->_M_val; }

      pointer
      operator->() const
      { return &(operator*()); }

      const_iterator&
      operator++();

      const_iterator
      operator++(int);

      bool
      operator==(const const_iterator& __it) const
      { return _M_cur == __it._M_cur; }

      bool
      operator!=(const const_iterator& __it) const
      { return _M_cur != __it._M_cur; }
    };

  // Note: assumes long is at least 32 bits.
  enum { _S_num_primes = 29 };

  template<typename _PrimeType>
    struct _Hashtable_prime_list
    {
      static const _PrimeType  __stl_prime_list[_S_num_primes];

      static const _PrimeType*
      _S_get_prime_list();
    };

  template<typename _PrimeType> const _PrimeType
  _Hashtable_prime_list<_PrimeType>::__stl_prime_list[_S_num_primes] =
    {
      5ul,          53ul,         97ul,         193ul,       389ul,
      769ul,        1543ul,       3079ul,       6151ul,      12289ul,
      24593ul,      49157ul,      98317ul,      196613ul,    393241ul,
      786433ul,     1572869ul,    3145739ul,    6291469ul,   12582917ul,
      25165843ul,   50331653ul,   100663319ul,  201326611ul, 402653189ul,
      805306457ul,  1610612741ul, 3221225473ul, 4294967291ul
    };

 template<class _PrimeType> inline const _PrimeType*
 _Hashtable_prime_list<_PrimeType>::_S_get_prime_list()
 {
   return __stl_prime_list;
 }

  inline unsigned long
  __stl_next_prime(unsigned long __n)
  {
    const unsigned long* __first = _Hashtable_prime_list<unsigned long>::_S_get_prime_list();
    const unsigned long* __last = __first + (int)_S_num_primes;
    const unsigned long* pos = std::lower_bound(__first, __last, __n);
    return pos == __last ? *(__last - 1) : *pos;
  }

  // Forward declaration of operator==.  
  template<class _Val, class _Key, class _HF, class _Ex,
	   class _Eq, class _All>
    class hashtable;

  template<class _Val, class _Key, class _HF, class _Ex,
	   class _Eq, class _All>
    bool
    operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);

  // Hashtables handle allocators a bit differently than other
  // containers do.  If we're using standard-conforming allocators, then
  // a hashtable unconditionally has a member variable to hold its
  // allocator, even if it so happens that all instances of the
  // allocator type are identical.  This is because, for hashtables,
  // this extra storage is negligible.  Additionally, a base class
  // wouldn't serve any other purposes; it wouldn't, for example,
  // simplify the exception-handling code.  
  template<class _Val, class _Key, class _HashFcn,
	   class _ExtractKey, class _EqualKey, class _Alloc>
    class hashtable
    {
    public:
      typedef _Key key_type;
      typedef _Val value_type;
      typedef _HashFcn hasher;
      typedef _EqualKey key_equal;

      typedef std::size_t            size_type;
      typedef std::ptrdiff_t         difference_type;
      typedef value_type*       pointer;
      typedef const value_type* const_pointer;
      typedef value_type&       reference;
      typedef const value_type& const_reference;

      hasher
      hash_funct() const
      { return _M_hash; }

      key_equal
      key_eq() const
      { return _M_equals; }

    private:
      typedef _Hashtable_node<_Val> _Node;

    public:
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
	rebind<value_type>::other allocator_type;

      allocator_type
      get_allocator() const
      { return _M_node_allocator; }

    private:
      typedef __gnu_cxx::__alloc_traits<allocator_type> _Alloc_traits;
      typedef typename _Alloc_traits::template rebind<_Node>::other
	_Node_Alloc;
      typedef typename _Alloc_traits::template rebind<_Node*>::other
	_Nodeptr_Alloc;
      typedef std::vector<_Node*, _Nodeptr_Alloc> _Vector_type;

      _Node_Alloc _M_node_allocator;

      _Node*
      _M_get_node()
      { return _M_node_allocator.allocate(1); }

      void
      _M_put_node(_Node* __p)
      { _M_node_allocator.deallocate(__p, 1); }

    private:
      hasher                _M_hash;
      key_equal             _M_equals;
      _ExtractKey           _M_get_key;
      _Vector_type          _M_buckets;
      size_type             _M_num_elements;
      
    public:
      typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
				  _EqualKey, _Alloc>
        iterator;
      typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
					_EqualKey, _Alloc>
        const_iterator;

      friend struct
      _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;

      friend struct
      _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
				_EqualKey, _Alloc>;

    public:
      hashtable(size_type __n, const _HashFcn& __hf,
		const _EqualKey& __eql, const _ExtractKey& __ext,
		const allocator_type& __a = allocator_type())
      : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
	_M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
      { _M_initialize_buckets(__n); }

      hashtable(size_type __n, const _HashFcn& __hf,
		const _EqualKey& __eql,
		const allocator_type& __a = allocator_type())
      : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
	_M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
      { _M_initialize_buckets(__n); }

      hashtable(const hashtable& __ht)
      : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
      _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
      _M_buckets(__ht.get_allocator()), _M_num_elements(0)
      { _M_copy_from(__ht); }

      hashtable&
      operator= (const hashtable& __ht)
      {
	if (&__ht != this)
	  {
	    clear();
	    _M_hash = __ht._M_hash;
	    _M_equals = __ht._M_equals;
	    _M_get_key = __ht._M_get_key;
	    _M_copy_from(__ht);
	  }
	return *this;
      }

      ~hashtable()
      { clear(); }

      size_type
      size() const
      { return _M_num_elements; }

      size_type
      max_size() const
      { return size_type(-1); }

      _GLIBCXX_NODISCARD bool
      empty() const
      { return size() == 0; }

      void
      swap(hashtable& __ht)
      {
	std::swap(_M_hash, __ht._M_hash);
	std::swap(_M_equals, __ht._M_equals);
	std::swap(_M_get_key, __ht._M_get_key);
	_M_buckets.swap(__ht._M_buckets);
	std::swap(_M_num_elements, __ht._M_num_elements);
      }

      iterator
      begin()
      {
	for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
	  if (_M_buckets[__n])
	    return iterator(_M_buckets[__n], this);
	return end();
      }

      iterator
      end()
      { return iterator(0, this); }

      const_iterator
      begin() const
      {
	for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
	  if (_M_buckets[__n])
	    return const_iterator(_M_buckets[__n], this);
	return end();
      }

      const_iterator
      end() const
      { return const_iterator(0, this); }

      template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq,
		class _Al>
        friend bool
        operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
		   const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);

    public:
      size_type
      bucket_count() const
      { return _M_buckets.size(); }

      size_type
      max_bucket_count() const
      { return _Hashtable_prime_list<unsigned long>::
               _S_get_prime_list()[(int)_S_num_primes - 1];
      }

      size_type
      elems_in_bucket(size_type __bucket) const
      {
	size_type __result = 0;
	for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
	  __result += 1;
	return __result;
      }

      std::pair<iterator, bool>
      insert_unique(const value_type& __obj)
      {
	resize(_M_num_elements + 1);
	return insert_unique_noresize(__obj);
      }

      iterator
      insert_equal(const value_type& __obj)
      {
	resize(_M_num_elements + 1);
	return insert_equal_noresize(__obj);
      }

      std::pair<iterator, bool>
      insert_unique_noresize(const value_type& __obj);

      iterator
      insert_equal_noresize(const value_type& __obj);

      template<class _InputIterator>
        void
        insert_unique(_InputIterator __f, _InputIterator __l)
        { insert_unique(__f, __l, std::__iterator_category(__f)); }

      template<class _InputIterator>
        void
        insert_equal(_InputIterator __f, _InputIterator __l)
        { insert_equal(__f, __l, std::__iterator_category(__f)); }

      template<class _InputIterator>
        void
        insert_unique(_InputIterator __f, _InputIterator __l,
		      std::input_iterator_tag)
        {
	  for ( ; __f != __l; ++__f)
	    insert_unique(*__f);
	}

      template<class _InputIterator>
        void
        insert_equal(_InputIterator __f, _InputIterator __l,
		     std::input_iterator_tag)
        {
	  for ( ; __f != __l; ++__f)
	    insert_equal(*__f);
	}

      template<class _ForwardIterator>
        void
        insert_unique(_ForwardIterator __f, _ForwardIterator __l,
		      std::forward_iterator_tag)
        {
	  size_type __n = std::distance(__f, __l);
	  resize(_M_num_elements + __n);
	  for ( ; __n > 0; --__n, ++__f)
	    insert_unique_noresize(*__f);
	}

      template<class _ForwardIterator>
        void
        insert_equal(_ForwardIterator __f, _ForwardIterator __l,
		     std::forward_iterator_tag)
        {
	  size_type __n = std::distance(__f, __l);
	  resize(_M_num_elements + __n);
	  for ( ; __n > 0; --__n, ++__f)
	    insert_equal_noresize(*__f);
	}

      reference
      find_or_insert(const value_type& __obj);

      iterator
      find(const key_type& __key)
      {
	size_type __n = _M_bkt_num_key(__key);
	_Node* __first;
	for (__first = _M_buckets[__n];
	     __first && !_M_equals(_M_get_key(__first->_M_val), __key);
	     __first = __first->_M_next)
	  { }
	return iterator(__first, this);
      }

      const_iterator
      find(const key_type& __key) const
      {
	size_type __n = _M_bkt_num_key(__key);
	const _Node* __first;
	for (__first = _M_buckets[__n];
	     __first && !_M_equals(_M_get_key(__first->_M_val), __key);
	     __first = __first->_M_next)
	  { }
	return const_iterator(__first, this);
      }

      size_type
      count(const key_type& __key) const
      {
	const size_type __n = _M_bkt_num_key(__key);
	size_type __result = 0;
	
	for (const _Node* __cur = _M_buckets[__n]; __cur;
	     __cur = __cur->_M_next)
	  if (_M_equals(_M_get_key(__cur->_M_val), __key))
	    ++__result;
	return __result;
      }

      std::pair<iterator, iterator>
      equal_range(const key_type& __key);

      std::pair<const_iterator, const_iterator>
      equal_range(const key_type& __key) const;

      size_type
      erase(const key_type& __key);
      
      void
      erase(const iterator& __it);

      void
      erase(iterator __first, iterator __last);

      void
      erase(const const_iterator& __it);

      void
      erase(const_iterator __first, const_iterator __last);

      void
      resize(size_type __num_elements_hint);

      void
      clear();

    private:
      size_type
      _M_next_size(size_type __n) const
      { return __stl_next_prime(__n); }

      void
      _M_initialize_buckets(size_type __n)
      {
	const size_type __n_buckets = _M_next_size(__n);
	_M_buckets.reserve(__n_buckets);
	_M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
	_M_num_elements = 0;
      }

      size_type
      _M_bkt_num_key(const key_type& __key) const
      { return _M_bkt_num_key(__key, _M_buckets.size()); }

      size_type
      _M_bkt_num(const value_type& __obj) const
      { return _M_bkt_num_key(_M_get_key(__obj)); }

      size_type
      _M_bkt_num_key(const key_type& __key, std::size_t __n) const
      { return _M_hash(__key) % __n; }

      size_type
      _M_bkt_num(const value_type& __obj, std::size_t __n) const
      { return _M_bkt_num_key(_M_get_key(__obj), __n); }

      _Node*
      _M_new_node(const value_type& __obj)
      {
	_Node* __n = _M_get_node();
	__n->_M_next = 0;
	__try
	  {
	    allocator_type __a = this->get_allocator();
	    _Alloc_traits::construct(__a, &__n->_M_val, __obj);
	    return __n;
	  }
	__catch(...)
	  {
	    _M_put_node(__n);
	    __throw_exception_again;
	  }
      }

      void
      _M_delete_node(_Node* __n)
      {
	allocator_type __a = this->get_allocator();
	_Alloc_traits::destroy(__a, &__n->_M_val);
	_M_put_node(__n);
      }
      
      void
      _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);

      void
      _M_erase_bucket(const size_type __n, _Node* __last);

      void
      _M_copy_from(const hashtable& __ht);
    };

  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
	    class _All>
    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
    operator++()
    {
      const _Node* __old = _M_cur;
      _M_cur = _M_cur->_M_next;
      if (!_M_cur)
	{
	  size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
	  while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
	    _M_cur = _M_ht->_M_buckets[__bucket];
	}
      return *this;
    }

  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
	    class _All>
    inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
    _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
    operator++(int)
    {
      iterator __tmp = *this;
      ++*this;
      return __tmp;
    }

  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
	    class _All>
    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
    operator++()
    {
      const _Node* __old = _M_cur;
      _M_cur = _M_cur->_M_next;
      if (!_M_cur)
	{
	  size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
	  while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
	    _M_cur = _M_ht->_M_buckets[__bucket];
	}
      return *this;
    }

  template<class _Val, class _Key, class _HF, class _ExK, class _EqK,
	    class _All>
    inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
    _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
    operator++(int)
    {
      const_iterator __tmp = *this;
      ++*this;
      return __tmp;
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    bool
    operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
    {
      typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;

      if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
	return false;

      for (std::size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
	{
	  _Node* __cur1 = __ht1._M_buckets[__n];
	  _Node* __cur2 = __ht2._M_buckets[__n];
	  // Check same length of lists
	  for (; __cur1 && __cur2;
	       __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
	    { } 
	  if (__cur1 || __cur2)
	    return false;
	  // Now check one's elements are in the other
	  for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
	       __cur1 = __cur1->_M_next)
	    {
	      bool _found__cur1 = false;
	      for (__cur2 = __ht2._M_buckets[__n];
		   __cur2; __cur2 = __cur2->_M_next)
		{
		  if (__cur1->_M_val == __cur2->_M_val)
		    {
		      _found__cur1 = true;
		      break;
		    }
		}
	      if (!_found__cur1)
		return false;
	    }
	}
      return true;
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    inline bool
    operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
	       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
    { return !(__ht1 == __ht2); }

  template<class _Val, class _Key, class _HF, class _Extract, class _EqKey,
	    class _All>
    inline void
    swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
	 hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
    { __ht1.swap(__ht2); }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
	      bool>
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    insert_unique_noresize(const value_type& __obj)
    {
      const size_type __n = _M_bkt_num(__obj);
      _Node* __first = _M_buckets[__n];
      
      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
	  return std::pair<iterator, bool>(iterator(__cur, this), false);
      
      _Node* __tmp = _M_new_node(__obj);
      __tmp->_M_next = __first;
      _M_buckets[__n] = __tmp;
      ++_M_num_elements;
      return std::pair<iterator, bool>(iterator(__tmp, this), true);
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    insert_equal_noresize(const value_type& __obj)
    {
      const size_type __n = _M_bkt_num(__obj);
      _Node* __first = _M_buckets[__n];
      
      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
	  {
	    _Node* __tmp = _M_new_node(__obj);
	    __tmp->_M_next = __cur->_M_next;
	    __cur->_M_next = __tmp;
	    ++_M_num_elements;
	    return iterator(__tmp, this);
	  }

      _Node* __tmp = _M_new_node(__obj);
      __tmp->_M_next = __first;
      _M_buckets[__n] = __tmp;
      ++_M_num_elements;
      return iterator(__tmp, this);
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    find_or_insert(const value_type& __obj)
    {
      resize(_M_num_elements + 1);

      size_type __n = _M_bkt_num(__obj);
      _Node* __first = _M_buckets[__n];
      
      for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
	if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
	  return __cur->_M_val;
      
      _Node* __tmp = _M_new_node(__obj);
      __tmp->_M_next = __first;
      _M_buckets[__n] = __tmp;
      ++_M_num_elements;
      return __tmp->_M_val;
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
	      typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    equal_range(const key_type& __key)
    {
      typedef std::pair<iterator, iterator> _Pii;
      const size_type __n = _M_bkt_num_key(__key);

      for (_Node* __first = _M_buckets[__n]; __first;
	   __first = __first->_M_next)
	if (_M_equals(_M_get_key(__first->_M_val), __key))
	  {
	    for (_Node* __cur = __first->_M_next; __cur;
		 __cur = __cur->_M_next)
	      if (!_M_equals(_M_get_key(__cur->_M_val), __key))
		return _Pii(iterator(__first, this), iterator(__cur, this));
	    for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
	      if (_M_buckets[__m])
		return _Pii(iterator(__first, this),
			    iterator(_M_buckets[__m], this));
	    return _Pii(iterator(__first, this), end());
	  }
      return _Pii(end(), end());
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    std::pair<
	typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
	typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    equal_range(const key_type& __key) const
    {
      typedef std::pair<const_iterator, const_iterator> _Pii;
      const size_type __n = _M_bkt_num_key(__key);

      for (const _Node* __first = _M_buckets[__n]; __first;
	   __first = __first->_M_next)
	{
	  if (_M_equals(_M_get_key(__first->_M_val), __key))
	    {
	      for (const _Node* __cur = __first->_M_next; __cur;
		   __cur = __cur->_M_next)
		if (!_M_equals(_M_get_key(__cur->_M_val), __key))
		  return _Pii(const_iterator(__first, this),
			      const_iterator(__cur, this));
	      for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
		if (_M_buckets[__m])
		  return _Pii(const_iterator(__first, this),
			      const_iterator(_M_buckets[__m], this));
	      return _Pii(const_iterator(__first, this), end());
	    }
	}
      return _Pii(end(), end());
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    erase(const key_type& __key)
    {
      const size_type __n = _M_bkt_num_key(__key);
      _Node* __first = _M_buckets[__n];
      _Node* __saved_slot = 0;
      size_type __erased = 0;

      if (__first)
	{
	  _Node* __cur = __first;
	  _Node* __next = __cur->_M_next;
	  while (__next)
	    {
	      if (_M_equals(_M_get_key(__next->_M_val), __key))
		{
		  if (&_M_get_key(__next->_M_val) != &__key)
		    {
		      __cur->_M_next = __next->_M_next;
		      _M_delete_node(__next);
		      __next = __cur->_M_next;
		      ++__erased;
		      --_M_num_elements;
		    }
		  else
		    {
		      __saved_slot = __cur;
		      __cur = __next;
		      __next = __cur->_M_next;
		    }
		}
	      else
		{
		  __cur = __next;
		  __next = __cur->_M_next;
		}
	    }
	  bool __delete_first = _M_equals(_M_get_key(__first->_M_val), __key);
	  if (__saved_slot)
	    {
	      __next = __saved_slot->_M_next;
	      __saved_slot->_M_next = __next->_M_next;
	      _M_delete_node(__next);
	      ++__erased;
	      --_M_num_elements;
	    }
	  if (__delete_first)
	    {
	      _M_buckets[__n] = __first->_M_next;
	      _M_delete_node(__first);
	      ++__erased;
	      --_M_num_elements;
	    }
	}
      return __erased;
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    erase(const iterator& __it)
    {
      _Node* __p = __it._M_cur;
      if (__p)
	{
	  const size_type __n = _M_bkt_num(__p->_M_val);
	  _Node* __cur = _M_buckets[__n];
	  
	  if (__cur == __p)
	    {
	      _M_buckets[__n] = __cur->_M_next;
	      _M_delete_node(__cur);
	      --_M_num_elements;
	    }
	  else
	    {
	      _Node* __next = __cur->_M_next;
	      while (__next)
		{
		  if (__next == __p)
		    {
		      __cur->_M_next = __next->_M_next;
		      _M_delete_node(__next);
		      --_M_num_elements;
		      break;
		    }
		  else
		    {
		      __cur = __next;
		      __next = __cur->_M_next;
		    }
		}
	    }
	}
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    erase(iterator __first, iterator __last)
    {
      size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
	                                    : _M_buckets.size();

      size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
	                                   : _M_buckets.size();

      if (__first._M_cur == __last._M_cur)
	return;
      else if (__f_bucket == __l_bucket)
	_M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
      else
	{
	  _M_erase_bucket(__f_bucket, __first._M_cur, 0);
	  for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
	    _M_erase_bucket(__n, 0);
	  if (__l_bucket != _M_buckets.size())
	    _M_erase_bucket(__l_bucket, __last._M_cur);
	}
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    inline void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    erase(const_iterator __first, const_iterator __last)
    {
      erase(iterator(const_cast<_Node*>(__first._M_cur),
		     const_cast<hashtable*>(__first._M_ht)),
	    iterator(const_cast<_Node*>(__last._M_cur),
		     const_cast<hashtable*>(__last._M_ht)));
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    inline void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    erase(const const_iterator& __it)
    { erase(iterator(const_cast<_Node*>(__it._M_cur),
		     const_cast<hashtable*>(__it._M_ht))); }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    resize(size_type __num_elements_hint)
    {
      const size_type __old_n = _M_buckets.size();
      if (__num_elements_hint > __old_n)
	{
	  const size_type __n = _M_next_size(__num_elements_hint);
	  if (__n > __old_n)
	    {
	      _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
	      __try
		{
		  for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
		    {
		      _Node* __first = _M_buckets[__bucket];
		      while (__first)
			{
			  size_type __new_bucket = _M_bkt_num(__first->_M_val,
							      __n);
			  _M_buckets[__bucket] = __first->_M_next;
			  __first->_M_next = __tmp[__new_bucket];
			  __tmp[__new_bucket] = __first;
			  __first = _M_buckets[__bucket];
			}
		    }
		  _M_buckets.swap(__tmp);
		}
	      __catch(...)
		{
		  for (size_type __bucket = 0; __bucket < __tmp.size();
		       ++__bucket)
		    {
		      while (__tmp[__bucket])
			{
			  _Node* __next = __tmp[__bucket]->_M_next;
			  _M_delete_node(__tmp[__bucket]);
			  __tmp[__bucket] = __next;
			}
		    }
		  __throw_exception_again;
		}
	    }
	}
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
    {
      _Node* __cur = _M_buckets[__n];
      if (__cur == __first)
	_M_erase_bucket(__n, __last);
      else
	{
	  _Node* __next;
	  for (__next = __cur->_M_next;
	       __next != __first;
	       __cur = __next, __next = __cur->_M_next)
	    ;
	  while (__next != __last)
	    {
	      __cur->_M_next = __next->_M_next;
	      _M_delete_node(__next);
	      __next = __cur->_M_next;
	      --_M_num_elements;
	    }
	}
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    _M_erase_bucket(const size_type __n, _Node* __last)
    {
      _Node* __cur = _M_buckets[__n];
      while (__cur != __last)
	{
	  _Node* __next = __cur->_M_next;
	  _M_delete_node(__cur);
	  __cur = __next;
	  _M_buckets[__n] = __cur;
	  --_M_num_elements;
	}
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    clear()
    {
      if (_M_num_elements == 0)
	return;

      for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
	{
	  _Node* __cur = _M_buckets[__i];
	  while (__cur != 0)
	    {
	      _Node* __next = __cur->_M_next;
	      _M_delete_node(__cur);
	      __cur = __next;
	    }
	  _M_buckets[__i] = 0;
	}
      _M_num_elements = 0;
    }

  template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
    void
    hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
    _M_copy_from(const hashtable& __ht)
    {
      _M_buckets.clear();
      _M_buckets.reserve(__ht._M_buckets.size());
      _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
      __try
	{
	  for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
	    const _Node* __cur = __ht._M_buckets[__i];
	    if (__cur)
	      {
		_Node* __local_copy = _M_new_node(__cur->_M_val);
		_M_buckets[__i] = __local_copy;
		
		for (_Node* __next = __cur->_M_next;
		     __next;
		     __cur = __next, __next = __cur->_M_next)
		  {
		    __local_copy->_M_next = _M_new_node(__next->_M_val);
		    __local_copy = __local_copy->_M_next;
		  }
	      }
	  }
	  _M_num_elements = __ht._M_num_elements;
	}
      __catch(...)
	{
	  clear();
	  __throw_exception_again;
	}
    }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif
