xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/hashtable_policy.h (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 // Internal policy header for unordered_set and unordered_map -*- C++ -*-
2 
3 // Copyright (C) 2010-2022 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 #include <tuple>		// for std::tuple, std::forward_as_tuple
35 #include <bits/stl_algobase.h>	// for std::min, std::is_permutation.
36 #include <ext/aligned_buffer.h>	// for __gnu_cxx::__aligned_buffer
37 #include <ext/alloc_traits.h>	// for std::__alloc_rebind
38 #include <ext/numeric_traits.h>	// for __gnu_cxx::__int_traits
39 
_GLIBCXX_VISIBILITY(default)40 namespace std _GLIBCXX_VISIBILITY(default)
41 {
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 /// @cond undocumented
44 
45   template<typename _Key, typename _Value, typename _Alloc,
46 	   typename _ExtractKey, typename _Equal,
47 	   typename _Hash, typename _RangeHash, typename _Unused,
48 	   typename _RehashPolicy, typename _Traits>
49     class _Hashtable;
50 
51 namespace __detail
52 {
53   /**
54    *  @defgroup hashtable-detail Base and Implementation Classes
55    *  @ingroup unordered_associative_containers
56    *  @{
57    */
58   template<typename _Key, typename _Value, typename _ExtractKey,
59 	   typename _Equal, typename _Hash, typename _RangeHash,
60 	   typename _Unused, typename _Traits>
61     struct _Hashtable_base;
62 
63   // Helper function: return distance(first, last) for forward
64   // iterators, or 0/1 for input iterators.
65   template<typename _Iterator>
66     inline typename std::iterator_traits<_Iterator>::difference_type
67     __distance_fw(_Iterator __first, _Iterator __last,
68 		  std::input_iterator_tag)
69     { return __first != __last ? 1 : 0; }
70 
71   template<typename _Iterator>
72     inline typename std::iterator_traits<_Iterator>::difference_type
73     __distance_fw(_Iterator __first, _Iterator __last,
74 		  std::forward_iterator_tag)
75     { return std::distance(__first, __last); }
76 
77   template<typename _Iterator>
78     inline typename std::iterator_traits<_Iterator>::difference_type
79     __distance_fw(_Iterator __first, _Iterator __last)
80     { return __distance_fw(__first, __last,
81 			   std::__iterator_category(__first)); }
82 
83   struct _Identity
84   {
85     template<typename _Tp>
86       _Tp&&
87       operator()(_Tp&& __x) const noexcept
88       { return std::forward<_Tp>(__x); }
89   };
90 
91   struct _Select1st
92   {
93     template<typename _Pair>
94       struct __1st_type;
95 
96     template<typename _Tp, typename _Up>
97       struct __1st_type<pair<_Tp, _Up>>
98       { using type = _Tp; };
99 
100     template<typename _Tp, typename _Up>
101       struct __1st_type<const pair<_Tp, _Up>>
102       { using type = const _Tp; };
103 
104     template<typename _Pair>
105       struct __1st_type<_Pair&>
106       { using type = typename __1st_type<_Pair>::type&; };
107 
108     template<typename _Tp>
109       typename __1st_type<_Tp>::type&&
110       operator()(_Tp&& __x) const noexcept
111       { return std::forward<_Tp>(__x).first; }
112   };
113 
114   template<typename _ExKey>
115     struct _NodeBuilder;
116 
117   template<>
118     struct _NodeBuilder<_Select1st>
119     {
120       template<typename _Kt, typename _Arg, typename _NodeGenerator>
121 	static auto
122 	_S_build(_Kt&& __k, _Arg&& __arg, const _NodeGenerator& __node_gen)
123 	-> typename _NodeGenerator::__node_type*
124 	{
125 	  return __node_gen(std::forward<_Kt>(__k),
126 			    std::forward<_Arg>(__arg).second);
127 	}
128     };
129 
130   template<>
131     struct _NodeBuilder<_Identity>
132     {
133       template<typename _Kt, typename _Arg, typename _NodeGenerator>
134 	static auto
135 	_S_build(_Kt&& __k, _Arg&&, const _NodeGenerator& __node_gen)
136 	-> typename _NodeGenerator::__node_type*
137 	{ return __node_gen(std::forward<_Kt>(__k)); }
138     };
139 
140   template<typename _NodeAlloc>
141     struct _Hashtable_alloc;
142 
143   // Functor recycling a pool of nodes and using allocation once the pool is
144   // empty.
145   template<typename _NodeAlloc>
146     struct _ReuseOrAllocNode
147     {
148     private:
149       using __node_alloc_type = _NodeAlloc;
150       using __hashtable_alloc = _Hashtable_alloc<__node_alloc_type>;
151       using __node_alloc_traits =
152 	typename __hashtable_alloc::__node_alloc_traits;
153 
154     public:
155       using __node_type = typename __hashtable_alloc::__node_type;
156 
157       _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h)
158       : _M_nodes(__nodes), _M_h(__h) { }
159       _ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete;
160 
161       ~_ReuseOrAllocNode()
162       { _M_h._M_deallocate_nodes(_M_nodes); }
163 
164       template<typename... _Args>
165 	__node_type*
166 	operator()(_Args&&... __args) const
167 	{
168 	  if (_M_nodes)
169 	    {
170 	      __node_type* __node = _M_nodes;
171 	      _M_nodes = _M_nodes->_M_next();
172 	      __node->_M_nxt = nullptr;
173 	      auto& __a = _M_h._M_node_allocator();
174 	      __node_alloc_traits::destroy(__a, __node->_M_valptr());
175 	      __try
176 		{
177 		  __node_alloc_traits::construct(__a, __node->_M_valptr(),
178 						 std::forward<_Args>(__args)...);
179 		}
180 	      __catch(...)
181 		{
182 		  _M_h._M_deallocate_node_ptr(__node);
183 		  __throw_exception_again;
184 		}
185 	      return __node;
186 	    }
187 	  return _M_h._M_allocate_node(std::forward<_Args>(__args)...);
188 	}
189 
190     private:
191       mutable __node_type* _M_nodes;
192       __hashtable_alloc& _M_h;
193     };
194 
195   // Functor similar to the previous one but without any pool of nodes to
196   // recycle.
197   template<typename _NodeAlloc>
198     struct _AllocNode
199     {
200     private:
201       using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>;
202 
203     public:
204       using __node_type = typename __hashtable_alloc::__node_type;
205 
206       _AllocNode(__hashtable_alloc& __h)
207       : _M_h(__h) { }
208 
209       template<typename... _Args>
210 	__node_type*
211 	operator()(_Args&&... __args) const
212 	{ return _M_h._M_allocate_node(std::forward<_Args>(__args)...); }
213 
214     private:
215       __hashtable_alloc& _M_h;
216     };
217 
218   // Auxiliary types used for all instantiations of _Hashtable nodes
219   // and iterators.
220 
221   /**
222    *  struct _Hashtable_traits
223    *
224    *  Important traits for hash tables.
225    *
226    *  @tparam _Cache_hash_code  Boolean value. True if the value of
227    *  the hash function is stored along with the value. This is a
228    *  time-space tradeoff.  Storing it may improve lookup speed by
229    *  reducing the number of times we need to call the _Hash or _Equal
230    *  functors.
231    *
232    *  @tparam _Constant_iterators  Boolean value. True if iterator and
233    *  const_iterator are both constant iterator types. This is true
234    *  for unordered_set and unordered_multiset, false for
235    *  unordered_map and unordered_multimap.
236    *
237    *  @tparam _Unique_keys  Boolean value. True if the return value
238    *  of _Hashtable::count(k) is always at most one, false if it may
239    *  be an arbitrary number. This is true for unordered_set and
240    *  unordered_map, false for unordered_multiset and
241    *  unordered_multimap.
242    */
243   template<bool _Cache_hash_code, bool _Constant_iterators, bool _Unique_keys>
244     struct _Hashtable_traits
245     {
246       using __hash_cached = __bool_constant<_Cache_hash_code>;
247       using __constant_iterators = __bool_constant<_Constant_iterators>;
248       using __unique_keys = __bool_constant<_Unique_keys>;
249     };
250 
251   /**
252    *  struct _Hashtable_hash_traits
253    *
254    *  Important traits for hash tables depending on associated hasher.
255    *
256    */
257   template<typename _Hash>
258     struct _Hashtable_hash_traits
259     {
260       static constexpr std::size_t
261       __small_size_threshold() noexcept
262       { return std::__is_fast_hash<_Hash>::value ? 0 : 20; }
263     };
264 
265   /**
266    *  struct _Hash_node_base
267    *
268    *  Nodes, used to wrap elements stored in the hash table.  A policy
269    *  template parameter of class template _Hashtable controls whether
270    *  nodes also store a hash code. In some cases (e.g. strings) this
271    *  may be a performance win.
272    */
273   struct _Hash_node_base
274   {
275     _Hash_node_base* _M_nxt;
276 
277     _Hash_node_base() noexcept : _M_nxt() { }
278 
279     _Hash_node_base(_Hash_node_base* __next) noexcept : _M_nxt(__next) { }
280   };
281 
282   /**
283    *  struct _Hash_node_value_base
284    *
285    *  Node type with the value to store.
286    */
287   template<typename _Value>
288     struct _Hash_node_value_base
289     {
290       typedef _Value value_type;
291 
292       __gnu_cxx::__aligned_buffer<_Value> _M_storage;
293 
294       [[__gnu__::__always_inline__]]
295       _Value*
296       _M_valptr() noexcept
297       { return _M_storage._M_ptr(); }
298 
299       [[__gnu__::__always_inline__]]
300       const _Value*
301       _M_valptr() const noexcept
302       { return _M_storage._M_ptr(); }
303 
304       [[__gnu__::__always_inline__]]
305       _Value&
306       _M_v() noexcept
307       { return *_M_valptr(); }
308 
309       [[__gnu__::__always_inline__]]
310       const _Value&
311       _M_v() const noexcept
312       { return *_M_valptr(); }
313     };
314 
315   /**
316    *  Primary template struct _Hash_node_code_cache.
317    */
318   template<bool _Cache_hash_code>
319     struct _Hash_node_code_cache
320     { };
321 
322   /**
323    *  Specialization for node with cache, struct _Hash_node_code_cache.
324    */
325   template<>
326     struct _Hash_node_code_cache<true>
327     { std::size_t  _M_hash_code; };
328 
329   template<typename _Value, bool _Cache_hash_code>
330     struct _Hash_node_value
331     : _Hash_node_value_base<_Value>
332     , _Hash_node_code_cache<_Cache_hash_code>
333     { };
334 
335   /**
336    *  Primary template struct _Hash_node.
337    */
338   template<typename _Value, bool _Cache_hash_code>
339     struct _Hash_node
340     : _Hash_node_base
341     , _Hash_node_value<_Value, _Cache_hash_code>
342     {
343       _Hash_node*
344       _M_next() const noexcept
345       { return static_cast<_Hash_node*>(this->_M_nxt); }
346     };
347 
348   /// Base class for node iterators.
349   template<typename _Value, bool _Cache_hash_code>
350     struct _Node_iterator_base
351     {
352       using __node_type = _Hash_node<_Value, _Cache_hash_code>;
353 
354       __node_type* _M_cur;
355 
356       _Node_iterator_base() : _M_cur(nullptr) { }
357       _Node_iterator_base(__node_type* __p) noexcept
358       : _M_cur(__p) { }
359 
360       void
361       _M_incr() noexcept
362       { _M_cur = _M_cur->_M_next(); }
363 
364       friend bool
365       operator==(const _Node_iterator_base& __x, const _Node_iterator_base& __y)
366       noexcept
367       { return __x._M_cur == __y._M_cur; }
368 
369 #if __cpp_impl_three_way_comparison < 201907L
370       friend bool
371       operator!=(const _Node_iterator_base& __x, const _Node_iterator_base& __y)
372       noexcept
373       { return __x._M_cur != __y._M_cur; }
374 #endif
375     };
376 
377   /// Node iterators, used to iterate through all the hashtable.
378   template<typename _Value, bool __constant_iterators, bool __cache>
379     struct _Node_iterator
380     : public _Node_iterator_base<_Value, __cache>
381     {
382     private:
383       using __base_type = _Node_iterator_base<_Value, __cache>;
384       using __node_type = typename __base_type::__node_type;
385 
386     public:
387       using value_type = _Value;
388       using difference_type = std::ptrdiff_t;
389       using iterator_category = std::forward_iterator_tag;
390 
391       using pointer = __conditional_t<__constant_iterators,
392 				      const value_type*, value_type*>;
393 
394       using reference = __conditional_t<__constant_iterators,
395 					const value_type&, value_type&>;
396 
397       _Node_iterator() = default;
398 
399       explicit
400       _Node_iterator(__node_type* __p) noexcept
401       : __base_type(__p) { }
402 
403       reference
404       operator*() const noexcept
405       { return this->_M_cur->_M_v(); }
406 
407       pointer
408       operator->() const noexcept
409       { return this->_M_cur->_M_valptr(); }
410 
411       _Node_iterator&
412       operator++() noexcept
413       {
414 	this->_M_incr();
415 	return *this;
416       }
417 
418       _Node_iterator
419       operator++(int) noexcept
420       {
421 	_Node_iterator __tmp(*this);
422 	this->_M_incr();
423 	return __tmp;
424       }
425     };
426 
427   /// Node const_iterators, used to iterate through all the hashtable.
428   template<typename _Value, bool __constant_iterators, bool __cache>
429     struct _Node_const_iterator
430     : public _Node_iterator_base<_Value, __cache>
431     {
432     private:
433       using __base_type = _Node_iterator_base<_Value, __cache>;
434       using __node_type = typename __base_type::__node_type;
435 
436     public:
437       typedef _Value					value_type;
438       typedef std::ptrdiff_t				difference_type;
439       typedef std::forward_iterator_tag			iterator_category;
440 
441       typedef const value_type*				pointer;
442       typedef const value_type&				reference;
443 
444       _Node_const_iterator() = default;
445 
446       explicit
447       _Node_const_iterator(__node_type* __p) noexcept
448       : __base_type(__p) { }
449 
450       _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
451 			   __cache>& __x) noexcept
452       : __base_type(__x._M_cur) { }
453 
454       reference
455       operator*() const noexcept
456       { return this->_M_cur->_M_v(); }
457 
458       pointer
459       operator->() const noexcept
460       { return this->_M_cur->_M_valptr(); }
461 
462       _Node_const_iterator&
463       operator++() noexcept
464       {
465 	this->_M_incr();
466 	return *this;
467       }
468 
469       _Node_const_iterator
470       operator++(int) noexcept
471       {
472 	_Node_const_iterator __tmp(*this);
473 	this->_M_incr();
474 	return __tmp;
475       }
476     };
477 
478   // Many of class template _Hashtable's template parameters are policy
479   // classes.  These are defaults for the policies.
480 
481   /// Default range hashing function: use division to fold a large number
482   /// into the range [0, N).
483   struct _Mod_range_hashing
484   {
485     typedef std::size_t first_argument_type;
486     typedef std::size_t second_argument_type;
487     typedef std::size_t result_type;
488 
489     result_type
490     operator()(first_argument_type __num,
491 	       second_argument_type __den) const noexcept
492     { return __num % __den; }
493   };
494 
495   /// Default ranged hash function H.  In principle it should be a
496   /// function object composed from objects of type H1 and H2 such that
497   /// h(k, N) = h2(h1(k), N), but that would mean making extra copies of
498   /// h1 and h2.  So instead we'll just use a tag to tell class template
499   /// hashtable to do that composition.
500   struct _Default_ranged_hash { };
501 
502   /// Default value for rehash policy.  Bucket size is (usually) the
503   /// smallest prime that keeps the load factor small enough.
504   struct _Prime_rehash_policy
505   {
506     using __has_load_factor = true_type;
507 
508     _Prime_rehash_policy(float __z = 1.0) noexcept
509     : _M_max_load_factor(__z), _M_next_resize(0) { }
510 
511     float
512     max_load_factor() const noexcept
513     { return _M_max_load_factor; }
514 
515     // Return a bucket size no smaller than n.
516     std::size_t
517     _M_next_bkt(std::size_t __n) const;
518 
519     // Return a bucket count appropriate for n elements
520     std::size_t
521     _M_bkt_for_elements(std::size_t __n) const
522     { return __builtin_ceil(__n / (double)_M_max_load_factor); }
523 
524     // __n_bkt is current bucket count, __n_elt is current element count,
525     // and __n_ins is number of elements to be inserted.  Do we need to
526     // increase bucket count?  If so, return make_pair(true, n), where n
527     // is the new bucket count.  If not, return make_pair(false, 0).
528     std::pair<bool, std::size_t>
529     _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
530 		   std::size_t __n_ins) const;
531 
532     typedef std::size_t _State;
533 
534     _State
535     _M_state() const
536     { return _M_next_resize; }
537 
538     void
539     _M_reset() noexcept
540     { _M_next_resize = 0; }
541 
542     void
543     _M_reset(_State __state)
544     { _M_next_resize = __state; }
545 
546     static const std::size_t _S_growth_factor = 2;
547 
548     float		_M_max_load_factor;
549     mutable std::size_t	_M_next_resize;
550   };
551 
552   /// Range hashing function assuming that second arg is a power of 2.
553   struct _Mask_range_hashing
554   {
555     typedef std::size_t first_argument_type;
556     typedef std::size_t second_argument_type;
557     typedef std::size_t result_type;
558 
559     result_type
560     operator()(first_argument_type __num,
561 	       second_argument_type __den) const noexcept
562     { return __num & (__den - 1); }
563   };
564 
565   /// Compute closest power of 2 not less than __n
566   inline std::size_t
567   __clp2(std::size_t __n) noexcept
568   {
569     using __gnu_cxx::__int_traits;
570     // Equivalent to return __n ? std::bit_ceil(__n) : 0;
571     if (__n < 2)
572       return __n;
573     const unsigned __lz = sizeof(size_t) > sizeof(long)
574       ? __builtin_clzll(__n - 1ull)
575       : __builtin_clzl(__n - 1ul);
576     // Doing two shifts avoids undefined behaviour when __lz == 0.
577     return (size_t(1) << (__int_traits<size_t>::__digits - __lz - 1)) << 1;
578   }
579 
580   /// Rehash policy providing power of 2 bucket numbers. Avoids modulo
581   /// operations.
582   struct _Power2_rehash_policy
583   {
584     using __has_load_factor = true_type;
585 
586     _Power2_rehash_policy(float __z = 1.0) noexcept
587     : _M_max_load_factor(__z), _M_next_resize(0) { }
588 
589     float
590     max_load_factor() const noexcept
591     { return _M_max_load_factor; }
592 
593     // Return a bucket size no smaller than n (as long as n is not above the
594     // highest power of 2).
595     std::size_t
596     _M_next_bkt(std::size_t __n) noexcept
597     {
598       if (__n == 0)
599 	// Special case on container 1st initialization with 0 bucket count
600 	// hint. We keep _M_next_resize to 0 to make sure that next time we
601 	// want to add an element allocation will take place.
602 	return 1;
603 
604       const auto __max_width = std::min<size_t>(sizeof(size_t), 8);
605       const auto __max_bkt = size_t(1) << (__max_width * __CHAR_BIT__ - 1);
606       std::size_t __res = __clp2(__n);
607 
608       if (__res == 0)
609 	__res = __max_bkt;
610       else if (__res == 1)
611 	// If __res is 1 we force it to 2 to make sure there will be an
612 	// allocation so that nothing need to be stored in the initial
613 	// single bucket
614 	__res = 2;
615 
616       if (__res == __max_bkt)
617 	// Set next resize to the max value so that we never try to rehash again
618 	// as we already reach the biggest possible bucket number.
619 	// Note that it might result in max_load_factor not being respected.
620 	_M_next_resize = size_t(-1);
621       else
622 	_M_next_resize
623 	  = __builtin_floor(__res * (double)_M_max_load_factor);
624 
625       return __res;
626     }
627 
628     // Return a bucket count appropriate for n elements
629     std::size_t
630     _M_bkt_for_elements(std::size_t __n) const noexcept
631     { return __builtin_ceil(__n / (double)_M_max_load_factor); }
632 
633     // __n_bkt is current bucket count, __n_elt is current element count,
634     // and __n_ins is number of elements to be inserted.  Do we need to
635     // increase bucket count?  If so, return make_pair(true, n), where n
636     // is the new bucket count.  If not, return make_pair(false, 0).
637     std::pair<bool, std::size_t>
638     _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
639 		   std::size_t __n_ins) noexcept
640     {
641       if (__n_elt + __n_ins > _M_next_resize)
642 	{
643 	  // If _M_next_resize is 0 it means that we have nothing allocated so
644 	  // far and that we start inserting elements. In this case we start
645 	  // with an initial bucket size of 11.
646 	  double __min_bkts
647 	    = std::max<std::size_t>(__n_elt + __n_ins, _M_next_resize ? 0 : 11)
648 	      / (double)_M_max_load_factor;
649 	  if (__min_bkts >= __n_bkt)
650 	    return { true,
651 	      _M_next_bkt(std::max<std::size_t>(__builtin_floor(__min_bkts) + 1,
652 						__n_bkt * _S_growth_factor)) };
653 
654 	  _M_next_resize
655 	    = __builtin_floor(__n_bkt * (double)_M_max_load_factor);
656 	  return { false, 0 };
657 	}
658       else
659 	return { false, 0 };
660     }
661 
662     typedef std::size_t _State;
663 
664     _State
665     _M_state() const noexcept
666     { return _M_next_resize; }
667 
668     void
669     _M_reset() noexcept
670     { _M_next_resize = 0; }
671 
672     void
673     _M_reset(_State __state) noexcept
674     { _M_next_resize = __state; }
675 
676     static const std::size_t _S_growth_factor = 2;
677 
678     float	_M_max_load_factor;
679     std::size_t	_M_next_resize;
680   };
681 
682   // Base classes for std::_Hashtable.  We define these base classes
683   // because in some cases we want to do different things depending on
684   // the value of a policy class.  In some cases the policy class
685   // affects which member functions and nested typedefs are defined;
686   // we handle that by specializing base class templates.  Several of
687   // the base class templates need to access other members of class
688   // template _Hashtable, so we use a variant of the "Curiously
689   // Recurring Template Pattern" (CRTP) technique.
690 
691   /**
692    *  Primary class template _Map_base.
693    *
694    *  If the hashtable has a value type of the form pair<const T1, T2> and
695    *  a key extraction policy (_ExtractKey) that returns the first part
696    *  of the pair, the hashtable gets a mapped_type typedef.  If it
697    *  satisfies those criteria and also has unique keys, then it also
698    *  gets an operator[].
699    */
700   template<typename _Key, typename _Value, typename _Alloc,
701 	   typename _ExtractKey, typename _Equal,
702 	   typename _Hash, typename _RangeHash, typename _Unused,
703 	   typename _RehashPolicy, typename _Traits,
704 	   bool _Unique_keys = _Traits::__unique_keys::value>
705     struct _Map_base { };
706 
707   /// Partial specialization, __unique_keys set to false, std::pair value type.
708   template<typename _Key, typename _Val, typename _Alloc, typename _Equal,
709 	   typename _Hash, typename _RangeHash, typename _Unused,
710 	   typename _RehashPolicy, typename _Traits>
711     struct _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
712 		     _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>
713     {
714       using mapped_type = _Val;
715     };
716 
717   /// Partial specialization, __unique_keys set to true.
718   template<typename _Key, typename _Val, typename _Alloc, typename _Equal,
719 	   typename _Hash, typename _RangeHash, typename _Unused,
720 	   typename _RehashPolicy, typename _Traits>
721     struct _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
722 		     _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>
723     {
724     private:
725       using __hashtable_base = _Hashtable_base<_Key, pair<const _Key, _Val>,
726 					       _Select1st, _Equal, _Hash,
727 					       _RangeHash, _Unused,
728 					       _Traits>;
729 
730       using __hashtable = _Hashtable<_Key, pair<const _Key, _Val>, _Alloc,
731 				     _Select1st, _Equal, _Hash, _RangeHash,
732 				     _Unused, _RehashPolicy, _Traits>;
733 
734       using __hash_code = typename __hashtable_base::__hash_code;
735 
736     public:
737       using key_type = typename __hashtable_base::key_type;
738       using mapped_type = _Val;
739 
740       mapped_type&
741       operator[](const key_type& __k);
742 
743       mapped_type&
744       operator[](key_type&& __k);
745 
746       // _GLIBCXX_RESOLVE_LIB_DEFECTS
747       // DR 761. unordered_map needs an at() member function.
748       mapped_type&
749       at(const key_type& __k)
750       {
751 	auto __ite = static_cast<__hashtable*>(this)->find(__k);
752 	if (!__ite._M_cur)
753 	  __throw_out_of_range(__N("unordered_map::at"));
754 	return __ite->second;
755       }
756 
757       const mapped_type&
758       at(const key_type& __k) const
759       {
760 	auto __ite = static_cast<const __hashtable*>(this)->find(__k);
761 	if (!__ite._M_cur)
762 	  __throw_out_of_range(__N("unordered_map::at"));
763 	return __ite->second;
764       }
765     };
766 
767   template<typename _Key, typename _Val, typename _Alloc, typename _Equal,
768 	   typename _Hash, typename _RangeHash, typename _Unused,
769 	   typename _RehashPolicy, typename _Traits>
770     auto
771     _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
772 	      _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>::
773     operator[](const key_type& __k)
774     -> mapped_type&
775     {
776       __hashtable* __h = static_cast<__hashtable*>(this);
777       __hash_code __code = __h->_M_hash_code(__k);
778       std::size_t __bkt = __h->_M_bucket_index(__code);
779       if (auto __node = __h->_M_find_node(__bkt, __k, __code))
780 	return __node->_M_v().second;
781 
782       typename __hashtable::_Scoped_node __node {
783 	__h,
784 	std::piecewise_construct,
785 	std::tuple<const key_type&>(__k),
786 	std::tuple<>()
787       };
788       auto __pos
789 	= __h->_M_insert_unique_node(__bkt, __code, __node._M_node);
790       __node._M_node = nullptr;
791       return __pos->second;
792     }
793 
794   template<typename _Key, typename _Val, typename _Alloc, typename _Equal,
795 	   typename _Hash, typename _RangeHash, typename _Unused,
796 	   typename _RehashPolicy, typename _Traits>
797     auto
798     _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
799 	      _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>::
800     operator[](key_type&& __k)
801     -> mapped_type&
802     {
803       __hashtable* __h = static_cast<__hashtable*>(this);
804       __hash_code __code = __h->_M_hash_code(__k);
805       std::size_t __bkt = __h->_M_bucket_index(__code);
806       if (auto __node = __h->_M_find_node(__bkt, __k, __code))
807 	return __node->_M_v().second;
808 
809       typename __hashtable::_Scoped_node __node {
810 	__h,
811 	std::piecewise_construct,
812 	std::forward_as_tuple(std::move(__k)),
813 	std::tuple<>()
814       };
815       auto __pos
816 	= __h->_M_insert_unique_node(__bkt, __code, __node._M_node);
817       __node._M_node = nullptr;
818       return __pos->second;
819     }
820 
821   // Partial specialization for unordered_map<const T, U>, see PR 104174.
822   template<typename _Key, typename _Val, typename _Alloc, typename _Equal,
823 	   typename _Hash, typename _RangeHash, typename _Unused,
824 	   typename _RehashPolicy, typename _Traits, bool __uniq>
825     struct _Map_base<const _Key, pair<const _Key, _Val>,
826 		     _Alloc, _Select1st, _Equal, _Hash,
827 		     _RangeHash, _Unused, _RehashPolicy, _Traits, __uniq>
828     : _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal, _Hash,
829 		_RangeHash, _Unused, _RehashPolicy, _Traits, __uniq>
830     { };
831 
832   /**
833    *  Primary class template _Insert_base.
834    *
835    *  Defines @c insert member functions appropriate to all _Hashtables.
836    */
837   template<typename _Key, typename _Value, typename _Alloc,
838 	   typename _ExtractKey, typename _Equal,
839 	   typename _Hash, typename _RangeHash, typename _Unused,
840 	   typename _RehashPolicy, typename _Traits>
841     struct _Insert_base
842     {
843     protected:
844       using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey,
845 					       _Equal, _Hash, _RangeHash,
846 					       _Unused, _Traits>;
847 
848       using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
849 				     _Hash, _RangeHash,
850 				     _Unused, _RehashPolicy, _Traits>;
851 
852       using __hash_cached = typename _Traits::__hash_cached;
853       using __constant_iterators = typename _Traits::__constant_iterators;
854 
855       using __hashtable_alloc = _Hashtable_alloc<
856 	__alloc_rebind<_Alloc, _Hash_node<_Value,
857 					  __hash_cached::value>>>;
858 
859       using value_type = typename __hashtable_base::value_type;
860       using size_type = typename __hashtable_base::size_type;
861 
862       using __unique_keys = typename _Traits::__unique_keys;
863       using __node_alloc_type = typename __hashtable_alloc::__node_alloc_type;
864       using __node_gen_type = _AllocNode<__node_alloc_type>;
865 
866       __hashtable&
867       _M_conjure_hashtable()
868       { return *(static_cast<__hashtable*>(this)); }
869 
870       template<typename _InputIterator, typename _NodeGetter>
871 	void
872 	_M_insert_range(_InputIterator __first, _InputIterator __last,
873 			const _NodeGetter&, true_type __uks);
874 
875       template<typename _InputIterator, typename _NodeGetter>
876 	void
877 	_M_insert_range(_InputIterator __first, _InputIterator __last,
878 			const _NodeGetter&, false_type __uks);
879 
880     public:
881       using iterator = _Node_iterator<_Value, __constant_iterators::value,
882 				      __hash_cached::value>;
883 
884       using const_iterator = _Node_const_iterator<_Value,
885 						  __constant_iterators::value,
886 						  __hash_cached::value>;
887 
888       using __ireturn_type = __conditional_t<__unique_keys::value,
889 					     std::pair<iterator, bool>,
890 					     iterator>;
891 
892       __ireturn_type
893       insert(const value_type& __v)
894       {
895 	__hashtable& __h = _M_conjure_hashtable();
896 	__node_gen_type __node_gen(__h);
897 	return __h._M_insert(__v, __node_gen, __unique_keys{});
898       }
899 
900       iterator
901       insert(const_iterator __hint, const value_type& __v)
902       {
903 	__hashtable& __h = _M_conjure_hashtable();
904 	__node_gen_type __node_gen(__h);
905 	return __h._M_insert(__hint, __v, __node_gen, __unique_keys{});
906       }
907 
908       template<typename _KType, typename... _Args>
909 	std::pair<iterator, bool>
910 	try_emplace(const_iterator, _KType&& __k, _Args&&... __args)
911 	{
912 	  __hashtable& __h = _M_conjure_hashtable();
913 	  auto __code = __h._M_hash_code(__k);
914 	  std::size_t __bkt = __h._M_bucket_index(__code);
915 	  if (auto __node = __h._M_find_node(__bkt, __k, __code))
916 	    return { iterator(__node), false };
917 
918 	  typename __hashtable::_Scoped_node __node {
919 	    &__h,
920 	    std::piecewise_construct,
921 	    std::forward_as_tuple(std::forward<_KType>(__k)),
922 	    std::forward_as_tuple(std::forward<_Args>(__args)...)
923 	    };
924 	  auto __it
925 	    = __h._M_insert_unique_node(__bkt, __code, __node._M_node);
926 	  __node._M_node = nullptr;
927 	  return { __it, true };
928 	}
929 
930       void
931       insert(initializer_list<value_type> __l)
932       { this->insert(__l.begin(), __l.end()); }
933 
934       template<typename _InputIterator>
935 	void
936 	insert(_InputIterator __first, _InputIterator __last)
937 	{
938 	  __hashtable& __h = _M_conjure_hashtable();
939 	  __node_gen_type __node_gen(__h);
940 	  return _M_insert_range(__first, __last, __node_gen, __unique_keys{});
941 	}
942     };
943 
944   template<typename _Key, typename _Value, typename _Alloc,
945 	   typename _ExtractKey, typename _Equal,
946 	   typename _Hash, typename _RangeHash, typename _Unused,
947 	   typename _RehashPolicy, typename _Traits>
948     template<typename _InputIterator, typename _NodeGetter>
949       void
950       _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
951 		   _Hash, _RangeHash, _Unused,
952 		   _RehashPolicy, _Traits>::
953       _M_insert_range(_InputIterator __first, _InputIterator __last,
954 		      const _NodeGetter& __node_gen, true_type __uks)
955       {
956 	__hashtable& __h = _M_conjure_hashtable();
957 	for (; __first != __last; ++__first)
958 	  __h._M_insert(*__first, __node_gen, __uks);
959       }
960 
961   template<typename _Key, typename _Value, typename _Alloc,
962 	   typename _ExtractKey, typename _Equal,
963 	   typename _Hash, typename _RangeHash, typename _Unused,
964 	   typename _RehashPolicy, typename _Traits>
965     template<typename _InputIterator, typename _NodeGetter>
966       void
967       _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
968 		   _Hash, _RangeHash, _Unused,
969 		   _RehashPolicy, _Traits>::
970       _M_insert_range(_InputIterator __first, _InputIterator __last,
971 		      const _NodeGetter& __node_gen, false_type __uks)
972       {
973 	using __rehash_type = typename __hashtable::__rehash_type;
974 	using __rehash_state = typename __hashtable::__rehash_state;
975 	using pair_type = std::pair<bool, std::size_t>;
976 
977 	size_type __n_elt = __detail::__distance_fw(__first, __last);
978 	if (__n_elt == 0)
979 	  return;
980 
981 	__hashtable& __h = _M_conjure_hashtable();
982 	__rehash_type& __rehash = __h._M_rehash_policy;
983 	const __rehash_state& __saved_state = __rehash._M_state();
984 	pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
985 							__h._M_element_count,
986 							__n_elt);
987 
988 	if (__do_rehash.first)
989 	  __h._M_rehash(__do_rehash.second, __saved_state);
990 
991 	for (; __first != __last; ++__first)
992 	  __h._M_insert(*__first, __node_gen, __uks);
993       }
994 
995   /**
996    *  Primary class template _Insert.
997    *
998    *  Defines @c insert member functions that depend on _Hashtable policies,
999    *  via partial specializations.
1000    */
1001   template<typename _Key, typename _Value, typename _Alloc,
1002 	   typename _ExtractKey, typename _Equal,
1003 	   typename _Hash, typename _RangeHash, typename _Unused,
1004 	   typename _RehashPolicy, typename _Traits,
1005 	   bool _Constant_iterators = _Traits::__constant_iterators::value>
1006     struct _Insert;
1007 
1008   /// Specialization.
1009   template<typename _Key, typename _Value, typename _Alloc,
1010 	   typename _ExtractKey, typename _Equal,
1011 	   typename _Hash, typename _RangeHash, typename _Unused,
1012 	   typename _RehashPolicy, typename _Traits>
1013     struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1014 		   _Hash, _RangeHash, _Unused,
1015 		   _RehashPolicy, _Traits, true>
1016     : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1017 			  _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>
1018     {
1019       using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
1020 				       _Equal, _Hash, _RangeHash, _Unused,
1021 				       _RehashPolicy, _Traits>;
1022 
1023       using value_type = typename __base_type::value_type;
1024       using iterator = typename __base_type::iterator;
1025       using const_iterator =  typename __base_type::const_iterator;
1026       using __ireturn_type = typename __base_type::__ireturn_type;
1027 
1028       using __unique_keys = typename __base_type::__unique_keys;
1029       using __hashtable = typename __base_type::__hashtable;
1030       using __node_gen_type = typename __base_type::__node_gen_type;
1031 
1032       using __base_type::insert;
1033 
1034       __ireturn_type
1035       insert(value_type&& __v)
1036       {
1037 	__hashtable& __h = this->_M_conjure_hashtable();
1038 	__node_gen_type __node_gen(__h);
1039 	return __h._M_insert(std::move(__v), __node_gen, __unique_keys{});
1040       }
1041 
1042       iterator
1043       insert(const_iterator __hint, value_type&& __v)
1044       {
1045 	__hashtable& __h = this->_M_conjure_hashtable();
1046 	__node_gen_type __node_gen(__h);
1047 	return __h._M_insert(__hint, std::move(__v), __node_gen,
1048 			     __unique_keys{});
1049       }
1050     };
1051 
1052   /// Specialization.
1053   template<typename _Key, typename _Value, typename _Alloc,
1054 	   typename _ExtractKey, typename _Equal,
1055 	   typename _Hash, typename _RangeHash, typename _Unused,
1056 	   typename _RehashPolicy, typename _Traits>
1057     struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1058 		   _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>
1059     : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1060 			  _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>
1061     {
1062       using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
1063 				       _Equal, _Hash, _RangeHash, _Unused,
1064 				       _RehashPolicy, _Traits>;
1065       using value_type = typename __base_type::value_type;
1066       using iterator = typename __base_type::iterator;
1067       using const_iterator =  typename __base_type::const_iterator;
1068 
1069       using __unique_keys = typename __base_type::__unique_keys;
1070       using __hashtable = typename __base_type::__hashtable;
1071       using __ireturn_type = typename __base_type::__ireturn_type;
1072 
1073       using __base_type::insert;
1074 
1075       template<typename _Pair>
1076 	using __is_cons = std::is_constructible<value_type, _Pair&&>;
1077 
1078       template<typename _Pair>
1079 	using _IFcons = std::enable_if<__is_cons<_Pair>::value>;
1080 
1081       template<typename _Pair>
1082 	using _IFconsp = typename _IFcons<_Pair>::type;
1083 
1084       template<typename _Pair, typename = _IFconsp<_Pair>>
1085 	__ireturn_type
1086 	insert(_Pair&& __v)
1087 	{
1088 	  __hashtable& __h = this->_M_conjure_hashtable();
1089 	  return __h._M_emplace(__unique_keys{}, std::forward<_Pair>(__v));
1090 	}
1091 
1092       template<typename _Pair, typename = _IFconsp<_Pair>>
1093 	iterator
1094 	insert(const_iterator __hint, _Pair&& __v)
1095 	{
1096 	  __hashtable& __h = this->_M_conjure_hashtable();
1097 	  return __h._M_emplace(__hint, __unique_keys{},
1098 				std::forward<_Pair>(__v));
1099 	}
1100    };
1101 
1102   template<typename _Policy>
1103     using __has_load_factor = typename _Policy::__has_load_factor;
1104 
1105   /**
1106    *  Primary class template  _Rehash_base.
1107    *
1108    *  Give hashtable the max_load_factor functions and reserve iff the
1109    *  rehash policy supports it.
1110   */
1111   template<typename _Key, typename _Value, typename _Alloc,
1112 	   typename _ExtractKey, typename _Equal,
1113 	   typename _Hash, typename _RangeHash, typename _Unused,
1114 	   typename _RehashPolicy, typename _Traits,
1115 	   typename =
1116 	     __detected_or_t<false_type, __has_load_factor, _RehashPolicy>>
1117     struct _Rehash_base;
1118 
1119   /// Specialization when rehash policy doesn't provide load factor management.
1120   template<typename _Key, typename _Value, typename _Alloc,
1121 	   typename _ExtractKey, typename _Equal,
1122 	   typename _Hash, typename _RangeHash, typename _Unused,
1123 	   typename _RehashPolicy, typename _Traits>
1124     struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1125 			_Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
1126 			false_type /* Has load factor */>
1127     {
1128     };
1129 
1130   /// Specialization when rehash policy provide load factor management.
1131   template<typename _Key, typename _Value, typename _Alloc,
1132 	   typename _ExtractKey, typename _Equal,
1133 	   typename _Hash, typename _RangeHash, typename _Unused,
1134 	   typename _RehashPolicy, typename _Traits>
1135     struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1136 			_Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
1137 			true_type /* Has load factor */>
1138     {
1139     private:
1140       using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
1141 				     _Equal, _Hash, _RangeHash, _Unused,
1142 				     _RehashPolicy, _Traits>;
1143 
1144     public:
1145       float
1146       max_load_factor() const noexcept
1147       {
1148 	const __hashtable* __this = static_cast<const __hashtable*>(this);
1149 	return __this->__rehash_policy().max_load_factor();
1150       }
1151 
1152       void
1153       max_load_factor(float __z)
1154       {
1155 	__hashtable* __this = static_cast<__hashtable*>(this);
1156 	__this->__rehash_policy(_RehashPolicy(__z));
1157       }
1158 
1159       void
1160       reserve(std::size_t __n)
1161       {
1162 	__hashtable* __this = static_cast<__hashtable*>(this);
1163 	__this->rehash(__this->__rehash_policy()._M_bkt_for_elements(__n));
1164       }
1165     };
1166 
1167   /**
1168    *  Primary class template _Hashtable_ebo_helper.
1169    *
1170    *  Helper class using EBO when it is not forbidden (the type is not
1171    *  final) and when it is worth it (the type is empty.)
1172    */
1173   template<int _Nm, typename _Tp,
1174 	   bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
1175     struct _Hashtable_ebo_helper;
1176 
1177   /// Specialization using EBO.
1178   template<int _Nm, typename _Tp>
1179     struct _Hashtable_ebo_helper<_Nm, _Tp, true>
1180     : private _Tp
1181     {
1182       _Hashtable_ebo_helper() noexcept(noexcept(_Tp())) : _Tp() { }
1183 
1184       template<typename _OtherTp>
1185 	_Hashtable_ebo_helper(_OtherTp&& __tp)
1186 	: _Tp(std::forward<_OtherTp>(__tp))
1187 	{ }
1188 
1189       const _Tp& _M_cget() const { return static_cast<const _Tp&>(*this); }
1190       _Tp& _M_get() { return static_cast<_Tp&>(*this); }
1191     };
1192 
1193   /// Specialization not using EBO.
1194   template<int _Nm, typename _Tp>
1195     struct _Hashtable_ebo_helper<_Nm, _Tp, false>
1196     {
1197       _Hashtable_ebo_helper() = default;
1198 
1199       template<typename _OtherTp>
1200 	_Hashtable_ebo_helper(_OtherTp&& __tp)
1201 	: _M_tp(std::forward<_OtherTp>(__tp))
1202 	{ }
1203 
1204       const _Tp& _M_cget() const { return _M_tp; }
1205       _Tp& _M_get() { return _M_tp; }
1206 
1207     private:
1208       _Tp _M_tp{};
1209     };
1210 
1211   /**
1212    *  Primary class template _Local_iterator_base.
1213    *
1214    *  Base class for local iterators, used to iterate within a bucket
1215    *  but not between buckets.
1216    */
1217   template<typename _Key, typename _Value, typename _ExtractKey,
1218 	   typename _Hash, typename _RangeHash, typename _Unused,
1219 	   bool __cache_hash_code>
1220     struct _Local_iterator_base;
1221 
1222   /**
1223    *  Primary class template _Hash_code_base.
1224    *
1225    *  Encapsulates two policy issues that aren't quite orthogonal.
1226    *   (1) the difference between using a ranged hash function and using
1227    *       the combination of a hash function and a range-hashing function.
1228    *       In the former case we don't have such things as hash codes, so
1229    *       we have a dummy type as placeholder.
1230    *   (2) Whether or not we cache hash codes.  Caching hash codes is
1231    *       meaningless if we have a ranged hash function.
1232    *
1233    *  We also put the key extraction objects here, for convenience.
1234    *  Each specialization derives from one or more of the template
1235    *  parameters to benefit from Ebo. This is important as this type
1236    *  is inherited in some cases by the _Local_iterator_base type used
1237    *  to implement local_iterator and const_local_iterator. As with
1238    *  any iterator type we prefer to make it as small as possible.
1239    */
1240   template<typename _Key, typename _Value, typename _ExtractKey,
1241 	   typename _Hash, typename _RangeHash, typename _Unused,
1242 	   bool __cache_hash_code>
1243     struct _Hash_code_base
1244     : private _Hashtable_ebo_helper<1, _Hash>
1245     {
1246     private:
1247       using __ebo_hash = _Hashtable_ebo_helper<1, _Hash>;
1248 
1249       // Gives the local iterator implementation access to _M_bucket_index().
1250       friend struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1251 					 _Hash, _RangeHash, _Unused, false>;
1252 
1253     public:
1254       typedef _Hash					hasher;
1255 
1256       hasher
1257       hash_function() const
1258       { return _M_hash(); }
1259 
1260     protected:
1261       typedef std::size_t 				__hash_code;
1262 
1263       // We need the default constructor for the local iterators and _Hashtable
1264       // default constructor.
1265       _Hash_code_base() = default;
1266 
1267       _Hash_code_base(const _Hash& __hash) : __ebo_hash(__hash) { }
1268 
1269       __hash_code
1270       _M_hash_code(const _Key& __k) const
1271       {
1272 	static_assert(__is_invocable<const _Hash&, const _Key&>{},
1273 	    "hash function must be invocable with an argument of key type");
1274 	return _M_hash()(__k);
1275       }
1276 
1277       template<typename _Kt>
1278 	__hash_code
1279 	_M_hash_code_tr(const _Kt& __k) const
1280 	{
1281 	  static_assert(__is_invocable<const _Hash&, const _Kt&>{},
1282 	    "hash function must be invocable with an argument of key type");
1283 	  return _M_hash()(__k);
1284 	}
1285 
1286       __hash_code
1287       _M_hash_code(const _Hash_node_value<_Value, false>& __n) const
1288       { return _M_hash_code(_ExtractKey{}(__n._M_v())); }
1289 
1290       __hash_code
1291       _M_hash_code(const _Hash_node_value<_Value, true>& __n) const
1292       { return __n._M_hash_code; }
1293 
1294       std::size_t
1295       _M_bucket_index(__hash_code __c, std::size_t __bkt_count) const
1296       { return _RangeHash{}(__c, __bkt_count); }
1297 
1298       std::size_t
1299       _M_bucket_index(const _Hash_node_value<_Value, false>& __n,
1300 		      std::size_t __bkt_count) const
1301 	noexcept( noexcept(declval<const _Hash&>()(declval<const _Key&>()))
1302 		  && noexcept(declval<const _RangeHash&>()((__hash_code)0,
1303 							   (std::size_t)0)) )
1304       {
1305 	return _RangeHash{}(_M_hash_code(_ExtractKey{}(__n._M_v())),
1306 			    __bkt_count);
1307       }
1308 
1309       std::size_t
1310       _M_bucket_index(const _Hash_node_value<_Value, true>& __n,
1311 		      std::size_t __bkt_count) const
1312 	noexcept( noexcept(declval<const _RangeHash&>()((__hash_code)0,
1313 							(std::size_t)0)) )
1314       { return _RangeHash{}(__n._M_hash_code, __bkt_count); }
1315 
1316       void
1317       _M_store_code(_Hash_node_code_cache<false>&, __hash_code) const
1318       { }
1319 
1320       void
1321       _M_copy_code(_Hash_node_code_cache<false>&,
1322 		   const _Hash_node_code_cache<false>&) const
1323       { }
1324 
1325       void
1326       _M_store_code(_Hash_node_code_cache<true>& __n, __hash_code __c) const
1327       { __n._M_hash_code = __c; }
1328 
1329       void
1330       _M_copy_code(_Hash_node_code_cache<true>& __to,
1331 		   const _Hash_node_code_cache<true>& __from) const
1332       { __to._M_hash_code = __from._M_hash_code; }
1333 
1334       void
1335       _M_swap(_Hash_code_base& __x)
1336       { std::swap(__ebo_hash::_M_get(), __x.__ebo_hash::_M_get()); }
1337 
1338       const _Hash&
1339       _M_hash() const { return __ebo_hash::_M_cget(); }
1340     };
1341 
1342   /// Partial specialization used when nodes contain a cached hash code.
1343   template<typename _Key, typename _Value, typename _ExtractKey,
1344 	   typename _Hash, typename _RangeHash, typename _Unused>
1345     struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1346 				_Hash, _RangeHash, _Unused, true>
1347     : public _Node_iterator_base<_Value, true>
1348     {
1349     protected:
1350       using __base_node_iter = _Node_iterator_base<_Value, true>;
1351       using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1352 					      _Hash, _RangeHash, _Unused, true>;
1353 
1354       _Local_iterator_base() = default;
1355       _Local_iterator_base(const __hash_code_base&,
1356 			   _Hash_node<_Value, true>* __p,
1357 			   std::size_t __bkt, std::size_t __bkt_count)
1358       : __base_node_iter(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
1359       { }
1360 
1361       void
1362       _M_incr()
1363       {
1364 	__base_node_iter::_M_incr();
1365 	if (this->_M_cur)
1366 	  {
1367 	    std::size_t __bkt
1368 	      = _RangeHash{}(this->_M_cur->_M_hash_code, _M_bucket_count);
1369 	    if (__bkt != _M_bucket)
1370 	      this->_M_cur = nullptr;
1371 	  }
1372       }
1373 
1374       std::size_t _M_bucket;
1375       std::size_t _M_bucket_count;
1376 
1377     public:
1378       std::size_t
1379       _M_get_bucket() const { return _M_bucket; }  // for debug mode
1380     };
1381 
1382   // Uninitialized storage for a _Hash_code_base.
1383   // This type is DefaultConstructible and Assignable even if the
1384   // _Hash_code_base type isn't, so that _Local_iterator_base<..., false>
1385   // can be DefaultConstructible and Assignable.
1386   template<typename _Tp, bool _IsEmpty = std::is_empty<_Tp>::value>
1387     struct _Hash_code_storage
1388     {
1389       __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
1390 
1391       _Tp*
1392       _M_h() { return _M_storage._M_ptr(); }
1393 
1394       const _Tp*
1395       _M_h() const { return _M_storage._M_ptr(); }
1396     };
1397 
1398   // Empty partial specialization for empty _Hash_code_base types.
1399   template<typename _Tp>
1400     struct _Hash_code_storage<_Tp, true>
1401     {
1402       static_assert( std::is_empty<_Tp>::value, "Type must be empty" );
1403 
1404       // As _Tp is an empty type there will be no bytes written/read through
1405       // the cast pointer, so no strict-aliasing violation.
1406       _Tp*
1407       _M_h() { return reinterpret_cast<_Tp*>(this); }
1408 
1409       const _Tp*
1410       _M_h() const { return reinterpret_cast<const _Tp*>(this); }
1411     };
1412 
1413   template<typename _Key, typename _Value, typename _ExtractKey,
1414 	   typename _Hash, typename _RangeHash, typename _Unused>
1415     using __hash_code_for_local_iter
1416       = _Hash_code_storage<_Hash_code_base<_Key, _Value, _ExtractKey,
1417 					   _Hash, _RangeHash, _Unused, false>>;
1418 
1419   // Partial specialization used when hash codes are not cached
1420   template<typename _Key, typename _Value, typename _ExtractKey,
1421 	   typename _Hash, typename _RangeHash, typename _Unused>
1422     struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1423 				_Hash, _RangeHash, _Unused, false>
1424     : __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _Hash, _RangeHash,
1425 				 _Unused>
1426     , _Node_iterator_base<_Value, false>
1427     {
1428     protected:
1429       using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1430 					     _Hash, _RangeHash, _Unused, false>;
1431       using __node_iter_base = _Node_iterator_base<_Value, false>;
1432 
1433       _Local_iterator_base() : _M_bucket_count(-1) { }
1434 
1435       _Local_iterator_base(const __hash_code_base& __base,
1436 			   _Hash_node<_Value, false>* __p,
1437 			   std::size_t __bkt, std::size_t __bkt_count)
1438       : __node_iter_base(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
1439       { _M_init(__base); }
1440 
1441       ~_Local_iterator_base()
1442       {
1443 	if (_M_bucket_count != size_t(-1))
1444 	  _M_destroy();
1445       }
1446 
1447       _Local_iterator_base(const _Local_iterator_base& __iter)
1448       : __node_iter_base(__iter._M_cur), _M_bucket(__iter._M_bucket)
1449       , _M_bucket_count(__iter._M_bucket_count)
1450       {
1451 	if (_M_bucket_count != size_t(-1))
1452 	  _M_init(*__iter._M_h());
1453       }
1454 
1455       _Local_iterator_base&
1456       operator=(const _Local_iterator_base& __iter)
1457       {
1458 	if (_M_bucket_count != -1)
1459 	  _M_destroy();
1460 	this->_M_cur = __iter._M_cur;
1461 	_M_bucket = __iter._M_bucket;
1462 	_M_bucket_count = __iter._M_bucket_count;
1463 	if (_M_bucket_count != -1)
1464 	  _M_init(*__iter._M_h());
1465 	return *this;
1466       }
1467 
1468       void
1469       _M_incr()
1470       {
1471 	__node_iter_base::_M_incr();
1472 	if (this->_M_cur)
1473 	  {
1474 	    std::size_t __bkt = this->_M_h()->_M_bucket_index(*this->_M_cur,
1475 							      _M_bucket_count);
1476 	    if (__bkt != _M_bucket)
1477 	      this->_M_cur = nullptr;
1478 	  }
1479       }
1480 
1481       std::size_t _M_bucket;
1482       std::size_t _M_bucket_count;
1483 
1484       void
1485       _M_init(const __hash_code_base& __base)
1486       { ::new(this->_M_h()) __hash_code_base(__base); }
1487 
1488       void
1489       _M_destroy() { this->_M_h()->~__hash_code_base(); }
1490 
1491     public:
1492       std::size_t
1493       _M_get_bucket() const { return _M_bucket; }  // for debug mode
1494     };
1495 
1496   /// local iterators
1497   template<typename _Key, typename _Value, typename _ExtractKey,
1498 	   typename _Hash, typename _RangeHash, typename _Unused,
1499 	   bool __constant_iterators, bool __cache>
1500     struct _Local_iterator
1501     : public _Local_iterator_base<_Key, _Value, _ExtractKey,
1502 				  _Hash, _RangeHash, _Unused, __cache>
1503     {
1504     private:
1505       using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1506 					   _Hash, _RangeHash, _Unused, __cache>;
1507       using __hash_code_base = typename __base_type::__hash_code_base;
1508 
1509     public:
1510       using value_type = _Value;
1511       using pointer = __conditional_t<__constant_iterators,
1512 				      const value_type*, value_type*>;
1513       using reference = __conditional_t<__constant_iterators,
1514 					const value_type&, value_type&>;
1515       using difference_type = ptrdiff_t;
1516       using iterator_category = forward_iterator_tag;
1517 
1518       _Local_iterator() = default;
1519 
1520       _Local_iterator(const __hash_code_base& __base,
1521 		      _Hash_node<_Value, __cache>* __n,
1522 		      std::size_t __bkt, std::size_t __bkt_count)
1523       : __base_type(__base, __n, __bkt, __bkt_count)
1524       { }
1525 
1526       reference
1527       operator*() const
1528       { return this->_M_cur->_M_v(); }
1529 
1530       pointer
1531       operator->() const
1532       { return this->_M_cur->_M_valptr(); }
1533 
1534       _Local_iterator&
1535       operator++()
1536       {
1537 	this->_M_incr();
1538 	return *this;
1539       }
1540 
1541       _Local_iterator
1542       operator++(int)
1543       {
1544 	_Local_iterator __tmp(*this);
1545 	this->_M_incr();
1546 	return __tmp;
1547       }
1548     };
1549 
1550   /// local const_iterators
1551   template<typename _Key, typename _Value, typename _ExtractKey,
1552 	   typename _Hash, typename _RangeHash, typename _Unused,
1553 	   bool __constant_iterators, bool __cache>
1554     struct _Local_const_iterator
1555     : public _Local_iterator_base<_Key, _Value, _ExtractKey,
1556 				  _Hash, _RangeHash, _Unused, __cache>
1557     {
1558     private:
1559       using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1560 					   _Hash, _RangeHash, _Unused, __cache>;
1561       using __hash_code_base = typename __base_type::__hash_code_base;
1562 
1563     public:
1564       typedef _Value					value_type;
1565       typedef const value_type*				pointer;
1566       typedef const value_type&				reference;
1567       typedef std::ptrdiff_t				difference_type;
1568       typedef std::forward_iterator_tag			iterator_category;
1569 
1570       _Local_const_iterator() = default;
1571 
1572       _Local_const_iterator(const __hash_code_base& __base,
1573 			    _Hash_node<_Value, __cache>* __n,
1574 			    std::size_t __bkt, std::size_t __bkt_count)
1575       : __base_type(__base, __n, __bkt, __bkt_count)
1576       { }
1577 
1578       _Local_const_iterator(const _Local_iterator<_Key, _Value, _ExtractKey,
1579 						  _Hash, _RangeHash, _Unused,
1580 						  __constant_iterators,
1581 						  __cache>& __x)
1582       : __base_type(__x)
1583       { }
1584 
1585       reference
1586       operator*() const
1587       { return this->_M_cur->_M_v(); }
1588 
1589       pointer
1590       operator->() const
1591       { return this->_M_cur->_M_valptr(); }
1592 
1593       _Local_const_iterator&
1594       operator++()
1595       {
1596 	this->_M_incr();
1597 	return *this;
1598       }
1599 
1600       _Local_const_iterator
1601       operator++(int)
1602       {
1603 	_Local_const_iterator __tmp(*this);
1604 	this->_M_incr();
1605 	return __tmp;
1606       }
1607     };
1608 
1609   /**
1610    *  Primary class template _Hashtable_base.
1611    *
1612    *  Helper class adding management of _Equal functor to
1613    *  _Hash_code_base type.
1614    *
1615    *  Base class templates are:
1616    *    - __detail::_Hash_code_base
1617    *    - __detail::_Hashtable_ebo_helper
1618    */
1619   template<typename _Key, typename _Value, typename _ExtractKey,
1620 	   typename _Equal, typename _Hash, typename _RangeHash,
1621 	   typename _Unused, typename _Traits>
1622     struct _Hashtable_base
1623     : public _Hash_code_base<_Key, _Value, _ExtractKey, _Hash, _RangeHash,
1624 			     _Unused, _Traits::__hash_cached::value>,
1625       private _Hashtable_ebo_helper<0, _Equal>
1626     {
1627     public:
1628       typedef _Key					key_type;
1629       typedef _Value					value_type;
1630       typedef _Equal					key_equal;
1631       typedef std::size_t				size_type;
1632       typedef std::ptrdiff_t				difference_type;
1633 
1634       using __traits_type = _Traits;
1635       using __hash_cached = typename __traits_type::__hash_cached;
1636 
1637       using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1638 					       _Hash, _RangeHash, _Unused,
1639 					       __hash_cached::value>;
1640 
1641       using __hash_code = typename __hash_code_base::__hash_code;
1642 
1643     private:
1644       using _EqualEBO = _Hashtable_ebo_helper<0, _Equal>;
1645 
1646       static bool
1647       _S_equals(__hash_code, const _Hash_node_code_cache<false>&)
1648       { return true; }
1649 
1650       static bool
1651       _S_node_equals(const _Hash_node_code_cache<false>&,
1652 		     const _Hash_node_code_cache<false>&)
1653       { return true; }
1654 
1655       static bool
1656       _S_equals(__hash_code __c, const _Hash_node_code_cache<true>& __n)
1657       { return __c == __n._M_hash_code; }
1658 
1659       static bool
1660       _S_node_equals(const _Hash_node_code_cache<true>& __lhn,
1661 		     const _Hash_node_code_cache<true>& __rhn)
1662       { return __lhn._M_hash_code == __rhn._M_hash_code; }
1663 
1664     protected:
1665       _Hashtable_base() = default;
1666 
1667       _Hashtable_base(const _Hash& __hash, const _Equal& __eq)
1668       : __hash_code_base(__hash), _EqualEBO(__eq)
1669       { }
1670 
1671       bool
1672       _M_key_equals(const _Key& __k,
1673 		    const _Hash_node_value<_Value,
1674 					   __hash_cached::value>& __n) const
1675       {
1676 	static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
1677 	  "key equality predicate must be invocable with two arguments of "
1678 	  "key type");
1679 	return _M_eq()(__k, _ExtractKey{}(__n._M_v()));
1680       }
1681 
1682       template<typename _Kt>
1683 	bool
1684 	_M_key_equals_tr(const _Kt& __k,
1685 			 const _Hash_node_value<_Value,
1686 					     __hash_cached::value>& __n) const
1687 	{
1688 	  static_assert(
1689 	    __is_invocable<const _Equal&, const _Kt&, const _Key&>{},
1690 	    "key equality predicate must be invocable with two arguments of "
1691 	    "key type");
1692 	  return _M_eq()(__k, _ExtractKey{}(__n._M_v()));
1693 	}
1694 
1695       bool
1696       _M_equals(const _Key& __k, __hash_code __c,
1697 		const _Hash_node_value<_Value, __hash_cached::value>& __n) const
1698       { return _S_equals(__c, __n) && _M_key_equals(__k, __n); }
1699 
1700       template<typename _Kt>
1701 	bool
1702 	_M_equals_tr(const _Kt& __k, __hash_code __c,
1703 		     const _Hash_node_value<_Value,
1704 					    __hash_cached::value>& __n) const
1705 	{ return _S_equals(__c, __n) && _M_key_equals_tr(__k, __n); }
1706 
1707       bool
1708       _M_node_equals(
1709 	const _Hash_node_value<_Value, __hash_cached::value>& __lhn,
1710 	const _Hash_node_value<_Value, __hash_cached::value>& __rhn) const
1711       {
1712 	return _S_node_equals(__lhn, __rhn)
1713 	  && _M_key_equals(_ExtractKey{}(__lhn._M_v()), __rhn);
1714       }
1715 
1716       void
1717       _M_swap(_Hashtable_base& __x)
1718       {
1719 	__hash_code_base::_M_swap(__x);
1720 	std::swap(_EqualEBO::_M_get(), __x._EqualEBO::_M_get());
1721       }
1722 
1723       const _Equal&
1724       _M_eq() const { return _EqualEBO::_M_cget(); }
1725     };
1726 
1727   /**
1728    *  Primary class template  _Equality.
1729    *
1730    *  This is for implementing equality comparison for unordered
1731    *  containers, per N3068, by John Lakos and Pablo Halpern.
1732    *  Algorithmically, we follow closely the reference implementations
1733    *  therein.
1734    */
1735   template<typename _Key, typename _Value, typename _Alloc,
1736 	   typename _ExtractKey, typename _Equal,
1737 	   typename _Hash, typename _RangeHash, typename _Unused,
1738 	   typename _RehashPolicy, typename _Traits,
1739 	   bool _Unique_keys = _Traits::__unique_keys::value>
1740     struct _Equality;
1741 
1742   /// unordered_map and unordered_set specializations.
1743   template<typename _Key, typename _Value, typename _Alloc,
1744 	   typename _ExtractKey, typename _Equal,
1745 	   typename _Hash, typename _RangeHash, typename _Unused,
1746 	   typename _RehashPolicy, typename _Traits>
1747     struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1748 		     _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>
1749     {
1750       using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1751 				     _Hash, _RangeHash, _Unused,
1752 				     _RehashPolicy, _Traits>;
1753 
1754       bool
1755       _M_equal(const __hashtable&) const;
1756     };
1757 
1758   template<typename _Key, typename _Value, typename _Alloc,
1759 	   typename _ExtractKey, typename _Equal,
1760 	   typename _Hash, typename _RangeHash, typename _Unused,
1761 	   typename _RehashPolicy, typename _Traits>
1762     bool
1763     _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1764 	      _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>::
1765     _M_equal(const __hashtable& __other) const
1766     {
1767       using __node_type = typename __hashtable::__node_type;
1768       const __hashtable* __this = static_cast<const __hashtable*>(this);
1769       if (__this->size() != __other.size())
1770 	return false;
1771 
1772       for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1773 	{
1774 	  std::size_t __ybkt = __other._M_bucket_index(*__itx._M_cur);
1775 	  auto __prev_n = __other._M_buckets[__ybkt];
1776 	  if (!__prev_n)
1777 	    return false;
1778 
1779 	  for (__node_type* __n = static_cast<__node_type*>(__prev_n->_M_nxt);;
1780 	       __n = __n->_M_next())
1781 	    {
1782 	      if (__n->_M_v() == *__itx)
1783 		break;
1784 
1785 	      if (!__n->_M_nxt
1786 		  || __other._M_bucket_index(*__n->_M_next()) != __ybkt)
1787 		return false;
1788 	    }
1789 	}
1790 
1791       return true;
1792     }
1793 
1794   /// unordered_multiset and unordered_multimap specializations.
1795   template<typename _Key, typename _Value, typename _Alloc,
1796 	   typename _ExtractKey, typename _Equal,
1797 	   typename _Hash, typename _RangeHash, typename _Unused,
1798 	   typename _RehashPolicy, typename _Traits>
1799     struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1800 		     _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>
1801     {
1802       using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1803 				     _Hash, _RangeHash, _Unused,
1804 				     _RehashPolicy, _Traits>;
1805 
1806       bool
1807       _M_equal(const __hashtable&) const;
1808     };
1809 
1810   template<typename _Key, typename _Value, typename _Alloc,
1811 	   typename _ExtractKey, typename _Equal,
1812 	   typename _Hash, typename _RangeHash, typename _Unused,
1813 	   typename _RehashPolicy, typename _Traits>
1814     bool
1815     _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1816 	      _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>::
1817     _M_equal(const __hashtable& __other) const
1818     {
1819       using __node_type = typename __hashtable::__node_type;
1820       const __hashtable* __this = static_cast<const __hashtable*>(this);
1821       if (__this->size() != __other.size())
1822 	return false;
1823 
1824       for (auto __itx = __this->begin(); __itx != __this->end();)
1825 	{
1826 	  std::size_t __x_count = 1;
1827 	  auto __itx_end = __itx;
1828 	  for (++__itx_end; __itx_end != __this->end()
1829 		 && __this->key_eq()(_ExtractKey{}(*__itx),
1830 				     _ExtractKey{}(*__itx_end));
1831 	       ++__itx_end)
1832 	    ++__x_count;
1833 
1834 	  std::size_t __ybkt = __other._M_bucket_index(*__itx._M_cur);
1835 	  auto __y_prev_n = __other._M_buckets[__ybkt];
1836 	  if (!__y_prev_n)
1837 	    return false;
1838 
1839 	  __node_type* __y_n = static_cast<__node_type*>(__y_prev_n->_M_nxt);
1840 	  for (;;)
1841 	    {
1842 	      if (__this->key_eq()(_ExtractKey{}(__y_n->_M_v()),
1843 				   _ExtractKey{}(*__itx)))
1844 		break;
1845 
1846 	      auto __y_ref_n = __y_n;
1847 	      for (__y_n = __y_n->_M_next(); __y_n; __y_n = __y_n->_M_next())
1848 		if (!__other._M_node_equals(*__y_ref_n, *__y_n))
1849 		  break;
1850 
1851 	      if (!__y_n || __other._M_bucket_index(*__y_n) != __ybkt)
1852 		return false;
1853 	    }
1854 
1855 	  typename __hashtable::const_iterator __ity(__y_n);
1856 	  for (auto __ity_end = __ity; __ity_end != __other.end(); ++__ity_end)
1857 	    if (--__x_count == 0)
1858 	      break;
1859 
1860 	  if (__x_count != 0)
1861 	    return false;
1862 
1863 	  if (!std::is_permutation(__itx, __itx_end, __ity))
1864 	    return false;
1865 
1866 	  __itx = __itx_end;
1867 	}
1868       return true;
1869     }
1870 
1871   /**
1872    * This type deals with all allocation and keeps an allocator instance
1873    * through inheritance to benefit from EBO when possible.
1874    */
1875   template<typename _NodeAlloc>
1876     struct _Hashtable_alloc : private _Hashtable_ebo_helper<0, _NodeAlloc>
1877     {
1878     private:
1879       using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>;
1880 
1881       template<typename>
1882 	struct __get_value_type;
1883       template<typename _Val, bool _Cache_hash_code>
1884 	struct __get_value_type<_Hash_node<_Val, _Cache_hash_code>>
1885 	{ using type = _Val; };
1886 
1887     public:
1888       using __node_type = typename _NodeAlloc::value_type;
1889       using __node_alloc_type = _NodeAlloc;
1890       // Use __gnu_cxx to benefit from _S_always_equal and al.
1891       using __node_alloc_traits = __gnu_cxx::__alloc_traits<__node_alloc_type>;
1892 
1893       using __value_alloc_traits = typename __node_alloc_traits::template
1894 	rebind_traits<typename __get_value_type<__node_type>::type>;
1895 
1896       using __node_ptr = __node_type*;
1897       using __node_base = _Hash_node_base;
1898       using __node_base_ptr = __node_base*;
1899       using __buckets_alloc_type =
1900 	__alloc_rebind<__node_alloc_type, __node_base_ptr>;
1901       using __buckets_alloc_traits = std::allocator_traits<__buckets_alloc_type>;
1902       using __buckets_ptr = __node_base_ptr*;
1903 
1904       _Hashtable_alloc() = default;
1905       _Hashtable_alloc(const _Hashtable_alloc&) = default;
1906       _Hashtable_alloc(_Hashtable_alloc&&) = default;
1907 
1908       template<typename _Alloc>
1909 	_Hashtable_alloc(_Alloc&& __a)
1910 	: __ebo_node_alloc(std::forward<_Alloc>(__a))
1911 	{ }
1912 
1913       __node_alloc_type&
1914       _M_node_allocator()
1915       { return __ebo_node_alloc::_M_get(); }
1916 
1917       const __node_alloc_type&
1918       _M_node_allocator() const
1919       { return __ebo_node_alloc::_M_cget(); }
1920 
1921       // Allocate a node and construct an element within it.
1922       template<typename... _Args>
1923 	__node_ptr
1924 	_M_allocate_node(_Args&&... __args);
1925 
1926       // Destroy the element within a node and deallocate the node.
1927       void
1928       _M_deallocate_node(__node_ptr __n);
1929 
1930       // Deallocate a node.
1931       void
1932       _M_deallocate_node_ptr(__node_ptr __n);
1933 
1934       // Deallocate the linked list of nodes pointed to by __n.
1935       // The elements within the nodes are destroyed.
1936       void
1937       _M_deallocate_nodes(__node_ptr __n);
1938 
1939       __buckets_ptr
1940       _M_allocate_buckets(std::size_t __bkt_count);
1941 
1942       void
1943       _M_deallocate_buckets(__buckets_ptr, std::size_t __bkt_count);
1944     };
1945 
1946   // Definitions of class template _Hashtable_alloc's out-of-line member
1947   // functions.
1948   template<typename _NodeAlloc>
1949     template<typename... _Args>
1950       auto
1951       _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
1952       -> __node_ptr
1953       {
1954 	auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
1955 	__node_ptr __n = std::__to_address(__nptr);
1956 	__try
1957 	  {
1958 	    ::new ((void*)__n) __node_type;
1959 	    __node_alloc_traits::construct(_M_node_allocator(),
1960 					   __n->_M_valptr(),
1961 					   std::forward<_Args>(__args)...);
1962 	    return __n;
1963 	  }
1964 	__catch(...)
1965 	  {
1966 	    __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
1967 	    __throw_exception_again;
1968 	  }
1969       }
1970 
1971   template<typename _NodeAlloc>
1972     void
1973     _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_ptr __n)
1974     {
1975       __node_alloc_traits::destroy(_M_node_allocator(), __n->_M_valptr());
1976       _M_deallocate_node_ptr(__n);
1977     }
1978 
1979   template<typename _NodeAlloc>
1980     void
1981     _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node_ptr(__node_ptr __n)
1982     {
1983       typedef typename __node_alloc_traits::pointer _Ptr;
1984       auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n);
1985       __n->~__node_type();
1986       __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
1987     }
1988 
1989   template<typename _NodeAlloc>
1990     void
1991     _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_ptr __n)
1992     {
1993       while (__n)
1994 	{
1995 	  __node_ptr __tmp = __n;
1996 	  __n = __n->_M_next();
1997 	  _M_deallocate_node(__tmp);
1998 	}
1999     }
2000 
2001   template<typename _NodeAlloc>
2002     auto
2003     _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __bkt_count)
2004     -> __buckets_ptr
2005     {
2006       __buckets_alloc_type __alloc(_M_node_allocator());
2007 
2008       auto __ptr = __buckets_alloc_traits::allocate(__alloc, __bkt_count);
2009       __buckets_ptr __p = std::__to_address(__ptr);
2010       __builtin_memset(__p, 0, __bkt_count * sizeof(__node_base_ptr));
2011       return __p;
2012     }
2013 
2014   template<typename _NodeAlloc>
2015     void
2016     _Hashtable_alloc<_NodeAlloc>::
2017     _M_deallocate_buckets(__buckets_ptr __bkts,
2018 			  std::size_t __bkt_count)
2019     {
2020       typedef typename __buckets_alloc_traits::pointer _Ptr;
2021       auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts);
2022       __buckets_alloc_type __alloc(_M_node_allocator());
2023       __buckets_alloc_traits::deallocate(__alloc, __ptr, __bkt_count);
2024     }
2025 
2026  ///@} hashtable-detail
2027 } // namespace __detail
2028 /// @endcond
2029 _GLIBCXX_END_NAMESPACE_VERSION
2030 } // namespace std
2031 
2032 #endif // _HASHTABLE_POLICY_H
2033