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
00031 #ifndef __SGI_STL_INTERNAL_HASHTABLE_H
00032 #define __SGI_STL_INTERNAL_HASHTABLE_H
00033
00034
00035
00036
00037 #include <stl_algobase.h>
00038 #include <stl_alloc.h>
00039 #include <stl_construct.h>
00040 #include <stl_tempbuf.h>
00041 #include <stl_algo.h>
00042 #include <stl_uninitialized.h>
00043 #include <stl_function.h>
00044 #include <stl_vector.h>
00045 #include <stl_hash_fun.h>
00046
00047 __STL_BEGIN_NAMESPACE
00048
00049 template <class _Val>
00050 struct _Hashtable_node
00051 {
00052 _Hashtable_node* _M_next;
00053 _Val _M_val;
00054 };
00055
00056 template <class _Val, class _Key, class _HashFcn,
00057 class _ExtractKey, class _EqualKey, class _Alloc = alloc>
00058 class hashtable;
00059
00060 template <class _Val, class _Key, class _HashFcn,
00061 class _ExtractKey, class _EqualKey, class _Alloc>
00062 struct _Hashtable_iterator;
00063
00064 template <class _Val, class _Key, class _HashFcn,
00065 class _ExtractKey, class _EqualKey, class _Alloc>
00066 struct _Hashtable_const_iterator;
00067
00068 template <class _Val, class _Key, class _HashFcn,
00069 class _ExtractKey, class _EqualKey, class _Alloc>
00070 struct _Hashtable_iterator {
00071 typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
00072 _Hashtable;
00073 typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
00074 _ExtractKey, _EqualKey, _Alloc>
00075 iterator;
00076 typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
00077 _ExtractKey, _EqualKey, _Alloc>
00078 const_iterator;
00079 typedef _Hashtable_node<_Val> _Node;
00080
00081 typedef forward_iterator_tag iterator_category;
00082 typedef _Val value_type;
00083 typedef ptrdiff_t difference_type;
00084 typedef size_t size_type;
00085 typedef _Val& reference;
00086 typedef _Val* pointer;
00087
00088 _Node* _M_cur;
00089 _Hashtable* _M_ht;
00090
00091 _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
00092 : _M_cur(__n), _M_ht(__tab) {}
00093 _Hashtable_iterator() {}
00094 reference operator*() const { return _M_cur->_M_val; }
00095 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00096 pointer operator->() const { return &(operator*()); }
00097 #endif
00098 iterator& operator++();
00099 iterator operator++(int);
00100 bool operator==(const iterator& __it) const
00101 { return _M_cur == __it._M_cur; }
00102 bool operator!=(const iterator& __it) const
00103 { return _M_cur != __it._M_cur; }
00104 };
00105
00106
00107 template <class _Val, class _Key, class _HashFcn,
00108 class _ExtractKey, class _EqualKey, class _Alloc>
00109 struct _Hashtable_const_iterator {
00110 typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
00111 _Hashtable;
00112 typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
00113 _ExtractKey,_EqualKey,_Alloc>
00114 iterator;
00115 typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
00116 _ExtractKey, _EqualKey, _Alloc>
00117 const_iterator;
00118 typedef _Hashtable_node<_Val> _Node;
00119
00120 typedef forward_iterator_tag iterator_category;
00121 typedef _Val value_type;
00122 typedef ptrdiff_t difference_type;
00123 typedef size_t size_type;
00124 typedef const _Val& reference;
00125 typedef const _Val* pointer;
00126
00127 const _Node* _M_cur;
00128 const _Hashtable* _M_ht;
00129
00130 _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
00131 : _M_cur(__n), _M_ht(__tab) {}
00132 _Hashtable_const_iterator() {}
00133 _Hashtable_const_iterator(const iterator& __it)
00134 : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
00135 reference operator*() const { return _M_cur->_M_val; }
00136 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00137 pointer operator->() const { return &(operator*()); }
00138 #endif
00139 const_iterator& operator++();
00140 const_iterator operator++(int);
00141 bool operator==(const const_iterator& __it) const
00142 { return _M_cur == __it._M_cur; }
00143 bool operator!=(const const_iterator& __it) const
00144 { return _M_cur != __it._M_cur; }
00145 };
00146
00147
00148 enum { __stl_num_primes = 28 };
00149
00150 static const unsigned long __stl_prime_list[__stl_num_primes] =
00151 {
00152 53ul, 97ul, 193ul, 389ul, 769ul,
00153 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
00154 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
00155 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
00156 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
00157 1610612741ul, 3221225473ul, 4294967291ul
00158 };
00159
00160 inline unsigned long __stl_next_prime(unsigned long __n)
00161 {
00162 const unsigned long* __first = __stl_prime_list;
00163 const unsigned long* __last = __stl_prime_list + (int)__stl_num_primes;
00164 const unsigned long* pos = lower_bound(__first, __last, __n);
00165 return pos == __last ? *(__last - 1) : *pos;
00166 }
00167
00168
00169
00170 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00171 class hashtable;
00172
00173 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00174 bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
00175 const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2);
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 template <class _Val, class _Key, class _HashFcn,
00187 class _ExtractKey, class _EqualKey, class _Alloc>
00188 class hashtable {
00189 public:
00190 typedef _Key key_type;
00191 typedef _Val value_type;
00192 typedef _HashFcn hasher;
00193 typedef _EqualKey key_equal;
00194
00195 typedef size_t size_type;
00196 typedef ptrdiff_t difference_type;
00197 typedef value_type* pointer;
00198 typedef const value_type* const_pointer;
00199 typedef value_type& reference;
00200 typedef const value_type& const_reference;
00201
00202 hasher hash_funct() const { return _M_hash; }
00203 key_equal key_eq() const { return _M_equals; }
00204
00205 private:
00206 typedef _Hashtable_node<_Val> _Node;
00207
00208 #ifdef __STL_USE_STD_ALLOCATORS
00209 public:
00210 typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type;
00211 allocator_type get_allocator() const { return _M_node_allocator; }
00212 private:
00213 typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator;
00214 _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
00215 void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
00216 # define __HASH_ALLOC_INIT(__a) _M_node_allocator(__a),
00217 #else
00218 public:
00219 typedef _Alloc allocator_type;
00220 allocator_type get_allocator() const { return allocator_type(); }
00221 private:
00222 typedef simple_alloc<_Node, _Alloc> _M_node_allocator_type;
00223 _Node* _M_get_node() { return _M_node_allocator_type::allocate(1); }
00224 void _M_put_node(_Node* __p) { _M_node_allocator_type::deallocate(__p, 1); }
00225 # define __HASH_ALLOC_INIT(__a)
00226 #endif
00227
00228 private:
00229 hasher _M_hash;
00230 key_equal _M_equals;
00231 _ExtractKey _M_get_key;
00232 vector<_Node*,_Alloc> _M_buckets;
00233 size_type _M_num_elements;
00234
00235 public:
00236 typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
00237 iterator;
00238 typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,
00239 _Alloc>
00240 const_iterator;
00241
00242 friend struct
00243 _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
00244 friend struct
00245 _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
00246
00247 public:
00248 hashtable(size_type __n,
00249 const _HashFcn& __hf,
00250 const _EqualKey& __eql,
00251 const _ExtractKey& __ext,
00252 const allocator_type& __a = allocator_type())
00253 : __HASH_ALLOC_INIT(__a)
00254 _M_hash(__hf),
00255 _M_equals(__eql),
00256 _M_get_key(__ext),
00257 _M_buckets(__a),
00258 _M_num_elements(0)
00259 {
00260 _M_initialize_buckets(__n);
00261 }
00262
00263 hashtable(size_type __n,
00264 const _HashFcn& __hf,
00265 const _EqualKey& __eql,
00266 const allocator_type& __a = allocator_type())
00267 : __HASH_ALLOC_INIT(__a)
00268 _M_hash(__hf),
00269 _M_equals(__eql),
00270 _M_get_key(_ExtractKey()),
00271 _M_buckets(__a),
00272 _M_num_elements(0)
00273 {
00274 _M_initialize_buckets(__n);
00275 }
00276
00277 hashtable(const hashtable& __ht)
00278 : __HASH_ALLOC_INIT(__ht.get_allocator())
00279 _M_hash(__ht._M_hash),
00280 _M_equals(__ht._M_equals),
00281 _M_get_key(__ht._M_get_key),
00282 _M_buckets(__ht.get_allocator()),
00283 _M_num_elements(0)
00284 {
00285 _M_copy_from(__ht);
00286 }
00287
00288 #undef __HASH_ALLOC_INIT
00289
00290 hashtable& operator= (const hashtable& __ht)
00291 {
00292 if (&__ht != this) {
00293 clear();
00294 _M_hash = __ht._M_hash;
00295 _M_equals = __ht._M_equals;
00296 _M_get_key = __ht._M_get_key;
00297 _M_copy_from(__ht);
00298 }
00299 return *this;
00300 }
00301
00302 ~hashtable() { clear(); }
00303
00304 size_type size() const { return _M_num_elements; }
00305 size_type max_size() const { return size_type(-1); }
00306 bool empty() const { return size() == 0; }
00307
00308 void swap(hashtable& __ht)
00309 {
00310 __STD::swap(_M_hash, __ht._M_hash);
00311 __STD::swap(_M_equals, __ht._M_equals);
00312 __STD::swap(_M_get_key, __ht._M_get_key);
00313 _M_buckets.swap(__ht._M_buckets);
00314 __STD::swap(_M_num_elements, __ht._M_num_elements);
00315 }
00316
00317 iterator begin()
00318 {
00319 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
00320 if (_M_buckets[__n])
00321 return iterator(_M_buckets[__n], this);
00322 return end();
00323 }
00324
00325 iterator end() { return iterator(0, this); }
00326
00327 const_iterator begin() const
00328 {
00329 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
00330 if (_M_buckets[__n])
00331 return const_iterator(_M_buckets[__n], this);
00332 return end();
00333 }
00334
00335 const_iterator end() const { return const_iterator(0, this); }
00336
00337 #ifdef __STL_MEMBER_TEMPLATES
00338 template <class _Vl, class _Ky, class _HF, class _Ex, class _Eq, class _Al>
00339 friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
00340 const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
00341 #else
00342 friend bool __STD_QUALIFIER
00343 operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&);
00344 #endif
00345
00346 public:
00347
00348 size_type bucket_count() const { return _M_buckets.size(); }
00349
00350 size_type max_bucket_count() const
00351 { return __stl_prime_list[(int)__stl_num_primes - 1]; }
00352
00353 size_type elems_in_bucket(size_type __bucket) const
00354 {
00355 size_type __result = 0;
00356 for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
00357 __result += 1;
00358 return __result;
00359 }
00360
00361 pair<iterator, bool> insert_unique(const value_type& __obj)
00362 {
00363 resize(_M_num_elements + 1);
00364 return insert_unique_noresize(__obj);
00365 }
00366
00367 iterator insert_equal(const value_type& __obj)
00368 {
00369 resize(_M_num_elements + 1);
00370 return insert_equal_noresize(__obj);
00371 }
00372
00373 pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
00374 iterator insert_equal_noresize(const value_type& __obj);
00375
00376 #ifdef __STL_MEMBER_TEMPLATES
00377 template <class _InputIterator>
00378 void insert_unique(_InputIterator __f, _InputIterator __l)
00379 {
00380 insert_unique(__f, __l, __ITERATOR_CATEGORY(__f));
00381 }
00382
00383 template <class _InputIterator>
00384 void insert_equal(_InputIterator __f, _InputIterator __l)
00385 {
00386 insert_equal(__f, __l, __ITERATOR_CATEGORY(__f));
00387 }
00388
00389 template <class _InputIterator>
00390 void insert_unique(_InputIterator __f, _InputIterator __l,
00391 input_iterator_tag)
00392 {
00393 for ( ; __f != __l; ++__f)
00394 insert_unique(*__f);
00395 }
00396
00397 template <class _InputIterator>
00398 void insert_equal(_InputIterator __f, _InputIterator __l,
00399 input_iterator_tag)
00400 {
00401 for ( ; __f != __l; ++__f)
00402 insert_equal(*__f);
00403 }
00404
00405 template <class _ForwardIterator>
00406 void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
00407 forward_iterator_tag)
00408 {
00409 size_type __n = 0;
00410 distance(__f, __l, __n);
00411 resize(_M_num_elements + __n);
00412 for ( ; __n > 0; --__n, ++__f)
00413 insert_unique_noresize(*__f);
00414 }
00415
00416 template <class _ForwardIterator>
00417 void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
00418 forward_iterator_tag)
00419 {
00420 size_type __n = 0;
00421 distance(__f, __l, __n);
00422 resize(_M_num_elements + __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 + __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 + __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 = 0;
00447 distance(__f, __l, __n);
00448 resize(_M_num_elements + __n);
00449 for ( ; __n > 0; --__n, ++__f)
00450 insert_unique_noresize(*__f);
00451 }
00452
00453 void insert_equal(const_iterator __f, const_iterator __l)
00454 {
00455 size_type __n = 0;
00456 distance(__f, __l, __n);
00457 resize(_M_num_elements + __n);
00458 for ( ; __n > 0; --__n, ++__f)
00459 insert_equal_noresize(*__f);
00460 }
00461 #endif
00462
00463 reference find_or_insert(const value_type& __obj);
00464
00465 iterator find(const key_type& __key)
00466 {
00467 size_type __n = _M_bkt_num_key(__key);
00468 _Node* __first;
00469 for ( __first = _M_buckets[__n];
00470 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
00471 __first = __first->_M_next)
00472 {}
00473 return iterator(__first, this);
00474 }
00475
00476 const_iterator find(const key_type& __key) const
00477 {
00478 size_type __n = _M_bkt_num_key(__key);
00479 const _Node* __first;
00480 for ( __first = _M_buckets[__n];
00481 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
00482 __first = __first->_M_next)
00483 {}
00484 return const_iterator(__first, this);
00485 }
00486
00487 size_type count(const key_type& __key) const
00488 {
00489 const size_type __n = _M_bkt_num_key(__key);
00490 size_type __result = 0;
00491
00492 for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next)
00493 if (_M_equals(_M_get_key(__cur->_M_val), __key))
00494 ++__result;
00495 return __result;
00496 }
00497
00498 pair<iterator, iterator>
00499 equal_range(const key_type& __key);
00500
00501 pair<const_iterator, const_iterator>
00502 equal_range(const key_type& __key) const;
00503
00504 size_type erase(const key_type& __key);
00505 void erase(const iterator& __it);
00506 void erase(iterator __first, iterator __last);
00507
00508 void erase(const const_iterator& __it);
00509 void erase(const_iterator __first, const_iterator __last);
00510
00511 void resize(size_type __num_elements_hint);
00512 void clear();
00513
00514 private:
00515 size_type _M_next_size(size_type __n) const
00516 { return __stl_next_prime(__n); }
00517
00518 void _M_initialize_buckets(size_type __n)
00519 {
00520 const size_type __n_buckets = _M_next_size(__n);
00521 _M_buckets.reserve(__n_buckets);
00522 _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
00523 _M_num_elements = 0;
00524 }
00525
00526 size_type _M_bkt_num_key(const key_type& __key) const
00527 {
00528 return _M_bkt_num_key(__key, _M_buckets.size());
00529 }
00530
00531 size_type _M_bkt_num(const value_type& __obj) const
00532 {
00533 return _M_bkt_num_key(_M_get_key(__obj));
00534 }
00535
00536 size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
00537 {
00538 return _M_hash(__key) % __n;
00539 }
00540
00541 size_type _M_bkt_num(const value_type& __obj, size_t __n) const
00542 {
00543 return _M_bkt_num_key(_M_get_key(__obj), __n);
00544 }
00545
00546 _Node* _M_new_node(const value_type& __obj)
00547 {
00548 _Node* __n = _M_get_node();
00549 __n->_M_next = 0;
00550 __STL_TRY {
00551 construct(&__n->_M_val, __obj);
00552 return __n;
00553 }
00554 __STL_UNWIND(_M_put_node(__n));
00555 }
00556
00557 void _M_delete_node(_Node* __n)
00558 {
00559 destroy(&__n->_M_val);
00560 _M_put_node(__n);
00561 }
00562
00563 void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
00564 void _M_erase_bucket(const size_type __n, _Node* __last);
00565
00566 void _M_copy_from(const hashtable& __ht);
00567
00568 };
00569
00570 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00571 class _All>
00572 _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
00573 _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
00574 {
00575 const _Node* __old = _M_cur;
00576 _M_cur = _M_cur->_M_next;
00577 if (!_M_cur) {
00578 size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
00579 while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
00580 _M_cur = _M_ht->_M_buckets[__bucket];
00581 }
00582 return *this;
00583 }
00584
00585 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00586 class _All>
00587 inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
00588 _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
00589 {
00590 iterator __tmp = *this;
00591 ++*this;
00592 return __tmp;
00593 }
00594
00595 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00596 class _All>
00597 _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
00598 _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
00599 {
00600 const _Node* __old = _M_cur;
00601 _M_cur = _M_cur->_M_next;
00602 if (!_M_cur) {
00603 size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
00604 while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
00605 _M_cur = _M_ht->_M_buckets[__bucket];
00606 }
00607 return *this;
00608 }
00609
00610 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00611 class _All>
00612 inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
00613 _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
00614 {
00615 const_iterator __tmp = *this;
00616 ++*this;
00617 return __tmp;
00618 }
00619
00620 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
00621
00622 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00623 class _All>
00624 inline forward_iterator_tag
00625 iterator_category(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&)
00626 {
00627 return forward_iterator_tag();
00628 }
00629
00630 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00631 class _All>
00632 inline _Val*
00633 value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&)
00634 {
00635 return (_Val*) 0;
00636 }
00637
00638 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00639 class _All>
00640 inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*
00641 distance_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&)
00642 {
00643 return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0;
00644 }
00645
00646 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00647 class _All>
00648 inline forward_iterator_tag
00649 iterator_category(const _Hashtable_const_iterator<_Val,_Key,_HF,
00650 _ExK,_EqK,_All>&)
00651 {
00652 return forward_iterator_tag();
00653 }
00654
00655 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00656 class _All>
00657 inline _Val*
00658 value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&)
00659 {
00660 return (_Val*) 0;
00661 }
00662
00663 template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
00664 class _All>
00665 inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*
00666 distance_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&)
00667 {
00668 return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0;
00669 }
00670
00671 #endif
00672
00673 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00674 bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
00675 const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2)
00676 {
00677 typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node;
00678 if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
00679 return false;
00680 for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
00681 _Node* __cur1 = __ht1._M_buckets[__n];
00682 _Node* __cur2 = __ht2._M_buckets[__n];
00683 for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
00684 __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
00685 {}
00686 if (__cur1 || __cur2)
00687 return false;
00688 }
00689 return true;
00690 }
00691
00692 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
00693
00694 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00695 inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
00696 const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) {
00697 return !(__ht1 == __ht2);
00698 }
00699
00700 template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
00701 class _All>
00702 inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
00703 hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) {
00704 __ht1.swap(__ht2);
00705 }
00706
00707 #endif
00708
00709
00710 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00711 pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
00712 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
00713 ::insert_unique_noresize(const value_type& __obj)
00714 {
00715 const size_type __n = _M_bkt_num(__obj);
00716 _Node* __first = _M_buckets[__n];
00717
00718 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
00719 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
00720 return pair<iterator, bool>(iterator(__cur, this), false);
00721
00722 _Node* __tmp = _M_new_node(__obj);
00723 __tmp->_M_next = __first;
00724 _M_buckets[__n] = __tmp;
00725 ++_M_num_elements;
00726 return pair<iterator, bool>(iterator(__tmp, this), true);
00727 }
00728
00729 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00730 typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator
00731 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
00732 ::insert_equal_noresize(const value_type& __obj)
00733 {
00734 const size_type __n = _M_bkt_num(__obj);
00735 _Node* __first = _M_buckets[__n];
00736
00737 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
00738 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
00739 _Node* __tmp = _M_new_node(__obj);
00740 __tmp->_M_next = __cur->_M_next;
00741 __cur->_M_next = __tmp;
00742 ++_M_num_elements;
00743 return iterator(__tmp, this);
00744 }
00745
00746 _Node* __tmp = _M_new_node(__obj);
00747 __tmp->_M_next = __first;
00748 _M_buckets[__n] = __tmp;
00749 ++_M_num_elements;
00750 return iterator(__tmp, this);
00751 }
00752
00753 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00754 typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference
00755 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
00756 {
00757 resize(_M_num_elements + 1);
00758
00759 size_type __n = _M_bkt_num(__obj);
00760 _Node* __first = _M_buckets[__n];
00761
00762 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
00763 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
00764 return __cur->_M_val;
00765
00766 _Node* __tmp = _M_new_node(__obj);
00767 __tmp->_M_next = __first;
00768 _M_buckets[__n] = __tmp;
00769 ++_M_num_elements;
00770 return __tmp->_M_val;
00771 }
00772
00773 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00774 pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
00775 typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
00776 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
00777 {
00778 typedef pair<iterator, iterator> _Pii;
00779 const size_type __n = _M_bkt_num_key(__key);
00780
00781 for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
00782 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
00783 for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
00784 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
00785 return _Pii(iterator(__first, this), iterator(__cur, this));
00786 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
00787 if (_M_buckets[__m])
00788 return _Pii(iterator(__first, this),
00789 iterator(_M_buckets[__m], this));
00790 return _Pii(iterator(__first, this), end());
00791 }
00792 return _Pii(end(), end());
00793 }
00794
00795 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00796 pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
00797 typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
00798 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
00799 ::equal_range(const key_type& __key) const
00800 {
00801 typedef pair<const_iterator, const_iterator> _Pii;
00802 const size_type __n = _M_bkt_num_key(__key);
00803
00804 for (const _Node* __first = _M_buckets[__n] ;
00805 __first;
00806 __first = __first->_M_next) {
00807 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
00808 for (const _Node* __cur = __first->_M_next;
00809 __cur;
00810 __cur = __cur->_M_next)
00811 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
00812 return _Pii(const_iterator(__first, this),
00813 const_iterator(__cur, this));
00814 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
00815 if (_M_buckets[__m])
00816 return _Pii(const_iterator(__first, this),
00817 const_iterator(_M_buckets[__m], this));
00818 return _Pii(const_iterator(__first, this), end());
00819 }
00820 }
00821 return _Pii(end(), end());
00822 }
00823
00824 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00825 typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type
00826 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
00827 {
00828 const size_type __n = _M_bkt_num_key(__key);
00829 _Node* __first = _M_buckets[__n];
00830 size_type __erased = 0;
00831
00832 if (__first) {
00833 _Node* __cur = __first;
00834 _Node* __next = __cur->_M_next;
00835 while (__next) {
00836 if (_M_equals(_M_get_key(__next->_M_val), __key)) {
00837 __cur->_M_next = __next->_M_next;
00838 _M_delete_node(__next);
00839 __next = __cur->_M_next;
00840 ++__erased;
00841 --_M_num_elements;
00842 }
00843 else {
00844 __cur = __next;
00845 __next = __cur->_M_next;
00846 }
00847 }
00848 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
00849 _M_buckets[__n] = __first->_M_next;
00850 _M_delete_node(__first);
00851 ++__erased;
00852 --_M_num_elements;
00853 }
00854 }
00855 return __erased;
00856 }
00857
00858 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00859 void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
00860 {
00861 _Node* __p = __it._M_cur;
00862 if (__p) {
00863 const size_type __n = _M_bkt_num(__p->_M_val);
00864 _Node* __cur = _M_buckets[__n];
00865
00866 if (__cur == __p) {
00867 _M_buckets[__n] = __cur->_M_next;
00868 _M_delete_node(__cur);
00869 --_M_num_elements;
00870 }
00871 else {
00872 _Node* __next = __cur->_M_next;
00873 while (__next) {
00874 if (__next == __p) {
00875 __cur->_M_next = __next->_M_next;
00876 _M_delete_node(__next);
00877 --_M_num_elements;
00878 break;
00879 }
00880 else {
00881 __cur = __next;
00882 __next = __cur->_M_next;
00883 }
00884 }
00885 }
00886 }
00887 }
00888
00889 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00890 void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
00891 ::erase(iterator __first, iterator __last)
00892 {
00893 size_type __f_bucket = __first._M_cur ?
00894 _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
00895 size_type __l_bucket = __last._M_cur ?
00896 _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
00897
00898 if (__first._M_cur == __last._M_cur)
00899 return;
00900 else if (__f_bucket == __l_bucket)
00901 _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
00902 else {
00903 _M_erase_bucket(__f_bucket, __first._M_cur, 0);
00904 for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
00905 _M_erase_bucket(__n, 0);
00906 if (__l_bucket != _M_buckets.size())
00907 _M_erase_bucket(__l_bucket, __last._M_cur);
00908 }
00909 }
00910
00911 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00912 inline void
00913 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first,
00914 const_iterator __last)
00915 {
00916 erase(iterator(const_cast<_Node*>(__first._M_cur),
00917 const_cast<hashtable*>(__first._M_ht)),
00918 iterator(const_cast<_Node*>(__last._M_cur),
00919 const_cast<hashtable*>(__last._M_ht)));
00920 }
00921
00922 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00923 inline void
00924 hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it)
00925 {
00926 erase(iterator(const_cast<_Node*>(__it._M_cur),
00927 const_cast<hashtable*>(__it._M_ht)));
00928 }
00929
00930 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00931 void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
00932 ::resize(size_type __num_elements_hint)
00933 {
00934 const size_type __old_n = _M_buckets.size();
00935 if (__num_elements_hint > __old_n) {
00936 const size_type __n = _M_next_size(__num_elements_hint);
00937 if (__n > __old_n) {
00938 vector<_Node*, _All> __tmp(__n, (_Node*)(0),
00939 _M_buckets.get_allocator());
00940 __STL_TRY {
00941 for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
00942 _Node* __first = _M_buckets[__bucket];
00943 while (__first) {
00944 size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
00945 _M_buckets[__bucket] = __first->_M_next;
00946 __first->_M_next = __tmp[__new_bucket];
00947 __tmp[__new_bucket] = __first;
00948 __first = _M_buckets[__bucket];
00949 }
00950 }
00951 _M_buckets.swap(__tmp);
00952 }
00953 # ifdef __STL_USE_EXCEPTIONS
00954 catch(...) {
00955 for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
00956 while (__tmp[__bucket]) {
00957 _Node* __next = __tmp[__bucket]->_M_next;
00958 _M_delete_node(__tmp[__bucket]);
00959 __tmp[__bucket] = __next;
00960 }
00961 }
00962 throw;
00963 }
00964 # endif
00965 }
00966 }
00967 }
00968
00969 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00970 void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
00971 ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
00972 {
00973 _Node* __cur = _M_buckets[__n];
00974 if (__cur == __first)
00975 _M_erase_bucket(__n, __last);
00976 else {
00977 _Node* __next;
00978 for (__next = __cur->_M_next;
00979 __next != __first;
00980 __cur = __next, __next = __cur->_M_next)
00981 ;
00982 while (__next != __last) {
00983 __cur->_M_next = __next->_M_next;
00984 _M_delete_node(__next);
00985 __next = __cur->_M_next;
00986 --_M_num_elements;
00987 }
00988 }
00989 }
00990
00991 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
00992 void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
00993 ::_M_erase_bucket(const size_type __n, _Node* __last)
00994 {
00995 _Node* __cur = _M_buckets[__n];
00996 while (__cur != __last) {
00997 _Node* __next = __cur->_M_next;
00998 _M_delete_node(__cur);
00999 __cur = __next;
01000 _M_buckets[__n] = __cur;
01001 --_M_num_elements;
01002 }
01003 }
01004
01005 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
01006 void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear()
01007 {
01008 for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
01009 _Node* __cur = _M_buckets[__i];
01010 while (__cur != 0) {
01011 _Node* __next = __cur->_M_next;
01012 _M_delete_node(__cur);
01013 __cur = __next;
01014 }
01015 _M_buckets[__i] = 0;
01016 }
01017 _M_num_elements = 0;
01018 }
01019
01020
01021 template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
01022 void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
01023 ::_M_copy_from(const hashtable& __ht)
01024 {
01025 _M_buckets.clear();
01026 _M_buckets.reserve(__ht._M_buckets.size());
01027 _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
01028 __STL_TRY {
01029 for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
01030 const _Node* __cur = __ht._M_buckets[__i];
01031 if (__cur) {
01032 _Node* __copy = _M_new_node(__cur->_M_val);
01033 _M_buckets[__i] = __copy;
01034
01035 for (_Node* __next = __cur->_M_next;
01036 __next;
01037 __cur = __next, __next = __cur->_M_next) {
01038 __copy->_M_next = _M_new_node(__next->_M_val);
01039 __copy = __copy->_M_next;
01040 }
01041 }
01042 }
01043 _M_num_elements = __ht._M_num_elements;
01044 }
01045 __STL_UNWIND(clear());
01046 }
01047
01048 __STL_END_NAMESPACE
01049
01050 #endif
01051
01052
01053
01054