Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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