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 _HASHTABLE_POLICY_H
00031 #define _HASHTABLE_POLICY_H 1
00032
00033 namespace std
00034 {
00035 namespace __detail
00036 {
00037
00038
00039 template<class _Iterator>
00040 inline typename std::iterator_traits<_Iterator>::difference_type
00041 __distance_fw(_Iterator __first, _Iterator __last,
00042 std::input_iterator_tag)
00043 { return 0; }
00044
00045 template<class _Iterator>
00046 inline typename std::iterator_traits<_Iterator>::difference_type
00047 __distance_fw(_Iterator __first, _Iterator __last,
00048 std::forward_iterator_tag)
00049 { return std::distance(__first, __last); }
00050
00051 template<class _Iterator>
00052 inline typename std::iterator_traits<_Iterator>::difference_type
00053 __distance_fw(_Iterator __first, _Iterator __last)
00054 {
00055 typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
00056 return __distance_fw(__first, __last, _Tag());
00057 }
00058
00059 template<typename _RAIter, typename _Tp>
00060 _RAIter
00061 __lower_bound(_RAIter __first, _RAIter __last, const _Tp& __val)
00062 {
00063 typedef typename std::iterator_traits<_RAIter>::difference_type _DType;
00064
00065 _DType __len = __last - __first;
00066 while (__len > 0)
00067 {
00068 _DType __half = __len >> 1;
00069 _RAIter __middle = __first + __half;
00070 if (*__middle < __val)
00071 {
00072 __first = __middle;
00073 ++__first;
00074 __len = __len - __half - 1;
00075 }
00076 else
00077 __len = __half;
00078 }
00079 return __first;
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 template<typename _Value, bool __cache_hash_code>
00090 struct _Hash_node;
00091
00092 template<typename _Value>
00093 struct _Hash_node<_Value, true>
00094 {
00095 _Value _M_v;
00096 std::size_t _M_hash_code;
00097 _Hash_node* _M_next;
00098
00099 template<typename... _Args>
00100 _Hash_node(_Args&&... __args)
00101 : _M_v(std::forward<_Args>(__args)...),
00102 _M_hash_code(), _M_next() { }
00103 };
00104
00105 template<typename _Value>
00106 struct _Hash_node<_Value, false>
00107 {
00108 _Value _M_v;
00109 _Hash_node* _M_next;
00110
00111 template<typename... _Args>
00112 _Hash_node(_Args&&... __args)
00113 : _M_v(std::forward<_Args>(__args)...),
00114 _M_next() { }
00115 };
00116
00117
00118
00119 template<typename _Value, bool __cache>
00120 struct _Node_iterator_base
00121 {
00122 _Node_iterator_base(_Hash_node<_Value, __cache>* __p)
00123 : _M_cur(__p) { }
00124
00125 void
00126 _M_incr()
00127 { _M_cur = _M_cur->_M_next; }
00128
00129 _Hash_node<_Value, __cache>* _M_cur;
00130 };
00131
00132 template<typename _Value, bool __cache>
00133 inline bool
00134 operator==(const _Node_iterator_base<_Value, __cache>& __x,
00135 const _Node_iterator_base<_Value, __cache>& __y)
00136 { return __x._M_cur == __y._M_cur; }
00137
00138 template<typename _Value, bool __cache>
00139 inline bool
00140 operator!=(const _Node_iterator_base<_Value, __cache>& __x,
00141 const _Node_iterator_base<_Value, __cache>& __y)
00142 { return __x._M_cur != __y._M_cur; }
00143
00144 template<typename _Value, bool __constant_iterators, bool __cache>
00145 struct _Node_iterator
00146 : public _Node_iterator_base<_Value, __cache>
00147 {
00148 typedef _Value value_type;
00149 typedef typename std::conditional<__constant_iterators,
00150 const _Value*, _Value*>::type
00151 pointer;
00152 typedef typename std::conditional<__constant_iterators,
00153 const _Value&, _Value&>::type
00154 reference;
00155 typedef std::ptrdiff_t difference_type;
00156 typedef std::forward_iterator_tag iterator_category;
00157
00158 _Node_iterator()
00159 : _Node_iterator_base<_Value, __cache>(0) { }
00160
00161 explicit
00162 _Node_iterator(_Hash_node<_Value, __cache>* __p)
00163 : _Node_iterator_base<_Value, __cache>(__p) { }
00164
00165 reference
00166 operator*() const
00167 { return this->_M_cur->_M_v; }
00168
00169 pointer
00170 operator->() const
00171 { return &this->_M_cur->_M_v; }
00172
00173 _Node_iterator&
00174 operator++()
00175 {
00176 this->_M_incr();
00177 return *this;
00178 }
00179
00180 _Node_iterator
00181 operator++(int)
00182 {
00183 _Node_iterator __tmp(*this);
00184 this->_M_incr();
00185 return __tmp;
00186 }
00187 };
00188
00189 template<typename _Value, bool __constant_iterators, bool __cache>
00190 struct _Node_const_iterator
00191 : public _Node_iterator_base<_Value, __cache>
00192 {
00193 typedef _Value value_type;
00194 typedef const _Value* pointer;
00195 typedef const _Value& reference;
00196 typedef std::ptrdiff_t difference_type;
00197 typedef std::forward_iterator_tag iterator_category;
00198
00199 _Node_const_iterator()
00200 : _Node_iterator_base<_Value, __cache>(0) { }
00201
00202 explicit
00203 _Node_const_iterator(_Hash_node<_Value, __cache>* __p)
00204 : _Node_iterator_base<_Value, __cache>(__p) { }
00205
00206 _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
00207 __cache>& __x)
00208 : _Node_iterator_base<_Value, __cache>(__x._M_cur) { }
00209
00210 reference
00211 operator*() const
00212 { return this->_M_cur->_M_v; }
00213
00214 pointer
00215 operator->() const
00216 { return &this->_M_cur->_M_v; }
00217
00218 _Node_const_iterator&
00219 operator++()
00220 {
00221 this->_M_incr();
00222 return *this;
00223 }
00224
00225 _Node_const_iterator
00226 operator++(int)
00227 {
00228 _Node_const_iterator __tmp(*this);
00229 this->_M_incr();
00230 return __tmp;
00231 }
00232 };
00233
00234 template<typename _Value, bool __cache>
00235 struct _Hashtable_iterator_base
00236 {
00237 _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node,
00238 _Hash_node<_Value, __cache>** __bucket)
00239 : _M_cur_node(__node), _M_cur_bucket(__bucket) { }
00240
00241 void
00242 _M_incr()
00243 {
00244 _M_cur_node = _M_cur_node->_M_next;
00245 if (!_M_cur_node)
00246 _M_incr_bucket();
00247 }
00248
00249 void
00250 _M_incr_bucket();
00251
00252 _Hash_node<_Value, __cache>* _M_cur_node;
00253 _Hash_node<_Value, __cache>** _M_cur_bucket;
00254 };
00255
00256
00257
00258 template<typename _Value, bool __cache>
00259 void
00260 _Hashtable_iterator_base<_Value, __cache>::
00261 _M_incr_bucket()
00262 {
00263 ++_M_cur_bucket;
00264
00265
00266 while (!*_M_cur_bucket)
00267 ++_M_cur_bucket;
00268 _M_cur_node = *_M_cur_bucket;
00269 }
00270
00271 template<typename _Value, bool __cache>
00272 inline bool
00273 operator==(const _Hashtable_iterator_base<_Value, __cache>& __x,
00274 const _Hashtable_iterator_base<_Value, __cache>& __y)
00275 { return __x._M_cur_node == __y._M_cur_node; }
00276
00277 template<typename _Value, bool __cache>
00278 inline bool
00279 operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x,
00280 const _Hashtable_iterator_base<_Value, __cache>& __y)
00281 { return __x._M_cur_node != __y._M_cur_node; }
00282
00283 template<typename _Value, bool __constant_iterators, bool __cache>
00284 struct _Hashtable_iterator
00285 : public _Hashtable_iterator_base<_Value, __cache>
00286 {
00287 typedef _Value value_type;
00288 typedef typename std::conditional<__constant_iterators,
00289 const _Value*, _Value*>::type
00290 pointer;
00291 typedef typename std::conditional<__constant_iterators,
00292 const _Value&, _Value&>::type
00293 reference;
00294 typedef std::ptrdiff_t difference_type;
00295 typedef std::forward_iterator_tag iterator_category;
00296
00297 _Hashtable_iterator()
00298 : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
00299
00300 _Hashtable_iterator(_Hash_node<_Value, __cache>* __p,
00301 _Hash_node<_Value, __cache>** __b)
00302 : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
00303
00304 explicit
00305 _Hashtable_iterator(_Hash_node<_Value, __cache>** __b)
00306 : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
00307
00308 reference
00309 operator*() const
00310 { return this->_M_cur_node->_M_v; }
00311
00312 pointer
00313 operator->() const
00314 { return &this->_M_cur_node->_M_v; }
00315
00316 _Hashtable_iterator&
00317 operator++()
00318 {
00319 this->_M_incr();
00320 return *this;
00321 }
00322
00323 _Hashtable_iterator
00324 operator++(int)
00325 {
00326 _Hashtable_iterator __tmp(*this);
00327 this->_M_incr();
00328 return __tmp;
00329 }
00330 };
00331
00332 template<typename _Value, bool __constant_iterators, bool __cache>
00333 struct _Hashtable_const_iterator
00334 : public _Hashtable_iterator_base<_Value, __cache>
00335 {
00336 typedef _Value value_type;
00337 typedef const _Value* pointer;
00338 typedef const _Value& reference;
00339 typedef std::ptrdiff_t difference_type;
00340 typedef std::forward_iterator_tag iterator_category;
00341
00342 _Hashtable_const_iterator()
00343 : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
00344
00345 _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p,
00346 _Hash_node<_Value, __cache>** __b)
00347 : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
00348
00349 explicit
00350 _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b)
00351 : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
00352
00353 _Hashtable_const_iterator(const _Hashtable_iterator<_Value,
00354 __constant_iterators, __cache>& __x)
00355 : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node,
00356 __x._M_cur_bucket) { }
00357
00358 reference
00359 operator*() const
00360 { return this->_M_cur_node->_M_v; }
00361
00362 pointer
00363 operator->() const
00364 { return &this->_M_cur_node->_M_v; }
00365
00366 _Hashtable_const_iterator&
00367 operator++()
00368 {
00369 this->_M_incr();
00370 return *this;
00371 }
00372
00373 _Hashtable_const_iterator
00374 operator++(int)
00375 {
00376 _Hashtable_const_iterator __tmp(*this);
00377 this->_M_incr();
00378 return __tmp;
00379 }
00380 };
00381
00382
00383
00384
00385
00386
00387
00388 struct _Mod_range_hashing
00389 {
00390 typedef std::size_t first_argument_type;
00391 typedef std::size_t second_argument_type;
00392 typedef std::size_t result_type;
00393
00394 result_type
00395 operator()(first_argument_type __num, second_argument_type __den) const
00396 { return __num % __den; }
00397 };
00398
00399
00400
00401
00402
00403
00404 struct _Default_ranged_hash { };
00405
00406
00407
00408 struct _Prime_rehash_policy
00409 {
00410 _Prime_rehash_policy(float __z = 1.0)
00411 : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) { }
00412
00413 float
00414 max_load_factor() const
00415 { return _M_max_load_factor; }
00416
00417
00418 std::size_t
00419 _M_next_bkt(std::size_t __n) const;
00420
00421
00422 std::size_t
00423 _M_bkt_for_elements(std::size_t __n) const;
00424
00425
00426
00427
00428
00429 std::pair<bool, std::size_t>
00430 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
00431 std::size_t __n_ins) const;
00432
00433 enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
00434
00435 float _M_max_load_factor;
00436 float _M_growth_factor;
00437 mutable std::size_t _M_next_resize;
00438 };
00439
00440 extern const unsigned long __prime_list[];
00441
00442
00443
00444
00445
00446 inline std::size_t
00447 _Prime_rehash_policy::
00448 _M_next_bkt(std::size_t __n) const
00449 {
00450 const unsigned long* __p = __lower_bound(__prime_list, __prime_list
00451 + _S_n_primes, __n);
00452 _M_next_resize =
00453 static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
00454 return *__p;
00455 }
00456
00457
00458
00459 inline std::size_t
00460 _Prime_rehash_policy::
00461 _M_bkt_for_elements(std::size_t __n) const
00462 {
00463 const float __min_bkts = __n / _M_max_load_factor;
00464 const unsigned long* __p = __lower_bound(__prime_list, __prime_list
00465 + _S_n_primes, __min_bkts);
00466 _M_next_resize =
00467 static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
00468 return *__p;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 inline std::pair<bool, std::size_t>
00481 _Prime_rehash_policy::
00482 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
00483 std::size_t __n_ins) const
00484 {
00485 if (__n_elt + __n_ins > _M_next_resize)
00486 {
00487 float __min_bkts = ((float(__n_ins) + float(__n_elt))
00488 / _M_max_load_factor);
00489 if (__min_bkts > __n_bkt)
00490 {
00491 __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
00492 const unsigned long* __p =
00493 __lower_bound(__prime_list, __prime_list + _S_n_primes,
00494 __min_bkts);
00495 _M_next_resize = static_cast<std::size_t>
00496 (__builtin_ceil(*__p * _M_max_load_factor));
00497 return std::make_pair(true, *__p);
00498 }
00499 else
00500 {
00501 _M_next_resize = static_cast<std::size_t>
00502 (__builtin_ceil(__n_bkt * _M_max_load_factor));
00503 return std::make_pair(false, 0);
00504 }
00505 }
00506 else
00507 return std::make_pair(false, 0);
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 template<typename _Key, typename _Value, typename _Ex, bool __unique,
00525 typename _Hashtable>
00526 struct _Map_base { };
00527
00528 template<typename _Key, typename _Pair, typename _Hashtable>
00529 struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable>
00530 {
00531 typedef typename _Pair::second_type mapped_type;
00532 };
00533
00534 template<typename _Key, typename _Pair, typename _Hashtable>
00535 struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>
00536 {
00537 typedef typename _Pair::second_type mapped_type;
00538
00539 mapped_type&
00540 operator[](const _Key& __k);
00541
00542
00543
00544 mapped_type&
00545 at(const _Key& __k);
00546
00547 const mapped_type&
00548 at(const _Key& __k) const;
00549 };
00550
00551 template<typename _Key, typename _Pair, typename _Hashtable>
00552 typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
00553 true, _Hashtable>::mapped_type&
00554 _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
00555 operator[](const _Key& __k)
00556 {
00557 _Hashtable* __h = static_cast<_Hashtable*>(this);
00558 typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
00559 std::size_t __n = __h->_M_bucket_index(__k, __code,
00560 __h->_M_bucket_count);
00561
00562 typename _Hashtable::_Node* __p =
00563 __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
00564 if (!__p)
00565 return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()),
00566 __n, __code)->second;
00567 return (__p->_M_v).second;
00568 }
00569
00570 template<typename _Key, typename _Pair, typename _Hashtable>
00571 typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
00572 true, _Hashtable>::mapped_type&
00573 _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
00574 at(const _Key& __k)
00575 {
00576 _Hashtable* __h = static_cast<_Hashtable*>(this);
00577 typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
00578 std::size_t __n = __h->_M_bucket_index(__k, __code,
00579 __h->_M_bucket_count);
00580
00581 typename _Hashtable::_Node* __p =
00582 __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
00583 if (!__p)
00584 __throw_out_of_range(__N("_Map_base::at"));
00585 return (__p->_M_v).second;
00586 }
00587
00588 template<typename _Key, typename _Pair, typename _Hashtable>
00589 const typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
00590 true, _Hashtable>::mapped_type&
00591 _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
00592 at(const _Key& __k) const
00593 {
00594 const _Hashtable* __h = static_cast<const _Hashtable*>(this);
00595 typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
00596 std::size_t __n = __h->_M_bucket_index(__k, __code,
00597 __h->_M_bucket_count);
00598
00599 typename _Hashtable::_Node* __p =
00600 __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
00601 if (!__p)
00602 __throw_out_of_range(__N("_Map_base::at"));
00603 return (__p->_M_v).second;
00604 }
00605
00606
00607
00608 template<typename _RehashPolicy, typename _Hashtable>
00609 struct _Rehash_base { };
00610
00611 template<typename _Hashtable>
00612 struct _Rehash_base<_Prime_rehash_policy, _Hashtable>
00613 {
00614 float
00615 max_load_factor() const
00616 {
00617 const _Hashtable* __this = static_cast<const _Hashtable*>(this);
00618 return __this->__rehash_policy().max_load_factor();
00619 }
00620
00621 void
00622 max_load_factor(float __z)
00623 {
00624 _Hashtable* __this = static_cast<_Hashtable*>(this);
00625 __this->__rehash_policy(_Prime_rehash_policy(__z));
00626 }
00627
00628 void
00629 reserve(std::size_t __n)
00630 {
00631 _Hashtable* __this = static_cast<_Hashtable*>(this);
00632 __this->rehash(__builtin_ceil(__n / max_load_factor()));
00633 }
00634 };
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 template<typename _Key, typename _Value,
00649 typename _ExtractKey, typename _Equal,
00650 typename _H1, typename _H2, typename _Hash,
00651 bool __cache_hash_code>
00652 struct _Hash_code_base;
00653
00654
00655
00656 template<typename _Key, typename _Value,
00657 typename _ExtractKey, typename _Equal,
00658 typename _H1, typename _H2, typename _Hash>
00659 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00660 _Hash, false>
00661 {
00662 protected:
00663 _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
00664 const _H1&, const _H2&, const _Hash& __h)
00665 : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { }
00666
00667 typedef void* _Hash_code_type;
00668
00669 _Hash_code_type
00670 _M_hash_code(const _Key& __key) const
00671 { return 0; }
00672
00673 std::size_t
00674 _M_bucket_index(const _Key& __k, _Hash_code_type,
00675 std::size_t __n) const
00676 { return _M_ranged_hash(__k, __n); }
00677
00678 std::size_t
00679 _M_bucket_index(const _Hash_node<_Value, false>* __p,
00680 std::size_t __n) const
00681 { return _M_ranged_hash(_M_extract(__p->_M_v), __n); }
00682
00683 bool
00684 _M_compare(const _Key& __k, _Hash_code_type,
00685 _Hash_node<_Value, false>* __n) const
00686 { return _M_eq(__k, _M_extract(__n->_M_v)); }
00687
00688 void
00689 _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
00690 { }
00691
00692 void
00693 _M_copy_code(_Hash_node<_Value, false>*,
00694 const _Hash_node<_Value, false>*) const
00695 { }
00696
00697 void
00698 _M_swap(_Hash_code_base& __x)
00699 {
00700 std::swap(_M_extract, __x._M_extract);
00701 std::swap(_M_eq, __x._M_eq);
00702 std::swap(_M_ranged_hash, __x._M_ranged_hash);
00703 }
00704
00705 protected:
00706 _ExtractKey _M_extract;
00707 _Equal _M_eq;
00708 _Hash _M_ranged_hash;
00709 };
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 template<typename _Key, typename _Value,
00720 typename _ExtractKey, typename _Equal,
00721 typename _H1, typename _H2, typename _Hash>
00722 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00723 _Hash, true>;
00724
00725
00726
00727
00728 template<typename _Key, typename _Value,
00729 typename _ExtractKey, typename _Equal,
00730 typename _H1, typename _H2>
00731 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00732 _Default_ranged_hash, false>
00733 {
00734 typedef _H1 hasher;
00735
00736 hasher
00737 hash_function() const
00738 { return _M_h1; }
00739
00740 protected:
00741 _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
00742 const _H1& __h1, const _H2& __h2,
00743 const _Default_ranged_hash&)
00744 : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
00745
00746 typedef std::size_t _Hash_code_type;
00747
00748 _Hash_code_type
00749 _M_hash_code(const _Key& __k) const
00750 { return _M_h1(__k); }
00751
00752 std::size_t
00753 _M_bucket_index(const _Key&, _Hash_code_type __c,
00754 std::size_t __n) const
00755 { return _M_h2(__c, __n); }
00756
00757 std::size_t
00758 _M_bucket_index(const _Hash_node<_Value, false>* __p,
00759 std::size_t __n) const
00760 { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); }
00761
00762 bool
00763 _M_compare(const _Key& __k, _Hash_code_type,
00764 _Hash_node<_Value, false>* __n) const
00765 { return _M_eq(__k, _M_extract(__n->_M_v)); }
00766
00767 void
00768 _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
00769 { }
00770
00771 void
00772 _M_copy_code(_Hash_node<_Value, false>*,
00773 const _Hash_node<_Value, false>*) const
00774 { }
00775
00776 void
00777 _M_swap(_Hash_code_base& __x)
00778 {
00779 std::swap(_M_extract, __x._M_extract);
00780 std::swap(_M_eq, __x._M_eq);
00781 std::swap(_M_h1, __x._M_h1);
00782 std::swap(_M_h2, __x._M_h2);
00783 }
00784
00785 protected:
00786 _ExtractKey _M_extract;
00787 _Equal _M_eq;
00788 _H1 _M_h1;
00789 _H2 _M_h2;
00790 };
00791
00792
00793
00794
00795 template<typename _Key, typename _Value,
00796 typename _ExtractKey, typename _Equal,
00797 typename _H1, typename _H2>
00798 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
00799 _Default_ranged_hash, true>
00800 {
00801 typedef _H1 hasher;
00802
00803 hasher
00804 hash_function() const
00805 { return _M_h1; }
00806
00807 protected:
00808 _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
00809 const _H1& __h1, const _H2& __h2,
00810 const _Default_ranged_hash&)
00811 : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
00812
00813 typedef std::size_t _Hash_code_type;
00814
00815 _Hash_code_type
00816 _M_hash_code(const _Key& __k) const
00817 { return _M_h1(__k); }
00818
00819 std::size_t
00820 _M_bucket_index(const _Key&, _Hash_code_type __c,
00821 std::size_t __n) const
00822 { return _M_h2(__c, __n); }
00823
00824 std::size_t
00825 _M_bucket_index(const _Hash_node<_Value, true>* __p,
00826 std::size_t __n) const
00827 { return _M_h2(__p->_M_hash_code, __n); }
00828
00829 bool
00830 _M_compare(const _Key& __k, _Hash_code_type __c,
00831 _Hash_node<_Value, true>* __n) const
00832 { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); }
00833
00834 void
00835 _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const
00836 { __n->_M_hash_code = __c; }
00837
00838 void
00839 _M_copy_code(_Hash_node<_Value, true>* __to,
00840 const _Hash_node<_Value, true>* __from) const
00841 { __to->_M_hash_code = __from->_M_hash_code; }
00842
00843 void
00844 _M_swap(_Hash_code_base& __x)
00845 {
00846 std::swap(_M_extract, __x._M_extract);
00847 std::swap(_M_eq, __x._M_eq);
00848 std::swap(_M_h1, __x._M_h1);
00849 std::swap(_M_h2, __x._M_h2);
00850 }
00851
00852 protected:
00853 _ExtractKey _M_extract;
00854 _Equal _M_eq;
00855 _H1 _M_h1;
00856 _H2 _M_h2;
00857 };
00858 }
00859 }
00860
00861 #endif // _HASHTABLE_POLICY_H