// hashtable.h header -*- C++ -*-

// Copyright (C) 2007-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file bits/hashtable.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{unordered_map, unordered_set}
 */

#ifndef _HASHTABLE_H
#define _HASHTABLE_H 1

#pragma GCC system_header

#include <bits/hashtable_policy.h>
#include <bits/enable_special_members.h>
#if __cplusplus > 201402L
# include <bits/node_handle.h>
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Tp, typename _Hash>
    using __cache_default
      =  __not_<__and_<// Do not cache for fast hasher.
		       __is_fast_hash<_Hash>,
		       // Mandatory to have erase not throwing.
		       __is_nothrow_invocable<const _Hash&, const _Tp&>>>;

  // Helper to conditionally delete the default constructor.
  // The _Hash_node_base type is used to distinguish this specialization
  // from any other potentially-overlapping subobjects of the hashtable.
  template<typename _Equal, typename _Hash, typename _Allocator>
    using _Hashtable_enable_default_ctor
      = _Enable_default_constructor<__and_<is_default_constructible<_Equal>,
				       is_default_constructible<_Hash>,
				       is_default_constructible<_Allocator>>{},
				    __detail::_Hash_node_base>;

  /**
   *  Primary class template _Hashtable.
   *
   *  @ingroup hashtable-detail
   *
   *  @tparam _Value  CopyConstructible type.
   *
   *  @tparam _Key    CopyConstructible type.
   *
   *  @tparam _Alloc  An allocator type
   *  ([lib.allocator.requirements]) whose _Alloc::value_type is
   *  _Value.  As a conforming extension, we allow for
   *  _Alloc::value_type != _Value.
   *
   *  @tparam _ExtractKey  Function object that takes an object of type
   *  _Value and returns a value of type _Key.
   *
   *  @tparam _Equal  Function object that takes two objects of type k
   *  and returns a bool-like value that is true if the two objects
   *  are considered equal.
   *
   *  @tparam _Hash  The hash function. A unary function object with
   *  argument type _Key and result type size_t. Return values should
   *  be distributed over the entire range [0, numeric_limits<size_t>:::max()].
   *
   *  @tparam _RangeHash  The range-hashing function (in the terminology of
   *  Tavori and Dreizin).  A binary function object whose argument
   *  types and result type are all size_t.  Given arguments r and N,
   *  the return value is in the range [0, N).
   *
   *  @tparam _Unused  Not used.
   *
   *  @tparam _RehashPolicy  Policy class with three members, all of
   *  which govern the bucket count. _M_next_bkt(n) returns a bucket
   *  count no smaller than n.  _M_bkt_for_elements(n) returns a
   *  bucket count appropriate for an element count of n.
   *  _M_need_rehash(n_bkt, n_elt, n_ins) determines whether, if the
   *  current bucket count is n_bkt and the current element count is
   *  n_elt, we need to increase the bucket count for n_ins insertions.
   *  If so, returns make_pair(true, n), where n is the new bucket count. If
   *  not, returns make_pair(false, <anything>)
   *
   *  @tparam _Traits  Compile-time class with three boolean
   *  std::integral_constant members:  __cache_hash_code, __constant_iterators,
   *   __unique_keys.
   *
   *  Each _Hashtable data structure has:
   *
   *  - _Bucket[]       _M_buckets
   *  - _Hash_node_base _M_before_begin
   *  - size_type       _M_bucket_count
   *  - size_type       _M_element_count
   *
   *  with _Bucket being _Hash_node_base* and _Hash_node containing:
   *
   *  - _Hash_node*   _M_next
   *  - Tp            _M_value
   *  - size_t        _M_hash_code if cache_hash_code is true
   *
   *  In terms of Standard containers the hashtable is like the aggregation of:
   *
   *  - std::forward_list<_Node> containing the elements
   *  - std::vector<std::forward_list<_Node>::iterator> representing the buckets
   *
   *  The non-empty buckets contain the node before the first node in the
   *  bucket. This design makes it possible to implement something like a
   *  std::forward_list::insert_after on container insertion and
   *  std::forward_list::erase_after on container erase
   *  calls. _M_before_begin is equivalent to
   *  std::forward_list::before_begin. Empty buckets contain
   *  nullptr.  Note that one of the non-empty buckets contains
   *  &_M_before_begin which is not a dereferenceable node so the
   *  node pointer in a bucket shall never be dereferenced, only its
   *  next node can be.
   *
   *  Walking through a bucket's nodes requires a check on the hash code to
   *  see if each node is still in the bucket. Such a design assumes a
   *  quite efficient hash functor and is one of the reasons it is
   *  highly advisable to set __cache_hash_code to true.
   *
   *  The container iterators are simply built from nodes. This way
   *  incrementing the iterator is perfectly efficient independent of
   *  how many empty buckets there are in the container.
   *
   *  On insert we compute the element's hash code and use it to find the
   *  bucket index. If the element must be inserted in an empty bucket
   *  we add it at the beginning of the singly linked list and make the
   *  bucket point to _M_before_begin. The bucket that used to point to
   *  _M_before_begin, if any, is updated to point to its new before
   *  begin node.
   *
   *  On erase, the simple iterator design requires using the hash
   *  functor to get the index of the bucket to update. For this
   *  reason, when __cache_hash_code is set to false the hash functor must
   *  not throw and this is enforced by a static assertion.
   *
   *  Functionality is implemented by decomposition into base classes,
   *  where the derived _Hashtable class is used in _Map_base,
   *  _Insert, _Rehash_base, and _Equality base classes to access the
   *  "this" pointer. _Hashtable_base is used in the base classes as a
   *  non-recursive, fully-completed-type so that detailed nested type
   *  information, such as iterator type and node type, can be
   *  used. This is similar to the "Curiously Recurring Template
   *  Pattern" (CRTP) technique, but uses a reconstructed, not
   *  explicitly passed, template pattern.
   *
   *  Base class templates are: 
   *    - __detail::_Hashtable_base
   *    - __detail::_Map_base
   *    - __detail::_Insert
   *    - __detail::_Rehash_base
   *    - __detail::_Equality
   */
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    class _Hashtable
    : public __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal,
				       _Hash, _RangeHash, _Unused, _Traits>,
      public __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
				 _Hash, _RangeHash, _Unused,
				 _RehashPolicy, _Traits>,
      public __detail::_Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal,
			       _Hash, _RangeHash, _Unused,
			       _RehashPolicy, _Traits>,
      public __detail::_Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
				    _Hash, _RangeHash, _Unused,
				    _RehashPolicy, _Traits>,
      public __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
				 _Hash, _RangeHash, _Unused,
				 _RehashPolicy, _Traits>,
      private __detail::_Hashtable_alloc<
	__alloc_rebind<_Alloc,
		       __detail::_Hash_node<_Value,
					    _Traits::__hash_cached::value>>>,
      private _Hashtable_enable_default_ctor<_Equal, _Hash, _Alloc>
    {
      static_assert(is_same<typename remove_cv<_Value>::type, _Value>::value,
	  "unordered container must have a non-const, non-volatile value_type");
#if __cplusplus > 201703L || defined __STRICT_ANSI__
      static_assert(is_same<typename _Alloc::value_type, _Value>{},
	  "unordered container must have the same value_type as its allocator");
#endif

      using __traits_type = _Traits;
      using __hash_cached = typename __traits_type::__hash_cached;
      using __constant_iterators = typename __traits_type::__constant_iterators;
      using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>;
      using __node_alloc_type = __alloc_rebind<_Alloc, __node_type>;

      using __hashtable_alloc = __detail::_Hashtable_alloc<__node_alloc_type>;

      using __node_value_type =
	__detail::_Hash_node_value<_Value, __hash_cached::value>;
      using __node_ptr = typename __hashtable_alloc::__node_ptr;
      using __value_alloc_traits =
	typename __hashtable_alloc::__value_alloc_traits;
      using __node_alloc_traits =
	typename __hashtable_alloc::__node_alloc_traits;
      using __node_base = typename __hashtable_alloc::__node_base;
      using __node_base_ptr = typename __hashtable_alloc::__node_base_ptr;
      using __buckets_ptr = typename __hashtable_alloc::__buckets_ptr;

      using __insert_base = __detail::_Insert<_Key, _Value, _Alloc, _ExtractKey,
					      _Equal, _Hash,
					      _RangeHash, _Unused,
					      _RehashPolicy, _Traits>;
      using __enable_default_ctor
	= _Hashtable_enable_default_ctor<_Equal, _Hash, _Alloc>;

    public:
      typedef _Key						key_type;
      typedef _Value						value_type;
      typedef _Alloc						allocator_type;
      typedef _Equal						key_equal;

      // mapped_type, if present, comes from _Map_base.
      // hasher, if present, comes from _Hash_code_base/_Hashtable_base.
      typedef typename __value_alloc_traits::pointer		pointer;
      typedef typename __value_alloc_traits::const_pointer	const_pointer;
      typedef value_type&					reference;
      typedef const value_type&					const_reference;

      using iterator = typename __insert_base::iterator;

      using const_iterator = typename __insert_base::const_iterator;

      using local_iterator = __detail::_Local_iterator<key_type, _Value,
			_ExtractKey, _Hash, _RangeHash, _Unused,
					     __constant_iterators::value,
					     __hash_cached::value>;

      using const_local_iterator = __detail::_Local_const_iterator<
			key_type, _Value,
			_ExtractKey, _Hash, _RangeHash, _Unused,
			__constant_iterators::value, __hash_cached::value>;

    private:
      using __rehash_type = _RehashPolicy;
      using __rehash_state = typename __rehash_type::_State;

      using __unique_keys = typename __traits_type::__unique_keys;

      using __hashtable_base = __detail::
	_Hashtable_base<_Key, _Value, _ExtractKey,
			_Equal, _Hash, _RangeHash, _Unused, _Traits>;

      using __hash_code_base =  typename __hashtable_base::__hash_code_base;
      using __hash_code =  typename __hashtable_base::__hash_code;
      using __ireturn_type = typename __insert_base::__ireturn_type;

      using __map_base = __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey,
					     _Equal, _Hash, _RangeHash, _Unused,
					     _RehashPolicy, _Traits>;

      using __rehash_base = __detail::_Rehash_base<_Key, _Value, _Alloc,
						   _ExtractKey, _Equal,
						   _Hash, _RangeHash, _Unused,
						   _RehashPolicy, _Traits>;

      using __eq_base = __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey,
					    _Equal, _Hash, _RangeHash, _Unused,
					    _RehashPolicy, _Traits>;

      using __reuse_or_alloc_node_gen_t =
	__detail::_ReuseOrAllocNode<__node_alloc_type>;
      using __alloc_node_gen_t =
	__detail::_AllocNode<__node_alloc_type>;
      using __node_builder_t =
	__detail::_NodeBuilder<_ExtractKey>;

      // Simple RAII type for managing a node containing an element
      struct _Scoped_node
      {
	// Take ownership of a node with a constructed element.
	_Scoped_node(__node_ptr __n, __hashtable_alloc* __h)
	: _M_h(__h), _M_node(__n) { }

	// Allocate a node and construct an element within it.
	template<typename... _Args>
	  _Scoped_node(__hashtable_alloc* __h, _Args&&... __args)
	  : _M_h(__h),
	    _M_node(__h->_M_allocate_node(std::forward<_Args>(__args)...))
	  { }

	// Destroy element and deallocate node.
	~_Scoped_node() { if (_M_node) _M_h->_M_deallocate_node(_M_node); };

	_Scoped_node(const _Scoped_node&) = delete;
	_Scoped_node& operator=(const _Scoped_node&) = delete;

	__hashtable_alloc* _M_h;
	__node_ptr _M_node;
      };

      template<typename _Ht>
	static constexpr
	__conditional_t<std::is_lvalue_reference<_Ht>::value,
			const value_type&, value_type&&>
	__fwd_value_for(value_type& __val) noexcept
	{ return std::move(__val); }

      // Compile-time diagnostics.

      // _Hash_code_base has everything protected, so use this derived type to
      // access it.
      struct __hash_code_base_access : __hash_code_base
      { using __hash_code_base::_M_bucket_index; };

      // To get bucket index we need _RangeHash not to throw.
      static_assert(is_nothrow_default_constructible<_RangeHash>::value,
		    "Functor used to map hash code to bucket index"
		    " must be nothrow default constructible");
      static_assert(noexcept(
	std::declval<const _RangeHash&>()((std::size_t)0, (std::size_t)0)),
		    "Functor used to map hash code to bucket index must be"
		    " noexcept");

      // To compute bucket index we also need _ExtratKey not to throw.
      static_assert(is_nothrow_default_constructible<_ExtractKey>::value,
		    "_ExtractKey must be nothrow default constructible");
      static_assert(noexcept(
	std::declval<const _ExtractKey&>()(std::declval<_Value>())),
		    "_ExtractKey functor must be noexcept invocable");

      template<typename _Keya, typename _Valuea, typename _Alloca,
	       typename _ExtractKeya, typename _Equala,
	       typename _Hasha, typename _RangeHasha, typename _Unuseda,
	       typename _RehashPolicya, typename _Traitsa,
	       bool _Unique_keysa>
	friend struct __detail::_Map_base;

      template<typename _Keya, typename _Valuea, typename _Alloca,
	       typename _ExtractKeya, typename _Equala,
	       typename _Hasha, typename _RangeHasha, typename _Unuseda,
	       typename _RehashPolicya, typename _Traitsa>
	friend struct __detail::_Insert_base;

      template<typename _Keya, typename _Valuea, typename _Alloca,
	       typename _ExtractKeya, typename _Equala,
	       typename _Hasha, typename _RangeHasha, typename _Unuseda,
	       typename _RehashPolicya, typename _Traitsa,
	       bool _Constant_iteratorsa>
	friend struct __detail::_Insert;

      template<typename _Keya, typename _Valuea, typename _Alloca,
	       typename _ExtractKeya, typename _Equala,
	       typename _Hasha, typename _RangeHasha, typename _Unuseda,
	       typename _RehashPolicya, typename _Traitsa,
	       bool _Unique_keysa>
	friend struct __detail::_Equality;

    public:
      using size_type = typename __hashtable_base::size_type;
      using difference_type = typename __hashtable_base::difference_type;

#if __cplusplus > 201402L
      using node_type = _Node_handle<_Key, _Value, __node_alloc_type>;
      using insert_return_type = _Node_insert_return<iterator, node_type>;
#endif

    private:
      __buckets_ptr		_M_buckets		= &_M_single_bucket;
      size_type			_M_bucket_count		= 1;
      __node_base		_M_before_begin;
      size_type			_M_element_count	= 0;
      _RehashPolicy		_M_rehash_policy;

      // A single bucket used when only need for 1 bucket. Especially
      // interesting in move semantic to leave hashtable with only 1 bucket
      // which is not allocated so that we can have those operations noexcept
      // qualified.
      // Note that we can't leave hashtable with 0 bucket without adding
      // numerous checks in the code to avoid 0 modulus.
      __node_base_ptr		_M_single_bucket	= nullptr;

      void
      _M_update_bbegin()
      {
	if (_M_begin())
	  _M_buckets[_M_bucket_index(*_M_begin())] = &_M_before_begin;
      }

      void
      _M_update_bbegin(__node_ptr __n)
      {
	_M_before_begin._M_nxt = __n;
	_M_update_bbegin();
      }

      bool
      _M_uses_single_bucket(__buckets_ptr __bkts) const
      { return __builtin_expect(__bkts == &_M_single_bucket, false); }

      bool
      _M_uses_single_bucket() const
      { return _M_uses_single_bucket(_M_buckets); }

      __hashtable_alloc&
      _M_base_alloc() { return *this; }

      __buckets_ptr
      _M_allocate_buckets(size_type __bkt_count)
      {
	if (__builtin_expect(__bkt_count == 1, false))
	  {
	    _M_single_bucket = nullptr;
	    return &_M_single_bucket;
	  }

	return __hashtable_alloc::_M_allocate_buckets(__bkt_count);
      }

      void
      _M_deallocate_buckets(__buckets_ptr __bkts, size_type __bkt_count)
      {
	if (_M_uses_single_bucket(__bkts))
	  return;

	__hashtable_alloc::_M_deallocate_buckets(__bkts, __bkt_count);
      }

      void
      _M_deallocate_buckets()
      { _M_deallocate_buckets(_M_buckets, _M_bucket_count); }

      // Gets bucket begin, deals with the fact that non-empty buckets contain
      // their before begin node.
      __node_ptr
      _M_bucket_begin(size_type __bkt) const;

      __node_ptr
      _M_begin() const
      { return static_cast<__node_ptr>(_M_before_begin._M_nxt); }

      // Assign *this using another _Hashtable instance. Whether elements
      // are copied or moved depends on the _Ht reference.
      template<typename _Ht>
	void
	_M_assign_elements(_Ht&&);

      template<typename _Ht, typename _NodeGenerator>
	void
	_M_assign(_Ht&&, const _NodeGenerator&);

      void
      _M_move_assign(_Hashtable&&, true_type);

      void
      _M_move_assign(_Hashtable&&, false_type);

      void
      _M_reset() noexcept;

      _Hashtable(const _Hash& __h, const _Equal& __eq,
		 const allocator_type& __a)
      : __hashtable_base(__h, __eq),
	__hashtable_alloc(__node_alloc_type(__a)),
	__enable_default_ctor(_Enable_default_constructor_tag{})
      { }

      template<bool _No_realloc = true>
	static constexpr bool
	_S_nothrow_move()
	{
#if __cplusplus <= 201402L
	  return __and_<__bool_constant<_No_realloc>,
			is_nothrow_copy_constructible<_Hash>,
			is_nothrow_copy_constructible<_Equal>>::value;
#else
	  if constexpr (_No_realloc)
	    if constexpr (is_nothrow_copy_constructible<_Hash>())
	      return is_nothrow_copy_constructible<_Equal>();
	  return false;
#endif
	}

      _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
		 true_type /* alloc always equal */)
	noexcept(_S_nothrow_move());

      _Hashtable(_Hashtable&&, __node_alloc_type&&,
		 false_type /* alloc always equal */);

      template<typename _InputIterator>
	_Hashtable(_InputIterator __first, _InputIterator __last,
		   size_type __bkt_count_hint,
		   const _Hash&, const _Equal&, const allocator_type&,
		   true_type __uks);

      template<typename _InputIterator>
	_Hashtable(_InputIterator __first, _InputIterator __last,
		   size_type __bkt_count_hint,
		   const _Hash&, const _Equal&, const allocator_type&,
		   false_type __uks);

    public:
      // Constructor, destructor, assignment, swap
      _Hashtable() = default;

      _Hashtable(const _Hashtable&);

      _Hashtable(const _Hashtable&, const allocator_type&);

      explicit
      _Hashtable(size_type __bkt_count_hint,
		 const _Hash& __hf = _Hash(),
		 const key_equal& __eql = key_equal(),
		 const allocator_type& __a = allocator_type());

      // Use delegating constructors.
      _Hashtable(_Hashtable&& __ht)
	noexcept(_S_nothrow_move())
      : _Hashtable(std::move(__ht), std::move(__ht._M_node_allocator()),
		   true_type{})
      { }

      _Hashtable(_Hashtable&& __ht, const allocator_type& __a)
	noexcept(_S_nothrow_move<__node_alloc_traits::_S_always_equal()>())
      : _Hashtable(std::move(__ht), __node_alloc_type(__a),
		   typename __node_alloc_traits::is_always_equal{})
      { }

      explicit
      _Hashtable(const allocator_type& __a)
      : __hashtable_alloc(__node_alloc_type(__a)),
	__enable_default_ctor(_Enable_default_constructor_tag{})
      { }

      template<typename _InputIterator>
	_Hashtable(_InputIterator __f, _InputIterator __l,
		   size_type __bkt_count_hint = 0,
		   const _Hash& __hf = _Hash(),
		   const key_equal& __eql = key_equal(),
		   const allocator_type& __a = allocator_type())
	: _Hashtable(__f, __l, __bkt_count_hint, __hf, __eql, __a,
		     __unique_keys{})
	{ }

      _Hashtable(initializer_list<value_type> __l,
		 size_type __bkt_count_hint = 0,
		 const _Hash& __hf = _Hash(),
		 const key_equal& __eql = key_equal(),
		 const allocator_type& __a = allocator_type())
      : _Hashtable(__l.begin(), __l.end(), __bkt_count_hint,
		   __hf, __eql, __a, __unique_keys{})
      { }

      _Hashtable&
      operator=(const _Hashtable& __ht);

      _Hashtable&
      operator=(_Hashtable&& __ht)
      noexcept(__node_alloc_traits::_S_nothrow_move()
	       && is_nothrow_move_assignable<_Hash>::value
	       && is_nothrow_move_assignable<_Equal>::value)
      {
	constexpr bool __move_storage =
	  __node_alloc_traits::_S_propagate_on_move_assign()
	  || __node_alloc_traits::_S_always_equal();
	_M_move_assign(std::move(__ht), __bool_constant<__move_storage>());
	return *this;
      }

      _Hashtable&
      operator=(initializer_list<value_type> __l)
      {
	__reuse_or_alloc_node_gen_t __roan(_M_begin(), *this);
	_M_before_begin._M_nxt = nullptr;
	clear();

	// We consider that all elements of __l are going to be inserted.
	auto __l_bkt_count = _M_rehash_policy._M_bkt_for_elements(__l.size());

	// Do not shrink to keep potential user reservation.
	if (_M_bucket_count < __l_bkt_count)
	  rehash(__l_bkt_count);

	this->_M_insert_range(__l.begin(), __l.end(), __roan, __unique_keys{});
	return *this;
      }

      ~_Hashtable() noexcept;

      void
      swap(_Hashtable&)
      noexcept(__and_<__is_nothrow_swappable<_Hash>,
		      __is_nothrow_swappable<_Equal>>::value);

      // Basic container operations
      iterator
      begin() noexcept
      { return iterator(_M_begin()); }

      const_iterator
      begin() const noexcept
      { return const_iterator(_M_begin()); }

      iterator
      end() noexcept
      { return iterator(nullptr); }

      const_iterator
      end() const noexcept
      { return const_iterator(nullptr); }

      const_iterator
      cbegin() const noexcept
      { return const_iterator(_M_begin()); }

      const_iterator
      cend() const noexcept
      { return const_iterator(nullptr); }

      size_type
      size() const noexcept
      { return _M_element_count; }

      _GLIBCXX_NODISCARD bool
      empty() const noexcept
      { return size() == 0; }

      allocator_type
      get_allocator() const noexcept
      { return allocator_type(this->_M_node_allocator()); }

      size_type
      max_size() const noexcept
      { return __node_alloc_traits::max_size(this->_M_node_allocator()); }

      // Observers
      key_equal
      key_eq() const
      { return this->_M_eq(); }

      // hash_function, if present, comes from _Hash_code_base.

      // Bucket operations
      size_type
      bucket_count() const noexcept
      { return _M_bucket_count; }

      size_type
      max_bucket_count() const noexcept
      { return max_size(); }

      size_type
      bucket_size(size_type __bkt) const
      { return std::distance(begin(__bkt), end(__bkt)); }

      size_type
      bucket(const key_type& __k) const
      { return _M_bucket_index(this->_M_hash_code(__k)); }

      local_iterator
      begin(size_type __bkt)
      {
	return local_iterator(*this, _M_bucket_begin(__bkt),
			      __bkt, _M_bucket_count);
      }

      local_iterator
      end(size_type __bkt)
      { return local_iterator(*this, nullptr, __bkt, _M_bucket_count); }

      const_local_iterator
      begin(size_type __bkt) const
      {
	return const_local_iterator(*this, _M_bucket_begin(__bkt),
				    __bkt, _M_bucket_count);
      }

      const_local_iterator
      end(size_type __bkt) const
      { return const_local_iterator(*this, nullptr, __bkt, _M_bucket_count); }

      // DR 691.
      const_local_iterator
      cbegin(size_type __bkt) const
      {
	return const_local_iterator(*this, _M_bucket_begin(__bkt),
				    __bkt, _M_bucket_count);
      }

      const_local_iterator
      cend(size_type __bkt) const
      { return const_local_iterator(*this, nullptr, __bkt, _M_bucket_count); }

      float
      load_factor() const noexcept
      {
	return static_cast<float>(size()) / static_cast<float>(bucket_count());
      }

      // max_load_factor, if present, comes from _Rehash_base.

      // Generalization of max_load_factor.  Extension, not found in
      // TR1.  Only useful if _RehashPolicy is something other than
      // the default.
      const _RehashPolicy&
      __rehash_policy() const
      { return _M_rehash_policy; }

      void
      __rehash_policy(const _RehashPolicy& __pol)
      { _M_rehash_policy = __pol; }

      // Lookup.
      iterator
      find(const key_type& __k);

      const_iterator
      find(const key_type& __k) const;

      size_type
      count(const key_type& __k) const;

      std::pair<iterator, iterator>
      equal_range(const key_type& __k);

      std::pair<const_iterator, const_iterator>
      equal_range(const key_type& __k) const;

#if __cplusplus >= 202002L
#define __cpp_lib_generic_unordered_lookup 201811L

      template<typename _Kt,
	       typename = __has_is_transparent_t<_Hash, _Kt>,
	       typename = __has_is_transparent_t<_Equal, _Kt>>
	iterator
	_M_find_tr(const _Kt& __k);

      template<typename _Kt,
	       typename = __has_is_transparent_t<_Hash, _Kt>,
	       typename = __has_is_transparent_t<_Equal, _Kt>>
	const_iterator
	_M_find_tr(const _Kt& __k) const;

      template<typename _Kt,
	       typename = __has_is_transparent_t<_Hash, _Kt>,
	       typename = __has_is_transparent_t<_Equal, _Kt>>
	size_type
	_M_count_tr(const _Kt& __k) const;

      template<typename _Kt,
	       typename = __has_is_transparent_t<_Hash, _Kt>,
	       typename = __has_is_transparent_t<_Equal, _Kt>>
	pair<iterator, iterator>
	_M_equal_range_tr(const _Kt& __k);

      template<typename _Kt,
	       typename = __has_is_transparent_t<_Hash, _Kt>,
	       typename = __has_is_transparent_t<_Equal, _Kt>>
	pair<const_iterator, const_iterator>
	_M_equal_range_tr(const _Kt& __k) const;
#endif // C++20

    private:
      // Bucket index computation helpers.
      size_type
      _M_bucket_index(const __node_value_type& __n) const noexcept
      { return __hash_code_base::_M_bucket_index(__n, _M_bucket_count); }

      size_type
      _M_bucket_index(__hash_code __c) const
      { return __hash_code_base::_M_bucket_index(__c, _M_bucket_count); }

      // Find and insert helper functions and types
      // Find the node before the one matching the criteria.
      __node_base_ptr
      _M_find_before_node(size_type, const key_type&, __hash_code) const;

      template<typename _Kt>
	__node_base_ptr
	_M_find_before_node_tr(size_type, const _Kt&, __hash_code) const;

      __node_ptr
      _M_find_node(size_type __bkt, const key_type& __key,
		   __hash_code __c) const
      {
	__node_base_ptr __before_n = _M_find_before_node(__bkt, __key, __c);
	if (__before_n)
	  return static_cast<__node_ptr>(__before_n->_M_nxt);
	return nullptr;
      }

      template<typename _Kt>
	__node_ptr
	_M_find_node_tr(size_type __bkt, const _Kt& __key,
			__hash_code __c) const
	{
	  auto __before_n = _M_find_before_node_tr(__bkt, __key, __c);
	  if (__before_n)
	    return static_cast<__node_ptr>(__before_n->_M_nxt);
	  return nullptr;
	}

      // Insert a node at the beginning of a bucket.
      void
      _M_insert_bucket_begin(size_type, __node_ptr);

      // Remove the bucket first node
      void
      _M_remove_bucket_begin(size_type __bkt, __node_ptr __next_n,
			     size_type __next_bkt);

      // Get the node before __n in the bucket __bkt
      __node_base_ptr
      _M_get_previous_node(size_type __bkt, __node_ptr __n);

      // Insert node __n with hash code __code, in bucket __bkt if no
      // rehash (assumes no element with same key already present).
      // Takes ownership of __n if insertion succeeds, throws otherwise.
      iterator
      _M_insert_unique_node(size_type __bkt, __hash_code,
			    __node_ptr __n, size_type __n_elt = 1);

      // Insert node __n with key __k and hash code __code.
      // Takes ownership of __n if insertion succeeds, throws otherwise.
      iterator
      _M_insert_multi_node(__node_ptr __hint,
			   __hash_code __code, __node_ptr __n);

      template<typename... _Args>
	std::pair<iterator, bool>
	_M_emplace(true_type __uks, _Args&&... __args);

      template<typename... _Args>
	iterator
	_M_emplace(false_type __uks, _Args&&... __args)
	{ return _M_emplace(cend(), __uks, std::forward<_Args>(__args)...); }

      // Emplace with hint, useless when keys are unique.
      template<typename... _Args>
	iterator
	_M_emplace(const_iterator, true_type __uks, _Args&&... __args)
	{ return _M_emplace(__uks, std::forward<_Args>(__args)...).first; }

      template<typename... _Args>
	iterator
	_M_emplace(const_iterator, false_type __uks, _Args&&... __args);

      template<typename _Kt, typename _Arg, typename _NodeGenerator>
	std::pair<iterator, bool>
	_M_insert_unique(_Kt&&, _Arg&&, const _NodeGenerator&);

      template<typename _Kt>
	static __conditional_t<
	  __and_<__is_nothrow_invocable<_Hash&, const key_type&>,
		 __not_<__is_nothrow_invocable<_Hash&, _Kt>>>::value,
	  key_type, _Kt&&>
	_S_forward_key(_Kt&& __k)
	{ return std::forward<_Kt>(__k); }

      static const key_type&
      _S_forward_key(const key_type& __k)
      { return __k; }

      static key_type&&
      _S_forward_key(key_type&& __k)
      { return std::move(__k); }

      template<typename _Arg, typename _NodeGenerator>
	std::pair<iterator, bool>
	_M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen,
		  true_type /* __uks */)
	{
	  return _M_insert_unique(
	    _S_forward_key(_ExtractKey{}(std::forward<_Arg>(__arg))),
	    std::forward<_Arg>(__arg), __node_gen);
	}

      template<typename _Arg, typename _NodeGenerator>
	iterator
	_M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen,
		  false_type __uks)
	{
	  return _M_insert(cend(), std::forward<_Arg>(__arg), __node_gen,
			   __uks);
	}

      // Insert with hint, not used when keys are unique.
      template<typename _Arg, typename _NodeGenerator>
	iterator
	_M_insert(const_iterator, _Arg&& __arg,
		  const _NodeGenerator& __node_gen, true_type __uks)
	{
	  return
	    _M_insert(std::forward<_Arg>(__arg), __node_gen, __uks).first;
	}

      // Insert with hint when keys are not unique.
      template<typename _Arg, typename _NodeGenerator>
	iterator
	_M_insert(const_iterator, _Arg&&,
		  const _NodeGenerator&, false_type __uks);

      size_type
      _M_erase(true_type __uks, const key_type&);

      size_type
      _M_erase(false_type __uks, const key_type&);

      iterator
      _M_erase(size_type __bkt, __node_base_ptr __prev_n, __node_ptr __n);

    public:
      // Emplace
      template<typename... _Args>
	__ireturn_type
	emplace(_Args&&... __args)
	{ return _M_emplace(__unique_keys{}, std::forward<_Args>(__args)...); }

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __hint, _Args&&... __args)
	{
	  return _M_emplace(__hint, __unique_keys{},
			    std::forward<_Args>(__args)...);
	}

      // Insert member functions via inheritance.

      // Erase
      iterator
      erase(const_iterator);

      // LWG 2059.
      iterator
      erase(iterator __it)
      { return erase(const_iterator(__it)); }

      size_type
      erase(const key_type& __k)
      { return _M_erase(__unique_keys{}, __k); }

      iterator
      erase(const_iterator, const_iterator);

      void
      clear() noexcept;

      // Set number of buckets keeping it appropriate for container's number
      // of elements.
      void rehash(size_type __bkt_count);

      // DR 1189.
      // reserve, if present, comes from _Rehash_base.

#if __cplusplus > 201402L
      /// Re-insert an extracted node into a container with unique keys.
      insert_return_type
      _M_reinsert_node(node_type&& __nh)
      {
	insert_return_type __ret;
	if (__nh.empty())
	  __ret.position = end();
	else
	  {
	    __glibcxx_assert(get_allocator() == __nh.get_allocator());

	    const key_type& __k = __nh._M_key();
	    __hash_code __code = this->_M_hash_code(__k);
	    size_type __bkt = _M_bucket_index(__code);
	    if (__node_ptr __n = _M_find_node(__bkt, __k, __code))
	      {
		__ret.node = std::move(__nh);
		__ret.position = iterator(__n);
		__ret.inserted = false;
	      }
	    else
	      {
		__ret.position
		  = _M_insert_unique_node(__bkt, __code, __nh._M_ptr);
		__nh._M_ptr = nullptr;
		__ret.inserted = true;
	      }
	  }
	return __ret;
      }

      /// Re-insert an extracted node into a container with equivalent keys.
      iterator
      _M_reinsert_node_multi(const_iterator __hint, node_type&& __nh)
      {
	if (__nh.empty())
	  return end();

	__glibcxx_assert(get_allocator() == __nh.get_allocator());

	const key_type& __k = __nh._M_key();
	auto __code = this->_M_hash_code(__k);
	auto __ret
	  = _M_insert_multi_node(__hint._M_cur, __code, __nh._M_ptr);
	__nh._M_ptr = nullptr;
	return __ret;
      }

    private:
      node_type
      _M_extract_node(size_t __bkt, __node_base_ptr __prev_n)
      {
	__node_ptr __n = static_cast<__node_ptr>(__prev_n->_M_nxt);
	if (__prev_n == _M_buckets[__bkt])
	  _M_remove_bucket_begin(__bkt, __n->_M_next(),
	     __n->_M_nxt ? _M_bucket_index(*__n->_M_next()) : 0);
	else if (__n->_M_nxt)
	  {
	    size_type __next_bkt = _M_bucket_index(*__n->_M_next());
	    if (__next_bkt != __bkt)
	      _M_buckets[__next_bkt] = __prev_n;
	  }

	__prev_n->_M_nxt = __n->_M_nxt;
	__n->_M_nxt = nullptr;
	--_M_element_count;
	return { __n, this->_M_node_allocator() };
      }

    public:
      // Extract a node.
      node_type
      extract(const_iterator __pos)
      {
	size_t __bkt = _M_bucket_index(*__pos._M_cur);
	return _M_extract_node(__bkt,
			       _M_get_previous_node(__bkt, __pos._M_cur));
      }

      /// Extract a node.
      node_type
      extract(const _Key& __k)
      {
	node_type __nh;
	__hash_code __code = this->_M_hash_code(__k);
	std::size_t __bkt = _M_bucket_index(__code);
	if (__node_base_ptr __prev_node = _M_find_before_node(__bkt, __k, __code))
	  __nh = _M_extract_node(__bkt, __prev_node);
	return __nh;
      }

      /// Merge from a compatible container into one with unique keys.
      template<typename _Compatible_Hashtable>
	void
	_M_merge_unique(_Compatible_Hashtable& __src) noexcept
	{
	  static_assert(is_same_v<typename _Compatible_Hashtable::node_type,
	      node_type>, "Node types are compatible");
	  __glibcxx_assert(get_allocator() == __src.get_allocator());

	  auto __n_elt = __src.size();
	  for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
	    {
	      auto __pos = __i++;
	      const key_type& __k = _ExtractKey{}(*__pos);
	      __hash_code __code = this->_M_hash_code(__k);
	      size_type __bkt = _M_bucket_index(__code);
	      if (_M_find_node(__bkt, __k, __code) == nullptr)
		{
		  auto __nh = __src.extract(__pos);
		  _M_insert_unique_node(__bkt, __code, __nh._M_ptr, __n_elt);
		  __nh._M_ptr = nullptr;
		  __n_elt = 1;
		}
	      else if (__n_elt != 1)
		--__n_elt;
	    }
	}

      /// Merge from a compatible container into one with equivalent keys.
      template<typename _Compatible_Hashtable>
	void
	_M_merge_multi(_Compatible_Hashtable& __src) noexcept
	{
	  static_assert(is_same_v<typename _Compatible_Hashtable::node_type,
	      node_type>, "Node types are compatible");
	  __glibcxx_assert(get_allocator() == __src.get_allocator());

	  this->reserve(size() + __src.size());
	  for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
	    _M_reinsert_node_multi(cend(), __src.extract(__i++));
	}
#endif // C++17

    private:
      // Helper rehash method used when keys are unique.
      void _M_rehash_aux(size_type __bkt_count, true_type __uks);

      // Helper rehash method used when keys can be non-unique.
      void _M_rehash_aux(size_type __bkt_count, false_type __uks);

      // Unconditionally change size of bucket array to n, restore
      // hash policy state to __state on exception.
      void _M_rehash(size_type __bkt_count, const __rehash_state& __state);
    };


  // Definitions of class template _Hashtable's out-of-line member functions.
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_bucket_begin(size_type __bkt) const
    -> __node_ptr
    {
      __node_base_ptr __n = _M_buckets[__bkt];
      return __n ? static_cast<__node_ptr>(__n->_M_nxt) : nullptr;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _Hashtable(size_type __bkt_count_hint,
	       const _Hash& __h, const _Equal& __eq, const allocator_type& __a)
    : _Hashtable(__h, __eq, __a)
    {
      auto __bkt_count = _M_rehash_policy._M_next_bkt(__bkt_count_hint);
      if (__bkt_count > _M_bucket_count)
	{
	  _M_buckets = _M_allocate_buckets(__bkt_count);
	  _M_bucket_count = __bkt_count;
	}
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _InputIterator>
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _Hashtable(_InputIterator __f, _InputIterator __l,
		 size_type __bkt_count_hint,
		 const _Hash& __h, const _Equal& __eq,
		 const allocator_type& __a, true_type /* __uks */)
      : _Hashtable(__bkt_count_hint, __h, __eq, __a)
      {
	for (; __f != __l; ++__f)
	  this->insert(*__f);
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _InputIterator>
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _Hashtable(_InputIterator __f, _InputIterator __l,
		 size_type __bkt_count_hint,
		 const _Hash& __h, const _Equal& __eq,
		 const allocator_type& __a, false_type /* __uks */)
      : _Hashtable(__h, __eq, __a)
      {
	auto __nb_elems = __detail::__distance_fw(__f, __l);
	auto __bkt_count =
	  _M_rehash_policy._M_next_bkt(
	    std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems),
		     __bkt_count_hint));

	if (__bkt_count > _M_bucket_count)
	  {
	    _M_buckets = _M_allocate_buckets(__bkt_count);
	    _M_bucket_count = __bkt_count;
	  }

	for (; __f != __l; ++__f)
	  this->insert(*__f);
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    operator=(const _Hashtable& __ht)
    -> _Hashtable&
    {
      if (&__ht == this)
	return *this;

      if (__node_alloc_traits::_S_propagate_on_copy_assign())
	{
	  auto& __this_alloc = this->_M_node_allocator();
	  auto& __that_alloc = __ht._M_node_allocator();
	  if (!__node_alloc_traits::_S_always_equal()
	      && __this_alloc != __that_alloc)
	    {
	      // Replacement allocator cannot free existing storage.
	      this->_M_deallocate_nodes(_M_begin());
	      _M_before_begin._M_nxt = nullptr;
	      _M_deallocate_buckets();
	      _M_buckets = nullptr;
	      std::__alloc_on_copy(__this_alloc, __that_alloc);
	      __hashtable_base::operator=(__ht);
	      _M_bucket_count = __ht._M_bucket_count;
	      _M_element_count = __ht._M_element_count;
	      _M_rehash_policy = __ht._M_rehash_policy;
	      __alloc_node_gen_t __alloc_node_gen(*this);
	      __try
		{
		  _M_assign(__ht, __alloc_node_gen);
		}
	      __catch(...)
		{
		  // _M_assign took care of deallocating all memory. Now we
		  // must make sure this instance remains in a usable state.
		  _M_reset();
		  __throw_exception_again;
		}
	      return *this;
	    }
	  std::__alloc_on_copy(__this_alloc, __that_alloc);
	}

      // Reuse allocated buckets and nodes.
      _M_assign_elements(__ht);
      return *this;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Ht>
      void
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_assign_elements(_Ht&& __ht)
      {
	__buckets_ptr __former_buckets = nullptr;
	std::size_t __former_bucket_count = _M_bucket_count;
	const __rehash_state& __former_state = _M_rehash_policy._M_state();

	if (_M_bucket_count != __ht._M_bucket_count)
	  {
	    __former_buckets = _M_buckets;
	    _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
	    _M_bucket_count = __ht._M_bucket_count;
	  }
	else
	  __builtin_memset(_M_buckets, 0,
			   _M_bucket_count * sizeof(__node_base_ptr));

	__try
	  {
	    __hashtable_base::operator=(std::forward<_Ht>(__ht));
	    _M_element_count = __ht._M_element_count;
	    _M_rehash_policy = __ht._M_rehash_policy;
	    __reuse_or_alloc_node_gen_t __roan(_M_begin(), *this);
	    _M_before_begin._M_nxt = nullptr;
	    _M_assign(std::forward<_Ht>(__ht), __roan);
	    if (__former_buckets)
	      _M_deallocate_buckets(__former_buckets, __former_bucket_count);
	  }
	__catch(...)
	  {
	    if (__former_buckets)
	      {
		// Restore previous buckets.
		_M_deallocate_buckets();
		_M_rehash_policy._M_reset(__former_state);
		_M_buckets = __former_buckets;
		_M_bucket_count = __former_bucket_count;
	      }
	    __builtin_memset(_M_buckets, 0,
			     _M_bucket_count * sizeof(__node_base_ptr));
	    __throw_exception_again;
	  }
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Ht, typename _NodeGenerator>
      void
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_assign(_Ht&& __ht, const _NodeGenerator& __node_gen)
      {
	__buckets_ptr __buckets = nullptr;
	if (!_M_buckets)
	  _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count);

	__try
	  {
	    if (!__ht._M_before_begin._M_nxt)
	      return;

	    // First deal with the special first node pointed to by
	    // _M_before_begin.
	    __node_ptr __ht_n = __ht._M_begin();
	    __node_ptr __this_n
	      = __node_gen(__fwd_value_for<_Ht>(__ht_n->_M_v()));
	    this->_M_copy_code(*__this_n, *__ht_n);
	    _M_update_bbegin(__this_n);

	    // Then deal with other nodes.
	    __node_ptr __prev_n = __this_n;
	    for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next())
	      {
		__this_n = __node_gen(__fwd_value_for<_Ht>(__ht_n->_M_v()));
		__prev_n->_M_nxt = __this_n;
		this->_M_copy_code(*__this_n, *__ht_n);
		size_type __bkt = _M_bucket_index(*__this_n);
		if (!_M_buckets[__bkt])
		  _M_buckets[__bkt] = __prev_n;
		__prev_n = __this_n;
	      }
	  }
	__catch(...)
	  {
	    clear();
	    if (__buckets)
	      _M_deallocate_buckets();
	    __throw_exception_again;
	  }
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_reset() noexcept
    {
      _M_rehash_policy._M_reset();
      _M_bucket_count = 1;
      _M_single_bucket = nullptr;
      _M_buckets = &_M_single_bucket;
      _M_before_begin._M_nxt = nullptr;
      _M_element_count = 0;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_move_assign(_Hashtable&& __ht, true_type)
    {
      if (__builtin_expect(std::__addressof(__ht) == this, false))
	return;

      this->_M_deallocate_nodes(_M_begin());
      _M_deallocate_buckets();
      __hashtable_base::operator=(std::move(__ht));
      _M_rehash_policy = __ht._M_rehash_policy;
      if (!__ht._M_uses_single_bucket())
	_M_buckets = __ht._M_buckets;
      else
	{
	  _M_buckets = &_M_single_bucket;
	  _M_single_bucket = __ht._M_single_bucket;
	}

      _M_bucket_count = __ht._M_bucket_count;
      _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
      _M_element_count = __ht._M_element_count;
      std::__alloc_on_move(this->_M_node_allocator(), __ht._M_node_allocator());

      // Fix bucket containing the _M_before_begin pointer that can't be moved.
      _M_update_bbegin();
      __ht._M_reset();
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_move_assign(_Hashtable&& __ht, false_type)
    {
      if (__ht._M_node_allocator() == this->_M_node_allocator())
	_M_move_assign(std::move(__ht), true_type{});
      else
	{
	  // Can't move memory, move elements then.
	  _M_assign_elements(std::move(__ht));
	  __ht.clear();
	}
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _Hashtable(const _Hashtable& __ht)
    : __hashtable_base(__ht),
      __map_base(__ht),
      __rehash_base(__ht),
      __hashtable_alloc(
	__node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())),
      __enable_default_ctor(__ht),
      _M_buckets(nullptr),
      _M_bucket_count(__ht._M_bucket_count),
      _M_element_count(__ht._M_element_count),
      _M_rehash_policy(__ht._M_rehash_policy)
    {
      __alloc_node_gen_t __alloc_node_gen(*this);
      _M_assign(__ht, __alloc_node_gen);
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
	       true_type /* alloc always equal */)
    noexcept(_S_nothrow_move())
    : __hashtable_base(__ht),
      __map_base(__ht),
      __rehash_base(__ht),
      __hashtable_alloc(std::move(__a)),
      __enable_default_ctor(__ht),
      _M_buckets(__ht._M_buckets),
      _M_bucket_count(__ht._M_bucket_count),
      _M_before_begin(__ht._M_before_begin._M_nxt),
      _M_element_count(__ht._M_element_count),
      _M_rehash_policy(__ht._M_rehash_policy)
    {
      // Update buckets if __ht is using its single bucket.
      if (__ht._M_uses_single_bucket())
	{
	  _M_buckets = &_M_single_bucket;
	  _M_single_bucket = __ht._M_single_bucket;
	}

      // Fix bucket containing the _M_before_begin pointer that can't be moved.
      _M_update_bbegin();

      __ht._M_reset();
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _Hashtable(const _Hashtable& __ht, const allocator_type& __a)
    : __hashtable_base(__ht),
      __map_base(__ht),
      __rehash_base(__ht),
      __hashtable_alloc(__node_alloc_type(__a)),
      __enable_default_ctor(__ht),
      _M_buckets(),
      _M_bucket_count(__ht._M_bucket_count),
      _M_element_count(__ht._M_element_count),
      _M_rehash_policy(__ht._M_rehash_policy)
    {
      __alloc_node_gen_t __alloc_node_gen(*this);
      _M_assign(__ht, __alloc_node_gen);
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a,
	       false_type /* alloc always equal */)
    : __hashtable_base(__ht),
      __map_base(__ht),
      __rehash_base(__ht),
      __hashtable_alloc(std::move(__a)),
      __enable_default_ctor(__ht),
      _M_buckets(nullptr),
      _M_bucket_count(__ht._M_bucket_count),
      _M_element_count(__ht._M_element_count),
      _M_rehash_policy(__ht._M_rehash_policy)
    {
      if (__ht._M_node_allocator() == this->_M_node_allocator())
	{
	  if (__ht._M_uses_single_bucket())
	    {
	      _M_buckets = &_M_single_bucket;
	      _M_single_bucket = __ht._M_single_bucket;
	    }
	  else
	    _M_buckets = __ht._M_buckets;

	  // Fix bucket containing the _M_before_begin pointer that can't be
	  // moved.
	  _M_update_bbegin(__ht._M_begin());

	  __ht._M_reset();
	}
      else
	{
	  __alloc_node_gen_t __alloc_gen(*this);

	  using _Fwd_Ht = __conditional_t<
	    __move_if_noexcept_cond<value_type>::value,
	    const _Hashtable&, _Hashtable&&>;
	  _M_assign(std::forward<_Fwd_Ht>(__ht), __alloc_gen);
	  __ht.clear();
	}
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    ~_Hashtable() noexcept
    {
      // Getting a bucket index from a node shall not throw because it is used
      // in methods (erase, swap...) that shall not throw. Need a complete
      // type to check this, so do it in the destructor not at class scope.
      static_assert(noexcept(declval<const __hash_code_base_access&>()
			._M_bucket_index(declval<const __node_value_type&>(),
					 (std::size_t)0)),
		    "Cache the hash code or qualify your functors involved"
		    " in hash code and bucket index computation with noexcept");

      clear();
      _M_deallocate_buckets();
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    swap(_Hashtable& __x)
    noexcept(__and_<__is_nothrow_swappable<_Hash>,
			__is_nothrow_swappable<_Equal>>::value)
    {
      // The only base class with member variables is hash_code_base.
      // We define _Hash_code_base::_M_swap because different
      // specializations have different members.
      this->_M_swap(__x);

      std::__alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator());
      std::swap(_M_rehash_policy, __x._M_rehash_policy);

      // Deal properly with potentially moved instances.
      if (this->_M_uses_single_bucket())
	{
	  if (!__x._M_uses_single_bucket())
	    {
	      _M_buckets = __x._M_buckets;
	      __x._M_buckets = &__x._M_single_bucket;
	    }
	}
      else if (__x._M_uses_single_bucket())
	{
	  __x._M_buckets = _M_buckets;
	  _M_buckets = &_M_single_bucket;
	}	
      else
	std::swap(_M_buckets, __x._M_buckets);

      std::swap(_M_bucket_count, __x._M_bucket_count);
      std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt);
      std::swap(_M_element_count, __x._M_element_count);
      std::swap(_M_single_bucket, __x._M_single_bucket);

      // Fix buckets containing the _M_before_begin pointers that can't be
      // swapped.
      _M_update_bbegin();
      __x._M_update_bbegin();
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    find(const key_type& __k)
    -> iterator
    {
      __hash_code __code = this->_M_hash_code(__k);
      std::size_t __bkt = _M_bucket_index(__code);
      return iterator(_M_find_node(__bkt, __k, __code));
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    find(const key_type& __k) const
    -> const_iterator
    {
      __hash_code __code = this->_M_hash_code(__k);
      std::size_t __bkt = _M_bucket_index(__code);
      return const_iterator(_M_find_node(__bkt, __k, __code));
    }

#if __cplusplus > 201703L
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Kt, typename, typename>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_find_tr(const _Kt& __k)
      -> iterator
      {
	__hash_code __code = this->_M_hash_code_tr(__k);
	std::size_t __bkt = _M_bucket_index(__code);
	return iterator(_M_find_node_tr(__bkt, __k, __code));
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Kt, typename, typename>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_find_tr(const _Kt& __k) const
      -> const_iterator
      {
	__hash_code __code = this->_M_hash_code_tr(__k);
	std::size_t __bkt = _M_bucket_index(__code);
	return const_iterator(_M_find_node_tr(__bkt, __k, __code));
      }
#endif

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    count(const key_type& __k) const
    -> size_type
    {
      auto __it = find(__k);
      if (!__it._M_cur)
	return 0;

      if (__unique_keys::value)
	return 1;

      // All equivalent values are next to each other, if we find a
      // non-equivalent value after an equivalent one it means that we won't
      // find any new equivalent value.
      size_type __result = 1;
      for (auto __ref = __it++;
	   __it._M_cur && this->_M_node_equals(*__ref._M_cur, *__it._M_cur);
	   ++__it)
	++__result;

      return __result;
    }

#if __cplusplus > 201703L
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Kt, typename, typename>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_count_tr(const _Kt& __k) const
      -> size_type
      {
	__hash_code __code = this->_M_hash_code_tr(__k);
	std::size_t __bkt = _M_bucket_index(__code);
	auto __n = _M_find_node_tr(__bkt, __k, __code);
	if (!__n)
	  return 0;

	// All equivalent values are next to each other, if we find a
	// non-equivalent value after an equivalent one it means that we won't
	// find any new equivalent value.
	iterator __it(__n);
	size_type __result = 1;
	for (++__it;
	     __it._M_cur && this->_M_equals_tr(__k, __code, *__it._M_cur);
	     ++__it)
	  ++__result;

	return __result;
      }
#endif

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    equal_range(const key_type& __k)
    -> pair<iterator, iterator>
    {
      auto __ite = find(__k);
      if (!__ite._M_cur)
	return { __ite, __ite };

      auto __beg = __ite++;
      if (__unique_keys::value)
	return { __beg, __ite };

      // All equivalent values are next to each other, if we find a
      // non-equivalent value after an equivalent one it means that we won't
      // find any new equivalent value.
      while (__ite._M_cur && this->_M_node_equals(*__beg._M_cur, *__ite._M_cur))
	++__ite;

      return { __beg, __ite };
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    equal_range(const key_type& __k) const
    -> pair<const_iterator, const_iterator>
    {
      auto __ite = find(__k);
      if (!__ite._M_cur)
	return { __ite, __ite };

      auto __beg = __ite++;
      if (__unique_keys::value)
	return { __beg, __ite };

      // All equivalent values are next to each other, if we find a
      // non-equivalent value after an equivalent one it means that we won't
      // find any new equivalent value.
      while (__ite._M_cur && this->_M_node_equals(*__beg._M_cur, *__ite._M_cur))
	++__ite;

      return { __beg, __ite };
    }

#if __cplusplus > 201703L
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Kt, typename, typename>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_equal_range_tr(const _Kt& __k)
      -> pair<iterator, iterator>
      {
	__hash_code __code = this->_M_hash_code_tr(__k);
	std::size_t __bkt = _M_bucket_index(__code);
	auto __n = _M_find_node_tr(__bkt, __k, __code);
	iterator __ite(__n);
	if (!__n)
	  return { __ite, __ite };

	// All equivalent values are next to each other, if we find a
	// non-equivalent value after an equivalent one it means that we won't
	// find any new equivalent value.
	auto __beg = __ite++;
	while (__ite._M_cur && this->_M_equals_tr(__k, __code, *__ite._M_cur))
	  ++__ite;

	return { __beg, __ite };
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Kt, typename, typename>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_equal_range_tr(const _Kt& __k) const
      -> pair<const_iterator, const_iterator>
      {
	__hash_code __code = this->_M_hash_code_tr(__k);
	std::size_t __bkt = _M_bucket_index(__code);
	auto __n = _M_find_node_tr(__bkt, __k, __code);
	const_iterator __ite(__n);
	if (!__n)
	  return { __ite, __ite };

	// All equivalent values are next to each other, if we find a
	// non-equivalent value after an equivalent one it means that we won't
	// find any new equivalent value.
	auto __beg = __ite++;
	while (__ite._M_cur && this->_M_equals_tr(__k, __code, *__ite._M_cur))
	  ++__ite;

	return { __beg, __ite };
      }
#endif

  // Find the node before the one whose key compares equal to k in the bucket
  // bkt. Return nullptr if no node is found.
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_find_before_node(size_type __bkt, const key_type& __k,
			__hash_code __code) const
    -> __node_base_ptr
    {
      __node_base_ptr __prev_p = _M_buckets[__bkt];
      if (!__prev_p)
	return nullptr;

      for (__node_ptr __p = static_cast<__node_ptr>(__prev_p->_M_nxt);;
	   __p = __p->_M_next())
	{
	  if (this->_M_equals(__k, __code, *__p))
	    return __prev_p;

	  if (!__p->_M_nxt || _M_bucket_index(*__p->_M_next()) != __bkt)
	    break;
	  __prev_p = __p;
	}

      return nullptr;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Kt>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_find_before_node_tr(size_type __bkt, const _Kt& __k,
			     __hash_code __code) const
      -> __node_base_ptr
      {
	__node_base_ptr __prev_p = _M_buckets[__bkt];
	if (!__prev_p)
	  return nullptr;

	for (__node_ptr __p = static_cast<__node_ptr>(__prev_p->_M_nxt);;
	     __p = __p->_M_next())
	  {
	    if (this->_M_equals_tr(__k, __code, *__p))
	      return __prev_p;

	    if (!__p->_M_nxt || _M_bucket_index(*__p->_M_next()) != __bkt)
	      break;
	    __prev_p = __p;
	  }

	return nullptr;
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_insert_bucket_begin(size_type __bkt, __node_ptr __node)
    {
      if (_M_buckets[__bkt])
	{
	  // Bucket is not empty, we just need to insert the new node
	  // after the bucket before begin.
	  __node->_M_nxt = _M_buckets[__bkt]->_M_nxt;
	  _M_buckets[__bkt]->_M_nxt = __node;
	}
      else
	{
	  // The bucket is empty, the new node is inserted at the
	  // beginning of the singly-linked list and the bucket will
	  // contain _M_before_begin pointer.
	  __node->_M_nxt = _M_before_begin._M_nxt;
	  _M_before_begin._M_nxt = __node;

	  if (__node->_M_nxt)
	    // We must update former begin bucket that is pointing to
	    // _M_before_begin.
	    _M_buckets[_M_bucket_index(*__node->_M_next())] = __node;

	  _M_buckets[__bkt] = &_M_before_begin;
	}
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_remove_bucket_begin(size_type __bkt, __node_ptr __next,
			   size_type __next_bkt)
    {
      if (!__next || __next_bkt != __bkt)
	{
	  // Bucket is now empty
	  // First update next bucket if any
	  if (__next)
	    _M_buckets[__next_bkt] = _M_buckets[__bkt];

	  // Second update before begin node if necessary
	  if (&_M_before_begin == _M_buckets[__bkt])
	    _M_before_begin._M_nxt = __next;
	  _M_buckets[__bkt] = nullptr;
	}
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_get_previous_node(size_type __bkt, __node_ptr __n)
    -> __node_base_ptr
    {
      __node_base_ptr __prev_n = _M_buckets[__bkt];
      while (__prev_n->_M_nxt != __n)
	__prev_n = __prev_n->_M_nxt;
      return __prev_n;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename... _Args>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_emplace(true_type /* __uks */, _Args&&... __args)
      -> pair<iterator, bool>
      {
	// First build the node to get access to the hash code
	_Scoped_node __node { this, std::forward<_Args>(__args)...  };
	const key_type& __k = _ExtractKey{}(__node._M_node->_M_v());
	__hash_code __code = this->_M_hash_code(__k);
	size_type __bkt = _M_bucket_index(__code);
	if (__node_ptr __p = _M_find_node(__bkt, __k, __code))
	  // There is already an equivalent node, no insertion
	  return std::make_pair(iterator(__p), false);

	// Insert the node
	auto __pos = _M_insert_unique_node(__bkt, __code, __node._M_node);
	__node._M_node = nullptr;
	return { __pos, true };
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename... _Args>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_emplace(const_iterator __hint, false_type /* __uks */,
		 _Args&&... __args)
      -> iterator
      {
	// First build the node to get its hash code.
	_Scoped_node __node { this, std::forward<_Args>(__args)...  };
	const key_type& __k = _ExtractKey{}(__node._M_node->_M_v());

	__hash_code __code = this->_M_hash_code(__k);
	auto __pos
	  = _M_insert_multi_node(__hint._M_cur, __code, __node._M_node);
	__node._M_node = nullptr;
	return __pos;
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_insert_unique_node(size_type __bkt, __hash_code __code,
			  __node_ptr __node, size_type __n_elt)
    -> iterator
    {
      const __rehash_state& __saved_state = _M_rehash_policy._M_state();
      std::pair<bool, std::size_t> __do_rehash
	= _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count,
					  __n_elt);

      if (__do_rehash.first)
	{
	  _M_rehash(__do_rehash.second, __saved_state);
	  __bkt = _M_bucket_index(__code);
	}

      this->_M_store_code(*__node, __code);

      // Always insert at the beginning of the bucket.
      _M_insert_bucket_begin(__bkt, __node);
      ++_M_element_count;
      return iterator(__node);
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_insert_multi_node(__node_ptr __hint,
			 __hash_code __code, __node_ptr __node)
    -> iterator
    {
      const __rehash_state& __saved_state = _M_rehash_policy._M_state();
      std::pair<bool, std::size_t> __do_rehash
	= _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1);

      if (__do_rehash.first)
	_M_rehash(__do_rehash.second, __saved_state);

      this->_M_store_code(*__node, __code);
      const key_type& __k = _ExtractKey{}(__node->_M_v());
      size_type __bkt = _M_bucket_index(__code);

      // Find the node before an equivalent one or use hint if it exists and
      // if it is equivalent.
      __node_base_ptr __prev
	= __builtin_expect(__hint != nullptr, false)
	  && this->_M_equals(__k, __code, *__hint)
	    ? __hint
	    : _M_find_before_node(__bkt, __k, __code);

      if (__prev)
	{
	  // Insert after the node before the equivalent one.
	  __node->_M_nxt = __prev->_M_nxt;
	  __prev->_M_nxt = __node;
	  if (__builtin_expect(__prev == __hint, false))
	    // hint might be the last bucket node, in this case we need to
	    // update next bucket.
	    if (__node->_M_nxt
		&& !this->_M_equals(__k, __code, *__node->_M_next()))
	      {
		size_type __next_bkt = _M_bucket_index(*__node->_M_next());
		if (__next_bkt != __bkt)
		  _M_buckets[__next_bkt] = __node;
	      }
	}
      else
	// The inserted node has no equivalent in the hashtable. We must
	// insert the new node at the beginning of the bucket to preserve
	// equivalent elements' relative positions.
	_M_insert_bucket_begin(__bkt, __node);
      ++_M_element_count;
      return iterator(__node);
    }

  // Insert v if no element with its key is already present.
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Kt, typename _Arg, typename _NodeGenerator>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_insert_unique(_Kt&& __k, _Arg&& __v,
		       const _NodeGenerator& __node_gen)
      -> pair<iterator, bool>
      {
	__hash_code __code = this->_M_hash_code_tr(__k);
	size_type __bkt = _M_bucket_index(__code);

	if (__node_ptr __node = _M_find_node_tr(__bkt, __k, __code))
	  return { iterator(__node), false };

	_Scoped_node __node {
	  __node_builder_t::_S_build(std::forward<_Kt>(__k),
				     std::forward<_Arg>(__v),
				     __node_gen),
	  this
	};
	auto __pos
	  = _M_insert_unique_node(__bkt, __code, __node._M_node);
	__node._M_node = nullptr;
	return { __pos, true };
      }

  // Insert v unconditionally.
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _Arg, typename _NodeGenerator>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_insert(const_iterator __hint, _Arg&& __v,
		const _NodeGenerator& __node_gen,
		false_type /* __uks */)
      -> iterator
      {
	// First allocate new node so that we don't do anything if it throws.
	_Scoped_node __node{ __node_gen(std::forward<_Arg>(__v)), this };

	// Second compute the hash code so that we don't rehash if it throws.
	__hash_code __code
	  = this->_M_hash_code(_ExtractKey{}(__node._M_node->_M_v()));

	auto __pos
	  = _M_insert_multi_node(__hint._M_cur, __code, __node._M_node);
	__node._M_node = nullptr;
	return __pos;
      }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    erase(const_iterator __it)
    -> iterator
    {
      __node_ptr __n = __it._M_cur;
      std::size_t __bkt = _M_bucket_index(*__n);

      // Look for previous node to unlink it from the erased one, this
      // is why we need buckets to contain the before begin to make
      // this search fast.
      __node_base_ptr __prev_n = _M_get_previous_node(__bkt, __n);
      return _M_erase(__bkt, __prev_n, __n);
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_erase(size_type __bkt, __node_base_ptr __prev_n, __node_ptr __n)
    -> iterator
    {
      if (__prev_n == _M_buckets[__bkt])
	_M_remove_bucket_begin(__bkt, __n->_M_next(),
	  __n->_M_nxt ? _M_bucket_index(*__n->_M_next()) : 0);
      else if (__n->_M_nxt)
	{
	  size_type __next_bkt = _M_bucket_index(*__n->_M_next());
	  if (__next_bkt != __bkt)
	    _M_buckets[__next_bkt] = __prev_n;
	}

      __prev_n->_M_nxt = __n->_M_nxt;
      iterator __result(__n->_M_next());
      this->_M_deallocate_node(__n);
      --_M_element_count;

      return __result;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_erase(true_type /* __uks */, const key_type& __k)
    -> size_type
    {
      __hash_code __code = this->_M_hash_code(__k);
      std::size_t __bkt = _M_bucket_index(__code);

      // Look for the node before the first matching node.
      __node_base_ptr __prev_n = _M_find_before_node(__bkt, __k, __code);
      if (!__prev_n)
	return 0;

      // We found a matching node, erase it.
      __node_ptr __n = static_cast<__node_ptr>(__prev_n->_M_nxt);
      _M_erase(__bkt, __prev_n, __n);
      return 1;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_erase(false_type /* __uks */, const key_type& __k)
    -> size_type
    {
      __hash_code __code = this->_M_hash_code(__k);
      std::size_t __bkt = _M_bucket_index(__code);

      // Look for the node before the first matching node.
      __node_base_ptr __prev_n = _M_find_before_node(__bkt, __k, __code);
      if (!__prev_n)
	return 0;

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 526. Is it undefined if a function in the standard changes
      // in parameters?
      // We use one loop to find all matching nodes and another to deallocate
      // them so that the key stays valid during the first loop. It might be
      // invalidated indirectly when destroying nodes.
      __node_ptr __n = static_cast<__node_ptr>(__prev_n->_M_nxt);
      __node_ptr __n_last = __n->_M_next();
      while (__n_last && this->_M_node_equals(*__n, *__n_last))
	__n_last = __n_last->_M_next();

      std::size_t __n_last_bkt = __n_last ? _M_bucket_index(*__n_last) : __bkt;

      // Deallocate nodes.
      size_type __result = 0;
      do
	{
	  __node_ptr __p = __n->_M_next();
	  this->_M_deallocate_node(__n);
	  __n = __p;
	  ++__result;
	}
      while (__n != __n_last);

      _M_element_count -= __result;
      if (__prev_n == _M_buckets[__bkt])
	_M_remove_bucket_begin(__bkt, __n_last, __n_last_bkt);
      else if (__n_last_bkt != __bkt)
	_M_buckets[__n_last_bkt] = __prev_n;
      __prev_n->_M_nxt = __n_last;
      return __result;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    auto
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    erase(const_iterator __first, const_iterator __last)
    -> iterator
    {
      __node_ptr __n = __first._M_cur;
      __node_ptr __last_n = __last._M_cur;
      if (__n == __last_n)
	return iterator(__n);

      std::size_t __bkt = _M_bucket_index(*__n);

      __node_base_ptr __prev_n = _M_get_previous_node(__bkt, __n);
      bool __is_bucket_begin = __n == _M_bucket_begin(__bkt);
      std::size_t __n_bkt = __bkt;
      for (;;)
	{
	  do
	    {
	      __node_ptr __tmp = __n;
	      __n = __n->_M_next();
	      this->_M_deallocate_node(__tmp);
	      --_M_element_count;
	      if (!__n)
		break;
	      __n_bkt = _M_bucket_index(*__n);
	    }
	  while (__n != __last_n && __n_bkt == __bkt);
	  if (__is_bucket_begin)
	    _M_remove_bucket_begin(__bkt, __n, __n_bkt);
	  if (__n == __last_n)
	    break;
	  __is_bucket_begin = true;
	  __bkt = __n_bkt;
	}

      if (__n && (__n_bkt != __bkt || __is_bucket_begin))
	_M_buckets[__n_bkt] = __prev_n;
      __prev_n->_M_nxt = __n;
      return iterator(__n);
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    clear() noexcept
    {
      this->_M_deallocate_nodes(_M_begin());
      __builtin_memset(_M_buckets, 0,
		       _M_bucket_count * sizeof(__node_base_ptr));
      _M_element_count = 0;
      _M_before_begin._M_nxt = nullptr;
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    rehash(size_type __bkt_count)
    {
      const __rehash_state& __saved_state = _M_rehash_policy._M_state();
      __bkt_count
	= std::max(_M_rehash_policy._M_bkt_for_elements(_M_element_count + 1),
		   __bkt_count);
      __bkt_count = _M_rehash_policy._M_next_bkt(__bkt_count);

      if (__bkt_count != _M_bucket_count)
	_M_rehash(__bkt_count, __saved_state);
      else
	// No rehash, restore previous state to keep it consistent with
	// container state.
	_M_rehash_policy._M_reset(__saved_state);
    }

  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_rehash(size_type __bkt_count, const __rehash_state& __state)
    {
      __try
	{
	  _M_rehash_aux(__bkt_count, __unique_keys{});
	}
      __catch(...)
	{
	  // A failure here means that buckets allocation failed.  We only
	  // have to restore hash policy previous state.
	  _M_rehash_policy._M_reset(__state);
	  __throw_exception_again;
	}
    }

  // Rehash when there is no equivalent elements.
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_rehash_aux(size_type __bkt_count, true_type /* __uks */)
    {
      __buckets_ptr __new_buckets = _M_allocate_buckets(__bkt_count);
      __node_ptr __p = _M_begin();
      _M_before_begin._M_nxt = nullptr;
      std::size_t __bbegin_bkt = 0;
      while (__p)
	{
	  __node_ptr __next = __p->_M_next();
	  std::size_t __bkt
	    = __hash_code_base::_M_bucket_index(*__p, __bkt_count);
	  if (!__new_buckets[__bkt])
	    {
	      __p->_M_nxt = _M_before_begin._M_nxt;
	      _M_before_begin._M_nxt = __p;
	      __new_buckets[__bkt] = &_M_before_begin;
	      if (__p->_M_nxt)
		__new_buckets[__bbegin_bkt] = __p;
	      __bbegin_bkt = __bkt;
	    }
	  else
	    {
	      __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
	      __new_buckets[__bkt]->_M_nxt = __p;
	    }

	  __p = __next;
	}

      _M_deallocate_buckets();
      _M_bucket_count = __bkt_count;
      _M_buckets = __new_buckets;
    }

  // Rehash when there can be equivalent elements, preserve their relative
  // order.
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    void
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_rehash_aux(size_type __bkt_count, false_type /* __uks */)
    {
      __buckets_ptr __new_buckets = _M_allocate_buckets(__bkt_count);
      __node_ptr __p = _M_begin();
      _M_before_begin._M_nxt = nullptr;
      std::size_t __bbegin_bkt = 0;
      std::size_t __prev_bkt = 0;
      __node_ptr __prev_p = nullptr;
      bool __check_bucket = false;

      while (__p)
	{
	  __node_ptr __next = __p->_M_next();
	  std::size_t __bkt
	    = __hash_code_base::_M_bucket_index(*__p, __bkt_count);

	  if (__prev_p && __prev_bkt == __bkt)
	    {
	      // Previous insert was already in this bucket, we insert after
	      // the previously inserted one to preserve equivalent elements
	      // relative order.
	      __p->_M_nxt = __prev_p->_M_nxt;
	      __prev_p->_M_nxt = __p;

	      // Inserting after a node in a bucket require to check that we
	      // haven't change the bucket last node, in this case next
	      // bucket containing its before begin node must be updated. We
	      // schedule a check as soon as we move out of the sequence of
	      // equivalent nodes to limit the number of checks.
	      __check_bucket = true;
	    }
	  else
	    {
	      if (__check_bucket)
		{
		  // Check if we shall update the next bucket because of
		  // insertions into __prev_bkt bucket.
		  if (__prev_p->_M_nxt)
		    {
		      std::size_t __next_bkt
			= __hash_code_base::_M_bucket_index(
			  *__prev_p->_M_next(), __bkt_count);
		      if (__next_bkt != __prev_bkt)
			__new_buckets[__next_bkt] = __prev_p;
		    }
		  __check_bucket = false;
		}

	      if (!__new_buckets[__bkt])
		{
		  __p->_M_nxt = _M_before_begin._M_nxt;
		  _M_before_begin._M_nxt = __p;
		  __new_buckets[__bkt] = &_M_before_begin;
		  if (__p->_M_nxt)
		    __new_buckets[__bbegin_bkt] = __p;
		  __bbegin_bkt = __bkt;
		}
	      else
		{
		  __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
		  __new_buckets[__bkt]->_M_nxt = __p;
		}
	    }
	  __prev_p = __p;
	  __prev_bkt = __bkt;
	  __p = __next;
	}

      if (__check_bucket && __prev_p->_M_nxt)
	{
	  std::size_t __next_bkt
	    = __hash_code_base::_M_bucket_index(*__prev_p->_M_next(),
						__bkt_count);
	  if (__next_bkt != __prev_bkt)
	    __new_buckets[__next_bkt] = __prev_p;
	}

      _M_deallocate_buckets();
      _M_bucket_count = __bkt_count;
      _M_buckets = __new_buckets;
    }

#if __cplusplus > 201402L
  template<typename, typename, typename> class _Hash_merge_helper { };
#endif // C++17

#if __cpp_deduction_guides >= 201606
  // Used to constrain deduction guides
  template<typename _Hash>
    using _RequireNotAllocatorOrIntegral
      = __enable_if_t<!__or_<is_integral<_Hash>, __is_allocator<_Hash>>::value>;
#endif

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // _HASHTABLE_H
