_hashtable.h

00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Copyright (c) 1996,1997
00007  * Silicon Graphics Computer Systems, Inc.
00008  *
00009  * Copyright (c) 1997
00010  * Moscow Center for SPARC Technology
00011  *
00012  * Copyright (c) 1999 
00013  * Boris Fomitchev
00014  *
00015  * This material is provided "as is", with absolutely no warranty expressed
00016  * or implied. Any use is at your own risk.
00017  *
00018  * Permission to use or copy this software for any purpose is hereby granted 
00019  * without fee, provided the above notices are retained on all copies.
00020  * Permission to modify the code and to distribute modified code is granted,
00021  * provided the above notices are retained, and a notice that the code was
00022  * modified is included with the above copyright notice.
00023  *
00024  */
00025 
00026 /* NOTE: This is an internal header file, included by other STL headers.
00027  *   You should not attempt to use it directly.
00028  */
00029 
00030 #ifndef _STLP_INTERNAL_HASHTABLE_H
00031 #define _STLP_INTERNAL_HASHTABLE_H
00032 
00033 # ifndef _STLP_INTERNAL_VECTOR_H
00034 #  include <stl/_vector.h>
00035 # endif
00036 
00037 # ifndef _STLP_INTERNAL_ITERATOR_H
00038 #  include <stl/_iterator.h>
00039 # endif
00040 
00041 # ifndef _STLP_INTERNAL_FUNCTION_H
00042 #  include <stl/_function_base.h>
00043 # endif
00044 
00045 # ifndef _STLP_INTERNAL_ALGOBASE_H
00046 #  include <stl/_algobase.h>
00047 # endif
00048 
00049 # ifndef _STLP_HASH_FUN_H
00050 #  include <stl/_hash_fun.h>
00051 # endif
00052 
00053 // Hashtable class, used to implement the hashed associative containers
00054 // hash_set, hash_map, hash_multiset, and hash_multimap.
00055 
00056 #ifdef _STLP_DEBUG
00057 #  define hashtable __WORKAROUND_DBG_RENAME(hashtable)
00058 #endif
00059 
00060 _STLP_BEGIN_NAMESPACE
00061 
00062 template <class _Val>
00063 struct _Hashtable_node
00064 {
00065   typedef _Hashtable_node<_Val> _Self;
00066   _Self* _M_next;
00067   _Val _M_val;
00068   __TRIVIAL_STUFF(_Hashtable_node)
00069 };  
00070 
00071 // some compilers require the names of template parameters to be the same
00072 template <class _Val, class _Key, class _HF,
00073           class _ExK, class _EqK, class _All>
00074 class hashtable;
00075 
00076 template <class _Val, class _Key, class _HF,
00077           class _ExK, class _EqK, class _All>
00078 struct _Hashtable_iterator
00079 {
00080   typedef hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
00081           _Hashtable;
00082   typedef _Hashtable_node<_Val> _Node;
00083 
00084   _Node* _M_cur;
00085   _Hashtable* _M_ht;
00086 
00087   _Hashtable_iterator(_Node* __n, _Hashtable* __tab) 
00088     : _M_cur(__n), _M_ht(__tab) {}
00089   _Hashtable_iterator() {}
00090 
00091   _Node* _M_skip_to_next();
00092 };
00093 
00094 
00095 template <class _Val, class _Traits, class _Key, class _HF,
00096           class _ExK, class _EqK, class _All>
00097 struct _Ht_iterator : public _Hashtable_iterator< _Val, _Key,_HF, _ExK,_EqK,_All>
00098 {
00099   
00100   typedef _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> _Base;
00101 
00102   //  typedef _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All> iterator;
00103   //  typedef _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK,_All> const_iterator;
00104   typedef _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All> _Self;
00105 
00106   typedef hashtable<_Val,_Key,_HF,_ExK,_EqK,_All> _Hashtable;
00107   typedef _Hashtable_node<_Val> _Node;
00108 
00109   typedef _Val value_type;
00110   typedef forward_iterator_tag iterator_category;
00111   typedef ptrdiff_t difference_type;
00112   typedef size_t size_type;
00113   typedef typename _Traits::reference reference;
00114   typedef typename _Traits::pointer   pointer;
00115 
00116   _Ht_iterator(const _Node* __n, const _Hashtable* __tab) :
00117     _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>((_Node*)__n, (_Hashtable*)__tab) {}
00118   _Ht_iterator() {}
00119   _Ht_iterator(const _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __it) : 
00120     _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>(__it) {}
00121 
00122   reference operator*() const { 
00123       return this->_M_cur->_M_val; 
00124   }
00125   _STLP_DEFINE_ARROW_OPERATOR
00126 
00127   _Self& operator++() {
00128     _Node* __n = this->_M_cur->_M_next;
00129     this->_M_cur =  (__n !=0 ? __n : this->_M_skip_to_next());
00130     return *this;
00131   }
00132   inline  _Self operator++(int) {
00133      _Self __tmp = *this;
00134     ++*this;
00135     return __tmp;
00136   }
00137 };
00138 
00139 template <class _Val, class _Traits, class _Traits1, class _Key, class _HF,
00140           class _ExK, class _EqK, class _All>
00141 inline bool 
00142 operator==(const _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All>& __x, 
00143            const _Ht_iterator<_Val, _Traits1,_Key,_HF,_ExK,_EqK,_All>& __y) { 
00144   return __x._M_cur == __y._M_cur; 
00145 }
00146 
00147 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
00148 template <class _Val, class _Key, class _HF,
00149           class _ExK, class _EqK, class _All>
00150 inline bool 
00151 operator!=(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& __x, 
00152            const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& __y) { 
00153   return __x._M_cur != __y._M_cur; 
00154 }
00155 #else
00156 
00157 # if (defined (__GNUC__) && (__GNUC_MINOR__ < 8) && !defined (__SYMBIAN32__))
00158 template <class _Val, class _Key, class _HF,
00159           class _ExK, class _EqK, class _All>
00160 inline bool
00161 operator!=(const _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __x,
00162            const _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __y) {
00163   return __x._M_cur != __y._M_cur;
00164 }
00165 # endif
00166 
00167 template <class _Val, class _Key, class _HF,
00168           class _ExK, class _EqK, class _All>
00169 inline bool 
00170 operator!=(const _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __x, 
00171            const _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>& __y) { 
00172   return __x._M_cur != __y._M_cur; 
00173 }
00174 #endif
00175 
00176 # ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
00177 template <class _Val, class _Traits, class _Key, class _HF, class _ExK, class _EqK, class _All>
00178 inline _Val* value_type(const _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All>&) { return (_Val*) 0; }
00179 template <class _Val, class _Traits, class _Key, class _HF, class _ExK, class _EqK, class _All>
00180 inline forward_iterator_tag iterator_category(const _Ht_iterator<_Val, _Traits,_Key,_HF,_ExK,_EqK,_All>&) { return forward_iterator_tag(); }
00181 template <class _Val, class _Traits, class _Key, class _HF, class _ExK, class _EqK, class _All>
00182 inline ptrdiff_t* distance_type(const _Ht_iterator<_Val,_Traits,_Key,_HF,_ExK,_EqK,_All>&) { return (ptrdiff_t*) 0; }
00183 #endif
00184 
00185 #define __stl_num_primes  28
00186 template <class _Tp>
00187 class _Stl_prime {
00188 public:
00189   static const size_t _M_list[__stl_num_primes];
00190 };
00191 
00192 # if defined (_STLP_USE_TEMPLATE_EXPORT) 
00193 _STLP_EXPORT_TEMPLATE_CLASS _Stl_prime<bool>;
00194 # endif
00195 
00196 typedef _Stl_prime<bool> _Stl_prime_type;
00197 
00198 
00199 // Hashtables handle allocators a bit differently than other containers
00200 //  do.  If we're using standard-conforming allocators, then a hashtable
00201 //  unconditionally has a member variable to hold its allocator, even if
00202 //  it so happens that all instances of the allocator type are identical.
00203 // This is because, for hashtables, this extra storage is negligible.  
00204 //  Additionally, a base class wouldn't serve any other purposes; it 
00205 //  wouldn't, for example, simplify the exception-handling code.
00206 template <class _Val, class _Key, class _HF,
00207           class _ExK, class _EqK, class _All>
00208 class hashtable {
00209   typedef hashtable<_Val, _Key, _HF, _ExK, _EqK, _All> _Self;
00210 public:
00211   typedef _Key key_type;
00212   typedef _Val value_type;
00213   typedef _HF hasher;
00214   typedef _EqK key_equal;
00215 
00216   typedef size_t            size_type;
00217   typedef ptrdiff_t         difference_type;
00218   typedef value_type*       pointer;
00219   typedef const value_type* const_pointer;
00220   typedef value_type&       reference;
00221   typedef const value_type& const_reference;
00222   typedef forward_iterator_tag _Iterator_category;
00223 
00224   hasher hash_funct() const { return _M_hash; }
00225   key_equal key_eq() const { return _M_equals; }
00226 
00227 private:
00228   typedef _Hashtable_node<_Val> _Node;
00229 
00230 private:
00231   _STLP_FORCE_ALLOCATORS(_Val, _All)
00232   typedef typename _Alloc_traits<_Node, _All>::allocator_type _M_node_allocator_type;
00233   typedef typename _Alloc_traits<void*, _All>::allocator_type _M_node_ptr_allocator_type;
00234   typedef __vector__<void*, _M_node_ptr_allocator_type> _BucketVector;
00235 public:
00236   typedef typename _Alloc_traits<_Val,_All>::allocator_type allocator_type;
00237   allocator_type get_allocator() const { 
00238     return _STLP_CONVERT_ALLOCATOR((const _M_node_allocator_type&)_M_num_elements, _Val); 
00239   }
00240 private:
00241   hasher                _M_hash;
00242   key_equal             _M_equals;
00243   _ExK                  _M_get_key;
00244   _BucketVector         _M_buckets;
00245   _STLP_alloc_proxy<size_type, _Node, _M_node_allocator_type>  _M_num_elements;
00246   const _Node* _M_get_bucket(size_t __n) const { return (_Node*)_M_buckets[__n]; }
00247 
00248 public:
00249   typedef _Const_traits<_Val> __const_val_traits;
00250   typedef _Nonconst_traits<_Val> __nonconst_val_traits;
00251   typedef _Ht_iterator<_Val, __const_val_traits,_Key,_HF,_ExK,_EqK, _All> const_iterator;
00252   typedef _Ht_iterator<_Val, __nonconst_val_traits,_Key,_HF,_ExK,_EqK,_All> iterator;
00253   friend struct _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>;
00254   friend struct _Ht_iterator<_Val, _Nonconst_traits<_Val>,_Key,_HF,_ExK,_EqK,_All>;
00255   friend struct _Ht_iterator<_Val, _Const_traits<_Val>,_Key,_HF,_ExK,_EqK, _All>;
00256 
00257 public:
00258   hashtable(size_type __n,
00259             const _HF&  __hf,
00260             const _EqK& __eql,
00261             const _ExK& __ext,
00262             const allocator_type& __a = allocator_type())
00263     :
00264       _M_hash(__hf),
00265       _M_equals(__eql),
00266       _M_get_key(__ext),
00267       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a,void*)),
00268       _M_num_elements(_STLP_CONVERT_ALLOCATOR(__a,_Node), (size_type)0)
00269   {
00270     _M_initialize_buckets(__n);
00271   }
00272 
00273   hashtable(size_type __n,
00274             const _HF&    __hf,
00275             const _EqK&   __eql,
00276             const allocator_type& __a = allocator_type())
00277     :
00278       _M_hash(__hf),
00279       _M_equals(__eql),
00280       _M_get_key(_ExK()),
00281       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a,void*)),
00282       _M_num_elements(_STLP_CONVERT_ALLOCATOR(__a,_Node), (size_type)0)
00283   {
00284     _M_initialize_buckets(__n);
00285   }
00286 
00287   hashtable(const _Self& __ht)
00288     :
00289       _M_hash(__ht._M_hash),
00290       _M_equals(__ht._M_equals),
00291       _M_get_key(__ht._M_get_key),
00292       _M_buckets(_STLP_CONVERT_ALLOCATOR(__ht.get_allocator(),void*)),
00293       _M_num_elements((const _M_node_allocator_type&)__ht._M_num_elements, (size_type)0)
00294   {
00295     _M_copy_from(__ht);
00296   }
00297 
00298   _Self& operator= (const _Self& __ht)
00299   {
00300     if (&__ht != this) {
00301       clear();
00302       _M_hash = __ht._M_hash;
00303       _M_equals = __ht._M_equals;
00304       _M_get_key = __ht._M_get_key;
00305       _M_copy_from(__ht);
00306     }
00307     return *this;
00308   }
00309 
00310   ~hashtable() { clear(); }
00311 
00312   size_type size() const { return _M_num_elements._M_data; }
00313   size_type max_size() const { return size_type(-1); }
00314   bool empty() const { return size() == 0; }
00315 
00316   void swap(_Self& __ht)
00317   {
00318     _STLP_STD::swap(_M_hash, __ht._M_hash);
00319     _STLP_STD::swap(_M_equals, __ht._M_equals);
00320     _STLP_STD::swap(_M_get_key, __ht._M_get_key);
00321     _M_buckets.swap(__ht._M_buckets);
00322     _STLP_STD::swap(_M_num_elements, __ht._M_num_elements);
00323   }
00324 
00325   iterator begin()
00326   { 
00327     for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
00328       if (_M_buckets[__n])
00329         return iterator((_Node*)_M_buckets[__n], this);
00330     return end();
00331   }
00332 
00333   iterator end() { return iterator((_Node*)0, this); }
00334 
00335   const_iterator begin() const
00336   {
00337     for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
00338       if (_M_buckets[__n])
00339         return const_iterator((_Node*)_M_buckets[__n], this);
00340     return end();
00341   }
00342 
00343   const_iterator end() const { return const_iterator((_Node*)0, this); }
00344 
00345   static bool _STLP_CALL _M_equal (const hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>&,
00346                         const hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>&);
00347 
00348 public:
00349 
00350   size_type bucket_count() const { return _M_buckets.size(); }
00351 
00352   size_type max_bucket_count() const
00353     { return _Stl_prime_type::_M_list[(int)__stl_num_primes - 1]; } 
00354 
00355   size_type elems_in_bucket(size_type __bucket) const
00356   {
00357     size_type __result = 0;
00358     for (_Node* __cur = (_Node*)_M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
00359       __result += 1;
00360     return __result;
00361   }
00362 
00363   pair<iterator, bool> insert_unique(const value_type& __obj)
00364   {
00365     resize(_M_num_elements._M_data + 1);
00366     return insert_unique_noresize(__obj);
00367   }
00368 
00369   iterator insert_equal(const value_type& __obj)
00370   {
00371     resize(_M_num_elements._M_data + 1);
00372     return insert_equal_noresize(__obj);
00373   }
00374 
00375   pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
00376   iterator insert_equal_noresize(const value_type& __obj);
00377  
00378 #ifdef _STLP_MEMBER_TEMPLATES
00379   template <class _InputIterator>
00380   void insert_unique(_InputIterator __f, _InputIterator __l)
00381   {
00382     insert_unique(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator));
00383   }
00384 
00385   template <class _InputIterator>
00386   void insert_equal(_InputIterator __f, _InputIterator __l)
00387   {
00388     insert_equal(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator));
00389   }
00390 
00391   template <class _InputIterator>
00392   void insert_unique(_InputIterator __f, _InputIterator __l,
00393                      const input_iterator_tag &)
00394   {
00395     for ( ; __f != __l; ++__f)
00396       insert_unique(*__f);
00397   }
00398 
00399   template <class _InputIterator>
00400   void insert_equal(_InputIterator __f, _InputIterator __l,
00401                     const input_iterator_tag &)
00402   {
00403     for ( ; __f != __l; ++__f)
00404       insert_equal(*__f);
00405   }
00406 
00407   template <class _ForwardIterator>
00408   void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
00409                      const forward_iterator_tag &)
00410   {
00411     size_type __n = distance(__f, __l);
00412     resize(_M_num_elements._M_data + __n);
00413     for ( ; __n > 0; --__n, ++__f)
00414       insert_unique_noresize(*__f);
00415   }
00416 
00417   template <class _ForwardIterator>
00418   void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
00419                     const forward_iterator_tag &)
00420   {
00421     size_type __n = distance(__f, __l);
00422     resize(_M_num_elements._M_data + __n);
00423     for ( ; __n > 0; --__n, ++__f)
00424       insert_equal_noresize(*__f);
00425   }
00426 
00427 #else /* _STLP_MEMBER_TEMPLATES */
00428   void insert_unique(const value_type* __f, const value_type* __l)
00429   {
00430     size_type __n = __l - __f;
00431     resize(_M_num_elements._M_data + __n);
00432     for ( ; __n > 0; --__n, ++__f)
00433       insert_unique_noresize(*__f);
00434   }
00435 
00436   void insert_equal(const value_type* __f, const value_type* __l)
00437   {
00438     size_type __n = __l - __f;
00439     resize(_M_num_elements._M_data + __n);
00440     for ( ; __n > 0; --__n, ++__f)
00441       insert_equal_noresize(*__f);
00442   }
00443 
00444   void insert_unique(const_iterator __f, const_iterator __l)
00445   {
00446     size_type __n = distance(__f, __l);
00447     resize(_M_num_elements._M_data + __n);
00448     for ( ; __n > 0; --__n, ++__f)
00449       insert_unique_noresize(*__f);
00450   }
00451 
00452   void insert_equal(const_iterator __f, const_iterator __l)
00453   {
00454     size_type __n = distance(__f, __l);
00455     resize(_M_num_elements._M_data + __n);
00456     for ( ; __n > 0; --__n, ++__f)
00457       insert_equal_noresize(*__f);
00458   }
00459 #endif /*_STLP_MEMBER_TEMPLATES */
00460 
00461   reference find_or_insert(const value_type& __obj);
00462 
00463 private:
00464 # if defined(_STLP_MEMBER_TEMPLATES) && ! defined ( _STLP_NO_EXTENSIONS )  && !(defined(__MRC__)||defined(__SC__))
00465   template <class _KT> 
00466    _Node* _M_find(const _KT& __key) const
00467 # else
00468    _Node* _M_find(const key_type& __key) const
00469 # endif
00470   {
00471     size_type __n = _M_hash(__key)% _M_buckets.size();
00472     _Node* __first;
00473     for ( __first = (_Node*)_M_buckets[__n];
00474           __first && !_M_equals(_M_get_key(__first->_M_val), __key);
00475           __first = __first->_M_next)
00476       {}
00477     return __first;
00478   } 
00479 
00480 public:
00481 # if defined(_STLP_MEMBER_TEMPLATES) && ! defined ( _STLP_NO_EXTENSIONS )  && !(defined(__MRC__)||defined(__SC__))
00482   template <class _KT> 
00483   iterator find(const _KT& __key) 
00484 # else
00485   iterator find(const key_type& __key) 
00486 # endif
00487   {
00488     return iterator(_M_find(__key), this);
00489   } 
00490 
00491 # if defined(_STLP_MEMBER_TEMPLATES) && ! defined ( _STLP_NO_EXTENSIONS )  && !(defined(__MRC__)||defined(__SC__))
00492   template <class _KT> 
00493   const_iterator find(const _KT& __key) const
00494 # else
00495   const_iterator find(const key_type& __key) const
00496 # endif
00497   {
00498     return const_iterator(_M_find(__key), this);
00499   } 
00500 
00501   size_type count(const key_type& __key) const
00502   {
00503     const size_type __n = _M_bkt_num_key(__key);
00504     size_type __result = 0;
00505 
00506     for (const _Node* __cur = (_Node*)_M_buckets[__n]; __cur; __cur = __cur->_M_next)
00507       if (_M_equals(_M_get_key(__cur->_M_val), __key))
00508         ++__result;
00509     return __result;
00510   }
00511 
00512   pair<iterator, iterator> 
00513   equal_range(const key_type& __key);
00514 
00515   pair<const_iterator, const_iterator> 
00516   equal_range(const key_type& __key) const;
00517 
00518   size_type erase(const key_type& __key);
00519   //   void erase(const iterator& __it); `
00520   void erase(const const_iterator& __it) ;
00521 
00522   //  void erase(const const_iterator& __first, const const_iterator __last) {
00523   //     erase((const iterator&)__first, (const iterator&)__last);
00524   //  }
00525   void erase(const_iterator __first, const_iterator __last);
00526   void resize(size_type __num_elements_hint);
00527   void clear();
00528 
00529 private:
00530 
00531   size_type _M_next_size(size_type __n) const;
00532 
00533   void _M_initialize_buckets(size_type __n)
00534   {
00535     const size_type __n_buckets = _M_next_size(__n);
00536     _M_buckets.reserve(__n_buckets);
00537     _M_buckets.insert(_M_buckets.end(), __n_buckets, (void*) 0);
00538     _M_num_elements._M_data = 0;
00539   }
00540 
00541   size_type _M_bkt_num_key(const key_type& __key) const
00542   {
00543     return _M_bkt_num_key(__key, _M_buckets.size());
00544   }
00545 
00546   size_type _M_bkt_num(const value_type& __obj) const
00547   {
00548     return _M_bkt_num_key(_M_get_key(__obj));
00549   }
00550 
00551   size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
00552   {
00553     return _M_hash(__key) % __n;
00554   }
00555 
00556   size_type _M_bkt_num(const value_type& __obj, size_t __n) const
00557   {
00558     return _M_bkt_num_key(_M_get_key(__obj), __n);
00559   }
00560 
00561   _Node* _M_new_node(const value_type& __obj)
00562   {
00563     _Node* __n = _M_num_elements.allocate(1);
00564     __n->_M_next = 0;
00565     _STLP_TRY {
00566       _Construct(&__n->_M_val, __obj);
00567       //      return __n;
00568     }
00569     _STLP_UNWIND(_M_num_elements.deallocate(__n, 1));
00570     return __n;
00571   }
00572   
00573   void _M_delete_node(_Node* __n)
00574   {
00575     _Destroy(&__n->_M_val);
00576     _M_num_elements.deallocate(__n, 1);
00577   }
00578 
00579   void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
00580   void _M_erase_bucket(const size_type __n, _Node* __last);
00581 
00582   void _M_copy_from(const _Self& __ht);
00583 };
00584 
00585 template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>
00586 inline bool _STLP_CALL operator==(const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __ht1,
00587                        const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __ht2)
00588 {
00589   return hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_equal( __ht1, __ht2 );
00590 }
00591 
00592 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
00593 
00594 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00595 inline bool _STLP_CALL operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
00596                        const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) {
00597   return !(__ht1 == __ht2);
00598 }
00599 
00600 template <class _Val, class _Key, class _HF, class _ExK, class _EqK, 
00601           class _All>
00602 inline void _STLP_CALL swap(hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>& __ht1,
00603                  hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>& __ht2) {
00604   __ht1.swap(__ht2);
00605 }
00606 
00607 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
00608 
00609 _STLP_END_NAMESPACE
00610 
00611 # undef hashtable
00612 
00613 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
00614 #  include <stl/_hashtable.c>
00615 # endif
00616 
00617 # if defined (_STLP_DEBUG)
00618 #  include <stl/debug/_hashtable.h>
00619 # endif
00620 
00621 #endif /* _STLP_INTERNAL_HASHTABLE_H */
00622 
00623 // Local Variables:
00624 // mode:C++
00625 // End:
00626 
00627 

Generated on Mon Jun 5 10:20:46 2006 for Intelligence.kdevelop by  doxygen 1.4.6