home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / hashtable.h < prev    next >
C/C++ Source or Header  |  2005-01-29  |  31KB  |  995 lines

  1. // Hashtable implementation used by containers -*- C++ -*-
  2.  
  3. // Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 2, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. /*
  31.  * Copyright (c) 1996,1997
  32.  * Silicon Graphics Computer Systems, Inc.
  33.  *
  34.  * Permission to use, copy, modify, distribute and sell this software
  35.  * and its documentation for any purpose is hereby granted without fee,
  36.  * provided that the above copyright notice appear in all copies and
  37.  * that both that copyright notice and this permission notice appear
  38.  * in supporting documentation.  Silicon Graphics makes no
  39.  * representations about the suitability of this software for any
  40.  * purpose.  It is provided "as is" without express or implied warranty.
  41.  *
  42.  *
  43.  * Copyright (c) 1994
  44.  * Hewlett-Packard Company
  45.  *
  46.  * Permission to use, copy, modify, distribute and sell this software
  47.  * and its documentation for any purpose is hereby granted without fee,
  48.  * provided that the above copyright notice appear in all copies and
  49.  * that both that copyright notice and this permission notice appear
  50.  * in supporting documentation.  Hewlett-Packard Company makes no
  51.  * representations about the suitability of this software for any
  52.  * purpose.  It is provided "as is" without express or implied warranty.
  53.  *
  54.  */
  55.  
  56. /** @file ext/hashtable.h
  57.  *  This file is a GNU extension to the Standard C++ Library (possibly
  58.  *  containing extensions from the HP/SGI STL subset).  You should only
  59.  *  include this header if you are using GCC 3 or later.
  60.  */
  61.  
  62. #ifndef _HASHTABLE_H
  63. #define _HASHTABLE_H 1
  64.  
  65. // Hashtable class, used to implement the hashed associative containers
  66. // hash_set, hash_map, hash_multiset, and hash_multimap.
  67.  
  68. #include <vector>
  69. #include <iterator>
  70. #include <bits/stl_algo.h>
  71. #include <bits/stl_function.h>
  72. #include <ext/hash_fun.h>
  73.  
  74. namespace __gnu_cxx
  75. {
  76. using std::size_t;
  77. using std::ptrdiff_t;
  78. using std::forward_iterator_tag;
  79. using std::input_iterator_tag;
  80. using std::_Construct;
  81. using std::_Destroy;
  82. using std::distance;
  83. using std::vector;
  84. using std::pair;
  85. using std::__iterator_category;
  86.  
  87. template <class _Val>
  88. struct _Hashtable_node
  89. {
  90.   _Hashtable_node* _M_next;
  91.   _Val _M_val;
  92. };
  93.  
  94. template <class _Val, class _Key, class _HashFcn, class _ExtractKey, 
  95.       class _EqualKey, class _Alloc = std::allocator<_Val> >
  96. class hashtable;
  97.  
  98. template <class _Val, class _Key, class _HashFcn,
  99.           class _ExtractKey, class _EqualKey, class _Alloc>
  100. struct _Hashtable_iterator;
  101.  
  102. template <class _Val, class _Key, class _HashFcn,
  103.           class _ExtractKey, class _EqualKey, class _Alloc>
  104. struct _Hashtable_const_iterator;
  105.  
  106. template <class _Val, class _Key, class _HashFcn,
  107.           class _ExtractKey, class _EqualKey, class _Alloc>
  108. struct _Hashtable_iterator {
  109.   typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  110.           _Hashtable;
  111.   typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
  112.                               _ExtractKey, _EqualKey, _Alloc>
  113.           iterator;
  114.   typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  115.                                     _ExtractKey, _EqualKey, _Alloc>
  116.           const_iterator;
  117.   typedef _Hashtable_node<_Val> _Node;
  118.  
  119.   typedef forward_iterator_tag iterator_category;
  120.   typedef _Val value_type;
  121.   typedef ptrdiff_t difference_type;
  122.   typedef size_t size_type;
  123.   typedef _Val& reference;
  124.   typedef _Val* pointer;
  125.  
  126.   _Node* _M_cur;
  127.   _Hashtable* _M_ht;
  128.  
  129.   _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
  130.     : _M_cur(__n), _M_ht(__tab) {}
  131.   _Hashtable_iterator() {}
  132.   reference operator*() const { return _M_cur->_M_val; }
  133.   pointer operator->() const { return &(operator*()); }
  134.   iterator& operator++();
  135.   iterator operator++(int);
  136.   bool operator==(const iterator& __it) const
  137.     { return _M_cur == __it._M_cur; }
  138.   bool operator!=(const iterator& __it) const
  139.     { return _M_cur != __it._M_cur; }
  140. };
  141.  
  142.  
  143. template <class _Val, class _Key, class _HashFcn,
  144.           class _ExtractKey, class _EqualKey, class _Alloc>
  145. struct _Hashtable_const_iterator {
  146.   typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  147.           _Hashtable;
  148.   typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
  149.                               _ExtractKey,_EqualKey,_Alloc>
  150.           iterator;
  151.   typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
  152.                                     _ExtractKey, _EqualKey, _Alloc>
  153.           const_iterator;
  154.   typedef _Hashtable_node<_Val> _Node;
  155.  
  156.   typedef forward_iterator_tag iterator_category;
  157.   typedef _Val value_type;
  158.   typedef ptrdiff_t difference_type;
  159.   typedef size_t size_type;
  160.   typedef const _Val& reference;
  161.   typedef const _Val* pointer;
  162.  
  163.   const _Node* _M_cur;
  164.   const _Hashtable* _M_ht;
  165.  
  166.   _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
  167.     : _M_cur(__n), _M_ht(__tab) {}
  168.   _Hashtable_const_iterator() {}
  169.   _Hashtable_const_iterator(const iterator& __it)
  170.     : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
  171.   reference operator*() const { return _M_cur->_M_val; }
  172.   pointer operator->() const { return &(operator*()); }
  173.   const_iterator& operator++();
  174.   const_iterator operator++(int);
  175.   bool operator==(const const_iterator& __it) const
  176.     { return _M_cur == __it._M_cur; }
  177.   bool operator!=(const const_iterator& __it) const
  178.     { return _M_cur != __it._M_cur; }
  179. };
  180.  
  181. // Note: assumes long is at least 32 bits.
  182. enum { _S_num_primes = 28 };
  183.  
  184. static const unsigned long __stl_prime_list[_S_num_primes] =
  185. {
  186.   53ul,         97ul,         193ul,       389ul,       769ul,
  187.   1543ul,       3079ul,       6151ul,      12289ul,     24593ul,
  188.   49157ul,      98317ul,      196613ul,    393241ul,    786433ul,
  189.   1572869ul,    3145739ul,    6291469ul,   12582917ul,  25165843ul,
  190.   50331653ul,   100663319ul,  201326611ul, 402653189ul, 805306457ul,
  191.   1610612741ul, 3221225473ul, 4294967291ul
  192. };
  193.  
  194. inline unsigned long __stl_next_prime(unsigned long __n)
  195. {
  196.   const unsigned long* __first = __stl_prime_list;
  197.   const unsigned long* __last = __stl_prime_list + (int)_S_num_primes;
  198.   const unsigned long* pos = std::lower_bound(__first, __last, __n);
  199.   return pos == __last ? *(__last - 1) : *pos;
  200. }
  201.  
  202. // Forward declaration of operator==.
  203.  
  204. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  205. class hashtable;
  206.  
  207. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  208. bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  209.                 const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2);
  210.  
  211.  
  212. // Hashtables handle allocators a bit differently than other
  213. // containers do.  If we're using standard-conforming allocators, then
  214. // a hashtable unconditionally has a member variable to hold its
  215. // allocator, even if it so happens that all instances of the
  216. // allocator type are identical.  This is because, for hashtables,
  217. // this extra storage is negligible.  Additionally, a base class
  218. // wouldn't serve any other purposes; it wouldn't, for example,
  219. // simplify the exception-handling code.
  220.  
  221. template <class _Val, class _Key, class _HashFcn,
  222.           class _ExtractKey, class _EqualKey, class _Alloc>
  223. class hashtable {
  224. public:
  225.   typedef _Key key_type;
  226.   typedef _Val value_type;
  227.   typedef _HashFcn hasher;
  228.   typedef _EqualKey key_equal;
  229.  
  230.   typedef size_t            size_type;
  231.   typedef ptrdiff_t         difference_type;
  232.   typedef value_type*       pointer;
  233.   typedef const value_type* const_pointer;
  234.   typedef value_type&       reference;
  235.   typedef const value_type& const_reference;
  236.  
  237.   hasher hash_funct() const { return _M_hash; }
  238.   key_equal key_eq() const { return _M_equals; }
  239.  
  240. private:
  241.   typedef _Hashtable_node<_Val> _Node;
  242.  
  243. public:
  244.   typedef _Alloc allocator_type;
  245.   allocator_type get_allocator() const { return _M_node_allocator; }
  246. private:
  247.   typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
  248.   typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
  249.   typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
  250.  
  251.   _Node_Alloc _M_node_allocator;
  252.   _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
  253.   void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
  254.  
  255. private:
  256.   hasher                _M_hash;
  257.   key_equal             _M_equals;
  258.   _ExtractKey           _M_get_key;
  259.   _Vector_type          _M_buckets;
  260.   size_type             _M_num_elements;
  261.  
  262. public:
  263.   typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
  264.           iterator;
  265.   typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,
  266.                                     _Alloc>
  267.           const_iterator;
  268.  
  269.   friend struct
  270.   _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
  271.   friend struct
  272.   _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
  273.  
  274. public:
  275.   hashtable(size_type __n,
  276.             const _HashFcn&    __hf,
  277.             const _EqualKey&   __eql,
  278.             const _ExtractKey& __ext,
  279.             const allocator_type& __a = allocator_type())
  280.     : _M_node_allocator(__a),
  281.       _M_hash(__hf),
  282.       _M_equals(__eql),
  283.       _M_get_key(__ext),
  284.       _M_buckets(__a),
  285.       _M_num_elements(0)
  286.   {
  287.     _M_initialize_buckets(__n);
  288.   }
  289.  
  290.   hashtable(size_type __n,
  291.             const _HashFcn&    __hf,
  292.             const _EqualKey&   __eql,
  293.             const allocator_type& __a = allocator_type())
  294.     : _M_node_allocator(__a),
  295.       _M_hash(__hf),
  296.       _M_equals(__eql),
  297.       _M_get_key(_ExtractKey()),
  298.       _M_buckets(__a),
  299.       _M_num_elements(0)
  300.   {
  301.     _M_initialize_buckets(__n);
  302.   }
  303.  
  304.   hashtable(const hashtable& __ht)
  305.     : _M_node_allocator(__ht.get_allocator()),
  306.       _M_hash(__ht._M_hash),
  307.       _M_equals(__ht._M_equals),
  308.       _M_get_key(__ht._M_get_key),
  309.       _M_buckets(__ht.get_allocator()),
  310.       _M_num_elements(0)
  311.   {
  312.     _M_copy_from(__ht);
  313.   }
  314.  
  315.   hashtable& operator= (const hashtable& __ht)
  316.   {
  317.     if (&__ht != this) {
  318.       clear();
  319.       _M_hash = __ht._M_hash;
  320.       _M_equals = __ht._M_equals;
  321.       _M_get_key = __ht._M_get_key;
  322.       _M_copy_from(__ht);
  323.     }
  324.     return *this;
  325.   }
  326.  
  327.   ~hashtable() { clear(); }
  328.  
  329.   size_type size() const { return _M_num_elements; }
  330.   size_type max_size() const { return size_type(-1); }
  331.   bool empty() const { return size() == 0; }
  332.  
  333.   void swap(hashtable& __ht)
  334.   {
  335.     std::swap(_M_hash, __ht._M_hash);
  336.     std::swap(_M_equals, __ht._M_equals);
  337.     std::swap(_M_get_key, __ht._M_get_key);
  338.     _M_buckets.swap(__ht._M_buckets);
  339.     std::swap(_M_num_elements, __ht._M_num_elements);
  340.   }
  341.  
  342.   iterator begin()
  343.   {
  344.     for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  345.       if (_M_buckets[__n])
  346.         return iterator(_M_buckets[__n], this);
  347.     return end();
  348.   }
  349.  
  350.   iterator end() { return iterator(0, this); }
  351.  
  352.   const_iterator begin() const
  353.   {
  354.     for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
  355.       if (_M_buckets[__n])
  356.         return const_iterator(_M_buckets[__n], this);
  357.     return end();
  358.   }
  359.  
  360.   const_iterator end() const { return const_iterator(0, this); }
  361.  
  362.   template <class _Vl, class _Ky, class _HF, class _Ex, class _Eq, class _Al>
  363.   friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
  364.                           const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
  365. public:
  366.  
  367.   size_type bucket_count() const { return _M_buckets.size(); }
  368.  
  369.   size_type max_bucket_count() const
  370.     { return __stl_prime_list[(int)_S_num_primes - 1]; }
  371.  
  372.   size_type elems_in_bucket(size_type __bucket) const
  373.   {
  374.     size_type __result = 0;
  375.     for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
  376.       __result += 1;
  377.     return __result;
  378.   }
  379.  
  380.   pair<iterator, bool> insert_unique(const value_type& __obj)
  381.   {
  382.     resize(_M_num_elements + 1);
  383.     return insert_unique_noresize(__obj);
  384.   }
  385.  
  386.   iterator insert_equal(const value_type& __obj)
  387.   {
  388.     resize(_M_num_elements + 1);
  389.     return insert_equal_noresize(__obj);
  390.   }
  391.  
  392.   pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
  393.   iterator insert_equal_noresize(const value_type& __obj);
  394.  
  395.   template <class _InputIterator>
  396.   void insert_unique(_InputIterator __f, _InputIterator __l)
  397.   {
  398.     insert_unique(__f, __l, __iterator_category(__f));
  399.   }
  400.  
  401.   template <class _InputIterator>
  402.   void insert_equal(_InputIterator __f, _InputIterator __l)
  403.   {
  404.     insert_equal(__f, __l, __iterator_category(__f));
  405.   }
  406.  
  407.   template <class _InputIterator>
  408.   void insert_unique(_InputIterator __f, _InputIterator __l,
  409.                      input_iterator_tag)
  410.   {
  411.     for ( ; __f != __l; ++__f)
  412.       insert_unique(*__f);
  413.   }
  414.  
  415.   template <class _InputIterator>
  416.   void insert_equal(_InputIterator __f, _InputIterator __l,
  417.                     input_iterator_tag)
  418.   {
  419.     for ( ; __f != __l; ++__f)
  420.       insert_equal(*__f);
  421.   }
  422.  
  423.   template <class _ForwardIterator>
  424.   void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
  425.                      forward_iterator_tag)
  426.   {
  427.     size_type __n = distance(__f, __l);
  428.     resize(_M_num_elements + __n);
  429.     for ( ; __n > 0; --__n, ++__f)
  430.       insert_unique_noresize(*__f);
  431.   }
  432.  
  433.   template <class _ForwardIterator>
  434.   void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
  435.                     forward_iterator_tag)
  436.   {
  437.     size_type __n = distance(__f, __l);
  438.     resize(_M_num_elements + __n);
  439.     for ( ; __n > 0; --__n, ++__f)
  440.       insert_equal_noresize(*__f);
  441.   }
  442.  
  443.   reference find_or_insert(const value_type& __obj);
  444.  
  445.   iterator find(const key_type& __key)
  446.   {
  447.     size_type __n = _M_bkt_num_key(__key);
  448.     _Node* __first;
  449.     for ( __first = _M_buckets[__n];
  450.           __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  451.           __first = __first->_M_next)
  452.       {}
  453.     return iterator(__first, this);
  454.   }
  455.  
  456.   const_iterator find(const key_type& __key) const
  457.   {
  458.     size_type __n = _M_bkt_num_key(__key);
  459.     const _Node* __first;
  460.     for ( __first = _M_buckets[__n];
  461.           __first && !_M_equals(_M_get_key(__first->_M_val), __key);
  462.           __first = __first->_M_next)
  463.       {}
  464.     return const_iterator(__first, this);
  465.   }
  466.  
  467.   size_type count(const key_type& __key) const
  468.   {
  469.     const size_type __n = _M_bkt_num_key(__key);
  470.     size_type __result = 0;
  471.  
  472.     for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next)
  473.       if (_M_equals(_M_get_key(__cur->_M_val), __key))
  474.         ++__result;
  475.     return __result;
  476.   }
  477.  
  478.   pair<iterator, iterator>
  479.   equal_range(const key_type& __key);
  480.  
  481.   pair<const_iterator, const_iterator>
  482.   equal_range(const key_type& __key) const;
  483.  
  484.   size_type erase(const key_type& __key);
  485.   void erase(const iterator& __it);
  486.   void erase(iterator __first, iterator __last);
  487.  
  488.   void erase(const const_iterator& __it);
  489.   void erase(const_iterator __first, const_iterator __last);
  490.  
  491.   void resize(size_type __num_elements_hint);
  492.   void clear();
  493.  
  494. private:
  495.   size_type _M_next_size(size_type __n) const
  496.     { return __stl_next_prime(__n); }
  497.  
  498.   void _M_initialize_buckets(size_type __n)
  499.   {
  500.     const size_type __n_buckets = _M_next_size(__n);
  501.     _M_buckets.reserve(__n_buckets);
  502.     _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
  503.     _M_num_elements = 0;
  504.   }
  505.  
  506.   size_type _M_bkt_num_key(const key_type& __key) const
  507.   {
  508.     return _M_bkt_num_key(__key, _M_buckets.size());
  509.   }
  510.  
  511.   size_type _M_bkt_num(const value_type& __obj) const
  512.   {
  513.     return _M_bkt_num_key(_M_get_key(__obj));
  514.   }
  515.  
  516.   size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
  517.   {
  518.     return _M_hash(__key) % __n;
  519.   }
  520.  
  521.   size_type _M_bkt_num(const value_type& __obj, size_t __n) const
  522.   {
  523.     return _M_bkt_num_key(_M_get_key(__obj), __n);
  524.   }
  525.  
  526.   _Node* _M_new_node(const value_type& __obj)
  527.   {
  528.     _Node* __n = _M_get_node();
  529.     __n->_M_next = 0;
  530.     try {
  531.       _Construct(&__n->_M_val, __obj);
  532.       return __n;
  533.     }
  534.     catch(...)
  535.       {
  536.     _M_put_node(__n);
  537.     __throw_exception_again;
  538.       }
  539.   }
  540.  
  541.   void _M_delete_node(_Node* __n)
  542.   {
  543.     _Destroy(&__n->_M_val);
  544.     _M_put_node(__n);
  545.   }
  546.  
  547.   void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
  548.   void _M_erase_bucket(const size_type __n, _Node* __last);
  549.  
  550.   void _M_copy_from(const hashtable& __ht);
  551.  
  552. };
  553.  
  554. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  555.           class _All>
  556. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
  557. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
  558. {
  559.   const _Node* __old = _M_cur;
  560.   _M_cur = _M_cur->_M_next;
  561.   if (!_M_cur) {
  562.     size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  563.     while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  564.       _M_cur = _M_ht->_M_buckets[__bucket];
  565.   }
  566.   return *this;
  567. }
  568.  
  569. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  570.           class _All>
  571. inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
  572. _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
  573. {
  574.   iterator __tmp = *this;
  575.   ++*this;
  576.   return __tmp;
  577. }
  578.  
  579. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  580.           class _All>
  581. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
  582. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
  583. {
  584.   const _Node* __old = _M_cur;
  585.   _M_cur = _M_cur->_M_next;
  586.   if (!_M_cur) {
  587.     size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
  588.     while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
  589.       _M_cur = _M_ht->_M_buckets[__bucket];
  590.   }
  591.   return *this;
  592. }
  593.  
  594. template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
  595.           class _All>
  596. inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
  597. _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
  598. {
  599.   const_iterator __tmp = *this;
  600.   ++*this;
  601.   return __tmp;
  602. }
  603.  
  604. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  605. bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  606.                 const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2)
  607. {
  608.   typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node;
  609.   if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
  610.     return false;
  611.   for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
  612.     _Node* __cur1 = __ht1._M_buckets[__n];
  613.     _Node* __cur2 = __ht2._M_buckets[__n];
  614.     // Check same length of lists
  615.     for ( ; __cur1 && __cur2;
  616.           __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
  617.       {}
  618.     if (__cur1 || __cur2)
  619.       return false;
  620.     // Now check one's elements are in the other
  621.     for (__cur1 = __ht1._M_buckets[__n] ; __cur1; __cur1 = __cur1->_M_next)
  622.     {
  623.       bool _found__cur1 = false;
  624.       for (_Node* __cur2 = __ht2._M_buckets[__n];
  625.            __cur2; __cur2 = __cur2->_M_next)
  626.       {
  627.         if (__cur1->_M_val == __cur2->_M_val)
  628.         {
  629.           _found__cur1 = true;
  630.           break;
  631.         }
  632.       }
  633.       if (!_found__cur1)
  634.         return false;
  635.     }
  636.   }
  637.   return true;
  638. }
  639.  
  640. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  641. inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
  642.                        const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) {
  643.   return !(__ht1 == __ht2);
  644. }
  645.  
  646. template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
  647.           class _All>
  648. inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
  649.                  hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) {
  650.   __ht1.swap(__ht2);
  651. }
  652.  
  653.  
  654. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  655. pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
  656. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  657.   ::insert_unique_noresize(const value_type& __obj)
  658. {
  659.   const size_type __n = _M_bkt_num(__obj);
  660.   _Node* __first = _M_buckets[__n];
  661.  
  662.   for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  663.     if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  664.       return pair<iterator, bool>(iterator(__cur, this), false);
  665.  
  666.   _Node* __tmp = _M_new_node(__obj);
  667.   __tmp->_M_next = __first;
  668.   _M_buckets[__n] = __tmp;
  669.   ++_M_num_elements;
  670.   return pair<iterator, bool>(iterator(__tmp, this), true);
  671. }
  672.  
  673. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  674. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator
  675. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  676.   ::insert_equal_noresize(const value_type& __obj)
  677. {
  678.   const size_type __n = _M_bkt_num(__obj);
  679.   _Node* __first = _M_buckets[__n];
  680.  
  681.   for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  682.     if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
  683.       _Node* __tmp = _M_new_node(__obj);
  684.       __tmp->_M_next = __cur->_M_next;
  685.       __cur->_M_next = __tmp;
  686.       ++_M_num_elements;
  687.       return iterator(__tmp, this);
  688.     }
  689.  
  690.   _Node* __tmp = _M_new_node(__obj);
  691.   __tmp->_M_next = __first;
  692.   _M_buckets[__n] = __tmp;
  693.   ++_M_num_elements;
  694.   return iterator(__tmp, this);
  695. }
  696.  
  697. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  698. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference
  699. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
  700. {
  701.   resize(_M_num_elements + 1);
  702.  
  703.   size_type __n = _M_bkt_num(__obj);
  704.   _Node* __first = _M_buckets[__n];
  705.  
  706.   for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
  707.     if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
  708.       return __cur->_M_val;
  709.  
  710.   _Node* __tmp = _M_new_node(__obj);
  711.   __tmp->_M_next = __first;
  712.   _M_buckets[__n] = __tmp;
  713.   ++_M_num_elements;
  714.   return __tmp->_M_val;
  715. }
  716.  
  717. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  718. pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
  719.      typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
  720. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
  721. {
  722.   typedef pair<iterator, iterator> _Pii;
  723.   const size_type __n = _M_bkt_num_key(__key);
  724.  
  725.   for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
  726.     if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  727.       for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
  728.         if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  729.           return _Pii(iterator(__first, this), iterator(__cur, this));
  730.       for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  731.         if (_M_buckets[__m])
  732.           return _Pii(iterator(__first, this),
  733.                      iterator(_M_buckets[__m], this));
  734.       return _Pii(iterator(__first, this), end());
  735.     }
  736.   return _Pii(end(), end());
  737. }
  738.  
  739. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  740. pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
  741.      typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
  742. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  743.   ::equal_range(const key_type& __key) const
  744. {
  745.   typedef pair<const_iterator, const_iterator> _Pii;
  746.   const size_type __n = _M_bkt_num_key(__key);
  747.  
  748.   for (const _Node* __first = _M_buckets[__n] ;
  749.        __first;
  750.        __first = __first->_M_next) {
  751.     if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  752.       for (const _Node* __cur = __first->_M_next;
  753.            __cur;
  754.            __cur = __cur->_M_next)
  755.         if (!_M_equals(_M_get_key(__cur->_M_val), __key))
  756.           return _Pii(const_iterator(__first, this),
  757.                       const_iterator(__cur, this));
  758.       for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
  759.         if (_M_buckets[__m])
  760.           return _Pii(const_iterator(__first, this),
  761.                       const_iterator(_M_buckets[__m], this));
  762.       return _Pii(const_iterator(__first, this), end());
  763.     }
  764.   }
  765.   return _Pii(end(), end());
  766. }
  767.  
  768. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  769. typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type
  770. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
  771. {
  772.   const size_type __n = _M_bkt_num_key(__key);
  773.   _Node* __first = _M_buckets[__n];
  774.   size_type __erased = 0;
  775.  
  776.   if (__first) {
  777.     _Node* __cur = __first;
  778.     _Node* __next = __cur->_M_next;
  779.     while (__next) {
  780.       if (_M_equals(_M_get_key(__next->_M_val), __key)) {
  781.         __cur->_M_next = __next->_M_next;
  782.         _M_delete_node(__next);
  783.         __next = __cur->_M_next;
  784.         ++__erased;
  785.         --_M_num_elements;
  786.       }
  787.       else {
  788.         __cur = __next;
  789.         __next = __cur->_M_next;
  790.       }
  791.     }
  792.     if (_M_equals(_M_get_key(__first->_M_val), __key)) {
  793.       _M_buckets[__n] = __first->_M_next;
  794.       _M_delete_node(__first);
  795.       ++__erased;
  796.       --_M_num_elements;
  797.     }
  798.   }
  799.   return __erased;
  800. }
  801.  
  802. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  803. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
  804. {
  805.   _Node* __p = __it._M_cur;
  806.   if (__p) {
  807.     const size_type __n = _M_bkt_num(__p->_M_val);
  808.     _Node* __cur = _M_buckets[__n];
  809.  
  810.     if (__cur == __p) {
  811.       _M_buckets[__n] = __cur->_M_next;
  812.       _M_delete_node(__cur);
  813.       --_M_num_elements;
  814.     }
  815.     else {
  816.       _Node* __next = __cur->_M_next;
  817.       while (__next) {
  818.         if (__next == __p) {
  819.           __cur->_M_next = __next->_M_next;
  820.           _M_delete_node(__next);
  821.           --_M_num_elements;
  822.           break;
  823.         }
  824.         else {
  825.           __cur = __next;
  826.           __next = __cur->_M_next;
  827.         }
  828.       }
  829.     }
  830.   }
  831. }
  832.  
  833. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  834. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  835.   ::erase(iterator __first, iterator __last)
  836. {
  837.   size_type __f_bucket = __first._M_cur ?
  838.     _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
  839.   size_type __l_bucket = __last._M_cur ?
  840.     _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
  841.  
  842.   if (__first._M_cur == __last._M_cur)
  843.     return;
  844.   else if (__f_bucket == __l_bucket)
  845.     _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
  846.   else {
  847.     _M_erase_bucket(__f_bucket, __first._M_cur, 0);
  848.     for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
  849.       _M_erase_bucket(__n, 0);
  850.     if (__l_bucket != _M_buckets.size())
  851.       _M_erase_bucket(__l_bucket, __last._M_cur);
  852.   }
  853. }
  854.  
  855. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  856. inline void
  857. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first,
  858.                                              const_iterator __last)
  859. {
  860.   erase(iterator(const_cast<_Node*>(__first._M_cur),
  861.                  const_cast<hashtable*>(__first._M_ht)),
  862.         iterator(const_cast<_Node*>(__last._M_cur),
  863.                  const_cast<hashtable*>(__last._M_ht)));
  864. }
  865.  
  866. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  867. inline void
  868. hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it)
  869. {
  870.   erase(iterator(const_cast<_Node*>(__it._M_cur),
  871.                  const_cast<hashtable*>(__it._M_ht)));
  872. }
  873.  
  874. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  875. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  876.   ::resize(size_type __num_elements_hint)
  877. {
  878.   const size_type __old_n = _M_buckets.size();
  879.   if (__num_elements_hint > __old_n) {
  880.     const size_type __n = _M_next_size(__num_elements_hint);
  881.     if (__n > __old_n) {
  882.       _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
  883.       try {
  884.         for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
  885.           _Node* __first = _M_buckets[__bucket];
  886.           while (__first) {
  887.             size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
  888.             _M_buckets[__bucket] = __first->_M_next;
  889.             __first->_M_next = __tmp[__new_bucket];
  890.             __tmp[__new_bucket] = __first;
  891.             __first = _M_buckets[__bucket];
  892.           }
  893.         }
  894.         _M_buckets.swap(__tmp);
  895.       }
  896.       catch(...) {
  897.         for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
  898.           while (__tmp[__bucket]) {
  899.             _Node* __next = __tmp[__bucket]->_M_next;
  900.             _M_delete_node(__tmp[__bucket]);
  901.             __tmp[__bucket] = __next;
  902.           }
  903.         }
  904.         __throw_exception_again;
  905.       }
  906.     }
  907.   }
  908. }
  909.  
  910. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  911. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  912.   ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
  913. {
  914.   _Node* __cur = _M_buckets[__n];
  915.   if (__cur == __first)
  916.     _M_erase_bucket(__n, __last);
  917.   else {
  918.     _Node* __next;
  919.     for (__next = __cur->_M_next;
  920.          __next != __first;
  921.          __cur = __next, __next = __cur->_M_next)
  922.       ;
  923.     while (__next != __last) {
  924.       __cur->_M_next = __next->_M_next;
  925.       _M_delete_node(__next);
  926.       __next = __cur->_M_next;
  927.       --_M_num_elements;
  928.     }
  929.   }
  930. }
  931.  
  932. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  933. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  934.   ::_M_erase_bucket(const size_type __n, _Node* __last)
  935. {
  936.   _Node* __cur = _M_buckets[__n];
  937.   while (__cur != __last) {
  938.     _Node* __next = __cur->_M_next;
  939.     _M_delete_node(__cur);
  940.     __cur = __next;
  941.     _M_buckets[__n] = __cur;
  942.     --_M_num_elements;
  943.   }
  944. }
  945.  
  946. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  947. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear()
  948. {
  949.   for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
  950.     _Node* __cur = _M_buckets[__i];
  951.     while (__cur != 0) {
  952.       _Node* __next = __cur->_M_next;
  953.       _M_delete_node(__cur);
  954.       __cur = __next;
  955.     }
  956.     _M_buckets[__i] = 0;
  957.   }
  958.   _M_num_elements = 0;
  959. }
  960.  
  961.  
  962. template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
  963. void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
  964.   ::_M_copy_from(const hashtable& __ht)
  965. {
  966.   _M_buckets.clear();
  967.   _M_buckets.reserve(__ht._M_buckets.size());
  968.   _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
  969.   try {
  970.     for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
  971.       const _Node* __cur = __ht._M_buckets[__i];
  972.       if (__cur) {
  973.         _Node* __local_copy = _M_new_node(__cur->_M_val);
  974.         _M_buckets[__i] = __local_copy;
  975.  
  976.         for (_Node* __next = __cur->_M_next;
  977.              __next;
  978.              __cur = __next, __next = __cur->_M_next) {
  979.           __local_copy->_M_next = _M_new_node(__next->_M_val);
  980.           __local_copy = __local_copy->_M_next;
  981.         }
  982.       }
  983.     }
  984.     _M_num_elements = __ht._M_num_elements;
  985.   }
  986.   catch(...)
  987.     {
  988.       clear();
  989.       __throw_exception_again;
  990.     }
  991. }
  992. } // namespace __gnu_cxx
  993.  
  994. #endif
  995.