1// Internal policy header for unordered_set and unordered_map -*- C++ -*- 2 3// Copyright (C) 2010, 2011 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file bits/hashtable_policy.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. 28 * @headername{unordered_map,unordered_set} 29 */ 30 31#ifndef _HASHTABLE_POLICY_H 32#define _HASHTABLE_POLICY_H 1 33 34namespace std _GLIBCXX_VISIBILITY(default) 35{ 36namespace __detail 37{ 38_GLIBCXX_BEGIN_NAMESPACE_VERSION 39 40 // Helper function: return distance(first, last) for forward 41 // iterators, or 0 for input iterators. 42 template<class _Iterator> 43 inline typename std::iterator_traits<_Iterator>::difference_type 44 __distance_fw(_Iterator __first, _Iterator __last, 45 std::input_iterator_tag) 46 { return 0; } 47 48 template<class _Iterator> 49 inline typename std::iterator_traits<_Iterator>::difference_type 50 __distance_fw(_Iterator __first, _Iterator __last, 51 std::forward_iterator_tag) 52 { return std::distance(__first, __last); } 53 54 template<class _Iterator> 55 inline typename std::iterator_traits<_Iterator>::difference_type 56 __distance_fw(_Iterator __first, _Iterator __last) 57 { 58 typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag; 59 return __distance_fw(__first, __last, _Tag()); 60 } 61 62 // Auxiliary types used for all instantiations of _Hashtable: nodes 63 // and iterators. 64 65 // Nodes, used to wrap elements stored in the hash table. A policy 66 // template parameter of class template _Hashtable controls whether 67 // nodes also store a hash code. In some cases (e.g. strings) this 68 // may be a performance win. 69 template<typename _Value, bool __cache_hash_code> 70 struct _Hash_node; 71 72 template<typename _Value> 73 struct _Hash_node<_Value, true> 74 { 75 _Value _M_v; 76 std::size_t _M_hash_code; 77 _Hash_node* _M_next; 78 79 template<typename... _Args> 80 _Hash_node(_Args&&... __args) 81 : _M_v(std::forward<_Args>(__args)...), 82 _M_hash_code(), _M_next() { } 83 }; 84 85 template<typename _Value> 86 struct _Hash_node<_Value, false> 87 { 88 _Value _M_v; 89 _Hash_node* _M_next; 90 91 template<typename... _Args> 92 _Hash_node(_Args&&... __args) 93 : _M_v(std::forward<_Args>(__args)...), 94 _M_next() { } 95 }; 96 97 // Local iterators, used to iterate within a bucket but not between 98 // buckets. 99 template<typename _Value, bool __cache> 100 struct _Node_iterator_base 101 { 102 _Node_iterator_base(_Hash_node<_Value, __cache>* __p) 103 : _M_cur(__p) { } 104 105 void 106 _M_incr() 107 { _M_cur = _M_cur->_M_next; } 108 109 _Hash_node<_Value, __cache>* _M_cur; 110 }; 111 112 template<typename _Value, bool __cache> 113 inline bool 114 operator==(const _Node_iterator_base<_Value, __cache>& __x, 115 const _Node_iterator_base<_Value, __cache>& __y) 116 { return __x._M_cur == __y._M_cur; } 117 118 template<typename _Value, bool __cache> 119 inline bool 120 operator!=(const _Node_iterator_base<_Value, __cache>& __x, 121 const _Node_iterator_base<_Value, __cache>& __y) 122 { return __x._M_cur != __y._M_cur; } 123 124 template<typename _Value, bool __constant_iterators, bool __cache> 125 struct _Node_iterator 126 : public _Node_iterator_base<_Value, __cache> 127 { 128 typedef _Value value_type; 129 typedef typename std::conditional<__constant_iterators, 130 const _Value*, _Value*>::type 131 pointer; 132 typedef typename std::conditional<__constant_iterators, 133 const _Value&, _Value&>::type 134 reference; 135 typedef std::ptrdiff_t difference_type; 136 typedef std::forward_iterator_tag iterator_category; 137 138 _Node_iterator() 139 : _Node_iterator_base<_Value, __cache>(0) { } 140 141 explicit 142 _Node_iterator(_Hash_node<_Value, __cache>* __p) 143 : _Node_iterator_base<_Value, __cache>(__p) { } 144 145 reference 146 operator*() const 147 { return this->_M_cur->_M_v; } 148 149 pointer 150 operator->() const 151 { return std::__addressof(this->_M_cur->_M_v); } 152 153 _Node_iterator& 154 operator++() 155 { 156 this->_M_incr(); 157 return *this; 158 } 159 160 _Node_iterator 161 operator++(int) 162 { 163 _Node_iterator __tmp(*this); 164 this->_M_incr(); 165 return __tmp; 166 } 167 }; 168 169 template<typename _Value, bool __constant_iterators, bool __cache> 170 struct _Node_const_iterator 171 : public _Node_iterator_base<_Value, __cache> 172 { 173 typedef _Value value_type; 174 typedef const _Value* pointer; 175 typedef const _Value& reference; 176 typedef std::ptrdiff_t difference_type; 177 typedef std::forward_iterator_tag iterator_category; 178 179 _Node_const_iterator() 180 : _Node_iterator_base<_Value, __cache>(0) { } 181 182 explicit 183 _Node_const_iterator(_Hash_node<_Value, __cache>* __p) 184 : _Node_iterator_base<_Value, __cache>(__p) { } 185 186 _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators, 187 __cache>& __x) 188 : _Node_iterator_base<_Value, __cache>(__x._M_cur) { } 189 190 reference 191 operator*() const 192 { return this->_M_cur->_M_v; } 193 194 pointer 195 operator->() const 196 { return std::__addressof(this->_M_cur->_M_v); } 197 198 _Node_const_iterator& 199 operator++() 200 { 201 this->_M_incr(); 202 return *this; 203 } 204 205 _Node_const_iterator 206 operator++(int) 207 { 208 _Node_const_iterator __tmp(*this); 209 this->_M_incr(); 210 return __tmp; 211 } 212 }; 213 214 template<typename _Value, bool __cache> 215 struct _Hashtable_iterator_base 216 { 217 _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node, 218 _Hash_node<_Value, __cache>** __bucket) 219 : _M_cur_node(__node), _M_cur_bucket(__bucket) { } 220 221 void 222 _M_incr() 223 { 224 _M_cur_node = _M_cur_node->_M_next; 225 if (!_M_cur_node) 226 _M_incr_bucket(); 227 } 228 229 void 230 _M_incr_bucket(); 231 232 _Hash_node<_Value, __cache>* _M_cur_node; 233 _Hash_node<_Value, __cache>** _M_cur_bucket; 234 }; 235 236 // Global iterators, used for arbitrary iteration within a hash 237 // table. Larger and more expensive than local iterators. 238 template<typename _Value, bool __cache> 239 void 240 _Hashtable_iterator_base<_Value, __cache>:: 241 _M_incr_bucket() 242 { 243 ++_M_cur_bucket; 244 245 // This loop requires the bucket array to have a non-null sentinel. 246 while (!*_M_cur_bucket) 247 ++_M_cur_bucket; 248 _M_cur_node = *_M_cur_bucket; 249 } 250 251 template<typename _Value, bool __cache> 252 inline bool 253 operator==(const _Hashtable_iterator_base<_Value, __cache>& __x, 254 const _Hashtable_iterator_base<_Value, __cache>& __y) 255 { return __x._M_cur_node == __y._M_cur_node; } 256 257 template<typename _Value, bool __cache> 258 inline bool 259 operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x, 260 const _Hashtable_iterator_base<_Value, __cache>& __y) 261 { return __x._M_cur_node != __y._M_cur_node; } 262 263 template<typename _Value, bool __constant_iterators, bool __cache> 264 struct _Hashtable_iterator 265 : public _Hashtable_iterator_base<_Value, __cache> 266 { 267 typedef _Value value_type; 268 typedef typename std::conditional<__constant_iterators, 269 const _Value*, _Value*>::type 270 pointer; 271 typedef typename std::conditional<__constant_iterators, 272 const _Value&, _Value&>::type 273 reference; 274 typedef std::ptrdiff_t difference_type; 275 typedef std::forward_iterator_tag iterator_category; 276 277 _Hashtable_iterator() 278 : _Hashtable_iterator_base<_Value, __cache>(0, 0) { } 279 280 _Hashtable_iterator(_Hash_node<_Value, __cache>* __p, 281 _Hash_node<_Value, __cache>** __b) 282 : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { } 283 284 explicit 285 _Hashtable_iterator(_Hash_node<_Value, __cache>** __b) 286 : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { } 287 288 reference 289 operator*() const 290 { return this->_M_cur_node->_M_v; } 291 292 pointer 293 operator->() const 294 { return std::__addressof(this->_M_cur_node->_M_v); } 295 296 _Hashtable_iterator& 297 operator++() 298 { 299 this->_M_incr(); 300 return *this; 301 } 302 303 _Hashtable_iterator 304 operator++(int) 305 { 306 _Hashtable_iterator __tmp(*this); 307 this->_M_incr(); 308 return __tmp; 309 } 310 }; 311 312 template<typename _Value, bool __constant_iterators, bool __cache> 313 struct _Hashtable_const_iterator 314 : public _Hashtable_iterator_base<_Value, __cache> 315 { 316 typedef _Value value_type; 317 typedef const _Value* pointer; 318 typedef const _Value& reference; 319 typedef std::ptrdiff_t difference_type; 320 typedef std::forward_iterator_tag iterator_category; 321 322 _Hashtable_const_iterator() 323 : _Hashtable_iterator_base<_Value, __cache>(0, 0) { } 324 325 _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p, 326 _Hash_node<_Value, __cache>** __b) 327 : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { } 328 329 explicit 330 _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b) 331 : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { } 332 333 _Hashtable_const_iterator(const _Hashtable_iterator<_Value, 334 __constant_iterators, __cache>& __x) 335 : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node, 336 __x._M_cur_bucket) { } 337 338 reference 339 operator*() const 340 { return this->_M_cur_node->_M_v; } 341 342 pointer 343 operator->() const 344 { return std::__addressof(this->_M_cur_node->_M_v); } 345 346 _Hashtable_const_iterator& 347 operator++() 348 { 349 this->_M_incr(); 350 return *this; 351 } 352 353 _Hashtable_const_iterator 354 operator++(int) 355 { 356 _Hashtable_const_iterator __tmp(*this); 357 this->_M_incr(); 358 return __tmp; 359 } 360 }; 361 362 363 // Many of class template _Hashtable's template parameters are policy 364 // classes. These are defaults for the policies. 365 366 // Default range hashing function: use division to fold a large number 367 // into the range [0, N). 368 struct _Mod_range_hashing 369 { 370 typedef std::size_t first_argument_type; 371 typedef std::size_t second_argument_type; 372 typedef std::size_t result_type; 373 374 result_type 375 operator()(first_argument_type __num, second_argument_type __den) const 376 { return __num % __den; } 377 }; 378 379 // Default ranged hash function H. In principle it should be a 380 // function object composed from objects of type H1 and H2 such that 381 // h(k, N) = h2(h1(k), N), but that would mean making extra copies of 382 // h1 and h2. So instead we'll just use a tag to tell class template 383 // hashtable to do that composition. 384 struct _Default_ranged_hash { }; 385 386 // Default value for rehash policy. Bucket size is (usually) the 387 // smallest prime that keeps the load factor small enough. 388 struct _Prime_rehash_policy 389 { 390 _Prime_rehash_policy(float __z = 1.0) 391 : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) { } 392 393 float 394 max_load_factor() const 395 { return _M_max_load_factor; } 396 397 // Return a bucket size no smaller than n. 398 std::size_t 399 _M_next_bkt(std::size_t __n) const; 400 401 // Return a bucket count appropriate for n elements 402 std::size_t 403 _M_bkt_for_elements(std::size_t __n) const; 404 405 // __n_bkt is current bucket count, __n_elt is current element count, 406 // and __n_ins is number of elements to be inserted. Do we need to 407 // increase bucket count? If so, return make_pair(true, n), where n 408 // is the new bucket count. If not, return make_pair(false, 0). 409 std::pair<bool, std::size_t> 410 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, 411 std::size_t __n_ins) const; 412 413 enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 }; 414 415 float _M_max_load_factor; 416 float _M_growth_factor; 417 mutable std::size_t _M_next_resize; 418 }; 419 420 extern const unsigned long __prime_list[]; 421 422 // XXX This is a hack. There's no good reason for any of 423 // _Prime_rehash_policy's member functions to be inline. 424 425 // Return a prime no smaller than n. 426 inline std::size_t 427 _Prime_rehash_policy:: 428 _M_next_bkt(std::size_t __n) const 429 { 430 const unsigned long* __p = std::lower_bound(__prime_list, __prime_list 431 + _S_n_primes, __n); 432 _M_next_resize = 433 static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor)); 434 return *__p; 435 } 436 437 // Return the smallest prime p such that alpha p >= n, where alpha 438 // is the load factor. 439 inline std::size_t 440 _Prime_rehash_policy:: 441 _M_bkt_for_elements(std::size_t __n) const 442 { 443 const float __min_bkts = __n / _M_max_load_factor; 444 const unsigned long* __p = std::lower_bound(__prime_list, __prime_list 445 + _S_n_primes, __min_bkts); 446 _M_next_resize = 447 static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor)); 448 return *__p; 449 } 450 451 // Finds the smallest prime p such that alpha p > __n_elt + __n_ins. 452 // If p > __n_bkt, return make_pair(true, p); otherwise return 453 // make_pair(false, 0). In principle this isn't very different from 454 // _M_bkt_for_elements. 455 456 // The only tricky part is that we're caching the element count at 457 // which we need to rehash, so we don't have to do a floating-point 458 // multiply for every insertion. 459 460 inline std::pair<bool, std::size_t> 461 _Prime_rehash_policy:: 462 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, 463 std::size_t __n_ins) const 464 { 465 if (__n_elt + __n_ins > _M_next_resize) 466 { 467 float __min_bkts = ((float(__n_ins) + float(__n_elt)) 468 / _M_max_load_factor); 469 if (__min_bkts > __n_bkt) 470 { 471 __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt); 472 const unsigned long* __p = 473 std::lower_bound(__prime_list, __prime_list + _S_n_primes, 474 __min_bkts); 475 _M_next_resize = static_cast<std::size_t> 476 (__builtin_ceil(*__p * _M_max_load_factor)); 477 return std::make_pair(true, *__p); 478 } 479 else 480 { 481 _M_next_resize = static_cast<std::size_t> 482 (__builtin_ceil(__n_bkt * _M_max_load_factor)); 483 return std::make_pair(false, 0); 484 } 485 } 486 else 487 return std::make_pair(false, 0); 488 } 489 490 // Base classes for std::_Hashtable. We define these base classes 491 // because in some cases we want to do different things depending 492 // on the value of a policy class. In some cases the policy class 493 // affects which member functions and nested typedefs are defined; 494 // we handle that by specializing base class templates. Several of 495 // the base class templates need to access other members of class 496 // template _Hashtable, so we use the "curiously recurring template 497 // pattern" for them. 498 499 // class template _Map_base. If the hashtable has a value type of 500 // the form pair<T1, T2> and a key extraction policy that returns the 501 // first part of the pair, the hashtable gets a mapped_type typedef. 502 // If it satisfies those criteria and also has unique keys, then it 503 // also gets an operator[]. 504 template<typename _Key, typename _Value, typename _Ex, bool __unique, 505 typename _Hashtable> 506 struct _Map_base { }; 507 508 template<typename _Key, typename _Pair, typename _Hashtable> 509 struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable> 510 { 511 typedef typename _Pair::second_type mapped_type; 512 }; 513 514 template<typename _Key, typename _Pair, typename _Hashtable> 515 struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable> 516 { 517 typedef typename _Pair::second_type mapped_type; 518 519 mapped_type& 520 operator[](const _Key& __k); 521 522 mapped_type& 523 operator[](_Key&& __k); 524 525 // _GLIBCXX_RESOLVE_LIB_DEFECTS 526 // DR 761. unordered_map needs an at() member function. 527 mapped_type& 528 at(const _Key& __k); 529 530 const mapped_type& 531 at(const _Key& __k) const; 532 }; 533 534 template<typename _Key, typename _Pair, typename _Hashtable> 535 typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, 536 true, _Hashtable>::mapped_type& 537 _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: 538 operator[](const _Key& __k) 539 { 540 _Hashtable* __h = static_cast<_Hashtable*>(this); 541 typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); 542 std::size_t __n = __h->_M_bucket_index(__k, __code, 543 __h->_M_bucket_count); 544 545 typename _Hashtable::_Node* __p = 546 __h->_M_find_node(__h->_M_buckets[__n], __k, __code); 547 if (!__p) 548 return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()), 549 __n, __code)->second; 550 return (__p->_M_v).second; 551 } 552 553 template<typename _Key, typename _Pair, typename _Hashtable> 554 typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, 555 true, _Hashtable>::mapped_type& 556 _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: 557 operator[](_Key&& __k) 558 { 559 _Hashtable* __h = static_cast<_Hashtable*>(this); 560 typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); 561 std::size_t __n = __h->_M_bucket_index(__k, __code, 562 __h->_M_bucket_count); 563 564 typename _Hashtable::_Node* __p = 565 __h->_M_find_node(__h->_M_buckets[__n], __k, __code); 566 if (!__p) 567 return __h->_M_insert_bucket(std::make_pair(std::move(__k), 568 mapped_type()), 569 __n, __code)->second; 570 return (__p->_M_v).second; 571 } 572 573 template<typename _Key, typename _Pair, typename _Hashtable> 574 typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, 575 true, _Hashtable>::mapped_type& 576 _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: 577 at(const _Key& __k) 578 { 579 _Hashtable* __h = static_cast<_Hashtable*>(this); 580 typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); 581 std::size_t __n = __h->_M_bucket_index(__k, __code, 582 __h->_M_bucket_count); 583 584 typename _Hashtable::_Node* __p = 585 __h->_M_find_node(__h->_M_buckets[__n], __k, __code); 586 if (!__p) 587 __throw_out_of_range(__N("_Map_base::at")); 588 return (__p->_M_v).second; 589 } 590 591 template<typename _Key, typename _Pair, typename _Hashtable> 592 const typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, 593 true, _Hashtable>::mapped_type& 594 _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: 595 at(const _Key& __k) const 596 { 597 const _Hashtable* __h = static_cast<const _Hashtable*>(this); 598 typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); 599 std::size_t __n = __h->_M_bucket_index(__k, __code, 600 __h->_M_bucket_count); 601 602 typename _Hashtable::_Node* __p = 603 __h->_M_find_node(__h->_M_buckets[__n], __k, __code); 604 if (!__p) 605 __throw_out_of_range(__N("_Map_base::at")); 606 return (__p->_M_v).second; 607 } 608 609 // class template _Rehash_base. Give hashtable the max_load_factor 610 // functions and reserve iff the rehash policy is _Prime_rehash_policy. 611 template<typename _RehashPolicy, typename _Hashtable> 612 struct _Rehash_base { }; 613 614 template<typename _Hashtable> 615 struct _Rehash_base<_Prime_rehash_policy, _Hashtable> 616 { 617 float 618 max_load_factor() const 619 { 620 const _Hashtable* __this = static_cast<const _Hashtable*>(this); 621 return __this->__rehash_policy().max_load_factor(); 622 } 623 624 void 625 max_load_factor(float __z) 626 { 627 _Hashtable* __this = static_cast<_Hashtable*>(this); 628 __this->__rehash_policy(_Prime_rehash_policy(__z)); 629 } 630 631 void 632 reserve(std::size_t __n) 633 { 634 _Hashtable* __this = static_cast<_Hashtable*>(this); 635 __this->rehash(__builtin_ceil(__n / max_load_factor())); 636 } 637 }; 638 639 // Class template _Hash_code_base. Encapsulates two policy issues that 640 // aren't quite orthogonal. 641 // (1) the difference between using a ranged hash function and using 642 // the combination of a hash function and a range-hashing function. 643 // In the former case we don't have such things as hash codes, so 644 // we have a dummy type as placeholder. 645 // (2) Whether or not we cache hash codes. Caching hash codes is 646 // meaningless if we have a ranged hash function. 647 // We also put the key extraction and equality comparison function 648 // objects here, for convenience. 649 650 // Primary template: unused except as a hook for specializations. 651 template<typename _Key, typename _Value, 652 typename _ExtractKey, typename _Equal, 653 typename _H1, typename _H2, typename _Hash, 654 bool __cache_hash_code> 655 struct _Hash_code_base; 656 657 // Specialization: ranged hash function, no caching hash codes. H1 658 // and H2 are provided but ignored. We define a dummy hash code type. 659 template<typename _Key, typename _Value, 660 typename _ExtractKey, typename _Equal, 661 typename _H1, typename _H2, typename _Hash> 662 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, 663 _Hash, false> 664 { 665 protected: 666 _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, 667 const _H1&, const _H2&, const _Hash& __h) 668 : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { } 669 670 typedef void* _Hash_code_type; 671 672 _Hash_code_type 673 _M_hash_code(const _Key& __key) const 674 { return 0; } 675 676 std::size_t 677 _M_bucket_index(const _Key& __k, _Hash_code_type, 678 std::size_t __n) const 679 { return _M_ranged_hash(__k, __n); } 680 681 std::size_t 682 _M_bucket_index(const _Hash_node<_Value, false>* __p, 683 std::size_t __n) const 684 { return _M_ranged_hash(_M_extract(__p->_M_v), __n); } 685 686 bool 687 _M_compare(const _Key& __k, _Hash_code_type, 688 _Hash_node<_Value, false>* __n) const 689 { return _M_eq(__k, _M_extract(__n->_M_v)); } 690 691 void 692 _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const 693 { } 694 695 void 696 _M_copy_code(_Hash_node<_Value, false>*, 697 const _Hash_node<_Value, false>*) const 698 { } 699 700 void 701 _M_swap(_Hash_code_base& __x) 702 { 703 std::swap(_M_extract, __x._M_extract); 704 std::swap(_M_eq, __x._M_eq); 705 std::swap(_M_ranged_hash, __x._M_ranged_hash); 706 } 707 708 protected: 709 _ExtractKey _M_extract; 710 _Equal _M_eq; 711 _Hash _M_ranged_hash; 712 }; 713 714 715 // No specialization for ranged hash function while caching hash codes. 716 // That combination is meaningless, and trying to do it is an error. 717 718 719 // Specialization: ranged hash function, cache hash codes. This 720 // combination is meaningless, so we provide only a declaration 721 // and no definition. 722 template<typename _Key, typename _Value, 723 typename _ExtractKey, typename _Equal, 724 typename _H1, typename _H2, typename _Hash> 725 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, 726 _Hash, true>; 727 728 // Specialization: hash function and range-hashing function, no 729 // caching of hash codes. H is provided but ignored. Provides 730 // typedef and accessor required by TR1. 731 template<typename _Key, typename _Value, 732 typename _ExtractKey, typename _Equal, 733 typename _H1, typename _H2> 734 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, 735 _Default_ranged_hash, false> 736 { 737 typedef _H1 hasher; 738 739 hasher 740 hash_function() const 741 { return _M_h1; } 742 743 protected: 744 _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, 745 const _H1& __h1, const _H2& __h2, 746 const _Default_ranged_hash&) 747 : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { } 748 749 typedef std::size_t _Hash_code_type; 750 751 _Hash_code_type 752 _M_hash_code(const _Key& __k) const 753 { return _M_h1(__k); } 754 755 std::size_t 756 _M_bucket_index(const _Key&, _Hash_code_type __c, 757 std::size_t __n) const 758 { return _M_h2(__c, __n); } 759 760 std::size_t 761 _M_bucket_index(const _Hash_node<_Value, false>* __p, 762 std::size_t __n) const 763 { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); } 764 765 bool 766 _M_compare(const _Key& __k, _Hash_code_type, 767 _Hash_node<_Value, false>* __n) const 768 { return _M_eq(__k, _M_extract(__n->_M_v)); } 769 770 void 771 _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const 772 { } 773 774 void 775 _M_copy_code(_Hash_node<_Value, false>*, 776 const _Hash_node<_Value, false>*) const 777 { } 778 779 void 780 _M_swap(_Hash_code_base& __x) 781 { 782 std::swap(_M_extract, __x._M_extract); 783 std::swap(_M_eq, __x._M_eq); 784 std::swap(_M_h1, __x._M_h1); 785 std::swap(_M_h2, __x._M_h2); 786 } 787 788 protected: 789 _ExtractKey _M_extract; 790 _Equal _M_eq; 791 _H1 _M_h1; 792 _H2 _M_h2; 793 }; 794 795 // Specialization: hash function and range-hashing function, 796 // caching hash codes. H is provided but ignored. Provides 797 // typedef and accessor required by TR1. 798 template<typename _Key, typename _Value, 799 typename _ExtractKey, typename _Equal, 800 typename _H1, typename _H2> 801 struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, 802 _Default_ranged_hash, true> 803 { 804 typedef _H1 hasher; 805 806 hasher 807 hash_function() const 808 { return _M_h1; } 809 810 protected: 811 _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq, 812 const _H1& __h1, const _H2& __h2, 813 const _Default_ranged_hash&) 814 : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { } 815 816 typedef std::size_t _Hash_code_type; 817 818 _Hash_code_type 819 _M_hash_code(const _Key& __k) const 820 { return _M_h1(__k); } 821 822 std::size_t 823 _M_bucket_index(const _Key&, _Hash_code_type __c, 824 std::size_t __n) const 825 { return _M_h2(__c, __n); } 826 827 std::size_t 828 _M_bucket_index(const _Hash_node<_Value, true>* __p, 829 std::size_t __n) const 830 { return _M_h2(__p->_M_hash_code, __n); } 831 832 bool 833 _M_compare(const _Key& __k, _Hash_code_type __c, 834 _Hash_node<_Value, true>* __n) const 835 { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); } 836 837 void 838 _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const 839 { __n->_M_hash_code = __c; } 840 841 void 842 _M_copy_code(_Hash_node<_Value, true>* __to, 843 const _Hash_node<_Value, true>* __from) const 844 { __to->_M_hash_code = __from->_M_hash_code; } 845 846 void 847 _M_swap(_Hash_code_base& __x) 848 { 849 std::swap(_M_extract, __x._M_extract); 850 std::swap(_M_eq, __x._M_eq); 851 std::swap(_M_h1, __x._M_h1); 852 std::swap(_M_h2, __x._M_h2); 853 } 854 855 protected: 856 _ExtractKey _M_extract; 857 _Equal _M_eq; 858 _H1 _M_h1; 859 _H2 _M_h2; 860 }; 861 862 863 // Class template _Equality_base. This is for implementing equality 864 // comparison for unordered containers, per N3068, by John Lakos and 865 // Pablo Halpern. Algorithmically, we follow closely the reference 866 // implementations therein. 867 template<typename _ExtractKey, bool __unique_keys, 868 typename _Hashtable> 869 struct _Equality_base; 870 871 template<typename _ExtractKey, typename _Hashtable> 872 struct _Equality_base<_ExtractKey, true, _Hashtable> 873 { 874 bool _M_equal(const _Hashtable&) const; 875 }; 876 877 template<typename _ExtractKey, typename _Hashtable> 878 bool 879 _Equality_base<_ExtractKey, true, _Hashtable>:: 880 _M_equal(const _Hashtable& __other) const 881 { 882 const _Hashtable* __this = static_cast<const _Hashtable*>(this); 883 884 if (__this->size() != __other.size()) 885 return false; 886 887 for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx) 888 { 889 const auto __ity = __other.find(_ExtractKey()(*__itx)); 890 if (__ity == __other.end() || *__ity != *__itx) 891 return false; 892 } 893 return true; 894 } 895 896 template<typename _ExtractKey, typename _Hashtable> 897 struct _Equality_base<_ExtractKey, false, _Hashtable> 898 { 899 bool _M_equal(const _Hashtable&) const; 900 901 private: 902 template<typename _Uiterator> 903 static bool 904 _S_is_permutation(_Uiterator, _Uiterator, _Uiterator); 905 }; 906 907 // See std::is_permutation in N3068. 908 template<typename _ExtractKey, typename _Hashtable> 909 template<typename _Uiterator> 910 bool 911 _Equality_base<_ExtractKey, false, _Hashtable>:: 912 _S_is_permutation(_Uiterator __first1, _Uiterator __last1, 913 _Uiterator __first2) 914 { 915 for (; __first1 != __last1; ++__first1, ++__first2) 916 if (!(*__first1 == *__first2)) 917 break; 918 919 if (__first1 == __last1) 920 return true; 921 922 _Uiterator __last2 = __first2; 923 std::advance(__last2, std::distance(__first1, __last1)); 924 925 for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1) 926 { 927 _Uiterator __tmp = __first1; 928 while (__tmp != __it1 && !(*__tmp == *__it1)) 929 ++__tmp; 930 931 // We've seen this one before. 932 if (__tmp != __it1) 933 continue; 934 935 std::ptrdiff_t __n2 = 0; 936 for (__tmp = __first2; __tmp != __last2; ++__tmp) 937 if (*__tmp == *__it1) 938 ++__n2; 939 940 if (!__n2) 941 return false; 942 943 std::ptrdiff_t __n1 = 0; 944 for (__tmp = __it1; __tmp != __last1; ++__tmp) 945 if (*__tmp == *__it1) 946 ++__n1; 947 948 if (__n1 != __n2) 949 return false; 950 } 951 return true; 952 } 953 954 template<typename _ExtractKey, typename _Hashtable> 955 bool 956 _Equality_base<_ExtractKey, false, _Hashtable>:: 957 _M_equal(const _Hashtable& __other) const 958 { 959 const _Hashtable* __this = static_cast<const _Hashtable*>(this); 960 961 if (__this->size() != __other.size()) 962 return false; 963 964 for (auto __itx = __this->begin(); __itx != __this->end();) 965 { 966 const auto __xrange = __this->equal_range(_ExtractKey()(*__itx)); 967 const auto __yrange = __other.equal_range(_ExtractKey()(*__itx)); 968 969 if (std::distance(__xrange.first, __xrange.second) 970 != std::distance(__yrange.first, __yrange.second)) 971 return false; 972 973 if (!_S_is_permutation(__xrange.first, 974 __xrange.second, 975 __yrange.first)) 976 return false; 977 978 __itx = __xrange.second; 979 } 980 return true; 981 } 982 983_GLIBCXX_END_NAMESPACE_VERSION 984} // namespace __detail 985} // namespace std 986 987#endif // _HASHTABLE_POLICY_H 988