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

// Copyright (C) 2001-2016 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 <backward/hash_fun.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  using std::size_t;
  using std::ptrdiff_t;
  using std::forward_iterator_tag;
  using std::input_iterator_tag;
  using std::_Construct;
  using std::_Destroy;
  using std::distance;
  using std::vector;
  using std::pair;
  using std::__iterator_category;

  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 forward_iterator_tag iterator_category;
      typedef _Val value_type;
      typedef ptrdiff_t difference_type;
      typedef 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 forward_iterator_tag iterator_category;
      typedef _Val value_type;
      typedef ptrdiff_t difference_type;
      typedef 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 size_t            size_type;
      typedef 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 _Alloc::template rebind<value_type>::other allocator_type;
      allocator_type
      get_allocator() const
      { return _M_node_allocator; }

    private:
      typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
      typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
      typedef 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); }

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

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

      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, __iterator_category(__f)); }

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

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

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

      template<class _ForwardIterator>
        void
        insert_unique(_ForwardIterator __f, _ForwardIterator __l,
		      forward_iterator_tag)
        {
	  size_type __n = 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,
		     forward_iterator_tag)
        {
	  size_type __n = 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;
      }

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

      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, size_t __n) const
      { return _M_hash(__key) % __n; }

      size_type
      _M_bkt_num(const value_type& __obj, 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
	  {
	    this->get_allocator().construct(&__n->_M_val, __obj);
	    return __n;
	  }
	__catch(...)
	  {
	    _M_put_node(__n);
	    __throw_exception_again;
	  }
      }

      void
      _M_delete_node(_Node* __n)
      {
	this->get_allocator().destroy(&__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 (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>
    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 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 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>
    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 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>
    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 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
