stl_hashtable.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:32k
源码类别:

3D图形编程

开发平台:

Visual C++

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