/home/ntakagi/work/STLport-5.1.5/stlport/stl/_hashtable.h

Go to the documentation of this file.
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_SLIST_H
00038 #  include <stl/_slist.h>
00039 #endif
00040 
00041 #ifndef _STLP_INTERNAL_ITERATOR_H
00042 #  include <stl/_iterator.h>
00043 #endif
00044 
00045 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H
00046 #  include <stl/_function_base.h>
00047 #endif
00048 
00049 #ifndef _STLP_INTERNAL_ALGOBASE_H
00050 #  include <stl/_algobase.h>
00051 #endif
00052 
00053 #ifndef _STLP_HASH_FUN_H
00054 #  include <stl/_hash_fun.h>
00055 #endif
00056 
00057 /*
00058  * Hashtable class, used to implement the hashed associative containers
00059  * hash_set, hash_map, hash_multiset, hash_multimap,
00060  * unordered_set, unordered_map, unordered_multiset, unordered_multimap.
00061  */
00062 
00063 _STLP_BEGIN_NAMESPACE
00064 
00065 #if defined (_STLP_USE_TEMPLATE_EXPORT)
00066 //Export of the classes used to represent buckets in the hashtable implementation.
00067 #  if !defined (_STLP_USE_PTR_SPECIALIZATIONS)
00068 //If pointer specialization is enabled vector<_Slist_node_base*> will use the void*
00069 //storage type for which internal classes have already been exported.
00070 _STLP_EXPORT_TEMPLATE_CLASS allocator<_STLP_PRIV _Slist_node_base*>;
00071 
00072 _STLP_MOVE_TO_PRIV_NAMESPACE
00073 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<_Slist_node_base**, _Slist_node_base*,
00074                                               allocator<_Slist_node_base*> >;
00075 _STLP_EXPORT_TEMPLATE_CLASS _Vector_base<_Slist_node_base*,
00076                                          allocator<_Slist_node_base*> >;
00077 _STLP_MOVE_TO_STD_NAMESPACE
00078 #  endif
00079 
00080 #  if defined (_STLP_DEBUG)
00081 _STLP_MOVE_TO_PRIV_NAMESPACE
00082 #    define _STLP_NON_DBG_VECTOR _STLP_NON_DBG_NAME(vector)
00083 _STLP_EXPORT_TEMPLATE_CLASS __construct_checker<_STLP_NON_DBG_VECTOR<_Slist_node_base*, allocator<_Slist_node_base*> > >;
00084 _STLP_EXPORT_TEMPLATE_CLASS _STLP_NON_DBG_VECTOR<_Slist_node_base*, allocator<_Slist_node_base*> >;
00085 #    undef _STLP_NON_DBG_VECTOR
00086 _STLP_MOVE_TO_STD_NAMESPACE
00087 #  endif
00088 
00089 _STLP_EXPORT_TEMPLATE_CLASS vector<_STLP_PRIV _Slist_node_base*,
00090                                    allocator<_STLP_PRIV _Slist_node_base*> >;
00091 #endif
00092 
00093 #if defined (_STLP_DEBUG)
00094 #  define hashtable _STLP_NON_DBG_NAME(hashtable)
00095 _STLP_MOVE_TO_PRIV_NAMESPACE
00096 #endif
00097 
00098 // some compilers require the names of template parameters to be the same
00099 template <class _Val, class _Key, class _HF,
00100           class _Traits, class _ExK, class _EqK, class _All>
00101 class hashtable;
00102 
00103 #if !defined (_STLP_DEBUG)
00104 _STLP_MOVE_TO_PRIV_NAMESPACE
00105 #endif
00106 
00107 template <class _BaseIte, class _Traits>
00108 struct _Ht_iterator {
00109   typedef typename _Traits::_ConstTraits _ConstTraits;
00110   typedef typename _Traits::_NonConstTraits _NonConstTraits;
00111 
00112   typedef _Ht_iterator<_BaseIte,_Traits> _Self;
00113 
00114   typedef typename _Traits::value_type value_type;
00115   typedef typename _Traits::pointer pointer;
00116   typedef typename _Traits::reference reference;
00117   typedef forward_iterator_tag iterator_category;
00118   typedef ptrdiff_t difference_type;
00119   typedef size_t size_type;
00120 
00121   typedef _Ht_iterator<_BaseIte, _NonConstTraits> iterator;
00122   typedef _Ht_iterator<_BaseIte, _ConstTraits> const_iterator;
00123 
00124   _Ht_iterator() {}
00125   //copy constructor for iterator and constructor from iterator for const_iterator
00126   _Ht_iterator(const iterator& __it) : _M_ite(__it._M_ite) {}
00127   _Ht_iterator(_BaseIte __it) : _M_ite(__it) {}
00128 
00129   reference operator*() const {
00130     return *_M_ite;
00131   }
00132   _STLP_DEFINE_ARROW_OPERATOR
00133 
00134   _Self& operator++() {
00135     ++_M_ite;
00136     return *this;
00137   }
00138   _Self operator++(int) {
00139     _Self __tmp = *this;
00140     ++*this;
00141     return __tmp;
00142   }
00143 
00144   bool operator == (const_iterator __rhs) const {
00145     return _M_ite == __rhs._M_ite;
00146   }
00147   bool operator != (const_iterator __rhs) const {
00148     return _M_ite != __rhs._M_ite;
00149   }
00150 
00151   _BaseIte _M_ite;
00152 };
00153 
00154 _STLP_MOVE_TO_STD_NAMESPACE
00155 
00156 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00157 template <class _BaseIte, class _Traits>
00158 struct __type_traits<_STLP_PRIV _Ht_iterator<_BaseIte, _Traits> > {
00159   typedef __false_type   has_trivial_default_constructor;
00160   typedef __true_type    has_trivial_copy_constructor;
00161   typedef __true_type    has_trivial_assignment_operator;
00162   typedef __true_type    has_trivial_destructor;
00163   typedef __false_type   is_POD_type;
00164 };
00165 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
00166 
00167 #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
00168 template <class _BaseIte, class _Traits>
00169 inline
00170 #  if defined (_STLP_NESTED_TYPE_PARAM_BUG)
00171 _STLP_TYPENAME_ON_RETURN_TYPE _Traits::value_type *
00172 #  else
00173 _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>::value_type *
00174 #  endif
00175 value_type(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&) {
00176   typedef typename _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>::value_type _Val;
00177   return (_Val*) 0;
00178 }
00179 template <class _BaseIte, class _Traits>
00180 inline forward_iterator_tag iterator_category(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&)
00181 { return forward_iterator_tag(); }
00182 template <class _BaseIte, class _Traits>
00183 inline ptrdiff_t* distance_type(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&)
00184 { return (ptrdiff_t*) 0; }
00185 #endif
00186 
00187 _STLP_MOVE_TO_PRIV_NAMESPACE
00188 
00189 template <class _Dummy>
00190 class _Stl_prime {
00191 public:
00192   //Returns the maximum number of buckets handled by the hashtable implementation
00193   static size_t _STLP_CALL _S_max_nb_buckets();
00194 
00195   //Returns the bucket size next to a required size
00196   static size_t _STLP_CALL _S_next_size(size_t);
00197 };
00198 
00199 #if defined (_STLP_USE_TEMPLATE_EXPORT)
00200 _STLP_EXPORT_TEMPLATE_CLASS _Stl_prime<bool>;
00201 #endif
00202 
00203 typedef _Stl_prime<bool> _Stl_prime_type;
00204 
00205 #if !defined (_STLP_DEBUG)
00206 _STLP_MOVE_TO_STD_NAMESPACE
00207 #endif
00208 
00209 /*
00210  * Hashtables handle allocators a bit differently than other containers
00211  * do. If we're using standard-conforming allocators, then a hashtable
00212  * unconditionally has a member variable to hold its allocator, even if
00213  * it so happens that all instances of the allocator type are identical.
00214  * This is because, for hashtables, this extra storage is negligible.
00215  * Additionally, a base class wouldn't serve any other purposes; it
00216  * wouldn't, for example, simplify the exception-handling code.
00217  */
00218 template <class _Val, class _Key, class _HF,
00219           class _Traits, class _ExK, class _EqK, class _All>
00220 class hashtable {
00221   typedef hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> _Self;
00222   typedef typename _Traits::_NonConstTraits _NonConstTraits;
00223   typedef typename _Traits::_ConstTraits _ConstTraits;
00224   typedef typename _Traits::_NonConstLocalTraits _NonConstLocalTraits;
00225   typedef typename _Traits::_ConstLocalTraits _ConstLocalTraits;
00226 
00227 public:
00228   typedef _Key key_type;
00229   typedef _Val value_type;
00230   typedef _HF hasher;
00231   typedef _EqK key_equal;
00232 
00233   typedef size_t            size_type;
00234   typedef ptrdiff_t         difference_type;
00235   typedef typename _NonConstTraits::pointer pointer;
00236   typedef const value_type* const_pointer;
00237   typedef typename _NonConstTraits::reference reference;
00238   typedef const value_type& const_reference;
00239   typedef forward_iterator_tag _Iterator_category;
00240 
00241   hasher hash_funct() const { return _M_hash; }
00242   key_equal key_eq() const { return _M_equals; }
00243 
00244 private:
00245   _STLP_FORCE_ALLOCATORS(_Val, _All)
00246 #if defined (_STLP_DEBUG)
00247   typedef _STLP_PRIV _STLP_NON_DBG_NAME(slist)<value_type, _All> _ElemsCont;
00248 #else
00249   typedef slist<value_type, _All> _ElemsCont;
00250 #endif
00251   typedef typename _ElemsCont::iterator _ElemsIte;
00252   typedef typename _ElemsCont::const_iterator _ElemsConstIte;
00253   typedef _STLP_PRIV _Slist_node_base _BucketType;
00254   typedef typename _Alloc_traits<_BucketType*, _All>::allocator_type _M_bucket_allocator_type;
00255   /*
00256    * We are going to use vector of _Slist_node_base pointers for 2 reasons:
00257    *  - limit code bloat, all hashtable instanciation use the same buckets representation.
00258    *  - avoid _STLP_DEBUG performance trouble: with a vector of iterator on slist the resize
00259    *    method would be too slow because the slist::splice_after method become linear on
00260    *    the number of iterators in the buckets rather than constant in time as the iterator
00261    *    has to be move from a slist to the other.
00262    */
00263 #if defined (_STLP_DEBUG)
00264   typedef _STLP_PRIV _STLP_NON_DBG_NAME(vector)<_BucketType*, _M_bucket_allocator_type> _BucketVector;
00265 #else
00266   typedef vector<_BucketType*, _M_bucket_allocator_type> _BucketVector;
00267 #endif
00268 
00269   hasher                _M_hash;
00270   key_equal             _M_equals;
00271   _ExK                  _M_get_key;
00272   _ElemsCont            _M_elems;
00273   _BucketVector         _M_buckets;
00274   size_type             _M_num_elements;
00275   float                 _M_max_load_factor;
00276   _STLP_KEY_TYPE_FOR_CONT_EXT(key_type)
00277 
00278 public:
00279   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstTraits> iterator;
00280   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstTraits> const_iterator;
00281   //TODO: Avoids this debug check and make the local_iterator different from
00282   //iterator in debug mode too.
00283 #if !defined (_STLP_DEBUG)
00284   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstLocalTraits> local_iterator;
00285   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstLocalTraits> const_local_iterator;
00286 #else
00287   typedef iterator       local_iterator;
00288   typedef const_iterator const_local_iterator;
00289 #endif
00290 
00291   typedef typename _Alloc_traits<_Val, _All>::allocator_type allocator_type;
00292   allocator_type get_allocator() const { return _M_elems.get_allocator(); }
00293 
00294 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00295   hashtable(size_type __n,
00296             const _HF&  __hf,
00297             const _EqK& __eql,
00298             const _ExK& __ext,
00299             const allocator_type& __a = allocator_type())
00300 #else
00301   hashtable(size_type __n,
00302             const _HF&  __hf,
00303             const _EqK& __eql,
00304             const _ExK& __ext)
00305     : _M_hash(__hf),
00306       _M_equals(__eql),
00307       _M_get_key(__ext),
00308       _M_elems(allocator_type()),
00309       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
00310       _M_num_elements(0),
00311       _M_max_load_factor(1.0f)
00312   { _M_initialize_buckets(__n); }
00313 
00314   hashtable(size_type __n,
00315             const _HF&  __hf,
00316             const _EqK& __eql,
00317             const _ExK& __ext,
00318             const allocator_type& __a)
00319 #endif
00320     : _M_hash(__hf),
00321       _M_equals(__eql),
00322       _M_get_key(__ext),
00323       _M_elems(__a),
00324       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
00325       _M_num_elements(0),
00326       _M_max_load_factor(1.0f)
00327   { _M_initialize_buckets(__n); }
00328 
00329 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
00330   hashtable(size_type __n,
00331             const _HF&    __hf,
00332             const _EqK&   __eql,
00333             const allocator_type& __a = allocator_type())
00334 #else
00335   hashtable(size_type __n,
00336             const _HF&    __hf,
00337             const _EqK&   __eql)
00338     : _M_hash(__hf),
00339       _M_equals(__eql),
00340       _M_get_key(_ExK()),
00341       _M_elems(allocator_type()),
00342       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
00343       _M_num_elements(0),
00344       _M_max_load_factor(1.0f)
00345   { _M_initialize_buckets(__n); }
00346 
00347   hashtable(size_type __n,
00348             const _HF&    __hf,
00349             const _EqK&   __eql,
00350             const allocator_type& __a)
00351 #endif
00352     : _M_hash(__hf),
00353       _M_equals(__eql),
00354       _M_get_key(_ExK()),
00355       _M_elems(__a),
00356       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
00357       _M_num_elements(0),
00358       _M_max_load_factor(1.0f)
00359   { _M_initialize_buckets(__n); }
00360 
00361   hashtable(const _Self& __ht)
00362     : _M_hash(__ht._M_hash),
00363       _M_equals(__ht._M_equals),
00364       _M_get_key(__ht._M_get_key),
00365       _M_elems(__ht.get_allocator()),
00366       _M_buckets(_STLP_CONVERT_ALLOCATOR(__ht.get_allocator(), _BucketType*)),
00367       _M_num_elements(0),
00368       _M_max_load_factor(1.0f)
00369   { _M_copy_from(__ht); }
00370 
00371   hashtable(__move_source<_Self> src)
00372     : _M_hash(_STLP_PRIV _AsMoveSource(src.get()._M_hash)),
00373       _M_equals(_STLP_PRIV _AsMoveSource(src.get()._M_equals)),
00374       _M_get_key(_STLP_PRIV _AsMoveSource(src.get()._M_get_key)),
00375       _M_elems(__move_source<_ElemsCont>(src.get()._M_elems)),
00376       _M_buckets(__move_source<_BucketVector>(src.get()._M_buckets)),
00377       _M_num_elements(src.get()._M_num_elements),
00378       _M_max_load_factor(src.get()._M_max_load_factor) {}
00379 
00380   _Self& operator= (const _Self& __ht) {
00381     if (&__ht != this) {
00382       clear();
00383       _M_hash = __ht._M_hash;
00384       _M_equals = __ht._M_equals;
00385       _M_get_key = __ht._M_get_key;
00386       _M_copy_from(__ht);
00387     }
00388     return *this;
00389   }
00390 
00391   ~hashtable() { clear(); }
00392 
00393   size_type size() const { return _M_num_elements; }
00394   size_type max_size() const { return size_type(-1); }
00395   bool empty() const { return size() == 0; }
00396 
00397   void swap(_Self& __ht) {
00398     _STLP_STD::swap(_M_hash, __ht._M_hash);
00399     _STLP_STD::swap(_M_equals, __ht._M_equals);
00400     _STLP_STD::swap(_M_get_key, __ht._M_get_key);
00401     _M_elems.swap(__ht._M_elems);
00402     _M_buckets.swap(__ht._M_buckets);
00403     _STLP_STD::swap(_M_num_elements, __ht._M_num_elements);
00404     _STLP_STD::swap(_M_max_load_factor, __ht._M_max_load_factor);
00405   }
00406 
00407   iterator begin() { return _M_elems.begin(); }
00408   iterator end() { return _M_elems.end(); }
00409   local_iterator begin(size_type __n) { return _ElemsIte(_M_buckets[__n]); }
00410   local_iterator end(size_type __n) { return _ElemsIte(_M_buckets[__n + 1]); }
00411 
00412   const_iterator begin() const { return __CONST_CAST(_ElemsCont&, _M_elems).begin(); }
00413   const_iterator end() const { return __CONST_CAST(_ElemsCont&, _M_elems).end(); }
00414   const_local_iterator begin(size_type __n) const { return _ElemsIte(_M_buckets[__n]); }
00415   const_local_iterator end(size_type __n) const { return _ElemsIte(_M_buckets[__n + 1]); }
00416 
00417   //static bool _STLP_CALL _M_equal (const _Self&, const _Self&);
00418 
00419 public:
00420   //The number of buckets is size() - 1 because the last bucket always contains
00421   //_M_elems.end() to make algo easier to implement.
00422   size_type bucket_count() const { return _M_buckets.size() - 1; }
00423   size_type max_bucket_count() const { return _STLP_PRIV _Stl_prime_type::_S_max_nb_buckets(); }
00424   size_type elems_in_bucket(size_type __bucket) const
00425   { return distance(_ElemsIte(_M_buckets[__bucket]), _ElemsIte(_M_buckets[__bucket + 1])); }
00426 
00427   _STLP_TEMPLATE_FOR_CONT_EXT
00428   size_type bucket(const _KT& __k) const { return _M_bkt_num_key(__k); }
00429 
00430   // hash policy
00431   float load_factor() const { return (float)size() / (float)bucket_count(); }
00432   float max_load_factor() const { return _M_max_load_factor; }
00433   void max_load_factor(float __z) { _M_max_load_factor = __z;}
00434 
00435   pair<iterator, bool> insert_unique(const value_type& __obj) {
00436     resize(_M_num_elements + 1);
00437     return insert_unique_noresize(__obj);
00438   }
00439 
00440   iterator insert_equal(const value_type& __obj) {
00441     resize(_M_num_elements + 1);
00442     return insert_equal_noresize(__obj);
00443   }
00444 
00445 protected:
00446   iterator _M_insert_noresize(size_type __n, const value_type& __obj);
00447 public:
00448   pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
00449   iterator insert_equal_noresize(const value_type& __obj);
00450 
00451 #if defined (_STLP_MEMBER_TEMPLATES)
00452   template <class _InputIterator>
00453   void insert_unique(_InputIterator __f, _InputIterator __l)
00454   { insert_unique(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); }
00455 
00456   template <class _InputIterator>
00457   void insert_equal(_InputIterator __f, _InputIterator __l)
00458   { insert_equal(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); }
00459 
00460   template <class _InputIterator>
00461   void insert_unique(_InputIterator __f, _InputIterator __l,
00462                      const input_iterator_tag &) {
00463     for ( ; __f != __l; ++__f)
00464       insert_unique(*__f);
00465   }
00466 
00467   template <class _InputIterator>
00468   void insert_equal(_InputIterator __f, _InputIterator __l,
00469                     const input_iterator_tag &) {
00470     for ( ; __f != __l; ++__f)
00471       insert_equal(*__f);
00472   }
00473 
00474   template <class _ForwardIterator>
00475   void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
00476                      const forward_iterator_tag &) {
00477     size_type __n = distance(__f, __l);
00478     resize(_M_num_elements + __n);
00479     for ( ; __n > 0; --__n, ++__f)
00480       insert_unique_noresize(*__f);
00481   }
00482 
00483   template <class _ForwardIterator>
00484   void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
00485                     const forward_iterator_tag &) {
00486     size_type __n = distance(__f, __l);
00487     resize(_M_num_elements + __n);
00488     for ( ; __n > 0; --__n, ++__f)
00489       insert_equal_noresize(*__f);
00490   }
00491 
00492 #else /* _STLP_MEMBER_TEMPLATES */
00493   void insert_unique(const value_type* __f, const value_type* __l) {
00494     size_type __n = __l - __f;
00495     resize(_M_num_elements + __n);
00496     for ( ; __n > 0; --__n, ++__f)
00497       insert_unique_noresize(*__f);
00498   }
00499 
00500   void insert_equal(const value_type* __f, const value_type* __l) {
00501     size_type __n = __l - __f;
00502     resize(_M_num_elements + __n);
00503     for ( ; __n > 0; --__n, ++__f)
00504       insert_equal_noresize(*__f);
00505   }
00506 
00507   void insert_unique(const_iterator __f, const_iterator __l) {
00508     size_type __n = distance(__f, __l);
00509     resize(_M_num_elements + __n);
00510     for ( ; __n > 0; --__n, ++__f)
00511       insert_unique_noresize(*__f);
00512   }
00513 
00514   void insert_equal(const_iterator __f, const_iterator __l) {
00515     size_type __n = distance(__f, __l);
00516     resize(_M_num_elements + __n);
00517     for ( ; __n > 0; --__n, ++__f)
00518       insert_equal_noresize(*__f);
00519   }
00520 #endif /*_STLP_MEMBER_TEMPLATES */
00521 
00522   //reference find_or_insert(const value_type& __obj);
00523 
00524 private:
00525   _STLP_TEMPLATE_FOR_CONT_EXT
00526   _ElemsIte _M_find(const _KT& __key) const {
00527     size_type __n = _M_bkt_num_key(__key);
00528     _ElemsIte __first(_M_buckets[__n]);
00529     _ElemsIte __last(_M_buckets[__n + 1]);
00530     for ( ; (__first != __last) && !_M_equals(_M_get_key(*__first), __key); ++__first);
00531     if (__first != __last)
00532       return __first;
00533     else
00534       return __CONST_CAST(_ElemsCont&, _M_elems).end();
00535   }
00536 
00537 public:
00538   _STLP_TEMPLATE_FOR_CONT_EXT
00539   iterator find(const _KT& __key) { return _M_find(__key); }
00540   _STLP_TEMPLATE_FOR_CONT_EXT
00541   const_iterator find(const _KT& __key) const { return _M_find(__key); }
00542 
00543   _STLP_TEMPLATE_FOR_CONT_EXT
00544   size_type count(const _KT& __key) const {
00545     const size_type __n = _M_bkt_num_key(__key);
00546 
00547     _ElemsIte __cur(_M_buckets[__n]);
00548     _ElemsIte __last(_M_buckets[__n + 1]);
00549     for (; __cur != __last; ++__cur) {
00550       if (_M_equals(_M_get_key(*__cur), __key)) {
00551         size_type __result = 1;
00552         for (++__cur;
00553              __cur != __last && _M_equals(_M_get_key(*__cur), __key);
00554              ++__result, ++__cur);
00555         return __result;
00556       }
00557     }
00558     return 0;
00559   }
00560 
00561   _STLP_TEMPLATE_FOR_CONT_EXT
00562   pair<iterator, iterator> equal_range(const _KT& __key) {
00563     typedef pair<iterator, iterator> _Pii;
00564     const size_type __n = _M_bkt_num_key(__key);
00565 
00566     for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]);
00567          __first != __last; ++__first) {
00568       if (_M_equals(_M_get_key(*__first), __key)) {
00569         _ElemsIte __cur(__first);
00570         for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur);
00571         return _Pii(__first, __cur);
00572       }
00573     }
00574     return _Pii(end(), end());
00575   }
00576 
00577   _STLP_TEMPLATE_FOR_CONT_EXT
00578   pair<const_iterator, const_iterator> equal_range(const _KT& __key) const {
00579     typedef pair<const_iterator, const_iterator> _Pii;
00580     const size_type __n = _M_bkt_num_key(__key);
00581 
00582     for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]);
00583          __first != __last; ++__first) {
00584       if (_M_equals(_M_get_key(*__first), __key)) {
00585         _ElemsIte __cur(__first);
00586         for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur);
00587         return _Pii(__first, __cur);
00588       }
00589     }
00590     return _Pii(end(), end());
00591   }
00592 
00593   size_type erase(const key_type& __key);
00594   void erase(const_iterator __it);
00595   void erase(const_iterator __first, const_iterator __last);
00596 
00597 private:
00598   void _M_rehash(size_type __num_buckets);
00599 #if defined (_STLP_DEBUG)
00600   void _M_check() const;
00601 #endif
00602 
00603 public:
00604   void rehash(size_type __num_buckets_hint);
00605   void resize(size_type __num_elements_hint);
00606   void clear();
00607 
00608   // this is for hash_map::operator[]
00609   reference _M_insert(const value_type& __obj);
00610 
00611 private:
00612   //__n is set to the first bucket that has to be modified if any
00613   //erase/insert operation is done after the returned iterator.
00614   iterator _M_before_begin(size_type &__n) const;
00615 
00616   static iterator _S_before_begin(const _ElemsCont& __elems, const _BucketVector& __buckets,
00617                                   size_type &__n);
00618 
00619   void _M_initialize_buckets(size_type __n) {
00620     const size_type __n_buckets = _STLP_PRIV _Stl_prime_type::_S_next_size(__n) + 1;
00621     _M_buckets.reserve(__n_buckets);
00622     _M_buckets.assign(__n_buckets, __STATIC_CAST(_BucketType*, 0));
00623   }
00624 
00625   _STLP_TEMPLATE_FOR_CONT_EXT
00626   size_type _M_bkt_num_key(const _KT& __key) const
00627   { return _M_bkt_num_key(__key, bucket_count()); }
00628 
00629   size_type _M_bkt_num(const value_type& __obj) const
00630   { return _M_bkt_num_key(_M_get_key(__obj)); }
00631 
00632   _STLP_TEMPLATE_FOR_CONT_EXT
00633   size_type _M_bkt_num_key(const _KT& __key, size_type __n) const
00634   { return _M_hash(__key) % __n; }
00635 
00636   size_type _M_bkt_num(const value_type& __obj, size_t __n) const
00637   { return _M_bkt_num_key(_M_get_key(__obj), __n); }
00638 
00639   void _M_copy_from(const _Self& __ht);
00640 };
00641 
00642 #if defined (_STLP_DEBUG)
00643 #  undef hashtable
00644 _STLP_MOVE_TO_STD_NAMESPACE
00645 #endif
00646 
00647 _STLP_END_NAMESPACE
00648 
00649 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
00650 #  include <stl/_hashtable.c>
00651 #endif
00652 
00653 #if defined (_STLP_DEBUG)
00654 #  include <stl/debug/_hashtable.h>
00655 #endif
00656 
00657 _STLP_BEGIN_NAMESPACE
00658 
00659 #define _STLP_TEMPLATE_HEADER template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All>
00660 #define _STLP_TEMPLATE_CONTAINER hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
00661 #include <stl/_relops_hash_cont.h>
00662 #undef _STLP_TEMPLATE_CONTAINER
00663 #undef _STLP_TEMPLATE_HEADER
00664 
00665 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00666 template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All>
00667 struct __move_traits<hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> > {
00668   //Hashtables are movable:
00669   typedef __stlp_movable implemented;
00670 
00671   //Completeness depends on many template parameters, for the moment we consider it not complete:
00672   typedef __false_type complete;
00673 };
00674 #endif
00675 
00676 _STLP_END_NAMESPACE
00677 
00678 #endif /* _STLP_INTERNAL_HASHTABLE_H */
00679 
00680 // Local Variables:
00681 // mode:C++
00682 // End:



Generated on Mon Mar 10 15:32:24 2008 by  doxygen 1.5.1