00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00054
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
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
00103
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
00200
00201
00202
00203
00204
00205
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
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
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
00520 void erase(const const_iterator& __it) ;
00521
00522
00523
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
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
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
00622
00623
00624
00625
00626
00627