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