You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

780 lines
24KB

  1. // Internal policy header for TR1 unordered_set and unordered_map -*- C++ -*-
  2. // Copyright (C) 2010-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file tr1/hashtable_policy.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly.
  23. * @headername{tr1/unordered_map, tr1/unordered_set}
  24. */
  25. namespace std _GLIBCXX_VISIBILITY(default)
  26. {
  27. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  28. namespace tr1
  29. {
  30. namespace __detail
  31. {
  32. // Helper function: return distance(first, last) for forward
  33. // iterators, or 0 for input iterators.
  34. template<class _Iterator>
  35. inline typename std::iterator_traits<_Iterator>::difference_type
  36. __distance_fw(_Iterator __first, _Iterator __last,
  37. std::input_iterator_tag)
  38. { return 0; }
  39. template<class _Iterator>
  40. inline typename std::iterator_traits<_Iterator>::difference_type
  41. __distance_fw(_Iterator __first, _Iterator __last,
  42. std::forward_iterator_tag)
  43. { return std::distance(__first, __last); }
  44. template<class _Iterator>
  45. inline typename std::iterator_traits<_Iterator>::difference_type
  46. __distance_fw(_Iterator __first, _Iterator __last)
  47. {
  48. typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
  49. return __distance_fw(__first, __last, _Tag());
  50. }
  51. // Auxiliary types used for all instantiations of _Hashtable: nodes
  52. // and iterators.
  53. // Nodes, used to wrap elements stored in the hash table. A policy
  54. // template parameter of class template _Hashtable controls whether
  55. // nodes also store a hash code. In some cases (e.g. strings) this
  56. // may be a performance win.
  57. template<typename _Value, bool __cache_hash_code>
  58. struct _Hash_node;
  59. template<typename _Value>
  60. struct _Hash_node<_Value, true>
  61. {
  62. _Value _M_v;
  63. std::size_t _M_hash_code;
  64. _Hash_node* _M_next;
  65. };
  66. template<typename _Value>
  67. struct _Hash_node<_Value, false>
  68. {
  69. _Value _M_v;
  70. _Hash_node* _M_next;
  71. };
  72. // Local iterators, used to iterate within a bucket but not between
  73. // buckets.
  74. template<typename _Value, bool __cache>
  75. struct _Node_iterator_base
  76. {
  77. _Node_iterator_base(_Hash_node<_Value, __cache>* __p)
  78. : _M_cur(__p) { }
  79. void
  80. _M_incr()
  81. { _M_cur = _M_cur->_M_next; }
  82. _Hash_node<_Value, __cache>* _M_cur;
  83. };
  84. template<typename _Value, bool __cache>
  85. inline bool
  86. operator==(const _Node_iterator_base<_Value, __cache>& __x,
  87. const _Node_iterator_base<_Value, __cache>& __y)
  88. { return __x._M_cur == __y._M_cur; }
  89. template<typename _Value, bool __cache>
  90. inline bool
  91. operator!=(const _Node_iterator_base<_Value, __cache>& __x,
  92. const _Node_iterator_base<_Value, __cache>& __y)
  93. { return __x._M_cur != __y._M_cur; }
  94. template<typename _Value, bool __constant_iterators, bool __cache>
  95. struct _Node_iterator
  96. : public _Node_iterator_base<_Value, __cache>
  97. {
  98. typedef _Value value_type;
  99. typedef typename
  100. __gnu_cxx::__conditional_type<__constant_iterators,
  101. const _Value*, _Value*>::__type
  102. pointer;
  103. typedef typename
  104. __gnu_cxx::__conditional_type<__constant_iterators,
  105. const _Value&, _Value&>::__type
  106. reference;
  107. typedef std::ptrdiff_t difference_type;
  108. typedef std::forward_iterator_tag iterator_category;
  109. _Node_iterator()
  110. : _Node_iterator_base<_Value, __cache>(0) { }
  111. explicit
  112. _Node_iterator(_Hash_node<_Value, __cache>* __p)
  113. : _Node_iterator_base<_Value, __cache>(__p) { }
  114. reference
  115. operator*() const
  116. { return this->_M_cur->_M_v; }
  117. pointer
  118. operator->() const
  119. { return std::__addressof(this->_M_cur->_M_v); }
  120. _Node_iterator&
  121. operator++()
  122. {
  123. this->_M_incr();
  124. return *this;
  125. }
  126. _Node_iterator
  127. operator++(int)
  128. {
  129. _Node_iterator __tmp(*this);
  130. this->_M_incr();
  131. return __tmp;
  132. }
  133. };
  134. template<typename _Value, bool __constant_iterators, bool __cache>
  135. struct _Node_const_iterator
  136. : public _Node_iterator_base<_Value, __cache>
  137. {
  138. typedef _Value value_type;
  139. typedef const _Value* pointer;
  140. typedef const _Value& reference;
  141. typedef std::ptrdiff_t difference_type;
  142. typedef std::forward_iterator_tag iterator_category;
  143. _Node_const_iterator()
  144. : _Node_iterator_base<_Value, __cache>(0) { }
  145. explicit
  146. _Node_const_iterator(_Hash_node<_Value, __cache>* __p)
  147. : _Node_iterator_base<_Value, __cache>(__p) { }
  148. _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
  149. __cache>& __x)
  150. : _Node_iterator_base<_Value, __cache>(__x._M_cur) { }
  151. reference
  152. operator*() const
  153. { return this->_M_cur->_M_v; }
  154. pointer
  155. operator->() const
  156. { return std::__addressof(this->_M_cur->_M_v); }
  157. _Node_const_iterator&
  158. operator++()
  159. {
  160. this->_M_incr();
  161. return *this;
  162. }
  163. _Node_const_iterator
  164. operator++(int)
  165. {
  166. _Node_const_iterator __tmp(*this);
  167. this->_M_incr();
  168. return __tmp;
  169. }
  170. };
  171. template<typename _Value, bool __cache>
  172. struct _Hashtable_iterator_base
  173. {
  174. _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node,
  175. _Hash_node<_Value, __cache>** __bucket)
  176. : _M_cur_node(__node), _M_cur_bucket(__bucket) { }
  177. void
  178. _M_incr()
  179. {
  180. _M_cur_node = _M_cur_node->_M_next;
  181. if (!_M_cur_node)
  182. _M_incr_bucket();
  183. }
  184. void
  185. _M_incr_bucket();
  186. _Hash_node<_Value, __cache>* _M_cur_node;
  187. _Hash_node<_Value, __cache>** _M_cur_bucket;
  188. };
  189. // Global iterators, used for arbitrary iteration within a hash
  190. // table. Larger and more expensive than local iterators.
  191. template<typename _Value, bool __cache>
  192. void
  193. _Hashtable_iterator_base<_Value, __cache>::
  194. _M_incr_bucket()
  195. {
  196. ++_M_cur_bucket;
  197. // This loop requires the bucket array to have a non-null sentinel.
  198. while (!*_M_cur_bucket)
  199. ++_M_cur_bucket;
  200. _M_cur_node = *_M_cur_bucket;
  201. }
  202. template<typename _Value, bool __cache>
  203. inline bool
  204. operator==(const _Hashtable_iterator_base<_Value, __cache>& __x,
  205. const _Hashtable_iterator_base<_Value, __cache>& __y)
  206. { return __x._M_cur_node == __y._M_cur_node; }
  207. template<typename _Value, bool __cache>
  208. inline bool
  209. operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x,
  210. const _Hashtable_iterator_base<_Value, __cache>& __y)
  211. { return __x._M_cur_node != __y._M_cur_node; }
  212. template<typename _Value, bool __constant_iterators, bool __cache>
  213. struct _Hashtable_iterator
  214. : public _Hashtable_iterator_base<_Value, __cache>
  215. {
  216. typedef _Value value_type;
  217. typedef typename
  218. __gnu_cxx::__conditional_type<__constant_iterators,
  219. const _Value*, _Value*>::__type
  220. pointer;
  221. typedef typename
  222. __gnu_cxx::__conditional_type<__constant_iterators,
  223. const _Value&, _Value&>::__type
  224. reference;
  225. typedef std::ptrdiff_t difference_type;
  226. typedef std::forward_iterator_tag iterator_category;
  227. _Hashtable_iterator()
  228. : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
  229. _Hashtable_iterator(_Hash_node<_Value, __cache>* __p,
  230. _Hash_node<_Value, __cache>** __b)
  231. : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
  232. explicit
  233. _Hashtable_iterator(_Hash_node<_Value, __cache>** __b)
  234. : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
  235. reference
  236. operator*() const
  237. { return this->_M_cur_node->_M_v; }
  238. pointer
  239. operator->() const
  240. { return std::__addressof(this->_M_cur_node->_M_v); }
  241. _Hashtable_iterator&
  242. operator++()
  243. {
  244. this->_M_incr();
  245. return *this;
  246. }
  247. _Hashtable_iterator
  248. operator++(int)
  249. {
  250. _Hashtable_iterator __tmp(*this);
  251. this->_M_incr();
  252. return __tmp;
  253. }
  254. };
  255. template<typename _Value, bool __constant_iterators, bool __cache>
  256. struct _Hashtable_const_iterator
  257. : public _Hashtable_iterator_base<_Value, __cache>
  258. {
  259. typedef _Value value_type;
  260. typedef const _Value* pointer;
  261. typedef const _Value& reference;
  262. typedef std::ptrdiff_t difference_type;
  263. typedef std::forward_iterator_tag iterator_category;
  264. _Hashtable_const_iterator()
  265. : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
  266. _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p,
  267. _Hash_node<_Value, __cache>** __b)
  268. : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
  269. explicit
  270. _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b)
  271. : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
  272. _Hashtable_const_iterator(const _Hashtable_iterator<_Value,
  273. __constant_iterators, __cache>& __x)
  274. : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node,
  275. __x._M_cur_bucket) { }
  276. reference
  277. operator*() const
  278. { return this->_M_cur_node->_M_v; }
  279. pointer
  280. operator->() const
  281. { return std::__addressof(this->_M_cur_node->_M_v); }
  282. _Hashtable_const_iterator&
  283. operator++()
  284. {
  285. this->_M_incr();
  286. return *this;
  287. }
  288. _Hashtable_const_iterator
  289. operator++(int)
  290. {
  291. _Hashtable_const_iterator __tmp(*this);
  292. this->_M_incr();
  293. return __tmp;
  294. }
  295. };
  296. // Many of class template _Hashtable's template parameters are policy
  297. // classes. These are defaults for the policies.
  298. // Default range hashing function: use division to fold a large number
  299. // into the range [0, N).
  300. struct _Mod_range_hashing
  301. {
  302. typedef std::size_t first_argument_type;
  303. typedef std::size_t second_argument_type;
  304. typedef std::size_t result_type;
  305. result_type
  306. operator()(first_argument_type __num, second_argument_type __den) const
  307. { return __num % __den; }
  308. };
  309. // Default ranged hash function H. In principle it should be a
  310. // function object composed from objects of type H1 and H2 such that
  311. // h(k, N) = h2(h1(k), N), but that would mean making extra copies of
  312. // h1 and h2. So instead we'll just use a tag to tell class template
  313. // hashtable to do that composition.
  314. struct _Default_ranged_hash { };
  315. // Default value for rehash policy. Bucket size is (usually) the
  316. // smallest prime that keeps the load factor small enough.
  317. struct _Prime_rehash_policy
  318. {
  319. _Prime_rehash_policy(float __z = 1.0)
  320. : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) { }
  321. float
  322. max_load_factor() const
  323. { return _M_max_load_factor; }
  324. // Return a bucket size no smaller than n.
  325. std::size_t
  326. _M_next_bkt(std::size_t __n) const;
  327. // Return a bucket count appropriate for n elements
  328. std::size_t
  329. _M_bkt_for_elements(std::size_t __n) const;
  330. // __n_bkt is current bucket count, __n_elt is current element count,
  331. // and __n_ins is number of elements to be inserted. Do we need to
  332. // increase bucket count? If so, return make_pair(true, n), where n
  333. // is the new bucket count. If not, return make_pair(false, 0).
  334. std::pair<bool, std::size_t>
  335. _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
  336. std::size_t __n_ins) const;
  337. enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
  338. float _M_max_load_factor;
  339. float _M_growth_factor;
  340. mutable std::size_t _M_next_resize;
  341. };
  342. extern const unsigned long __prime_list[];
  343. // XXX This is a hack. There's no good reason for any of
  344. // _Prime_rehash_policy's member functions to be inline.
  345. // Return a prime no smaller than n.
  346. inline std::size_t
  347. _Prime_rehash_policy::
  348. _M_next_bkt(std::size_t __n) const
  349. {
  350. // Don't include the last prime in the search, so that anything
  351. // higher than the second-to-last prime returns a past-the-end
  352. // iterator that can be dereferenced to get the last prime.
  353. const unsigned long* __p
  354. = std::lower_bound(__prime_list, __prime_list + _S_n_primes - 1, __n);
  355. _M_next_resize =
  356. static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
  357. return *__p;
  358. }
  359. // Return the smallest prime p such that alpha p >= n, where alpha
  360. // is the load factor.
  361. inline std::size_t
  362. _Prime_rehash_policy::
  363. _M_bkt_for_elements(std::size_t __n) const
  364. {
  365. const float __min_bkts = __n / _M_max_load_factor;
  366. return _M_next_bkt(__builtin_ceil(__min_bkts));
  367. }
  368. // Finds the smallest prime p such that alpha p > __n_elt + __n_ins.
  369. // If p > __n_bkt, return make_pair(true, p); otherwise return
  370. // make_pair(false, 0). In principle this isn't very different from
  371. // _M_bkt_for_elements.
  372. // The only tricky part is that we're caching the element count at
  373. // which we need to rehash, so we don't have to do a floating-point
  374. // multiply for every insertion.
  375. inline std::pair<bool, std::size_t>
  376. _Prime_rehash_policy::
  377. _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
  378. std::size_t __n_ins) const
  379. {
  380. if (__n_elt + __n_ins > _M_next_resize)
  381. {
  382. float __min_bkts = ((float(__n_ins) + float(__n_elt))
  383. / _M_max_load_factor);
  384. if (__min_bkts > __n_bkt)
  385. {
  386. __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
  387. return std::make_pair(true,
  388. _M_next_bkt(__builtin_ceil(__min_bkts)));
  389. }
  390. else
  391. {
  392. _M_next_resize = static_cast<std::size_t>
  393. (__builtin_ceil(__n_bkt * _M_max_load_factor));
  394. return std::make_pair(false, 0);
  395. }
  396. }
  397. else
  398. return std::make_pair(false, 0);
  399. }
  400. // Base classes for std::tr1::_Hashtable. We define these base
  401. // classes because in some cases we want to do different things
  402. // depending on the value of a policy class. In some cases the
  403. // policy class affects which member functions and nested typedefs
  404. // are defined; we handle that by specializing base class templates.
  405. // Several of the base class templates need to access other members
  406. // of class template _Hashtable, so we use the "curiously recurring
  407. // template pattern" for them.
  408. // class template _Map_base. If the hashtable has a value type of the
  409. // form pair<T1, T2> and a key extraction policy that returns the
  410. // first part of the pair, the hashtable gets a mapped_type typedef.
  411. // If it satisfies those criteria and also has unique keys, then it
  412. // also gets an operator[].
  413. template<typename _Key, typename _Value, typename _Ex, bool __unique,
  414. typename _Hashtable>
  415. struct _Map_base { };
  416. template<typename _Key, typename _Pair, typename _Hashtable>
  417. struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable>
  418. {
  419. typedef typename _Pair::second_type mapped_type;
  420. };
  421. template<typename _Key, typename _Pair, typename _Hashtable>
  422. struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>
  423. {
  424. typedef typename _Pair::second_type mapped_type;
  425. mapped_type&
  426. operator[](const _Key& __k);
  427. };
  428. template<typename _Key, typename _Pair, typename _Hashtable>
  429. typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
  430. true, _Hashtable>::mapped_type&
  431. _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
  432. operator[](const _Key& __k)
  433. {
  434. _Hashtable* __h = static_cast<_Hashtable*>(this);
  435. typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
  436. std::size_t __n = __h->_M_bucket_index(__k, __code,
  437. __h->_M_bucket_count);
  438. typename _Hashtable::_Node* __p =
  439. __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
  440. if (!__p)
  441. return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()),
  442. __n, __code)->second;
  443. return (__p->_M_v).second;
  444. }
  445. // class template _Rehash_base. Give hashtable the max_load_factor
  446. // functions iff the rehash policy is _Prime_rehash_policy.
  447. template<typename _RehashPolicy, typename _Hashtable>
  448. struct _Rehash_base { };
  449. template<typename _Hashtable>
  450. struct _Rehash_base<_Prime_rehash_policy, _Hashtable>
  451. {
  452. float
  453. max_load_factor() const
  454. {
  455. const _Hashtable* __this = static_cast<const _Hashtable*>(this);
  456. return __this->__rehash_policy().max_load_factor();
  457. }
  458. void
  459. max_load_factor(float __z)
  460. {
  461. _Hashtable* __this = static_cast<_Hashtable*>(this);
  462. __this->__rehash_policy(_Prime_rehash_policy(__z));
  463. }
  464. };
  465. // Class template _Hash_code_base. Encapsulates two policy issues that
  466. // aren't quite orthogonal.
  467. // (1) the difference between using a ranged hash function and using
  468. // the combination of a hash function and a range-hashing function.
  469. // In the former case we don't have such things as hash codes, so
  470. // we have a dummy type as placeholder.
  471. // (2) Whether or not we cache hash codes. Caching hash codes is
  472. // meaningless if we have a ranged hash function.
  473. // We also put the key extraction and equality comparison function
  474. // objects here, for convenience.
  475. // Primary template: unused except as a hook for specializations.
  476. template<typename _Key, typename _Value,
  477. typename _ExtractKey, typename _Equal,
  478. typename _H1, typename _H2, typename _Hash,
  479. bool __cache_hash_code>
  480. struct _Hash_code_base;
  481. // Specialization: ranged hash function, no caching hash codes. H1
  482. // and H2 are provided but ignored. We define a dummy hash code type.
  483. template<typename _Key, typename _Value,
  484. typename _ExtractKey, typename _Equal,
  485. typename _H1, typename _H2, typename _Hash>
  486. struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
  487. _Hash, false>
  488. {
  489. protected:
  490. _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
  491. const _H1&, const _H2&, const _Hash& __h)
  492. : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { }
  493. typedef void* _Hash_code_type;
  494. _Hash_code_type
  495. _M_hash_code(const _Key& __key) const
  496. { return 0; }
  497. std::size_t
  498. _M_bucket_index(const _Key& __k, _Hash_code_type,
  499. std::size_t __n) const
  500. { return _M_ranged_hash(__k, __n); }
  501. std::size_t
  502. _M_bucket_index(const _Hash_node<_Value, false>* __p,
  503. std::size_t __n) const
  504. { return _M_ranged_hash(_M_extract(__p->_M_v), __n); }
  505. bool
  506. _M_compare(const _Key& __k, _Hash_code_type,
  507. _Hash_node<_Value, false>* __n) const
  508. { return _M_eq(__k, _M_extract(__n->_M_v)); }
  509. void
  510. _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
  511. { }
  512. void
  513. _M_copy_code(_Hash_node<_Value, false>*,
  514. const _Hash_node<_Value, false>*) const
  515. { }
  516. void
  517. _M_swap(_Hash_code_base& __x)
  518. {
  519. std::swap(_M_extract, __x._M_extract);
  520. std::swap(_M_eq, __x._M_eq);
  521. std::swap(_M_ranged_hash, __x._M_ranged_hash);
  522. }
  523. protected:
  524. _ExtractKey _M_extract;
  525. _Equal _M_eq;
  526. _Hash _M_ranged_hash;
  527. };
  528. // No specialization for ranged hash function while caching hash codes.
  529. // That combination is meaningless, and trying to do it is an error.
  530. // Specialization: ranged hash function, cache hash codes. This
  531. // combination is meaningless, so we provide only a declaration
  532. // and no definition.
  533. template<typename _Key, typename _Value,
  534. typename _ExtractKey, typename _Equal,
  535. typename _H1, typename _H2, typename _Hash>
  536. struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
  537. _Hash, true>;
  538. // Specialization: hash function and range-hashing function, no
  539. // caching of hash codes. H is provided but ignored. Provides
  540. // typedef and accessor required by TR1.
  541. template<typename _Key, typename _Value,
  542. typename _ExtractKey, typename _Equal,
  543. typename _H1, typename _H2>
  544. struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
  545. _Default_ranged_hash, false>
  546. {
  547. typedef _H1 hasher;
  548. hasher
  549. hash_function() const
  550. { return _M_h1; }
  551. protected:
  552. _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
  553. const _H1& __h1, const _H2& __h2,
  554. const _Default_ranged_hash&)
  555. : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
  556. typedef std::size_t _Hash_code_type;
  557. _Hash_code_type
  558. _M_hash_code(const _Key& __k) const
  559. { return _M_h1(__k); }
  560. std::size_t
  561. _M_bucket_index(const _Key&, _Hash_code_type __c,
  562. std::size_t __n) const
  563. { return _M_h2(__c, __n); }
  564. std::size_t
  565. _M_bucket_index(const _Hash_node<_Value, false>* __p,
  566. std::size_t __n) const
  567. { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); }
  568. bool
  569. _M_compare(const _Key& __k, _Hash_code_type,
  570. _Hash_node<_Value, false>* __n) const
  571. { return _M_eq(__k, _M_extract(__n->_M_v)); }
  572. void
  573. _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
  574. { }
  575. void
  576. _M_copy_code(_Hash_node<_Value, false>*,
  577. const _Hash_node<_Value, false>*) const
  578. { }
  579. void
  580. _M_swap(_Hash_code_base& __x)
  581. {
  582. std::swap(_M_extract, __x._M_extract);
  583. std::swap(_M_eq, __x._M_eq);
  584. std::swap(_M_h1, __x._M_h1);
  585. std::swap(_M_h2, __x._M_h2);
  586. }
  587. protected:
  588. _ExtractKey _M_extract;
  589. _Equal _M_eq;
  590. _H1 _M_h1;
  591. _H2 _M_h2;
  592. };
  593. // Specialization: hash function and range-hashing function,
  594. // caching hash codes. H is provided but ignored. Provides
  595. // typedef and accessor required by TR1.
  596. template<typename _Key, typename _Value,
  597. typename _ExtractKey, typename _Equal,
  598. typename _H1, typename _H2>
  599. struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
  600. _Default_ranged_hash, true>
  601. {
  602. typedef _H1 hasher;
  603. hasher
  604. hash_function() const
  605. { return _M_h1; }
  606. protected:
  607. _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
  608. const _H1& __h1, const _H2& __h2,
  609. const _Default_ranged_hash&)
  610. : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
  611. typedef std::size_t _Hash_code_type;
  612. _Hash_code_type
  613. _M_hash_code(const _Key& __k) const
  614. { return _M_h1(__k); }
  615. std::size_t
  616. _M_bucket_index(const _Key&, _Hash_code_type __c,
  617. std::size_t __n) const
  618. { return _M_h2(__c, __n); }
  619. std::size_t
  620. _M_bucket_index(const _Hash_node<_Value, true>* __p,
  621. std::size_t __n) const
  622. { return _M_h2(__p->_M_hash_code, __n); }
  623. bool
  624. _M_compare(const _Key& __k, _Hash_code_type __c,
  625. _Hash_node<_Value, true>* __n) const
  626. { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); }
  627. void
  628. _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const
  629. { __n->_M_hash_code = __c; }
  630. void
  631. _M_copy_code(_Hash_node<_Value, true>* __to,
  632. const _Hash_node<_Value, true>* __from) const
  633. { __to->_M_hash_code = __from->_M_hash_code; }
  634. void
  635. _M_swap(_Hash_code_base& __x)
  636. {
  637. std::swap(_M_extract, __x._M_extract);
  638. std::swap(_M_eq, __x._M_eq);
  639. std::swap(_M_h1, __x._M_h1);
  640. std::swap(_M_h2, __x._M_h2);
  641. }
  642. protected:
  643. _ExtractKey _M_extract;
  644. _Equal _M_eq;
  645. _H1 _M_h1;
  646. _H2 _M_h2;
  647. };
  648. } // namespace __detail
  649. }
  650. _GLIBCXX_END_NAMESPACE_VERSION
  651. }