Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_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 _STLP_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 // Returns begining of primes list and size by reference. 00192 static const size_t* _S_primes(size_t&); 00193 public: 00194 //Returns the maximum number of buckets handled by the hashtable implementation 00195 static size_t _STLP_CALL _S_max_nb_buckets(); 00196 00197 //Returns the bucket size next to a required size 00198 static size_t _STLP_CALL _S_next_size(size_t); 00199 00200 // Returns the bucket range containing sorted list of prime numbers <= __hint. 00201 static void _STLP_CALL _S_prev_sizes(size_t __hint, const size_t *&__begin, const size_t *&__end); 00202 }; 00203 00204 #if defined (_STLP_USE_TEMPLATE_EXPORT) 00205 _STLP_EXPORT_TEMPLATE_CLASS _Stl_prime<bool>; 00206 #endif 00207 00208 typedef _Stl_prime<bool> _Stl_prime_type; 00209 00210 #if !defined (_STLP_DEBUG) 00211 _STLP_MOVE_TO_STD_NAMESPACE 00212 #endif 00213 00214 /* 00215 * Hashtables handle allocators a bit differently than other containers 00216 * do. If we're using standard-conforming allocators, then a hashtable 00217 * unconditionally has a member variable to hold its allocator, even if 00218 * it so happens that all instances of the allocator type are identical. 00219 * This is because, for hashtables, this extra storage is negligible. 00220 * Additionally, a base class wouldn't serve any other purposes; it 00221 * wouldn't, for example, simplify the exception-handling code. 00222 */ 00223 template <class _Val, class _Key, class _HF, 00224 class _Traits, class _ExK, class _EqK, class _All> 00225 class hashtable { 00226 typedef hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> _Self; 00227 typedef typename _Traits::_NonConstTraits _NonConstTraits; 00228 typedef typename _Traits::_ConstTraits _ConstTraits; 00229 typedef typename _Traits::_NonConstLocalTraits _NonConstLocalTraits; 00230 typedef typename _Traits::_ConstLocalTraits _ConstLocalTraits; 00231 00232 public: 00233 typedef _Key key_type; 00234 typedef _Val value_type; 00235 typedef _HF hasher; 00236 typedef _EqK key_equal; 00237 00238 typedef size_t size_type; 00239 typedef ptrdiff_t difference_type; 00240 typedef typename _NonConstTraits::pointer pointer; 00241 typedef const value_type* const_pointer; 00242 typedef typename _NonConstTraits::reference reference; 00243 typedef const value_type& const_reference; 00244 typedef forward_iterator_tag _Iterator_category; 00245 00246 hasher hash_funct() const { return _M_hash; } 00247 key_equal key_eq() const { return _M_equals; } 00248 00249 private: 00250 _STLP_FORCE_ALLOCATORS(_Val, _All) 00251 #if defined (_STLP_DEBUG) 00252 typedef _STLP_PRIV _STLP_NON_DBG_NAME(slist)<value_type, _All> _ElemsCont; 00253 #else 00254 typedef slist<value_type, _All> _ElemsCont; 00255 #endif 00256 typedef typename _ElemsCont::iterator _ElemsIte; 00257 typedef typename _ElemsCont::const_iterator _ElemsConstIte; 00258 typedef _STLP_PRIV _Slist_node_base _BucketType; 00259 typedef typename _Alloc_traits<_BucketType*, _All>::allocator_type _BucketAllocType; 00260 /* 00261 * We are going to use vector of _Slist_node_base pointers for 2 reasons: 00262 * - limit code bloat, all hashtable instanciation use the same buckets representation. 00263 * - avoid _STLP_DEBUG performance trouble: with a vector of iterator on slist the resize 00264 * method would be too slow because the slist::splice_after method become linear on 00265 * the number of iterators in the buckets rather than constant in time as the iterator 00266 * has to be move from a slist to the other. 00267 */ 00268 #if defined (_STLP_DEBUG) 00269 typedef _STLP_PRIV _STLP_NON_DBG_NAME(vector)<_BucketType*, _BucketAllocType> _BucketVector; 00270 #else 00271 typedef vector<_BucketType*, _BucketAllocType> _BucketVector; 00272 #endif 00273 00274 hasher _M_hash; 00275 key_equal _M_equals; 00276 _ElemsCont _M_elems; 00277 _BucketVector _M_buckets; 00278 size_type _M_num_elements; 00279 float _M_max_load_factor; 00280 _STLP_KEY_TYPE_FOR_CONT_EXT(key_type) 00281 00282 static const key_type& _M_get_key(const value_type& __val) { 00283 _ExK k; 00284 return k(__val); 00285 } 00286 public: 00287 typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstTraits> iterator; 00288 typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstTraits> const_iterator; 00289 //TODO: Avoids this debug check and make the local_iterator different from 00290 //iterator in debug mode too. 00291 #if !defined (_STLP_DEBUG) 00292 typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstLocalTraits> local_iterator; 00293 typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstLocalTraits> const_local_iterator; 00294 #else 00295 typedef iterator local_iterator; 00296 typedef const_iterator const_local_iterator; 00297 #endif 00298 00299 typedef _All allocator_type; 00300 allocator_type get_allocator() const { return _M_elems.get_allocator(); } 00301 00302 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 00303 hashtable(size_type __n, 00304 const _HF& __hf, 00305 const _EqK& __eql, 00306 const allocator_type& __a = allocator_type()) 00307 #else 00308 hashtable(size_type __n, 00309 const _HF& __hf, 00310 const _EqK& __eql) 00311 : _M_hash(__hf), 00312 _M_equals(__eql), 00313 _M_elems(allocator_type()), 00314 _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)), 00315 _M_num_elements(0), 00316 _M_max_load_factor(1.0f) 00317 { _M_initialize_buckets(__n); } 00318 00319 hashtable(size_type __n, 00320 const _HF& __hf, 00321 const _EqK& __eql, 00322 const allocator_type& __a) 00323 #endif 00324 : _M_hash(__hf), 00325 _M_equals(__eql), 00326 _M_elems(__a), 00327 _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)), 00328 _M_num_elements(0), 00329 _M_max_load_factor(1.0f) 00330 { _M_initialize_buckets(__n); } 00331 00332 hashtable(const _Self& __ht) 00333 : _M_hash(__ht._M_hash), 00334 _M_equals(__ht._M_equals), 00335 _M_elems(__ht.get_allocator()), 00336 _M_buckets(_STLP_CONVERT_ALLOCATOR(__ht.get_allocator(), _BucketType*)), 00337 _M_num_elements(0), 00338 _M_max_load_factor(1.0f) 00339 { _M_copy_from(__ht); } 00340 00341 #if !defined (_STLP_NO_MOVE_SEMANTIC) 00342 hashtable(__move_source<_Self> src) 00343 : _M_hash(_STLP_PRIV _AsMoveSource(src.get()._M_hash)), 00344 _M_equals(_STLP_PRIV _AsMoveSource(src.get()._M_equals)), 00345 _M_elems(__move_source<_ElemsCont>(src.get()._M_elems)), 00346 _M_buckets(__move_source<_BucketVector>(src.get()._M_buckets)), 00347 _M_num_elements(src.get()._M_num_elements), 00348 _M_max_load_factor(src.get()._M_max_load_factor) {} 00349 #endif 00350 00351 _Self& operator= (const _Self& __ht) { 00352 if (&__ht != this) { 00353 clear(); 00354 _M_hash = __ht._M_hash; 00355 _M_equals = __ht._M_equals; 00356 _M_copy_from(__ht); 00357 } 00358 return *this; 00359 } 00360 00361 ~hashtable() { clear(); } 00362 00363 size_type size() const { return _M_num_elements; } 00364 size_type max_size() const { return size_type(-1); } 00365 bool empty() const { return size() == 0; } 00366 00367 void swap(_Self& __ht) { 00368 _STLP_STD::swap(_M_hash, __ht._M_hash); 00369 _STLP_STD::swap(_M_equals, __ht._M_equals); 00370 _M_elems.swap(__ht._M_elems); 00371 _M_buckets.swap(__ht._M_buckets); 00372 _STLP_STD::swap(_M_num_elements, __ht._M_num_elements); 00373 _STLP_STD::swap(_M_max_load_factor, __ht._M_max_load_factor); 00374 } 00375 00376 iterator begin() { return _M_elems.begin(); } 00377 iterator end() { return _M_elems.end(); } 00378 local_iterator begin(size_type __n) { return _ElemsIte(_M_buckets[__n]); } 00379 local_iterator end(size_type __n) { return _ElemsIte(_M_buckets[__n + 1]); } 00380 00381 const_iterator begin() const { return __CONST_CAST(_ElemsCont&, _M_elems).begin(); } 00382 const_iterator end() const { return __CONST_CAST(_ElemsCont&, _M_elems).end(); } 00383 const_local_iterator begin(size_type __n) const { return _ElemsIte(_M_buckets[__n]); } 00384 const_local_iterator end(size_type __n) const { return _ElemsIte(_M_buckets[__n + 1]); } 00385 00386 //static bool _STLP_CALL _M_equal (const _Self&, const _Self&); 00387 00388 public: 00389 //The number of buckets is size() - 1 because the last bucket always contains 00390 //_M_elems.end() to make algo easier to implement. 00391 size_type bucket_count() const { return _M_buckets.size() - 1; } 00392 size_type max_bucket_count() const { return _STLP_PRIV _Stl_prime_type::_S_max_nb_buckets(); } 00393 size_type elems_in_bucket(size_type __bucket) const 00394 { return _STLP_STD::distance(_ElemsIte(_M_buckets[__bucket]), _ElemsIte(_M_buckets[__bucket + 1])); } 00395 00396 _STLP_TEMPLATE_FOR_CONT_EXT 00397 size_type bucket(const _KT& __k) const { return _M_bkt_num_key(__k); } 00398 00399 // hash policy 00400 float load_factor() const { return (float)size() / (float)bucket_count(); } 00401 float max_load_factor() const { return _M_max_load_factor; } 00402 void max_load_factor(float __z) { 00403 _M_max_load_factor = __z; 00404 _M_resize(); 00405 } 00406 00407 pair<iterator, bool> insert_unique(const value_type& __obj) { 00408 _M_enlarge(_M_num_elements + 1); 00409 return insert_unique_noresize(__obj); 00410 } 00411 00412 iterator insert_equal(const value_type& __obj) { 00413 _M_enlarge(_M_num_elements + 1); 00414 return insert_equal_noresize(__obj); 00415 } 00416 00417 protected: 00418 iterator _M_insert_noresize(size_type __n, const value_type& __obj); 00419 public: 00420 pair<iterator, bool> insert_unique_noresize(const value_type& __obj); 00421 iterator insert_equal_noresize(const value_type& __obj); 00422 00423 #if defined (_STLP_MEMBER_TEMPLATES) 00424 template <class _InputIterator> 00425 void insert_unique(_InputIterator __f, _InputIterator __l) 00426 { insert_unique(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); } 00427 00428 template <class _InputIterator> 00429 void insert_equal(_InputIterator __f, _InputIterator __l) 00430 { insert_equal(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); } 00431 00432 template <class _InputIterator> 00433 void insert_unique(_InputIterator __f, _InputIterator __l, 00434 const input_iterator_tag &) { 00435 for ( ; __f != __l; ++__f) 00436 insert_unique(*__f); 00437 } 00438 00439 template <class _InputIterator> 00440 void insert_equal(_InputIterator __f, _InputIterator __l, 00441 const input_iterator_tag &) { 00442 for ( ; __f != __l; ++__f) 00443 insert_equal(*__f); 00444 } 00445 00446 template <class _ForwardIterator> 00447 void insert_unique(_ForwardIterator __f, _ForwardIterator __l, 00448 const forward_iterator_tag &) { 00449 size_type __n = _STLP_STD::distance(__f, __l); 00450 _M_enlarge(_M_num_elements + __n); 00451 for ( ; __n > 0; --__n, ++__f) 00452 insert_unique_noresize(*__f); 00453 } 00454 00455 template <class _ForwardIterator> 00456 void insert_equal(_ForwardIterator __f, _ForwardIterator __l, 00457 const forward_iterator_tag &) { 00458 size_type __n = _STLP_STD::distance(__f, __l); 00459 _M_enlarge(_M_num_elements + __n); 00460 for ( ; __n > 0; --__n, ++__f) 00461 insert_equal_noresize(*__f); 00462 } 00463 00464 #else /* _STLP_MEMBER_TEMPLATES */ 00465 void insert_unique(const value_type* __f, const value_type* __l) { 00466 size_type __n = __l - __f; 00467 _M_enlarge(_M_num_elements + __n); 00468 for ( ; __n > 0; --__n, ++__f) 00469 insert_unique_noresize(*__f); 00470 } 00471 00472 void insert_equal(const value_type* __f, const value_type* __l) { 00473 size_type __n = __l - __f; 00474 _M_enlarge(_M_num_elements + __n); 00475 for ( ; __n > 0; --__n, ++__f) 00476 insert_equal_noresize(*__f); 00477 } 00478 00479 void insert_unique(const_iterator __f, const_iterator __l) { 00480 size_type __n = _STLP_STD::distance(__f, __l); 00481 _M_enlarge(_M_num_elements + __n); 00482 for ( ; __n > 0; --__n, ++__f) 00483 insert_unique_noresize(*__f); 00484 } 00485 00486 void insert_equal(const_iterator __f, const_iterator __l) { 00487 size_type __n = _STLP_STD::distance(__f, __l); 00488 _M_enlarge(_M_num_elements + __n); 00489 for ( ; __n > 0; --__n, ++__f) 00490 insert_equal_noresize(*__f); 00491 } 00492 #endif /*_STLP_MEMBER_TEMPLATES */ 00493 00494 //reference find_or_insert(const value_type& __obj); 00495 00496 private: 00497 _STLP_TEMPLATE_FOR_CONT_EXT 00498 _ElemsIte _M_find(const _KT& __key) const { 00499 size_type __n = _M_bkt_num_key(__key); 00500 _ElemsIte __first(_M_buckets[__n]); 00501 _ElemsIte __last(_M_buckets[__n + 1]); 00502 for ( ; (__first != __last) && !_M_equals(_M_get_key(*__first), __key); ++__first); 00503 if (__first != __last) 00504 return __first; 00505 else 00506 return __CONST_CAST(_ElemsCont&, _M_elems).end(); 00507 } 00508 00509 public: 00510 _STLP_TEMPLATE_FOR_CONT_EXT 00511 iterator find(const _KT& __key) { return _M_find(__key); } 00512 _STLP_TEMPLATE_FOR_CONT_EXT 00513 const_iterator find(const _KT& __key) const { return _M_find(__key); } 00514 00515 _STLP_TEMPLATE_FOR_CONT_EXT 00516 size_type count(const _KT& __key) const { 00517 const size_type __n = _M_bkt_num_key(__key); 00518 00519 _ElemsIte __cur(_M_buckets[__n]); 00520 _ElemsIte __last(_M_buckets[__n + 1]); 00521 for (; __cur != __last; ++__cur) { 00522 if (_M_equals(_M_get_key(*__cur), __key)) { 00523 size_type __result = 1; 00524 for (++__cur; 00525 __cur != __last && _M_equals(_M_get_key(*__cur), __key); 00526 ++__result, ++__cur); 00527 return __result; 00528 } 00529 } 00530 return 0; 00531 } 00532 00533 _STLP_TEMPLATE_FOR_CONT_EXT 00534 pair<iterator, iterator> equal_range(const _KT& __key) { 00535 typedef pair<iterator, iterator> _Pii; 00536 const size_type __n = _M_bkt_num_key(__key); 00537 00538 for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]); 00539 __first != __last; ++__first) { 00540 if (_M_equals(_M_get_key(*__first), __key)) { 00541 _ElemsIte __cur(__first); 00542 for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur); 00543 return _Pii(__first, __cur); 00544 } 00545 } 00546 return _Pii(end(), end()); 00547 } 00548 00549 _STLP_TEMPLATE_FOR_CONT_EXT 00550 pair<const_iterator, const_iterator> equal_range(const _KT& __key) const { 00551 typedef pair<const_iterator, const_iterator> _Pii; 00552 const size_type __n = _M_bkt_num_key(__key); 00553 00554 for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]); 00555 __first != __last; ++__first) { 00556 if (_M_equals(_M_get_key(*__first), __key)) { 00557 _ElemsIte __cur(__first); 00558 for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur); 00559 return _Pii(__first, __cur); 00560 } 00561 } 00562 return _Pii(end(), end()); 00563 } 00564 00565 size_type erase(const key_type& __key); 00566 void erase(const_iterator __it); 00567 void erase(const_iterator __first, const_iterator __last); 00568 00569 private: 00570 void _M_enlarge(size_type __n); 00571 void _M_reduce(); 00572 void _M_resize(); 00573 void _M_rehash(size_type __num_buckets); 00574 #if defined (_STLP_DEBUG) 00575 void _M_check() const; 00576 #endif 00577 00578 public: 00579 void rehash(size_type __num_buckets_hint); 00580 void resize(size_type __num_buckets_hint) 00581 { rehash(__num_buckets_hint); } 00582 void clear(); 00583 00584 // this is for hash_map::operator[] 00585 reference _M_insert(const value_type& __obj); 00586 00587 private: 00588 //__n is set to the first bucket that has to be modified if any 00589 //erase/insert operation is done after the returned iterator. 00590 iterator _M_before_begin(size_type &__n) const; 00591 00592 static iterator _S_before_begin(const _ElemsCont& __elems, const _BucketVector& __buckets, 00593 size_type &__n); 00594 00595 void _M_initialize_buckets(size_type __n) { 00596 const size_type __n_buckets = _STLP_PRIV _Stl_prime_type::_S_next_size(__n) + 1; 00597 _M_buckets.reserve(__n_buckets); 00598 _M_buckets.assign(__n_buckets, __STATIC_CAST(_BucketType*, 0)); 00599 } 00600 00601 _STLP_TEMPLATE_FOR_CONT_EXT 00602 size_type _M_bkt_num_key(const _KT& __key) const 00603 { return _M_bkt_num_key(__key, bucket_count()); } 00604 00605 size_type _M_bkt_num(const value_type& __obj) const 00606 { return _M_bkt_num_key(_M_get_key(__obj)); } 00607 00608 _STLP_TEMPLATE_FOR_CONT_EXT 00609 size_type _M_bkt_num_key(const _KT& __key, size_type __n) const 00610 { return _M_hash(__key) % __n; } 00611 00612 size_type _M_bkt_num(const value_type& __obj, size_t __n) const 00613 { return _M_bkt_num_key(_M_get_key(__obj), __n); } 00614 00615 void _M_copy_from(const _Self& __ht); 00616 }; 00617 00618 #if defined (_STLP_DEBUG) 00619 # undef hashtable 00620 _STLP_MOVE_TO_STD_NAMESPACE 00621 #endif 00622 00623 _STLP_END_NAMESPACE 00624 00625 #if !defined (_STLP_LINK_TIME_INSTANTIATION) 00626 # include <stl/_hashtable.c> 00627 #endif 00628 00629 #if defined (_STLP_DEBUG) 00630 # include <stl/debug/_hashtable.h> 00631 #endif 00632 00633 _STLP_BEGIN_NAMESPACE 00634 00635 #define _STLP_TEMPLATE_HEADER template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All> 00636 #define _STLP_TEMPLATE_CONTAINER hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All> 00637 #include <stl/_relops_hash_cont.h> 00638 #undef _STLP_TEMPLATE_CONTAINER 00639 #undef _STLP_TEMPLATE_HEADER 00640 00641 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_NO_MOVE_SEMANTIC) 00642 template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All> 00643 struct __move_traits<hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> > { 00644 //Hashtables are movable: 00645 typedef __true_type implemented; 00646 00647 //Completeness depends on many template parameters, for the moment we consider it not complete: 00648 typedef __false_type complete; 00649 }; 00650 #endif 00651 00652 _STLP_END_NAMESPACE 00653 00654 #endif /* _STLP_INTERNAL_HASHTABLE_H */ 00655 00656 // Local Variables: 00657 // mode:C++ 00658 // End: Generated on Sat May 26 2012 04:27:41 for ReactOS by
1.7.6.1
|