libstdc++
hashtable_policy.h
Go to the documentation of this file.
1 // Internal policy header for unordered_set and unordered_map -*- C++ -*-
2 
3 // Copyright (C) 2010-2013 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 
34 namespace std _GLIBCXX_VISIBILITY(default)
35 {
36 _GLIBCXX_BEGIN_NAMESPACE_VERSION
37 
38  template<typename _Key, typename _Value, typename _Alloc,
39  typename _ExtractKey, typename _Equal,
40  typename _H1, typename _H2, typename _Hash,
41  typename _RehashPolicy, typename _Traits>
42  class _Hashtable;
43 
44 _GLIBCXX_END_NAMESPACE_VERSION
45 
46 namespace __detail
47 {
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49 
50  /**
51  * @defgroup hashtable-detail Base and Implementation Classes
52  * @ingroup unordered_associative_containers
53  * @{
54  */
55  template<typename _Key, typename _Value,
56  typename _ExtractKey, typename _Equal,
57  typename _H1, typename _H2, typename _Hash, typename _Traits>
59 
60  // Helper function: return distance(first, last) for forward
61  // iterators, or 0 for input iterators.
62  template<class _Iterator>
63  inline typename std::iterator_traits<_Iterator>::difference_type
64  __distance_fw(_Iterator __first, _Iterator __last,
66  { return 0; }
67 
68  template<class _Iterator>
69  inline typename std::iterator_traits<_Iterator>::difference_type
70  __distance_fw(_Iterator __first, _Iterator __last,
72  { return std::distance(__first, __last); }
73 
74  template<class _Iterator>
75  inline typename std::iterator_traits<_Iterator>::difference_type
76  __distance_fw(_Iterator __first, _Iterator __last)
77  {
78  typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
79  return __distance_fw(__first, __last, _Tag());
80  }
81 
82  // Helper type used to detect whether the hash functor is noexcept.
83  template <typename _Key, typename _Hash>
84  struct __is_noexcept_hash : std::integral_constant<bool,
85  noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
86  { };
87 
88  struct _Identity
89  {
90  template<typename _Tp>
91  _Tp&&
92  operator()(_Tp&& __x) const
93  { return std::forward<_Tp>(__x); }
94  };
95 
96  struct _Select1st
97  {
98  template<typename _Tp>
99  auto
100  operator()(_Tp&& __x) const
101  -> decltype(std::get<0>(std::forward<_Tp>(__x)))
102  { return std::get<0>(std::forward<_Tp>(__x)); }
103  };
104 
105  // Auxiliary types used for all instantiations of _Hashtable nodes
106  // and iterators.
107 
108  /**
109  * struct _Hashtable_traits
110  *
111  * Important traits for hash tables.
112  *
113  * @tparam _Cache_hash_code Boolean value. True if the value of
114  * the hash function is stored along with the value. This is a
115  * time-space tradeoff. Storing it may improve lookup speed by
116  * reducing the number of times we need to call the _Equal
117  * function.
118  *
119  * @tparam _Constant_iterators Boolean value. True if iterator and
120  * const_iterator are both constant iterator types. This is true
121  * for unordered_set and unordered_multiset, false for
122  * unordered_map and unordered_multimap.
123  *
124  * @tparam _Unique_keys Boolean value. True if the return value
125  * of _Hashtable::count(k) is always at most one, false if it may
126  * be an arbitrary number. This is true for unordered_set and
127  * unordered_map, false for unordered_multiset and
128  * unordered_multimap.
129  */
130  template<bool _Cache_hash_code, bool _Constant_iterators, bool _Unique_keys>
132  {
133  template<bool _Cond>
135 
139  };
140 
141  /**
142  * struct _Hash_node_base
143  *
144  * Nodes, used to wrap elements stored in the hash table. A policy
145  * template parameter of class template _Hashtable controls whether
146  * nodes also store a hash code. In some cases (e.g. strings) this
147  * may be a performance win.
148  */
150  {
151  _Hash_node_base* _M_nxt;
152 
153  _Hash_node_base() : _M_nxt() { }
154 
155  _Hash_node_base(_Hash_node_base* __next) : _M_nxt(__next) { }
156  };
157 
158  /**
159  * struct _Hash_node_value_base
160  *
161  * Node type with the value to store.
162  */
163  template<typename _Value>
165  {
166  __gnu_cxx::__aligned_buffer<_Value> _M_storage;
167 
168  _Value*
169  _M_valptr() noexcept
170  { return _M_storage._M_ptr(); }
171 
172  const _Value*
173  _M_valptr() const noexcept
174  { return _M_storage._M_ptr(); }
175 
176  _Value&
177  _M_v() noexcept
178  { return *_M_valptr(); }
179 
180  const _Value&
181  _M_v() const noexcept
182  { return *_M_valptr(); }
183  };
184 
185  /**
186  * Primary template struct _Hash_node.
187  */
188  template<typename _Value, bool _Cache_hash_code>
189  struct _Hash_node;
190 
191  /**
192  * Specialization for nodes with caches, struct _Hash_node.
193  *
194  * Base class is __detail::_Hash_node_value_base.
195  */
196  template<typename _Value>
197  struct _Hash_node<_Value, true> : _Hash_node_value_base<_Value>
198  {
199  std::size_t _M_hash_code;
200 
201  _Hash_node*
202  _M_next() const { return static_cast<_Hash_node*>(this->_M_nxt); }
203  };
204 
205  /**
206  * Specialization for nodes without caches, struct _Hash_node.
207  *
208  * Base class is __detail::_Hash_node_value_base.
209  */
210  template<typename _Value>
211  struct _Hash_node<_Value, false> : _Hash_node_value_base<_Value>
212  {
213  _Hash_node*
214  _M_next() const { return static_cast<_Hash_node*>(this->_M_nxt); }
215  };
216 
217  /// Base class for node iterators.
218  template<typename _Value, bool _Cache_hash_code>
220  {
222 
223  __node_type* _M_cur;
224 
226  : _M_cur(__p) { }
227 
228  void
229  _M_incr()
230  { _M_cur = _M_cur->_M_next(); }
231  };
232 
233  template<typename _Value, bool _Cache_hash_code>
234  inline bool
235  operator==(const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
237  { return __x._M_cur == __y._M_cur; }
238 
239  template<typename _Value, bool _Cache_hash_code>
240  inline bool
241  operator!=(const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
242  const _Node_iterator_base<_Value, _Cache_hash_code>& __y)
243  { return __x._M_cur != __y._M_cur; }
244 
245  /// Node iterators, used to iterate through all the hashtable.
246  template<typename _Value, bool __constant_iterators, bool __cache>
248  : public _Node_iterator_base<_Value, __cache>
249  {
250  private:
252  using __node_type = typename __base_type::__node_type;
253 
254  public:
255  typedef _Value value_type;
256  typedef std::ptrdiff_t difference_type;
258 
259  using pointer = typename std::conditional<__constant_iterators,
260  const _Value*, _Value*>::type;
261 
262  using reference = typename std::conditional<__constant_iterators,
263  const _Value&, _Value&>::type;
264 
266  : __base_type(0) { }
267 
268  explicit
269  _Node_iterator(__node_type* __p)
270  : __base_type(__p) { }
271 
272  reference
273  operator*() const
274  { return this->_M_cur->_M_v(); }
275 
276  pointer
277  operator->() const
278  { return this->_M_cur->_M_valptr(); }
279 
281  operator++()
282  {
283  this->_M_incr();
284  return *this;
285  }
286 
288  operator++(int)
289  {
290  _Node_iterator __tmp(*this);
291  this->_M_incr();
292  return __tmp;
293  }
294  };
295 
296  /// Node const_iterators, used to iterate through all the hashtable.
297  template<typename _Value, bool __constant_iterators, bool __cache>
299  : public _Node_iterator_base<_Value, __cache>
300  {
301  private:
303  using __node_type = typename __base_type::__node_type;
304 
305  public:
306  typedef _Value value_type;
307  typedef std::ptrdiff_t difference_type;
309 
310  typedef const _Value* pointer;
311  typedef const _Value& reference;
312 
314  : __base_type(0) { }
315 
316  explicit
317  _Node_const_iterator(__node_type* __p)
318  : __base_type(__p) { }
319 
320  _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
321  __cache>& __x)
322  : __base_type(__x._M_cur) { }
323 
324  reference
325  operator*() const
326  { return this->_M_cur->_M_v(); }
327 
328  pointer
329  operator->() const
330  { return this->_M_cur->_M_valptr(); }
331 
333  operator++()
334  {
335  this->_M_incr();
336  return *this;
337  }
338 
340  operator++(int)
341  {
342  _Node_const_iterator __tmp(*this);
343  this->_M_incr();
344  return __tmp;
345  }
346  };
347 
348  // Many of class template _Hashtable's template parameters are policy
349  // classes. These are defaults for the policies.
350 
351  /// Default range hashing function: use division to fold a large number
352  /// into the range [0, N).
354  {
355  typedef std::size_t first_argument_type;
356  typedef std::size_t second_argument_type;
357  typedef std::size_t result_type;
358 
359  result_type
360  operator()(first_argument_type __num,
361  second_argument_type __den) const noexcept
362  { return __num % __den; }
363  };
364 
365  /// Default ranged hash function H. In principle it should be a
366  /// function object composed from objects of type H1 and H2 such that
367  /// h(k, N) = h2(h1(k), N), but that would mean making extra copies of
368  /// h1 and h2. So instead we'll just use a tag to tell class template
369  /// hashtable to do that composition.
371 
372  /// Default value for rehash policy. Bucket size is (usually) the
373  /// smallest prime that keeps the load factor small enough.
375  {
376  _Prime_rehash_policy(float __z = 1.0)
377  : _M_max_load_factor(__z), _M_next_resize(0) { }
378 
379  float
380  max_load_factor() const noexcept
381  { return _M_max_load_factor; }
382 
383  // Return a bucket size no smaller than n.
384  std::size_t
385  _M_next_bkt(std::size_t __n) const;
386 
387  // Return a bucket count appropriate for n elements
388  std::size_t
389  _M_bkt_for_elements(std::size_t __n) const
390  { return __builtin_ceil(__n / (long double)_M_max_load_factor); }
391 
392  // __n_bkt is current bucket count, __n_elt is current element count,
393  // and __n_ins is number of elements to be inserted. Do we need to
394  // increase bucket count? If so, return make_pair(true, n), where n
395  // is the new bucket count. If not, return make_pair(false, 0).
397  _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
398  std::size_t __n_ins) const;
399 
400  typedef std::size_t _State;
401 
402  _State
403  _M_state() const
404  { return _M_next_resize; }
405 
406  void
407  _M_reset() noexcept
408  { _M_next_resize = 0; }
409 
410  void
411  _M_reset(_State __state)
412  { _M_next_resize = __state; }
413 
414  enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
415 
416  static const std::size_t _S_growth_factor = 2;
417 
418  float _M_max_load_factor;
419  mutable std::size_t _M_next_resize;
420  };
421 
422  // Base classes for std::_Hashtable. We define these base classes
423  // because in some cases we want to do different things depending on
424  // the value of a policy class. In some cases the policy class
425  // affects which member functions and nested typedefs are defined;
426  // we handle that by specializing base class templates. Several of
427  // the base class templates need to access other members of class
428  // template _Hashtable, so we use a variant of the "Curiously
429  // Recurring Template Pattern" (CRTP) technique.
430 
431  /**
432  * Primary class template _Map_base.
433  *
434  * If the hashtable has a value type of the form pair<T1, T2> and a
435  * key extraction policy (_ExtractKey) that returns the first part
436  * of the pair, the hashtable gets a mapped_type typedef. If it
437  * satisfies those criteria and also has unique keys, then it also
438  * gets an operator[].
439  */
440  template<typename _Key, typename _Value, typename _Alloc,
441  typename _ExtractKey, typename _Equal,
442  typename _H1, typename _H2, typename _Hash,
443  typename _RehashPolicy, typename _Traits,
444  bool _Unique_keys = _Traits::__unique_keys::value>
445  struct _Map_base { };
446 
447  /// Partial specialization, __unique_keys set to false.
448  template<typename _Key, typename _Pair, typename _Alloc, typename _Equal,
449  typename _H1, typename _H2, typename _Hash,
450  typename _RehashPolicy, typename _Traits>
451  struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
452  _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
453  {
454  using mapped_type = typename std::tuple_element<1, _Pair>::type;
455  };
456 
457  /// Partial specialization, __unique_keys set to true.
458  template<typename _Key, typename _Pair, typename _Alloc, typename _Equal,
459  typename _H1, typename _H2, typename _Hash,
460  typename _RehashPolicy, typename _Traits>
461  struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
462  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
463  {
464  private:
465  using __hashtable_base = __detail::_Hashtable_base<_Key, _Pair,
466  _Select1st,
467  _Equal, _H1, _H2, _Hash,
468  _Traits>;
469 
470  using __hashtable = _Hashtable<_Key, _Pair, _Alloc,
471  _Select1st, _Equal,
472  _H1, _H2, _Hash, _RehashPolicy, _Traits>;
473 
474  using __hash_code = typename __hashtable_base::__hash_code;
475  using __node_type = typename __hashtable_base::__node_type;
476 
477  public:
478  using key_type = typename __hashtable_base::key_type;
479  using iterator = typename __hashtable_base::iterator;
480  using mapped_type = typename std::tuple_element<1, _Pair>::type;
481 
482  mapped_type&
483  operator[](const key_type& __k);
484 
485  mapped_type&
486  operator[](key_type&& __k);
487 
488  // _GLIBCXX_RESOLVE_LIB_DEFECTS
489  // DR 761. unordered_map needs an at() member function.
490  mapped_type&
491  at(const key_type& __k);
492 
493  const mapped_type&
494  at(const key_type& __k) const;
495  };
496 
497  template<typename _Key, typename _Pair, typename _Alloc, typename _Equal,
498  typename _H1, typename _H2, typename _Hash,
499  typename _RehashPolicy, typename _Traits>
500  typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
501  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
502  ::mapped_type&
503  _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
504  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::
505  operator[](const key_type& __k)
506  {
507  __hashtable* __h = static_cast<__hashtable*>(this);
508  __hash_code __code = __h->_M_hash_code(__k);
509  std::size_t __n = __h->_M_bucket_index(__k, __code);
510  __node_type* __p = __h->_M_find_node(__n, __k, __code);
511 
512  if (!__p)
513  {
514  __p = __h->_M_allocate_node(std::piecewise_construct,
516  std::tuple<>());
517  return __h->_M_insert_unique_node(__n, __code, __p)->second;
518  }
519 
520  return __p->_M_v().second;
521  }
522 
523  template<typename _Key, typename _Pair, typename _Alloc, typename _Equal,
524  typename _H1, typename _H2, typename _Hash,
525  typename _RehashPolicy, typename _Traits>
526  typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
527  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
528  ::mapped_type&
529  _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
530  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::
531  operator[](key_type&& __k)
532  {
533  __hashtable* __h = static_cast<__hashtable*>(this);
534  __hash_code __code = __h->_M_hash_code(__k);
535  std::size_t __n = __h->_M_bucket_index(__k, __code);
536  __node_type* __p = __h->_M_find_node(__n, __k, __code);
537 
538  if (!__p)
539  {
540  __p = __h->_M_allocate_node(std::piecewise_construct,
541  std::forward_as_tuple(std::move(__k)),
542  std::tuple<>());
543  return __h->_M_insert_unique_node(__n, __code, __p)->second;
544  }
545 
546  return __p->_M_v().second;
547  }
548 
549  template<typename _Key, typename _Pair, typename _Alloc, typename _Equal,
550  typename _H1, typename _H2, typename _Hash,
551  typename _RehashPolicy, typename _Traits>
552  typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
553  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
554  ::mapped_type&
555  _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
556  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::
557  at(const key_type& __k)
558  {
559  __hashtable* __h = static_cast<__hashtable*>(this);
560  __hash_code __code = __h->_M_hash_code(__k);
561  std::size_t __n = __h->_M_bucket_index(__k, __code);
562  __node_type* __p = __h->_M_find_node(__n, __k, __code);
563 
564  if (!__p)
565  __throw_out_of_range(__N("_Map_base::at"));
566  return __p->_M_v().second;
567  }
568 
569  template<typename _Key, typename _Pair, typename _Alloc, typename _Equal,
570  typename _H1, typename _H2, typename _Hash,
571  typename _RehashPolicy, typename _Traits>
572  const typename _Map_base<_Key, _Pair, _Alloc, _Select1st,
573  _Equal, _H1, _H2, _Hash, _RehashPolicy,
574  _Traits, true>::mapped_type&
575  _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
576  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::
577  at(const key_type& __k) const
578  {
579  const __hashtable* __h = static_cast<const __hashtable*>(this);
580  __hash_code __code = __h->_M_hash_code(__k);
581  std::size_t __n = __h->_M_bucket_index(__k, __code);
582  __node_type* __p = __h->_M_find_node(__n, __k, __code);
583 
584  if (!__p)
585  __throw_out_of_range(__N("_Map_base::at"));
586  return __p->_M_v().second;
587  }
588 
589  /**
590  * Primary class template _Insert_base.
591  *
592  * insert member functions appropriate to all _Hashtables.
593  */
594  template<typename _Key, typename _Value, typename _Alloc,
595  typename _ExtractKey, typename _Equal,
596  typename _H1, typename _H2, typename _Hash,
597  typename _RehashPolicy, typename _Traits>
599  {
600  using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
601  _Equal, _H1, _H2, _Hash,
602  _RehashPolicy, _Traits>;
603 
604  using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey,
605  _Equal, _H1, _H2, _Hash,
606  _Traits>;
607 
608  using value_type = typename __hashtable_base::value_type;
609  using iterator = typename __hashtable_base::iterator;
610  using const_iterator = typename __hashtable_base::const_iterator;
611  using size_type = typename __hashtable_base::size_type;
612 
613  using __unique_keys = typename __hashtable_base::__unique_keys;
614  using __ireturn_type = typename __hashtable_base::__ireturn_type;
615 
616  __hashtable&
617  _M_conjure_hashtable()
618  { return *(static_cast<__hashtable*>(this)); }
619 
620  __ireturn_type
621  insert(const value_type& __v)
622  {
623  __hashtable& __h = _M_conjure_hashtable();
624  return __h._M_insert(__v, __unique_keys());
625  }
626 
627  iterator
628  insert(const_iterator __hint, const value_type& __v)
629  {
630  __hashtable& __h = _M_conjure_hashtable();
631  return __h._M_insert(__hint, __v, __unique_keys());
632  }
633 
634  void
635  insert(initializer_list<value_type> __l)
636  { this->insert(__l.begin(), __l.end()); }
637 
638  template<typename _InputIterator>
639  void
640  insert(_InputIterator __first, _InputIterator __last);
641  };
642 
643  template<typename _Key, typename _Value, typename _Alloc,
644  typename _ExtractKey, typename _Equal,
645  typename _H1, typename _H2, typename _Hash,
646  typename _RehashPolicy, typename _Traits>
647  template<typename _InputIterator>
648  void
649  _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
650  _RehashPolicy, _Traits>::
651  insert(_InputIterator __first, _InputIterator __last)
652  {
653  using __rehash_type = typename __hashtable::__rehash_type;
654  using __rehash_state = typename __hashtable::__rehash_state;
655  using pair_type = std::pair<bool, std::size_t>;
656 
657  size_type __n_elt = __detail::__distance_fw(__first, __last);
658 
659  __hashtable& __h = _M_conjure_hashtable();
660  __rehash_type& __rehash = __h._M_rehash_policy;
661  const __rehash_state& __saved_state = __rehash._M_state();
662  pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
663  __h._M_element_count,
664  __n_elt);
665 
666  if (__do_rehash.first)
667  __h._M_rehash(__do_rehash.second, __saved_state);
668 
669  for (; __first != __last; ++__first)
670  __h._M_insert(*__first, __unique_keys());
671  }
672 
673  /**
674  * Primary class template _Insert.
675  *
676  * Select insert member functions appropriate to _Hashtable policy choices.
677  */
678  template<typename _Key, typename _Value, typename _Alloc,
679  typename _ExtractKey, typename _Equal,
680  typename _H1, typename _H2, typename _Hash,
681  typename _RehashPolicy, typename _Traits,
682  bool _Constant_iterators = _Traits::__constant_iterators::value,
683  bool _Unique_keys = _Traits::__unique_keys::value>
684  struct _Insert;
685 
686  /// Specialization.
687  template<typename _Key, typename _Value, typename _Alloc,
688  typename _ExtractKey, typename _Equal,
689  typename _H1, typename _H2, typename _Hash,
690  typename _RehashPolicy, typename _Traits>
691  struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
692  _RehashPolicy, _Traits, true, true>
693  : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
694  _H1, _H2, _Hash, _RehashPolicy, _Traits>
695  {
696  using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
697  _Equal, _H1, _H2, _Hash,
698  _RehashPolicy, _Traits>;
699  using value_type = typename __base_type::value_type;
700  using iterator = typename __base_type::iterator;
701  using const_iterator = typename __base_type::const_iterator;
702 
703  using __unique_keys = typename __base_type::__unique_keys;
704  using __hashtable = typename __base_type::__hashtable;
705 
706  using __base_type::insert;
707 
709  insert(value_type&& __v)
710  {
711  __hashtable& __h = this->_M_conjure_hashtable();
712  return __h._M_insert(std::move(__v), __unique_keys());
713  }
714 
715  iterator
716  insert(const_iterator __hint, value_type&& __v)
717  {
718  __hashtable& __h = this->_M_conjure_hashtable();
719  return __h._M_insert(__hint, std::move(__v), __unique_keys());
720  }
721  };
722 
723  /// Specialization.
724  template<typename _Key, typename _Value, typename _Alloc,
725  typename _ExtractKey, typename _Equal,
726  typename _H1, typename _H2, typename _Hash,
727  typename _RehashPolicy, typename _Traits>
728  struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
729  _RehashPolicy, _Traits, true, false>
730  : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
731  _H1, _H2, _Hash, _RehashPolicy, _Traits>
732  {
733  using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
734  _Equal, _H1, _H2, _Hash,
735  _RehashPolicy, _Traits>;
736  using value_type = typename __base_type::value_type;
737  using iterator = typename __base_type::iterator;
738  using const_iterator = typename __base_type::const_iterator;
739 
740  using __unique_keys = typename __base_type::__unique_keys;
741  using __hashtable = typename __base_type::__hashtable;
742 
743  using __base_type::insert;
744 
745  iterator
746  insert(value_type&& __v)
747  {
748  __hashtable& __h = this->_M_conjure_hashtable();
749  return __h._M_insert(std::move(__v), __unique_keys());
750  }
751 
752  iterator
753  insert(const_iterator __hint, value_type&& __v)
754  {
755  __hashtable& __h = this->_M_conjure_hashtable();
756  return __h._M_insert(__hint, std::move(__v), __unique_keys());
757  }
758  };
759 
760  /// Specialization.
761  template<typename _Key, typename _Value, typename _Alloc,
762  typename _ExtractKey, typename _Equal,
763  typename _H1, typename _H2, typename _Hash,
764  typename _RehashPolicy, typename _Traits, bool _Unique_keys>
765  struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
766  _RehashPolicy, _Traits, false, _Unique_keys>
767  : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
768  _H1, _H2, _Hash, _RehashPolicy, _Traits>
769  {
770  using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
771  _Equal, _H1, _H2, _Hash,
772  _RehashPolicy, _Traits>;
773  using value_type = typename __base_type::value_type;
774  using iterator = typename __base_type::iterator;
775  using const_iterator = typename __base_type::const_iterator;
776 
777  using __unique_keys = typename __base_type::__unique_keys;
778  using __hashtable = typename __base_type::__hashtable;
779  using __ireturn_type = typename __base_type::__ireturn_type;
780 
781  using __base_type::insert;
782 
783  template<typename _Pair>
784  using __is_cons = std::is_constructible<value_type, _Pair&&>;
785 
786  template<typename _Pair>
787  using _IFcons = std::enable_if<__is_cons<_Pair>::value>;
788 
789  template<typename _Pair>
790  using _IFconsp = typename _IFcons<_Pair>::type;
791 
792  template<typename _Pair, typename = _IFconsp<_Pair>>
793  __ireturn_type
794  insert(_Pair&& __v)
795  {
796  __hashtable& __h = this->_M_conjure_hashtable();
797  return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v));
798  }
799 
800  template<typename _Pair, typename = _IFconsp<_Pair>>
801  iterator
802  insert(const_iterator __hint, _Pair&& __v)
803  {
804  __hashtable& __h = this->_M_conjure_hashtable();
805  return __h._M_emplace(__hint, __unique_keys(),
806  std::forward<_Pair>(__v));
807  }
808  };
809 
810  /**
811  * Primary class template _Rehash_base.
812  *
813  * Give hashtable the max_load_factor functions and reserve iff the
814  * rehash policy is _Prime_rehash_policy.
815  */
816  template<typename _Key, typename _Value, typename _Alloc,
817  typename _ExtractKey, typename _Equal,
818  typename _H1, typename _H2, typename _Hash,
819  typename _RehashPolicy, typename _Traits>
820  struct _Rehash_base;
821 
822  /// Specialization.
823  template<typename _Key, typename _Value, typename _Alloc,
824  typename _ExtractKey, typename _Equal,
825  typename _H1, typename _H2, typename _Hash, typename _Traits>
826  struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
827  _H1, _H2, _Hash, _Prime_rehash_policy, _Traits>
828  {
829  using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
830  _Equal, _H1, _H2, _Hash,
831  _Prime_rehash_policy, _Traits>;
832 
833  float
834  max_load_factor() const noexcept
835  {
836  const __hashtable* __this = static_cast<const __hashtable*>(this);
837  return __this->__rehash_policy().max_load_factor();
838  }
839 
840  void
841  max_load_factor(float __z)
842  {
843  __hashtable* __this = static_cast<__hashtable*>(this);
844  __this->__rehash_policy(_Prime_rehash_policy(__z));
845  }
846 
847  void
848  reserve(std::size_t __n)
849  {
850  __hashtable* __this = static_cast<__hashtable*>(this);
851  __this->rehash(__builtin_ceil(__n / max_load_factor()));
852  }
853  };
854 
855  /**
856  * Primary class template _Hashtable_ebo_helper.
857  *
858  * Helper class using EBO when it is not forbidden (the type is not
859  * final) and when it is worth it (the type is empty.)
860  */
861  template<int _Nm, typename _Tp,
862  bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
864 
865  /// Specialization using EBO.
866  template<int _Nm, typename _Tp>
867  struct _Hashtable_ebo_helper<_Nm, _Tp, true>
868  : private _Tp
869  {
870  _Hashtable_ebo_helper() = default;
871 
872  _Hashtable_ebo_helper(const _Tp& __tp) : _Tp(__tp)
873  { }
874 
875  static const _Tp&
876  _S_cget(const _Hashtable_ebo_helper& __eboh)
877  { return static_cast<const _Tp&>(__eboh); }
878 
879  static _Tp&
880  _S_get(_Hashtable_ebo_helper& __eboh)
881  { return static_cast<_Tp&>(__eboh); }
882  };
883 
884  /// Specialization not using EBO.
885  template<int _Nm, typename _Tp>
886  struct _Hashtable_ebo_helper<_Nm, _Tp, false>
887  {
888  _Hashtable_ebo_helper() = default;
889 
890  _Hashtable_ebo_helper(const _Tp& __tp) : _M_tp(__tp)
891  { }
892 
893  static const _Tp&
894  _S_cget(const _Hashtable_ebo_helper& __eboh)
895  { return __eboh._M_tp; }
896 
897  static _Tp&
898  _S_get(_Hashtable_ebo_helper& __eboh)
899  { return __eboh._M_tp; }
900 
901  private:
902  _Tp _M_tp;
903  };
904 
905  /**
906  * Primary class template _Local_iterator_base.
907  *
908  * Base class for local iterators, used to iterate within a bucket
909  * but not between buckets.
910  */
911  template<typename _Key, typename _Value, typename _ExtractKey,
912  typename _H1, typename _H2, typename _Hash,
913  bool __cache_hash_code>
915 
916  /**
917  * Primary class template _Hash_code_base.
918  *
919  * Encapsulates two policy issues that aren't quite orthogonal.
920  * (1) the difference between using a ranged hash function and using
921  * the combination of a hash function and a range-hashing function.
922  * In the former case we don't have such things as hash codes, so
923  * we have a dummy type as placeholder.
924  * (2) Whether or not we cache hash codes. Caching hash codes is
925  * meaningless if we have a ranged hash function.
926  *
927  * We also put the key extraction objects here, for convenience.
928  * Each specialization derives from one or more of the template
929  * parameters to benefit from Ebo. This is important as this type
930  * is inherited in some cases by the _Local_iterator_base type used
931  * to implement local_iterator and const_local_iterator. As with
932  * any iterator type we prefer to make it as small as possible.
933  *
934  * Primary template is unused except as a hook for specializations.
935  */
936  template<typename _Key, typename _Value, typename _ExtractKey,
937  typename _H1, typename _H2, typename _Hash,
938  bool __cache_hash_code>
940 
941  /// Specialization: ranged hash function, no caching hash codes. H1
942  /// and H2 are provided but ignored. We define a dummy hash code type.
943  template<typename _Key, typename _Value, typename _ExtractKey,
944  typename _H1, typename _H2, typename _Hash>
945  struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false>
946  : private _Hashtable_ebo_helper<0, _ExtractKey>,
947  private _Hashtable_ebo_helper<1, _Hash>
948  {
949  private:
952 
953  protected:
954  typedef void* __hash_code;
956 
957  // We need the default constructor for the local iterators.
958  _Hash_code_base() = default;
959 
960  _Hash_code_base(const _ExtractKey& __ex, const _H1&, const _H2&,
961  const _Hash& __h)
962  : __ebo_extract_key(__ex), __ebo_hash(__h) { }
963 
964  __hash_code
965  _M_hash_code(const _Key& __key) const
966  { return 0; }
967 
968  std::size_t
969  _M_bucket_index(const _Key& __k, __hash_code, std::size_t __n) const
970  { return _M_ranged_hash()(__k, __n); }
971 
972  std::size_t
973  _M_bucket_index(const __node_type* __p, std::size_t __n) const
974  noexcept( noexcept(declval<const _Hash&>()(declval<const _Key&>(), (std::size_t)0)) )
975  { return _M_ranged_hash()(_M_extract()(__p->_M_v()), __n); }
976 
977  void
978  _M_store_code(__node_type*, __hash_code) const
979  { }
980 
981  void
982  _M_copy_code(__node_type*, const __node_type*) const
983  { }
984 
985  void
986  _M_swap(_Hash_code_base& __x)
987  {
988  std::swap(_M_extract(), __x._M_extract());
989  std::swap(_M_ranged_hash(), __x._M_ranged_hash());
990  }
991 
992  const _ExtractKey&
993  _M_extract() const { return __ebo_extract_key::_S_cget(*this); }
994 
995  _ExtractKey&
996  _M_extract() { return __ebo_extract_key::_S_get(*this); }
997 
998  const _Hash&
999  _M_ranged_hash() const { return __ebo_hash::_S_cget(*this); }
1000 
1001  _Hash&
1002  _M_ranged_hash() { return __ebo_hash::_S_get(*this); }
1003  };
1004 
1005  // No specialization for ranged hash function while caching hash codes.
1006  // That combination is meaningless, and trying to do it is an error.
1007 
1008  /// Specialization: ranged hash function, cache hash codes. This
1009  /// combination is meaningless, so we provide only a declaration
1010  /// and no definition.
1011  template<typename _Key, typename _Value, typename _ExtractKey,
1012  typename _H1, typename _H2, typename _Hash>
1013  struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>;
1014 
1015  /// Specialization: hash function and range-hashing function, no
1016  /// caching of hash codes.
1017  /// Provides typedef and accessor required by C++ 11.
1018  template<typename _Key, typename _Value, typename _ExtractKey,
1019  typename _H1, typename _H2>
1020  struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
1021  _Default_ranged_hash, false>
1022  : private _Hashtable_ebo_helper<0, _ExtractKey>,
1023  private _Hashtable_ebo_helper<1, _H1>,
1024  private _Hashtable_ebo_helper<2, _H2>
1025  {
1026  private:
1030 
1031  public:
1032  typedef _H1 hasher;
1033 
1034  hasher
1035  hash_function() const
1036  { return _M_h1(); }
1037 
1038  protected:
1039  typedef std::size_t __hash_code;
1041 
1042  // We need the default constructor for the local iterators.
1043  _Hash_code_base() = default;
1044 
1045  _Hash_code_base(const _ExtractKey& __ex,
1046  const _H1& __h1, const _H2& __h2,
1047  const _Default_ranged_hash&)
1048  : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { }
1049 
1050  __hash_code
1051  _M_hash_code(const _Key& __k) const
1052  { return _M_h1()(__k); }
1053 
1054  std::size_t
1055  _M_bucket_index(const _Key&, __hash_code __c, std::size_t __n) const
1056  { return _M_h2()(__c, __n); }
1057 
1058  std::size_t
1059  _M_bucket_index(const __node_type* __p, std::size_t __n) const
1060  noexcept( noexcept(declval<const _H1&>()(declval<const _Key&>()))
1061  && noexcept(declval<const _H2&>()((__hash_code)0, (std::size_t)0)) )
1062  { return _M_h2()(_M_h1()(_M_extract()(__p->_M_v())), __n); }
1063 
1064  void
1065  _M_store_code(__node_type*, __hash_code) const
1066  { }
1067 
1068  void
1069  _M_copy_code(__node_type*, const __node_type*) const
1070  { }
1071 
1072  void
1073  _M_swap(_Hash_code_base& __x)
1074  {
1075  std::swap(_M_extract(), __x._M_extract());
1076  std::swap(_M_h1(), __x._M_h1());
1077  std::swap(_M_h2(), __x._M_h2());
1078  }
1079 
1080  const _ExtractKey&
1081  _M_extract() const { return __ebo_extract_key::_S_cget(*this); }
1082 
1083  _ExtractKey&
1084  _M_extract() { return __ebo_extract_key::_S_get(*this); }
1085 
1086  const _H1&
1087  _M_h1() const { return __ebo_h1::_S_cget(*this); }
1088 
1089  _H1&
1090  _M_h1() { return __ebo_h1::_S_get(*this); }
1091 
1092  const _H2&
1093  _M_h2() const { return __ebo_h2::_S_cget(*this); }
1094 
1095  _H2&
1096  _M_h2() { return __ebo_h2::_S_get(*this); }
1097  };
1098 
1099  /// Specialization: hash function and range-hashing function,
1100  /// caching hash codes. H is provided but ignored. Provides
1101  /// typedef and accessor required by C++ 11.
1102  template<typename _Key, typename _Value, typename _ExtractKey,
1103  typename _H1, typename _H2>
1104  struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
1105  _Default_ranged_hash, true>
1106  : private _Hashtable_ebo_helper<0, _ExtractKey>,
1107  private _Hashtable_ebo_helper<1, _H1>,
1108  private _Hashtable_ebo_helper<2, _H2>
1109  {
1110  private:
1111  // Gives access to _M_h2() to the local iterator implementation.
1112  friend struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2,
1113  _Default_ranged_hash, true>;
1114 
1118 
1119  public:
1120  typedef _H1 hasher;
1121 
1122  hasher
1123  hash_function() const
1124  { return _M_h1(); }
1125 
1126  protected:
1127  typedef std::size_t __hash_code;
1129 
1130  _Hash_code_base(const _ExtractKey& __ex,
1131  const _H1& __h1, const _H2& __h2,
1132  const _Default_ranged_hash&)
1133  : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { }
1134 
1135  __hash_code
1136  _M_hash_code(const _Key& __k) const
1137  { return _M_h1()(__k); }
1138 
1139  std::size_t
1140  _M_bucket_index(const _Key&, __hash_code __c,
1141  std::size_t __n) const
1142  { return _M_h2()(__c, __n); }
1143 
1144  std::size_t
1145  _M_bucket_index(const __node_type* __p, std::size_t __n) const
1146  noexcept( noexcept(declval<const _H2&>()((__hash_code)0,
1147  (std::size_t)0)) )
1148  { return _M_h2()(__p->_M_hash_code, __n); }
1149 
1150  void
1151  _M_store_code(__node_type* __n, __hash_code __c) const
1152  { __n->_M_hash_code = __c; }
1153 
1154  void
1155  _M_copy_code(__node_type* __to, const __node_type* __from) const
1156  { __to->_M_hash_code = __from->_M_hash_code; }
1157 
1158  void
1159  _M_swap(_Hash_code_base& __x)
1160  {
1161  std::swap(_M_extract(), __x._M_extract());
1162  std::swap(_M_h1(), __x._M_h1());
1163  std::swap(_M_h2(), __x._M_h2());
1164  }
1165 
1166  const _ExtractKey&
1167  _M_extract() const { return __ebo_extract_key::_S_cget(*this); }
1168 
1169  _ExtractKey&
1170  _M_extract() { return __ebo_extract_key::_S_get(*this); }
1171 
1172  const _H1&
1173  _M_h1() const { return __ebo_h1::_S_cget(*this); }
1174 
1175  _H1&
1176  _M_h1() { return __ebo_h1::_S_get(*this); }
1177 
1178  const _H2&
1179  _M_h2() const { return __ebo_h2::_S_cget(*this); }
1180 
1181  _H2&
1182  _M_h2() { return __ebo_h2::_S_get(*this); }
1183  };
1184 
1185  /**
1186  * Primary class template _Equal_helper.
1187  *
1188  */
1189  template <typename _Key, typename _Value, typename _ExtractKey,
1190  typename _Equal, typename _HashCodeType,
1191  bool __cache_hash_code>
1193 
1194  /// Specialization.
1195  template<typename _Key, typename _Value, typename _ExtractKey,
1196  typename _Equal, typename _HashCodeType>
1197  struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType, true>
1198  {
1199  static bool
1200  _S_equals(const _Equal& __eq, const _ExtractKey& __extract,
1201  const _Key& __k, _HashCodeType __c, _Hash_node<_Value, true>* __n)
1202  { return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); }
1203  };
1204 
1205  /// Specialization.
1206  template<typename _Key, typename _Value, typename _ExtractKey,
1207  typename _Equal, typename _HashCodeType>
1208  struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType, false>
1209  {
1210  static bool
1211  _S_equals(const _Equal& __eq, const _ExtractKey& __extract,
1212  const _Key& __k, _HashCodeType, _Hash_node<_Value, false>* __n)
1213  { return __eq(__k, __extract(__n->_M_v())); }
1214  };
1215 
1216 
1217  /// Specialization.
1218  template<typename _Key, typename _Value, typename _ExtractKey,
1219  typename _H1, typename _H2, typename _Hash>
1220  struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1221  _H1, _H2, _Hash, true>
1222  : private _Hashtable_ebo_helper<0, _H2>
1223  {
1224  protected:
1226  using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1227  _H1, _H2, _Hash, true>;
1228 
1229  public:
1230  _Local_iterator_base() = default;
1233  std::size_t __bkt, std::size_t __bkt_count)
1234  : __base_type(__base._M_h2()),
1235  _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1236 
1237  void
1238  _M_incr()
1239  {
1240  _M_cur = _M_cur->_M_next();
1241  if (_M_cur)
1242  {
1243  std::size_t __bkt
1244  = __base_type::_S_get(*this)(_M_cur->_M_hash_code,
1245  _M_bucket_count);
1246  if (__bkt != _M_bucket)
1247  _M_cur = nullptr;
1248  }
1249  }
1250 
1251  _Hash_node<_Value, true>* _M_cur;
1252  std::size_t _M_bucket;
1253  std::size_t _M_bucket_count;
1254  };
1255 
1256  /// Specialization.
1257  template<typename _Key, typename _Value, typename _ExtractKey,
1258  typename _H1, typename _H2, typename _Hash>
1259  struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1260  _H1, _H2, _Hash, false>
1261  : private _Hash_code_base<_Key, _Value, _ExtractKey,
1262  _H1, _H2, _Hash, false>
1263  {
1264  protected:
1265  using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1266  _H1, _H2, _Hash, false>;
1267 
1268  public:
1269  _Local_iterator_base() = default;
1272  std::size_t __bkt, std::size_t __bkt_count)
1273  : __hash_code_base(__base),
1274  _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1275 
1276  void
1277  _M_incr()
1278  {
1279  _M_cur = _M_cur->_M_next();
1280  if (_M_cur)
1281  {
1282  std::size_t __bkt = this->_M_bucket_index(_M_cur, _M_bucket_count);
1283  if (__bkt != _M_bucket)
1284  _M_cur = nullptr;
1285  }
1286  }
1287 
1288  _Hash_node<_Value, false>* _M_cur;
1289  std::size_t _M_bucket;
1290  std::size_t _M_bucket_count;
1291  };
1292 
1293  template<typename _Key, typename _Value, typename _ExtractKey,
1294  typename _H1, typename _H2, typename _Hash, bool __cache>
1295  inline bool
1296  operator==(const _Local_iterator_base<_Key, _Value, _ExtractKey,
1297  _H1, _H2, _Hash, __cache>& __x,
1298  const _Local_iterator_base<_Key, _Value, _ExtractKey,
1299  _H1, _H2, _Hash, __cache>& __y)
1300  { return __x._M_cur == __y._M_cur; }
1301 
1302  template<typename _Key, typename _Value, typename _ExtractKey,
1303  typename _H1, typename _H2, typename _Hash, bool __cache>
1304  inline bool
1305  operator!=(const _Local_iterator_base<_Key, _Value, _ExtractKey,
1306  _H1, _H2, _Hash, __cache>& __x,
1307  const _Local_iterator_base<_Key, _Value, _ExtractKey,
1308  _H1, _H2, _Hash, __cache>& __y)
1309  { return __x._M_cur != __y._M_cur; }
1310 
1311  /// local iterators
1312  template<typename _Key, typename _Value, typename _ExtractKey,
1313  typename _H1, typename _H2, typename _Hash,
1314  bool __constant_iterators, bool __cache>
1316  : public _Local_iterator_base<_Key, _Value, _ExtractKey,
1317  _H1, _H2, _Hash, __cache>
1318  {
1319  private:
1320  using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1321  _H1, _H2, _Hash, __cache>;
1322  using __hash_code_base = typename __base_type::__hash_code_base;
1323  public:
1324  typedef _Value value_type;
1325  typedef typename std::conditional<__constant_iterators,
1326  const _Value*, _Value*>::type
1327  pointer;
1328  typedef typename std::conditional<__constant_iterators,
1329  const _Value&, _Value&>::type
1330  reference;
1331  typedef std::ptrdiff_t difference_type;
1333 
1334  _Local_iterator() = default;
1335 
1336  _Local_iterator(const __hash_code_base& __base,
1338  std::size_t __bkt, std::size_t __bkt_count)
1339  : __base_type(__base, __p, __bkt, __bkt_count)
1340  { }
1341 
1342  reference
1343  operator*() const
1344  { return this->_M_cur->_M_v(); }
1345 
1346  pointer
1347  operator->() const
1348  { return this->_M_cur->_M_valptr(); }
1349 
1351  operator++()
1352  {
1353  this->_M_incr();
1354  return *this;
1355  }
1356 
1358  operator++(int)
1359  {
1360  _Local_iterator __tmp(*this);
1361  this->_M_incr();
1362  return __tmp;
1363  }
1364  };
1365 
1366  /// local const_iterators
1367  template<typename _Key, typename _Value, typename _ExtractKey,
1368  typename _H1, typename _H2, typename _Hash,
1369  bool __constant_iterators, bool __cache>
1371  : public _Local_iterator_base<_Key, _Value, _ExtractKey,
1372  _H1, _H2, _Hash, __cache>
1373  {
1374  private:
1375  using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1376  _H1, _H2, _Hash, __cache>;
1377  using __hash_code_base = typename __base_type::__hash_code_base;
1378 
1379  public:
1380  typedef _Value value_type;
1381  typedef const _Value* pointer;
1382  typedef const _Value& reference;
1383  typedef std::ptrdiff_t difference_type;
1385 
1386  _Local_const_iterator() = default;
1387 
1388  _Local_const_iterator(const __hash_code_base& __base,
1390  std::size_t __bkt, std::size_t __bkt_count)
1391  : __base_type(__base, __p, __bkt, __bkt_count)
1392  { }
1393 
1394  _Local_const_iterator(const _Local_iterator<_Key, _Value, _ExtractKey,
1395  _H1, _H2, _Hash,
1396  __constant_iterators,
1397  __cache>& __x)
1398  : __base_type(__x)
1399  { }
1400 
1401  reference
1402  operator*() const
1403  { return this->_M_cur->_M_v(); }
1404 
1405  pointer
1406  operator->() const
1407  { return this->_M_cur->_M_valptr(); }
1408 
1410  operator++()
1411  {
1412  this->_M_incr();
1413  return *this;
1414  }
1415 
1417  operator++(int)
1418  {
1419  _Local_const_iterator __tmp(*this);
1420  this->_M_incr();
1421  return __tmp;
1422  }
1423  };
1424 
1425  /**
1426  * Primary class template _Hashtable_base.
1427  *
1428  * Helper class adding management of _Equal functor to
1429  * _Hash_code_base type.
1430  *
1431  * Base class templates are:
1432  * - __detail::_Hash_code_base
1433  * - __detail::_Hashtable_ebo_helper
1434  */
1435  template<typename _Key, typename _Value,
1436  typename _ExtractKey, typename _Equal,
1437  typename _H1, typename _H2, typename _Hash, typename _Traits>
1438  struct _Hashtable_base
1439  : public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
1440  _Traits::__hash_cached::value>,
1441  private _Hashtable_ebo_helper<0, _Equal>
1442  {
1443  public:
1444  typedef _Key key_type;
1445  typedef _Value value_type;
1446  typedef _Equal key_equal;
1447  typedef std::size_t size_type;
1448  typedef std::ptrdiff_t difference_type;
1449 
1450  using __traits_type = _Traits;
1451  using __hash_cached = typename __traits_type::__hash_cached;
1452  using __constant_iterators = typename __traits_type::__constant_iterators;
1453  using __unique_keys = typename __traits_type::__unique_keys;
1454 
1455  using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1456  _H1, _H2, _Hash,
1457  __hash_cached::value>;
1458 
1459  using __hash_code = typename __hash_code_base::__hash_code;
1460  using __node_type = typename __hash_code_base::__node_type;
1461 
1462  using iterator = __detail::_Node_iterator<value_type,
1463  __constant_iterators::value,
1464  __hash_cached::value>;
1465 
1466  using const_iterator = __detail::_Node_const_iterator<value_type,
1467  __constant_iterators::value,
1468  __hash_cached::value>;
1469 
1470  using local_iterator = __detail::_Local_iterator<key_type, value_type,
1471  _ExtractKey, _H1, _H2, _Hash,
1472  __constant_iterators::value,
1473  __hash_cached::value>;
1474 
1475  using const_local_iterator = __detail::_Local_const_iterator<key_type,
1476  value_type,
1477  _ExtractKey, _H1, _H2, _Hash,
1478  __constant_iterators::value,
1479  __hash_cached::value>;
1480 
1481  using __ireturn_type = typename std::conditional<__unique_keys::value,
1483  iterator>::type;
1484  private:
1485  using _EqualEBO = _Hashtable_ebo_helper<0, _Equal>;
1486  using _EqualHelper = _Equal_helper<_Key, _Value, _ExtractKey, _Equal,
1487  __hash_code, __hash_cached::value>;
1488 
1489  protected:
1490  using __node_base = __detail::_Hash_node_base;
1491  using __bucket_type = __node_base*;
1492 
1493  _Hashtable_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2,
1494  const _Hash& __hash, const _Equal& __eq)
1495  : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq)
1496  { }
1497 
1498  bool
1499  _M_equals(const _Key& __k, __hash_code __c, __node_type* __n) const
1500  {
1501  return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(),
1502  __k, __c, __n);
1503  }
1504 
1505  void
1506  _M_swap(_Hashtable_base& __x)
1507  {
1508  __hash_code_base::_M_swap(__x);
1509  std::swap(_M_eq(), __x._M_eq());
1510  }
1511 
1512  const _Equal&
1513  _M_eq() const { return _EqualEBO::_S_cget(*this); }
1514 
1515  _Equal&
1516  _M_eq() { return _EqualEBO::_S_get(*this); }
1517  };
1518 
1519  /**
1520  * struct _Equality_base.
1521  *
1522  * Common types and functions for class _Equality.
1523  */
1525  {
1526  protected:
1527  template<typename _Uiterator>
1528  static bool
1529  _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
1530  };
1531 
1532  // See std::is_permutation in N3068.
1533  template<typename _Uiterator>
1534  bool
1535  _Equality_base::
1536  _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
1537  _Uiterator __first2)
1538  {
1539  for (; __first1 != __last1; ++__first1, ++__first2)
1540  if (!(*__first1 == *__first2))
1541  break;
1542 
1543  if (__first1 == __last1)
1544  return true;
1545 
1546  _Uiterator __last2 = __first2;
1547  std::advance(__last2, std::distance(__first1, __last1));
1548 
1549  for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
1550  {
1551  _Uiterator __tmp = __first1;
1552  while (__tmp != __it1 && !bool(*__tmp == *__it1))
1553  ++__tmp;
1554 
1555  // We've seen this one before.
1556  if (__tmp != __it1)
1557  continue;
1558 
1559  std::ptrdiff_t __n2 = 0;
1560  for (__tmp = __first2; __tmp != __last2; ++__tmp)
1561  if (*__tmp == *__it1)
1562  ++__n2;
1563 
1564  if (!__n2)
1565  return false;
1566 
1567  std::ptrdiff_t __n1 = 0;
1568  for (__tmp = __it1; __tmp != __last1; ++__tmp)
1569  if (*__tmp == *__it1)
1570  ++__n1;
1571 
1572  if (__n1 != __n2)
1573  return false;
1574  }
1575  return true;
1576  }
1577 
1578  /**
1579  * Primary class template _Equality.
1580  *
1581  * This is for implementing equality comparison for unordered
1582  * containers, per N3068, by John Lakos and Pablo Halpern.
1583  * Algorithmically, we follow closely the reference implementations
1584  * therein.
1585  */
1586  template<typename _Key, typename _Value, typename _Alloc,
1587  typename _ExtractKey, typename _Equal,
1588  typename _H1, typename _H2, typename _Hash,
1589  typename _RehashPolicy, typename _Traits,
1590  bool _Unique_keys = _Traits::__unique_keys::value>
1591  struct _Equality;
1592 
1593  /// Specialization.
1594  template<typename _Key, typename _Value, typename _Alloc,
1595  typename _ExtractKey, typename _Equal,
1596  typename _H1, typename _H2, typename _Hash,
1597  typename _RehashPolicy, typename _Traits>
1598  struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1599  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
1600  {
1601  using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1602  _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1603 
1604  bool
1605  _M_equal(const __hashtable&) const;
1606  };
1607 
1608  template<typename _Key, typename _Value, typename _Alloc,
1609  typename _ExtractKey, typename _Equal,
1610  typename _H1, typename _H2, typename _Hash,
1611  typename _RehashPolicy, typename _Traits>
1612  bool
1613  _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1614  _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::
1615  _M_equal(const __hashtable& __other) const
1616  {
1617  const __hashtable* __this = static_cast<const __hashtable*>(this);
1618 
1619  if (__this->size() != __other.size())
1620  return false;
1621 
1622  for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1623  {
1624  const auto __ity = __other.find(_ExtractKey()(*__itx));
1625  if (__ity == __other.end() || !bool(*__ity == *__itx))
1626  return false;
1627  }
1628  return true;
1629  }
1630 
1631  /// Specialization.
1632  template<typename _Key, typename _Value, typename _Alloc,
1633  typename _ExtractKey, typename _Equal,
1634  typename _H1, typename _H2, typename _Hash,
1635  typename _RehashPolicy, typename _Traits>
1636  struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1637  _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
1638  : public _Equality_base
1639  {
1640  using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1641  _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1642 
1643  bool
1644  _M_equal(const __hashtable&) const;
1645  };
1646 
1647  template<typename _Key, typename _Value, typename _Alloc,
1648  typename _ExtractKey, typename _Equal,
1649  typename _H1, typename _H2, typename _Hash,
1650  typename _RehashPolicy, typename _Traits>
1651  bool
1652  _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1653  _H1, _H2, _Hash, _RehashPolicy, _Traits, false>::
1654  _M_equal(const __hashtable& __other) const
1655  {
1656  const __hashtable* __this = static_cast<const __hashtable*>(this);
1657 
1658  if (__this->size() != __other.size())
1659  return false;
1660 
1661  for (auto __itx = __this->begin(); __itx != __this->end();)
1662  {
1663  const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
1664  const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
1665 
1666  if (std::distance(__xrange.first, __xrange.second)
1667  != std::distance(__yrange.first, __yrange.second))
1668  return false;
1669 
1670  if (!_S_is_permutation(__xrange.first, __xrange.second,
1671  __yrange.first))
1672  return false;
1673 
1674  __itx = __xrange.second;
1675  }
1676  return true;
1677  }
1678 
1679  /**
1680  * This type is to combine a _Hash_node_base instance with an allocator
1681  * instance through inheritance to benefit from EBO when possible.
1682  */
1683  template<typename _NodeAlloc>
1684  struct _Before_begin : public _NodeAlloc
1685  {
1686  _Hash_node_base _M_node;
1687 
1688  _Before_begin(const _Before_begin&) = default;
1689  _Before_begin(_Before_begin&&) = default;
1690 
1691  template<typename _Alloc>
1692  _Before_begin(_Alloc&& __a)
1693  : _NodeAlloc(std::forward<_Alloc>(__a))
1694  { }
1695  };
1696 
1697  /*
1698  * Following are functors recyclicing a pool of nodes and using allocation
1699  * once the pool is empty.
1700  */
1701  /// Version using copy semantic through the copy constructor.
1702  template<typename _Key, typename _Value, typename _Alloc,
1703  typename _ExtractKey, typename _Equal,
1704  typename _H1, typename _H2, typename _Hash,
1705  typename _RehashPolicy, typename _Traits>
1707  {
1708  private:
1709  using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
1710  _Equal, _H1, _H2, _Hash,
1711  _RehashPolicy, _Traits>;
1712  using __val_alloc_type = typename __hashtable::_Value_alloc_type;
1713  using __val_alloc_traits = typename __hashtable::_Value_alloc_traits;
1714  using __node_alloc_traits = typename __hashtable::_Node_alloc_traits;
1715  using __node_type = typename __hashtable::__node_type;
1716 
1717  public:
1718  _ReuseOrAllocNode(__node_type* __nodes, __hashtable& __h)
1719  : _M_nodes(__nodes), _M_h(__h) { }
1720  _ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete;
1721 
1723  { _M_h._M_deallocate_nodes(_M_nodes); }
1724 
1725  __node_type*
1726  operator()(const __node_type* __n) const
1727  {
1728  if (_M_nodes)
1729  {
1730  __node_type* __node = _M_nodes;
1731  _M_nodes = _M_nodes->_M_next();
1732  __node->_M_nxt = nullptr;
1733  __val_alloc_type __a(_M_h._M_node_allocator());
1734  __val_alloc_traits::destroy(__a, __node->_M_valptr());
1735  __try
1736  {
1737  __val_alloc_traits::construct(__a, __node->_M_valptr(),
1738  __n->_M_v());
1739  }
1740  __catch(...)
1741  {
1742  __node->~__node_type();
1743  __node_alloc_traits::deallocate(_M_h._M_node_allocator(),
1744  __node, 1);
1745  __throw_exception_again;
1746  }
1747  return __node;
1748  }
1749  return _M_h._M_allocate_node(__n->_M_v());
1750  }
1751 
1752  mutable __node_type* _M_nodes;
1753  __hashtable& _M_h;
1754  };
1755 
1756  /// Version using move semantic through the move constructor.
1757  template<typename _Key, typename _Value, typename _Alloc,
1758  typename _ExtractKey, typename _Equal,
1759  typename _H1, typename _H2, typename _Hash,
1760  typename _RehashPolicy, typename _Traits>
1762  {
1763  private:
1764  using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
1765  _Equal, _H1, _H2, _Hash,
1766  _RehashPolicy, _Traits>;
1767  using __val_alloc_type = typename __hashtable::_Value_alloc_type;
1768  using __val_alloc_traits = typename __hashtable::_Value_alloc_traits;
1769  using __node_alloc_traits = typename __hashtable::_Node_alloc_traits;
1770  using __node_type = typename __hashtable::__node_type;
1771 
1772  public:
1773  _MoveReuseOrAllocNode(__node_type* __nodes, __hashtable& __h)
1774  : _M_nodes(__nodes), _M_h(__h) { }
1776 
1778  { _M_h._M_deallocate_nodes(_M_nodes); }
1779 
1780  __node_type*
1781  operator()(__node_type* __n) const
1782  {
1783  if (_M_nodes)
1784  {
1785  __node_type* __node = _M_nodes;
1786  _M_nodes = _M_nodes->_M_next();
1787  __node->_M_nxt = nullptr;
1788  __val_alloc_type __a(_M_h._M_node_allocator());
1789  __val_alloc_traits::destroy(__a, __node->_M_valptr());
1790  __try
1791  {
1792  __val_alloc_traits::construct(__a, __node->_M_valptr(),
1793  std::move_if_noexcept(__n->_M_v()));
1794  }
1795  __catch(...)
1796  {
1797  __node->~__node_type();
1798  __node_alloc_traits::deallocate(_M_h._M_node_allocator(),
1799  __node, 1);
1800  __throw_exception_again;
1801  }
1802  return __node;
1803  }
1804  return _M_h._M_allocate_node(std::move_if_noexcept(__n->_M_v()));
1805  }
1806 
1807  mutable __node_type* _M_nodes;
1808  __hashtable& _M_h;
1809  };
1810 
1811  //@} hashtable-detail
1812 _GLIBCXX_END_NAMESPACE_VERSION
1813 } // namespace __detail
1814 } // namespace std
1815 
1816 #endif // _HASHTABLE_POLICY_H