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

// Copyright (C) 2007-2026 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

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bits/hashtable_policy.h>
#include <bits/enable_special_members.h>
#include <bits/stl_algobase.h> // fill_n, is_permutation
#include <bits/stl_function.h> // __has_is_transparent_t
#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
# include <bits/node_handle.h>
#endif

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++11-extensions"

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented

  template<typename _Tp, typename _Hash>
    using __cache_default
      =  __not_<__and_<// Do not cache for fast hasher.
		       __is_fast_hash<_Hash>,
		       // Mandatory for the rehash process.
		       __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.
   *
   *  Note that all equivalent values, if any, 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.
   *
   *  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 and
   *  _Rehash_base 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::_Rehash_base
   */
  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::_Rehash_base<_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
      static_assert(is_copy_constructible<_Hash>::value,
	  "hash function must be copy constructible");

      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 __enable_default_ctor
	= _Hashtable_enable_default_ctor<_Equal, _Hash, _Alloc>;
      using __rehash_guard_t
	= __detail::_RehashStateGuard<_RehashPolicy>;

    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
	= __detail::_Node_iterator<_Value, __constant_iterators::value,
				   __hash_cached::value>;

      using const_iterator
	= __detail::_Node_const_iterator<_Value, __constant_iterators::value,
					 __hash_cached::value>;

      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 __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 = __conditional_t<__unique_keys::value,
					     std::pair<iterator, bool>,
					     iterator>;

      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 __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;
      };

      // 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 to be non-throwing.
      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 _ExtractKey to be non-throwing.
      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;

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

#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
      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 (auto __begin = _M_begin())
	  _M_buckets[_M_bucket_index(*__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); }

      static constexpr size_t
      __small_size_threshold() noexcept
      {
	return
	  __detail::_Hashtable_hash_traits<_Hash>::__small_size_threshold();
      }

      __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_base_ptr __n = _M_buckets[__bkt];
	return __n ? static_cast<__node_ptr>(__n->_M_nxt) : nullptr;
      }

      __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>
	void
	_M_assign(_Ht&& __ht)
	{
	  __detail::_AllocNode<__node_alloc_type> __alloc_node_gen(*this);
	  _M_assign(std::forward<_Ht>(__ht), __alloc_node_gen);
	}

      template<typename _Ht, typename _NodeGenerator>
	void
	_M_assign(_Ht&&, _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 __cpp_constexpr >= 201304 // >= C++14
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
	  if constexpr (_No_realloc)
	    if constexpr (is_nothrow_copy_constructible<_Hash>::value)
	      return is_nothrow_copy_constructible<_Equal>::value;
	  return false;
# pragma GCC diagnostic pop
#else // In C++11 a constexpr function must be a single statement.
	  return __and_<__bool_constant<_No_realloc>,
			is_nothrow_copy_constructible<_Hash>,
			is_nothrow_copy_constructible<_Equal>>::value;
#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;
      }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
      _Hashtable&
      operator=(initializer_list<value_type> __l)
      {
	using __reuse_or_alloc_node_gen_t =
	  __detail::_ReuseOrAllocNode<__node_alloc_type>;

	__reuse_or_alloc_node_gen_t __roan(_M_begin(), *this);
	_M_before_begin._M_nxt = nullptr;
	clear();

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

	// Excess buckets might have been intentionally reserved by the user,
	// so rehash if we need to grow, but don't shrink.
	if (_M_bucket_count < __l_bkt_count)
	  rehash(__l_bkt_count);

	__hash_code __code;
	size_type __bkt;
	for (auto& __e : __l)
	  {
	    const key_type& __k = _ExtractKey{}(__e);

	    if constexpr (__unique_keys::value)
	      {
		if (auto __loc = _M_locate(__k))
		  continue; // Found existing element with equivalent key
		else
		  {
		    __code = __loc._M_hash_code;
		    __bkt = __loc._M_bucket_index;
		  }
	      }
	    else
	      {
		__code = this->_M_hash_code(__k);
		__bkt = _M_bucket_index(__code);
	      }

	    _M_insert_unique_node(__bkt, __code, __roan(__e));
	  }

	return *this;
      }
#pragma GCC diagnostic pop

      ~_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)); }

#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26
      template <typename _Kt>
	size_type
	_M_bucket_tr(const _Kt& __k) const
	{ return _M_bucket_index(this->_M_hash_code_tr(__k)); }
#endif

      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;

#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
      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 // __glibcxx_generic_unordered_lookup

      void _M_rehash_insert(size_type __n);

    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); }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
      // Get hash code for a node that comes from another _Hashtable.
      // Reuse a cached hash code if the hash function is stateless,
      // otherwise recalculate it using our own hash function.
      __hash_code
      _M_hash_code_ext(const __node_value_type& __from) const
      {
	if constexpr (__and_<__hash_cached, is_empty<_Hash>>::value)
	  return __from._M_hash_code;
	else
	  return this->_M_hash_code(_ExtractKey{}(__from._M_v()));
      }

      // Like _M_bucket_index but when the node is coming from another
      // container instance.
      size_type
      _M_bucket_index_ext(const __node_value_type& __from) const
      { return _RangeHash{}(_M_hash_code_ext(__from), _M_bucket_count); }

      void
      _M_copy_code(__node_value_type& __to,
		   const __node_value_type& __from) const
      {
	if constexpr (__hash_cached::value)
	  __to._M_hash_code = _M_hash_code_ext(__from);
      }

      void
      _M_store_code(__node_value_type& __to, __hash_code __code) const
      {
	if constexpr (__hash_cached::value)
	  __to._M_hash_code = __code;
      }
#pragma GCC diagnostic pop

      // 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 __bkt, const key_type& __k, __hash_code __code) const
      { return _M_find_before_node_tr<key_type>(__bkt, __k, __code); }

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

      // A pointer to a particular node and/or a hash code and bucket index
      // where such a node would be found in the container.
      struct __location_type
      {
	// True if _M_node() is a valid node pointer.
	explicit operator bool() const noexcept
	{ return static_cast<bool>(_M_before); }

	// An iterator that refers to the node, or end().
	explicit operator iterator() const noexcept
	{ return iterator(_M_node()); }

	// A const_iterator that refers to the node, or cend().
	explicit operator const_iterator() const noexcept
	{ return const_iterator(_M_node()); }

	// A pointer to the node, or null.
	__node_ptr _M_node() const
	{
	  if (_M_before)
	    return static_cast<__node_ptr>(_M_before->_M_nxt);
	  return __node_ptr();
	}

	__node_base_ptr _M_before{}; // Must only be used to get _M_nxt
	__hash_code _M_hash_code{};  // Only valid if _M_bucket_index != -1
	size_type _M_bucket_index = size_type(-1);
      };

      // Adaptive lookup to find key, or which bucket it would be in.
      // For a container smaller than the small size threshold use a linear
      // search through the whole container, just testing for equality.
      // Otherwise, calculate the hash code and bucket index for the key,
      // and search in that bucket.
      // The return value will have a pointer to the node _before_ the first
      // node matching the key, if any such node exists. Returning the node
      // before the desired one allows the result to be used for erasure.
      // If no matching element is present, the hash code and bucket for the
      // key will be set, allowing a new node to be inserted at that location.
      // (The hash code and bucket might also be set when a node is found.)
      // The _M_before pointer might point to _M_before_begin, so must not be
      // cast to __node_ptr, and it must not be used to modify *_M_before
      // except in non-const member functions, such as erase.

      __location_type
      _M_locate(const key_type& __k) const
      { return _M_locate_tr<key_type>(__k); }

      template <typename _Kt>
	__location_type
	_M_locate_tr(const _Kt& __k) const;

      __node_ptr
      _M_find_node(size_type __bkt, const key_type& __key,
		   __hash_code __c) const
      {
	if (__node_base_ptr __before_n = _M_find_before_node(__bkt, __key, __c))
	  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
	{
	  if (auto __before_n = _M_find_before_node_tr(__bkt, __key, __c))
	    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 __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;
	  }
      }

      // Remove the bucket first node
      void
      _M_remove_bucket_begin(size_type __bkt, __node_ptr __next_n,
			     size_type __next_bkt)
      {
	if (!__next_n)
	  _M_buckets[__bkt] = nullptr;
	else if (__next_bkt != __bkt)
	  {
	    _M_buckets[__next_bkt] = _M_buckets[__bkt];
	    _M_buckets[__bkt] = nullptr;
	  }
      }

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

      pair<__node_ptr, __hash_code>
      _M_compute_hash_code(__node_ptr __hint, const key_type& __k) const;

      // Insert node __n with hash code __code, in bucket __bkt (or another
      // bucket if rehashing is needed).
      // Assumes no element with equivalent key is already present.
      // Takes ownership of __n if insertion succeeds, throws otherwise.
      // __n_elt is an estimated number of elements we expect to insert,
      // used as a hint for rehashing when inserting a range.
      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_uniq(_Args&&... __args);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++14-extensions" // variable templates
      template<typename _Arg, typename _DArg = __remove_cvref_t<_Arg>,
	       typename = _ExtractKey>
	static constexpr bool __is_key_type = false;

      template<typename _Arg>
	static constexpr bool
	__is_key_type<_Arg, key_type, __detail::_Identity> = true;

      template<typename _Arg, typename _Arg1, typename _Arg2>
	static constexpr bool
	__is_key_type<_Arg, pair<_Arg1, _Arg2>, __detail::_Select1st>
	  = is_same<__remove_cvref_t<_Arg1>, key_type>::value;
#pragma GCC diagnostic pop

      template<typename... _Args>
	iterator
	_M_emplace_multi(const_iterator, _Args&&... __args);

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

      size_type
      _M_erase_some(size_type __bkt, __node_base_ptr __prev_n, __node_ptr __n);

      template<typename _InputIterator>
	void
	_M_insert_range_multi(_InputIterator __first, _InputIterator __last);

    public:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
      // Emplace
      template<typename... _Args>
	__ireturn_type
	emplace(_Args&&... __args)
	{
	  if constexpr (__unique_keys::value)
	    return _M_emplace_uniq(std::forward<_Args>(__args)...);
	  else
	    return _M_emplace_multi(cend(), std::forward<_Args>(__args)...);
	}

      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __hint, _Args&&... __args)
	{
	  if constexpr (__unique_keys::value)
	    return _M_emplace_uniq(std::forward<_Args>(__args)...).first;
	  else
	    return _M_emplace_multi(__hint, std::forward<_Args>(__args)...);
	}

      // Insert
      __ireturn_type
      insert(const value_type& __v)
      {
	if constexpr (__unique_keys::value)
	  return _M_emplace_uniq(__v);
	else
	  return _M_emplace_multi(cend(), __v);
      }

      iterator
      insert(const_iterator __hint, const value_type& __v)
      {
	if constexpr (__unique_keys::value)
	  return _M_emplace_uniq(__v).first;
	else
	  return _M_emplace_multi(__hint, __v);
      }

      __ireturn_type
      insert(value_type&& __v)
      {
	if constexpr (__unique_keys::value)
	  return _M_emplace_uniq(std::move(__v));
	else
	  return _M_emplace_multi(cend(), std::move(__v));
      }

      iterator
      insert(const_iterator __hint, value_type&& __v)
      {
	if constexpr (__unique_keys::value)
	  return _M_emplace_uniq(std::move(__v)).first;
	else
	  return _M_emplace_multi(__hint, std::move(__v));
      }

#ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED
      template<typename _KType, typename... _Args>
	std::pair<iterator, bool>
	try_emplace(const_iterator, _KType&& __k, _Args&&... __args)
	{
	  // Note we ignore the hint argument.
	  __hash_code __code;
	  size_type __bkt;
	  if (auto __loc = _M_locate(__k))
	    return { iterator(__loc), false };
	  else
	    {
	      __code = __loc._M_hash_code;
	      __bkt = __loc._M_bucket_index;
	    }

	  _Scoped_node __node {
	    this,
	    std::piecewise_construct,
	    std::forward_as_tuple(std::forward<_KType>(__k)),
	    std::forward_as_tuple(std::forward<_Args>(__args)...)
	  };
	  auto __it = _M_insert_unique_node(__bkt, __code, __node._M_node);
	  __node._M_node = nullptr;
	  return { __it, true };
	}

#ifdef __glibcxx_associative_heterogeneous_insertion  // C++26
      template<typename _Kt>
	std::pair<iterator, bool>
	_M_insert_tr(_Kt&& __k)
	{
	  auto __loc = _M_locate_tr(__k);
	  if (__loc)
	    return { iterator(__loc), false };

	  _Scoped_node __node(
	    this->_M_allocate_node(std::forward<_Kt>(__k)), this);
	  auto __it = _M_insert_unique_node(
	    __loc._M_bucket_index, __loc._M_hash_code, __node._M_node);
	  __node._M_node = nullptr;
	  return { __it, true };
	}
#endif
#endif

      void
      insert(initializer_list<value_type> __l)
      { this->insert(__l.begin(), __l.end()); }

      template<typename _InputIterator>
	void
	insert(_InputIterator __first, _InputIterator __last)
	{
	  if constexpr (__unique_keys::value)
	    for (; __first != __last; ++__first)
	      _M_emplace_uniq(*__first);
	  else
	    return _M_insert_range_multi(__first, __last);
	}

      // This overload is only defined for maps, not sets.
      template<typename _Pair,
	       typename = _Require<__not_<is_same<_Key, _Value>>,
				   is_constructible<value_type, _Pair&&>>>
	__ireturn_type
	insert(_Pair&& __v)
	{
	  if constexpr (__unique_keys::value)
	    return _M_emplace_uniq(std::forward<_Pair>(__v));
	  else
	    return _M_emplace_multi(cend(), std::forward<_Pair>(__v));
	}

      // This overload is only defined for maps, not sets.
      template<typename _Pair,
	       typename = _Require<__not_<is_same<_Key, _Value>>,
				   is_constructible<value_type, _Pair&&>>>
	iterator
	insert(const_iterator __hint, _Pair&& __v)
	{
	  if constexpr (__unique_keys::value)
	    return _M_emplace_uniq(std::forward<_Pair>(__v));
	  else
	    return _M_emplace_multi(__hint, std::forward<_Pair>(__v));
	}
#pragma GCC diagnostic pop

      // Erase
      iterator
      erase(const_iterator);

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2059. C++0x ambiguity problem with map::erase
      iterator
      erase(iterator __it)
      { return erase(const_iterator(__it)); }

      size_type
      erase(const key_type& __k);

      template <typename _Kt>
	size_type
	_M_erase_tr(const _Kt& __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 __glibcxx_node_extract // >= C++17 && HOSTED
      /// 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());

	    if (auto __loc = _M_locate(__nh._M_key()))
	      {
		__ret.node = std::move(__nh);
		__ret.position = iterator(__loc);
		__ret.inserted = false;
	      }
	    else
	      {
		auto __code = __loc._M_hash_code;
		auto __bkt = __loc._M_bucket_index;
		__ret.position
		     = _M_insert_unique_node(__bkt, __code, __nh._M_ptr);
		__ret.inserted = true;
		__nh.release();
	      }
	  }
	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.release();
	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() };
      }

      // Hash code for node __src_n with key __k, using this->hash_function().
      // Will use a hash code cached in the node if safe to do so. This is
      // for use in _M_merge_multi where the node comes from another container
      // with a hash function that might not match this->hash_function().
      template<typename _H2>
	__hash_code
	_M_src_hash_code(const _H2&, const __node_value_type& __src_n) const
	{
	  if constexpr (__and_<__hash_cached,
			is_same<_H2, _Hash>, is_empty<_Hash>>::value)
	    // If the node has a cached hash code, it's OK to use it.
	    return __src_n._M_hash_code;
	  else
	    return this->_M_hash_code(_ExtractKey{}(__src_n._M_v()));
	}

    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)
      { return _M_extract_tr<_Key>(__k); }

      template <typename _Kt>
	node_type
	_M_extract_tr(const _Kt& __k)
	{
	  node_type __nh;
	  __hash_code __code = this->_M_hash_code_tr(__k);
	  std::size_t __bkt = _M_bucket_index(__code);
	  if (__node_base_ptr __prev_node =
	      _M_find_before_node_tr(__bkt, __k, __code))
	    __nh = _M_extract_node(__bkt, __prev_node);
	  return __nh;
	}

      /// Merge from another container of the same type.
      void
      _M_merge_unique(_Hashtable& __src)
      {
	__glibcxx_assert(get_allocator() == __src.get_allocator());

	using _PTr = pointer_traits<__node_base_ptr>;

	auto __n_elt = __src.size();
	size_type __first = 1;
	// For a container of identical type we can use its private members,
	// __src._M_before_begin, __src._M_bucket_index etc.
	auto __prev = _PTr::pointer_to(__src._M_before_begin);
	while (__n_elt--)
	  {
	    const auto __next = __prev->_M_nxt;
	    const auto& __node = static_cast<__node_type&>(*__next);
	    const key_type& __k = _ExtractKey{}(__node._M_v());
	    const auto __loc = _M_locate(__k);
	    if (__loc)
	      {
		__prev = __next;
		continue;
	      }

	    auto __src_bkt = __src._M_bucket_index(__node);
	    auto __nh = __src._M_extract_node(__src_bkt, __prev);
	    _M_insert_unique_node(__loc._M_bucket_index, __loc._M_hash_code,
				  __nh._M_ptr, __first * __n_elt + 1);
	    __nh.release();
	    __first = 0;
	  }
      }

      /// Merge from a compatible container into one with unique keys.
      template<typename _Compatible_Hashtable>
	void
	_M_merge_unique(_Compatible_Hashtable& __src)
	{
	  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();
	  size_type __first = 1;
	  // For a compatible container we can only use the public API,
	  // so cbegin(), cend(), hash_function(), and extract(iterator).
	  for (auto __i = __src.cbegin(), __end = __src.cend(); __i != __end;)
	    {
	      --__n_elt;
	      auto __pos = __i++;
	      const key_type& __k = _ExtractKey{}(*__pos);
	      const auto __loc = _M_locate(__k);
	      if (__loc)
		continue;

	      auto __nh = __src.extract(__pos);
	      _M_insert_unique_node(__loc._M_bucket_index,
				    __loc._M_hash_code, __nh._M_ptr,
				    __first * __n_elt + 1);
	      __nh.release();
	      __first = 0;
	    }
	}

      /// Merge from another container of the same type.
      void
      _M_merge_multi(_Hashtable& __src)
      {
	__glibcxx_assert(get_allocator() == __src.get_allocator());

	if (__src.size() == 0) [[__unlikely__]]
	  return;

	using _PTr = pointer_traits<__node_base_ptr>;

	__node_ptr __hint = nullptr;
	this->reserve(size() + __src.size());
	// For a container of identical type we can use its private members,
	// __src._M_before_begin, __src._M_bucket_index etc.
	auto __prev = _PTr::pointer_to(__src._M_before_begin);
	do
	  {
	    const auto& __node = static_cast<__node_type&>(*__prev->_M_nxt);
	    // Hash code from this:
	    auto __code = _M_hash_code_ext(__node);
	    // Bucket index in __src, using code from __src.hash_function():
	    size_type __src_bkt = __src._M_bucket_index(__node);
	    auto __nh = __src._M_extract_node(__src_bkt, __prev);
	    __hint = _M_insert_multi_node(__hint, __code, __nh._M_ptr)._M_cur;
	    __nh.release();
	  }
	while (__prev->_M_nxt != nullptr);
      }

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

	  __node_ptr __hint = nullptr;
	  this->reserve(size() + __src.size());
	  // For a compatible container we can only use the public API,
	  // so cbegin(), cend(), hash_function(), and extract(iterator).
	  for (auto __i = __src.cbegin(), __end = __src.cend(); __i != __end;)
	    {
	      auto __pos = __i++;
	      __hash_code __code
		= _M_src_hash_code(__src.hash_function(), *__pos._M_cur);
	      auto __nh = __src.extract(__pos);
	      __hint = _M_insert_multi_node(__hint, __code, __nh._M_ptr)._M_cur;
	      __nh.release();
	    }
	}
#endif // C++17 __glibcxx_node_extract

      bool
      _M_equal(const _Hashtable& __other) const;

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

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

  // 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>
    _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>
      inline
      _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)
      { this->insert(__f, __l); }

  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)
	  _M_emplace_multi(cend(), *__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;

	      struct _Guard
	      {
		~_Guard() { if (_M_ht) _M_ht->_M_reset(); }
		_Hashtable* _M_ht;
	      };
	      // If _M_assign exits via an exception it will have deallocated
	      // all memory. This guard will ensure *this is in a usable state.
	      _Guard __guard{this};
	      _M_assign(__ht);
	      __guard._M_ht = nullptr;
	      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)
      {
	using __reuse_or_alloc_node_gen_t =
	  __detail::_ReuseOrAllocNode<__node_alloc_type>;

	__buckets_ptr __former_buckets = nullptr;
	std::size_t __former_bucket_count = _M_bucket_count;
	__rehash_guard_t __rehash_guard(_M_rehash_policy);

	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
	  std::fill_n(_M_buckets, _M_bucket_count, nullptr);

	__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);
	    __rehash_guard._M_guarded_obj = nullptr;
	  }
	__catch(...)
	  {
	    if (__former_buckets)
	      {
		// Restore previous buckets.
		_M_deallocate_buckets();
		_M_buckets = __former_buckets;
		_M_bucket_count = __former_bucket_count;
	      }
	    std::fill_n(_M_buckets, _M_bucket_count, nullptr);
	    __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, _NodeGenerator& __node_gen)
      {
	struct _Guard
	{
	  ~_Guard()
	  {
	    if (_M_ht)
	      {
		_M_ht->clear();
		if (_M_dealloc_buckets)
		  _M_ht->_M_deallocate_buckets();
	      }
	  }
	  _Hashtable* _M_ht = nullptr;
	  bool _M_dealloc_buckets = false;
	};
	_Guard __guard;

	if (!_M_buckets)
	  {
	    _M_buckets = _M_allocate_buckets(_M_bucket_count);
	    __guard._M_dealloc_buckets = true;
	  }

	if (!__ht._M_before_begin._M_nxt)
	  return;

	__guard._M_ht = this;

	using _FromVal = __conditional_t<is_lvalue_reference<_Ht>::value,
					 const value_type&, value_type&&>;

	// 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(static_cast<_FromVal>(__ht_n->_M_v()));
	_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(static_cast<_FromVal>(__ht_n->_M_v()));
	    __prev_n->_M_nxt = __this_n;
	    _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;
	  }
	__guard._M_ht = 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_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>
    inline
    _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)
    {
      _M_assign(__ht);
    }

  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>
    inline
    _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)
    {
      _M_assign(__ht);
    }

  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
	{
	  using _Fwd_Ht = __conditional_t<
	    __move_if_noexcept_cond<value_type>::value,
	    const _Hashtable&, _Hashtable&&>;
	  _M_assign(std::forward<_Fwd_Ht>(__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() noexcept
    {
      // Getting a bucket index from a node shall not throw because it is used
      // during the rehash process. This static_assert purpose is limited to usage
      // of _Hashtable with _Hashtable_traits requesting non-cached hash code.
      // 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");

      this->_M_deallocate_nodes(_M_begin());
      _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)
    {
      using std::swap;
      swap(__hash_code_base::_M_hash._M_obj,
	   __x.__hash_code_base::_M_hash._M_obj);
      swap(__hashtable_base::_M_equal._M_obj,
	   __x.__hashtable_base::_M_equal._M_obj);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
      if constexpr (__node_alloc_traits::propagate_on_container_swap::value)
	swap(this->_M_node_allocator(), __x._M_node_allocator());
#pragma GCC diagnostic pop

      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
    { return iterator(_M_locate(__k)); }

  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
    { return const_iterator(_M_locate(__k)); }

#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
  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
      {
	if (size() <= __small_size_threshold())
	  {
	    for (auto __n = _M_begin(); __n; __n = __n->_M_next())
	      if (this->_M_key_equals_tr(__k, *__n))
		return iterator(__n);
	    return end();
	  }

	__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
      {
	if (size() <= __small_size_threshold())
	  {
	    for (auto __n = _M_begin(); __n; __n = __n->_M_next())
	      if (this->_M_key_equals_tr(__k, *__n))
		return const_iterator(__n);
	    return end();
	  }

	__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 // C++20 __glibcxx_generic_unordered_lookup

  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;

      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;
    }

#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
  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
      {
	if (size() <= __small_size_threshold())
	  {
	    size_type __result = 0;
	    for (auto __n = _M_begin(); __n; __n = __n->_M_next())
	      {
		if (this->_M_key_equals_tr(__k, *__n))
		  {
		    ++__result;
		    continue;
		  }

		if (__result)
		  break;
	      }

	    return __result;
	  }

	__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;

	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 // C++20 __glibcxx_generic_unordered_lookup

  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 };

      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 };

      while (__ite._M_cur && this->_M_node_equals(*__beg._M_cur, *__ite._M_cur))
	++__ite;

      return { __beg, __ite };
    }

#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
  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>
      {
	if (size() <= __small_size_threshold())
	  {
	    __node_ptr __n, __beg = nullptr;
	    for (__n = _M_begin(); __n; __n = __n->_M_next())
	      {
		if (this->_M_key_equals_tr(__k, *__n))
		  {
		    if (!__beg)
		      __beg = __n;
		    continue;
		  }

		if (__beg)
		  break;
	      }

	    return { iterator(__beg), iterator(__n) };
	  }

	__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 };

	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>
      {
	if (size() <= __small_size_threshold())
	  {
	    __node_ptr __n, __beg = nullptr;
	    for (__n = _M_begin(); __n; __n = __n->_M_next())
	      {
		if (this->_M_key_equals_tr(__k, *__n))
		  {
		    if (!__beg)
		      __beg = __n;
		    continue;
		  }

		if (__beg)
		  break;
	      }

	    return { const_iterator(__beg), const_iterator(__n) };
	  }

	__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 };

	auto __beg = __ite++;
	while (__ite._M_cur && this->_M_equals_tr(__k, __code, *__ite._M_cur))
	  ++__ite;

	return { __beg, __ite };
      }
#endif // C++20 __glibcxx_generic_unordered_lookup

  // 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>
    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 (__builtin_expect (
		  !__p->_M_nxt || _M_bucket_index(*__p->_M_next()) != __bkt, 0))
	      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>
      inline auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_locate_tr(const _Kt& __k) const
	-> __location_type
      {
	__location_type __loc;
	const auto __size = size();

	if (__size <= __small_size_threshold())
	  {
	    __loc._M_before = pointer_traits<__node_base_ptr>::
		 pointer_to(const_cast<__node_base&>(_M_before_begin));
	    while (__loc._M_before->_M_nxt)
	      {
		if (this->_M_key_equals_tr(__k, *__loc._M_node()))
		  return __loc;
		__loc._M_before = __loc._M_before->_M_nxt;
	      }
	    __loc._M_before = nullptr; // Didn't find it.
	  }

	__loc._M_hash_code = this->_M_hash_code_tr(__k);
	__loc._M_bucket_index = _M_bucket_index(__loc._M_hash_code);

	if (__size > __small_size_threshold())
	  __loc._M_before = _M_find_before_node_tr(
	    __loc._M_bucket_index, __k, __loc._M_hash_code);

	return __loc;
      }

  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;
    }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
  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_uniq(_Args&&... __args)
      -> pair<iterator, bool>
      {
	const key_type* __kp = nullptr;

	if constexpr (sizeof...(_Args) == 1)
	  {
	    if constexpr (__is_key_type<_Args...>)
	      {
		const auto& __key = _ExtractKey{}(__args...);
		__kp = std::addressof(__key);
	      }
	  }
	else if constexpr (sizeof...(_Args) == 2)
	  {
	    if constexpr (__is_key_type<pair<const _Args&...>>)
	      {
		pair<const _Args&...> __refs(__args...);
		const auto& __key = _ExtractKey{}(__refs);
		__kp = std::addressof(__key);
	      }
	  }

	_Scoped_node __node { __node_ptr(), this }; // Do not create node yet.
	__hash_code __code = 0;
	size_type __bkt = 0;

	if (__kp == nullptr)
	  {
	    // Didn't extract a key from the args, so build the node.
	    __node._M_node
		  = this->_M_allocate_node(std::forward<_Args>(__args)...);
	    const key_type& __key = _ExtractKey{}(__node._M_node->_M_v());
	    __kp = std::addressof(__key);
	  }

	if (auto __loc = _M_locate(*__kp))
	  // There is already an equivalent node, no insertion.
	  return { iterator(__loc), false };
	else
	  {
	    __code = __loc._M_hash_code;
	    __bkt = __loc._M_bucket_index;
	  }

	if (!__node._M_node)
	  __node._M_node
		= this->_M_allocate_node(std::forward<_Args>(__args)...);

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

#pragma GCC diagnostic pop

  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_multi(const_iterator __hint, _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());

	auto __res = this->_M_compute_hash_code(__hint._M_cur, __k);
	auto __pos
	  = _M_insert_multi_node(__res.first, __res.second, __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>
   void
  _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	     _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
  _M_rehash_insert(size_type __n)
  {
    using __pair_type = std::pair<bool, std::size_t>;
    if (__n == 0)
      return;

    __rehash_guard_t __rehash_guard(_M_rehash_policy);
    __pair_type __do_rehash
      = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, __n);

    if (__do_rehash.first)
      _M_rehash(__do_rehash.second, false_type{});

    __rehash_guard._M_guarded_obj = nullptr;
  }


  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    template<typename _InputIterator>
      void
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_insert_range_multi(_InputIterator __first, _InputIterator __last)
      {
	_M_rehash_insert(__detail::__distance_fw(__first, __last));
	for (; __first != __last; ++__first)
	  _M_emplace_multi(cend(), *__first);
      }

  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_compute_hash_code(__node_ptr __hint, const key_type& __k) const
    -> pair<__node_ptr, __hash_code>
    {
      if (size() <= __small_size_threshold())
	{
	  if (__hint)
	    {
	      for (auto __it = __hint; __it; __it = __it->_M_next())
		if (this->_M_key_equals(__k, *__it))
		  return { __it, this->_M_hash_code(*__it) };
	    }

	  for (auto __it = _M_begin(); __it != __hint; __it = __it->_M_next())
	    if (this->_M_key_equals(__k, *__it))
	      return { __it, this->_M_hash_code(*__it) };

	  __hint = nullptr;
	}

      return { __hint, this->_M_hash_code(__k) };
    }

  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
    {
      __rehash_guard_t __rehash_guard(_M_rehash_policy);
      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, true_type{});
	  __bkt = _M_bucket_index(__code);
	}

      __rehash_guard._M_guarded_obj = nullptr;
      _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
    {
      __rehash_guard_t __rehash_guard(_M_rehash_policy);
      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, false_type{});

      __rehash_guard._M_guarded_obj = nullptr;
      _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);
    }

  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;
    }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr

  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 key_type& __k)
    -> size_type
    {
      auto __loc = _M_locate(__k);
      if (!__loc)
	return 0;

      __node_base_ptr __prev_n = __loc._M_before;
      __node_ptr __n = __loc._M_node();
      auto __bkt = __loc._M_bucket_index;
      if (__bkt == size_type(-1))
	__bkt = _M_bucket_index(*__n);
      if constexpr (__unique_keys::value)
	{
	  _M_erase(__bkt, __prev_n, __n);
	  return 1;
	}
      else
	return _M_erase_some(__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_some(size_type __bkt, __node_base_ptr __prev_n, __node_ptr __n)
      -> size_type
    {
      // _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_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>
    template <typename _Kt>
      auto
      _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
		 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
      _M_erase_tr(const _Kt& __k)
	-> size_type
      {
	auto __loc = _M_locate_tr(__k);
	if (!__loc)
	  return 0;

	__node_base_ptr __prev_n = __loc._M_before;
	__node_ptr __n = __loc._M_node();
	auto __bkt = __loc._M_bucket_index;
	if (__bkt == size_type(-1))
	  __bkt = _M_bucket_index(*__n);
	if constexpr (__unique_keys::value)
	  {
	    _M_erase(__bkt, __prev_n, __n);
	    return 1;
	  }
	else
	  return _M_erase_some(__bkt, __prev_n, __n);
      }

#pragma GCC diagnostic pop

  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());
      std::fill_n(_M_buckets, _M_bucket_count, nullptr);
      _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)
    {
      __rehash_guard_t __rehash_guard(_M_rehash_policy);
      __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, __unique_keys{});
	  __rehash_guard._M_guarded_obj = nullptr;
	}
    }

  // 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(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(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;
    }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr

  // This is for implementing equality comparison for unordered containers,
  // per N3068, by John Lakos and Pablo Halpern.
  // Algorithmically, we follow closely the reference implementations therein.
  template<typename _Key, typename _Value, typename _Alloc,
	   typename _ExtractKey, typename _Equal,
	   typename _Hash, typename _RangeHash, typename _Unused,
	   typename _RehashPolicy, typename _Traits>
    bool
    _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
    _M_equal(const _Hashtable& __other) const
    {
      if (size() != __other.size())
	return false;

      if constexpr (__unique_keys::value)
	for (auto __x_n = _M_begin(); __x_n; __x_n = __x_n->_M_next())
	  {
	    std::size_t __ybkt = __other._M_bucket_index_ext(*__x_n);
	    auto __prev_n = __other._M_buckets[__ybkt];
	    if (!__prev_n)
	      return false;

	    for (__node_ptr __n = static_cast<__node_ptr>(__prev_n->_M_nxt);;
		 __n = __n->_M_next())
	      {
		if (__n->_M_v() == __x_n->_M_v())
		  break;

		if (!__n->_M_nxt
		    || __other._M_bucket_index(*__n->_M_next()) != __ybkt)
		  return false;
	      }
	  }
      else // non-unique keys
	for (auto __x_n = _M_begin(); __x_n;)
	  {
	    std::size_t __x_count = 1;
	    auto __x_n_end = __x_n->_M_next();
	    for (; __x_n_end
		   && key_eq()(_ExtractKey{}(__x_n->_M_v()),
			       _ExtractKey{}(__x_n_end->_M_v()));
		 __x_n_end = __x_n_end->_M_next())
	      ++__x_count;

	    std::size_t __ybkt = __other._M_bucket_index_ext(*__x_n);
	    auto __y_prev_n = __other._M_buckets[__ybkt];
	    if (!__y_prev_n)
	      return false;

	    __node_ptr __y_n = static_cast<__node_ptr>(__y_prev_n->_M_nxt);
	    for (;;)
	      {
		if (key_eq()(_ExtractKey{}(__y_n->_M_v()),
			     _ExtractKey{}(__x_n->_M_v())))
		  break;

		auto __y_ref_n = __y_n;
		for (__y_n = __y_n->_M_next(); __y_n; __y_n = __y_n->_M_next())
		  if (!__other._M_node_equals(*__y_ref_n, *__y_n))
		    break;

		if (!__y_n || __other._M_bucket_index(*__y_n) != __ybkt)
		  return false;
	      }

	    auto __y_n_end = __y_n;
	    for (; __y_n_end; __y_n_end = __y_n_end->_M_next())
	      if (--__x_count == 0)
		break;

	    if (__x_count != 0)
	      return false;

	    const_iterator __itx(__x_n), __itx_end(__x_n_end);
	    const_iterator __ity(__y_n);
	    if (!std::is_permutation(__itx, __itx_end, __ity))
	      return false;

	    __x_n = __x_n_end;
	  }

      return true;
    }
#pragma GCC diagnostic pop

#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
  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

#ifdef __glibcxx_associative_heterogeneous_erasure // C++ >= 23
template <typename _Kt, typename _Container>
  concept __heterogeneous_hash_key =
    __transparent_comparator<typename _Container::hasher> &&
    __transparent_comparator<typename _Container::key_equal> &&
    __heterogeneous_key<_Kt, _Container>;
#endif

/// @endcond
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#pragma GCC diagnostic pop

#endif // _HASHTABLE_H
