Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/c++/v1/__cxx03/__hash_table is written in an unsupported language. File is not indexed.

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03___HASH_TABLE
0011 #define _LIBCPP___CXX03___HASH_TABLE
0012 
0013 #include <__cxx03/__algorithm/max.h>
0014 #include <__cxx03/__algorithm/min.h>
0015 #include <__cxx03/__assert>
0016 #include <__cxx03/__bit/countl.h>
0017 #include <__cxx03/__config>
0018 #include <__cxx03/__functional/hash.h>
0019 #include <__cxx03/__functional/invoke.h>
0020 #include <__cxx03/__iterator/iterator_traits.h>
0021 #include <__cxx03/__memory/addressof.h>
0022 #include <__cxx03/__memory/allocator_traits.h>
0023 #include <__cxx03/__memory/compressed_pair.h>
0024 #include <__cxx03/__memory/construct_at.h>
0025 #include <__cxx03/__memory/pointer_traits.h>
0026 #include <__cxx03/__memory/swap_allocator.h>
0027 #include <__cxx03/__memory/unique_ptr.h>
0028 #include <__cxx03/__type_traits/can_extract_key.h>
0029 #include <__cxx03/__type_traits/conditional.h>
0030 #include <__cxx03/__type_traits/is_const.h>
0031 #include <__cxx03/__type_traits/is_constructible.h>
0032 #include <__cxx03/__type_traits/is_nothrow_assignable.h>
0033 #include <__cxx03/__type_traits/is_nothrow_constructible.h>
0034 #include <__cxx03/__type_traits/is_pointer.h>
0035 #include <__cxx03/__type_traits/is_reference.h>
0036 #include <__cxx03/__type_traits/is_swappable.h>
0037 #include <__cxx03/__type_traits/remove_const.h>
0038 #include <__cxx03/__type_traits/remove_cvref.h>
0039 #include <__cxx03/__utility/forward.h>
0040 #include <__cxx03/__utility/move.h>
0041 #include <__cxx03/__utility/pair.h>
0042 #include <__cxx03/__utility/swap.h>
0043 #include <__cxx03/cmath>
0044 #include <__cxx03/cstring>
0045 #include <__cxx03/initializer_list>
0046 #include <__cxx03/new> // __launder
0047 
0048 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0049 #  pragma GCC system_header
0050 #endif
0051 
0052 _LIBCPP_PUSH_MACROS
0053 #include <__cxx03/__undef_macros>
0054 
0055 _LIBCPP_BEGIN_NAMESPACE_STD
0056 
0057 template <class _Key, class _Tp>
0058 struct __hash_value_type;
0059 
0060 template <class _Tp>
0061 struct __is_hash_value_type_imp : false_type {};
0062 
0063 template <class _Key, class _Value>
0064 struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {};
0065 
0066 template <class... _Args>
0067 struct __is_hash_value_type : false_type {};
0068 
0069 template <class _One>
0070 struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {};
0071 
0072 _LIBCPP_EXPORTED_FROM_ABI size_t __next_prime(size_t __n);
0073 
0074 template <class _NodePtr>
0075 struct __hash_node_base {
0076   typedef typename pointer_traits<_NodePtr>::element_type __node_type;
0077   typedef __hash_node_base __first_node;
0078   typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer;
0079   typedef _NodePtr __node_pointer;
0080 
0081 #if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
0082   typedef __node_base_pointer __next_pointer;
0083 #else
0084   typedef __conditional_t<is_pointer<__node_pointer>::value, __node_base_pointer, __node_pointer> __next_pointer;
0085 #endif
0086 
0087   __next_pointer __next_;
0088 
0089   _LIBCPP_HIDE_FROM_ABI __next_pointer __ptr() _NOEXCEPT {
0090     return static_cast<__next_pointer>(pointer_traits<__node_base_pointer>::pointer_to(*this));
0091   }
0092 
0093   _LIBCPP_HIDE_FROM_ABI __node_pointer __upcast() _NOEXCEPT {
0094     return static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(*this));
0095   }
0096 
0097   _LIBCPP_HIDE_FROM_ABI size_t __hash() const _NOEXCEPT { return static_cast<__node_type const&>(*this).__hash_; }
0098 
0099   _LIBCPP_HIDE_FROM_ABI __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
0100   _LIBCPP_HIDE_FROM_ABI explicit __hash_node_base(__next_pointer __next) _NOEXCEPT : __next_(__next) {}
0101 };
0102 
0103 template <class _Tp, class _VoidPtr>
0104 struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > {
0105   typedef _Tp __node_value_type;
0106   using _Base          = __hash_node_base<__rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > >;
0107   using __next_pointer = typename _Base::__next_pointer;
0108 
0109   size_t __hash_;
0110 
0111   // We allow starting the lifetime of nodes without initializing the value held by the node,
0112   // since that is handled by the hash table itself in order to be allocator-aware.
0113 #ifndef _LIBCPP_CXX03_LANG
0114 
0115 private:
0116   union {
0117     _Tp __value_;
0118   };
0119 
0120 public:
0121   _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; }
0122 #else
0123 
0124 private:
0125   _ALIGNAS_TYPE(_Tp) char __buffer_[sizeof(_Tp)];
0126 
0127 public:
0128   _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
0129 #endif
0130 
0131   _LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {}
0132   _LIBCPP_HIDE_FROM_ABI ~__hash_node() {}
0133 };
0134 
0135 inline _LIBCPP_HIDE_FROM_ABI bool __is_hash_power2(size_t __bc) { return __bc > 2 && !(__bc & (__bc - 1)); }
0136 
0137 inline _LIBCPP_HIDE_FROM_ABI size_t __constrain_hash(size_t __h, size_t __bc) {
0138   return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : (__h < __bc ? __h : __h % __bc);
0139 }
0140 
0141 inline _LIBCPP_HIDE_FROM_ABI size_t __next_hash_pow2(size_t __n) {
0142   return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n - 1)));
0143 }
0144 
0145 template <class _Tp, class _Hash, class _Equal, class _Alloc>
0146 class __hash_table;
0147 
0148 template <class _NodePtr>
0149 class _LIBCPP_TEMPLATE_VIS __hash_iterator;
0150 template <class _ConstNodePtr>
0151 class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
0152 template <class _NodePtr>
0153 class _LIBCPP_TEMPLATE_VIS __hash_local_iterator;
0154 template <class _ConstNodePtr>
0155 class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
0156 template <class _HashIterator>
0157 class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
0158 template <class _HashIterator>
0159 class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
0160 
0161 template <class _Tp>
0162 struct __hash_key_value_types {
0163   static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
0164   typedef _Tp key_type;
0165   typedef _Tp __node_value_type;
0166   typedef _Tp __container_value_type;
0167   static const bool __is_map = false;
0168 
0169   _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Tp const& __v) { return __v; }
0170   _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; }
0171   _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n); }
0172   _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move(__v); }
0173 };
0174 
0175 template <class _Key, class _Tp>
0176 struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
0177   typedef _Key key_type;
0178   typedef _Tp mapped_type;
0179   typedef __hash_value_type<_Key, _Tp> __node_value_type;
0180   typedef pair<const _Key, _Tp> __container_value_type;
0181   typedef __container_value_type __map_value_type;
0182   static const bool __is_map = true;
0183 
0184   _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__container_value_type const& __v) { return __v.first; }
0185 
0186   template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, int> = 0>
0187   _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) {
0188     return __t.__get_value();
0189   }
0190 
0191   template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0>
0192   _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) {
0193     return __t;
0194   }
0195 
0196   _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) {
0197     return std::addressof(__n.__get_value());
0198   }
0199   _LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); }
0200 };
0201 
0202 template <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, bool = _KVTypes::__is_map>
0203 struct __hash_map_pointer_types {};
0204 
0205 template <class _Tp, class _AllocPtr, class _KVTypes>
0206 struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
0207   typedef typename _KVTypes::__map_value_type _Mv;
0208   typedef __rebind_pointer_t<_AllocPtr, _Mv> __map_value_type_pointer;
0209   typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer;
0210 };
0211 
0212 template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
0213 struct __hash_node_types;
0214 
0215 template <class _NodePtr, class _Tp, class _VoidPtr>
0216 struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> >
0217     : public __hash_key_value_types<_Tp>,
0218       __hash_map_pointer_types<_Tp, _VoidPtr>
0219 
0220 {
0221   typedef __hash_key_value_types<_Tp> __base;
0222 
0223 public:
0224   typedef ptrdiff_t difference_type;
0225   typedef size_t size_type;
0226 
0227   typedef __rebind_pointer_t<_NodePtr, void> __void_pointer;
0228 
0229   typedef typename pointer_traits<_NodePtr>::element_type __node_type;
0230   typedef _NodePtr __node_pointer;
0231 
0232   typedef __hash_node_base<__node_pointer> __node_base_type;
0233   typedef __rebind_pointer_t<_NodePtr, __node_base_type> __node_base_pointer;
0234 
0235   typedef typename __node_base_type::__next_pointer __next_pointer;
0236 
0237   typedef _Tp __node_value_type;
0238   typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer;
0239   typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer;
0240 
0241 private:
0242   static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const");
0243   static_assert(is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value,
0244                 "_VoidPtr does not point to unqualified void type");
0245   static_assert(is_same<__rebind_pointer_t<_VoidPtr, __node_type>, _NodePtr>::value,
0246                 "_VoidPtr does not rebind to _NodePtr.");
0247 };
0248 
0249 template <class _HashIterator>
0250 struct __hash_node_types_from_iterator;
0251 template <class _NodePtr>
0252 struct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
0253 template <class _NodePtr>
0254 struct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
0255 template <class _NodePtr>
0256 struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
0257 template <class _NodePtr>
0258 struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
0259 
0260 template <class _NodeValueTp, class _VoidPtr>
0261 struct __make_hash_node_types {
0262   typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp;
0263   typedef __rebind_pointer_t<_VoidPtr, _NodeTp> _NodePtr;
0264   typedef __hash_node_types<_NodePtr> type;
0265 };
0266 
0267 template <class _NodePtr>
0268 class _LIBCPP_TEMPLATE_VIS __hash_iterator {
0269   typedef __hash_node_types<_NodePtr> _NodeTypes;
0270   typedef _NodePtr __node_pointer;
0271   typedef typename _NodeTypes::__next_pointer __next_pointer;
0272 
0273   __next_pointer __node_;
0274 
0275 public:
0276   typedef forward_iterator_tag iterator_category;
0277   typedef typename _NodeTypes::__node_value_type value_type;
0278   typedef typename _NodeTypes::difference_type difference_type;
0279   typedef value_type& reference;
0280   typedef typename _NodeTypes::__node_value_type_pointer pointer;
0281 
0282   _LIBCPP_HIDE_FROM_ABI __hash_iterator() _NOEXCEPT : __node_(nullptr) {}
0283 
0284   _LIBCPP_HIDE_FROM_ABI reference operator*() const {
0285     _LIBCPP_ASSERT_NON_NULL(
0286         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container iterator");
0287     return __node_->__upcast()->__get_value();
0288   }
0289 
0290   _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
0291     _LIBCPP_ASSERT_NON_NULL(
0292         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container iterator");
0293     return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__get_value());
0294   }
0295 
0296   _LIBCPP_HIDE_FROM_ABI __hash_iterator& operator++() {
0297     _LIBCPP_ASSERT_NON_NULL(
0298         __node_ != nullptr, "Attempted to increment a non-incrementable unordered container iterator");
0299     __node_ = __node_->__next_;
0300     return *this;
0301   }
0302 
0303   _LIBCPP_HIDE_FROM_ABI __hash_iterator operator++(int) {
0304     __hash_iterator __t(*this);
0305     ++(*this);
0306     return __t;
0307   }
0308 
0309   friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) {
0310     return __x.__node_ == __y.__node_;
0311   }
0312   friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) {
0313     return !(__x == __y);
0314   }
0315 
0316 private:
0317   _LIBCPP_HIDE_FROM_ABI explicit __hash_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {}
0318 
0319   template <class, class, class, class>
0320   friend class __hash_table;
0321   template <class>
0322   friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
0323   template <class>
0324   friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
0325   template <class, class, class, class, class>
0326   friend class _LIBCPP_TEMPLATE_VIS unordered_map;
0327   template <class, class, class, class, class>
0328   friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
0329 };
0330 
0331 template <class _NodePtr>
0332 class _LIBCPP_TEMPLATE_VIS __hash_const_iterator {
0333   static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, "");
0334   typedef __hash_node_types<_NodePtr> _NodeTypes;
0335   typedef _NodePtr __node_pointer;
0336   typedef typename _NodeTypes::__next_pointer __next_pointer;
0337 
0338   __next_pointer __node_;
0339 
0340 public:
0341   typedef __hash_iterator<_NodePtr> __non_const_iterator;
0342 
0343   typedef forward_iterator_tag iterator_category;
0344   typedef typename _NodeTypes::__node_value_type value_type;
0345   typedef typename _NodeTypes::difference_type difference_type;
0346   typedef const value_type& reference;
0347   typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
0348 
0349   _LIBCPP_HIDE_FROM_ABI __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {}
0350 
0351   _LIBCPP_HIDE_FROM_ABI __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) {}
0352 
0353   _LIBCPP_HIDE_FROM_ABI reference operator*() const {
0354     _LIBCPP_ASSERT_NON_NULL(
0355         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
0356     return __node_->__upcast()->__get_value();
0357   }
0358   _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
0359     _LIBCPP_ASSERT_NON_NULL(
0360         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
0361     return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__get_value());
0362   }
0363 
0364   _LIBCPP_HIDE_FROM_ABI __hash_const_iterator& operator++() {
0365     _LIBCPP_ASSERT_NON_NULL(
0366         __node_ != nullptr, "Attempted to increment a non-incrementable unordered container const_iterator");
0367     __node_ = __node_->__next_;
0368     return *this;
0369   }
0370 
0371   _LIBCPP_HIDE_FROM_ABI __hash_const_iterator operator++(int) {
0372     __hash_const_iterator __t(*this);
0373     ++(*this);
0374     return __t;
0375   }
0376 
0377   friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) {
0378     return __x.__node_ == __y.__node_;
0379   }
0380   friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) {
0381     return !(__x == __y);
0382   }
0383 
0384 private:
0385   _LIBCPP_HIDE_FROM_ABI explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {}
0386 
0387   template <class, class, class, class>
0388   friend class __hash_table;
0389   template <class>
0390   friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
0391   template <class, class, class, class, class>
0392   friend class _LIBCPP_TEMPLATE_VIS unordered_map;
0393   template <class, class, class, class, class>
0394   friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
0395 };
0396 
0397 template <class _NodePtr>
0398 class _LIBCPP_TEMPLATE_VIS __hash_local_iterator {
0399   typedef __hash_node_types<_NodePtr> _NodeTypes;
0400   typedef _NodePtr __node_pointer;
0401   typedef typename _NodeTypes::__next_pointer __next_pointer;
0402 
0403   __next_pointer __node_;
0404   size_t __bucket_;
0405   size_t __bucket_count_;
0406 
0407 public:
0408   typedef forward_iterator_tag iterator_category;
0409   typedef typename _NodeTypes::__node_value_type value_type;
0410   typedef typename _NodeTypes::difference_type difference_type;
0411   typedef value_type& reference;
0412   typedef typename _NodeTypes::__node_value_type_pointer pointer;
0413 
0414   _LIBCPP_HIDE_FROM_ABI __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {}
0415 
0416   _LIBCPP_HIDE_FROM_ABI reference operator*() const {
0417     _LIBCPP_ASSERT_NON_NULL(
0418         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container local_iterator");
0419     return __node_->__upcast()->__get_value();
0420   }
0421 
0422   _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
0423     _LIBCPP_ASSERT_NON_NULL(
0424         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container local_iterator");
0425     return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__get_value());
0426   }
0427 
0428   _LIBCPP_HIDE_FROM_ABI __hash_local_iterator& operator++() {
0429     _LIBCPP_ASSERT_NON_NULL(
0430         __node_ != nullptr, "Attempted to increment a non-incrementable unordered container local_iterator");
0431     __node_ = __node_->__next_;
0432     if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
0433       __node_ = nullptr;
0434     return *this;
0435   }
0436 
0437   _LIBCPP_HIDE_FROM_ABI __hash_local_iterator operator++(int) {
0438     __hash_local_iterator __t(*this);
0439     ++(*this);
0440     return __t;
0441   }
0442 
0443   friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) {
0444     return __x.__node_ == __y.__node_;
0445   }
0446   friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) {
0447     return !(__x == __y);
0448   }
0449 
0450 private:
0451   _LIBCPP_HIDE_FROM_ABI explicit __hash_local_iterator(
0452       __next_pointer __node, size_t __bucket, size_t __bucket_count) _NOEXCEPT
0453       : __node_(__node),
0454         __bucket_(__bucket),
0455         __bucket_count_(__bucket_count) {
0456     if (__node_ != nullptr)
0457       __node_ = __node_->__next_;
0458   }
0459 
0460   template <class, class, class, class>
0461   friend class __hash_table;
0462   template <class>
0463   friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
0464   template <class>
0465   friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
0466 };
0467 
0468 template <class _ConstNodePtr>
0469 class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator {
0470   typedef __hash_node_types<_ConstNodePtr> _NodeTypes;
0471   typedef _ConstNodePtr __node_pointer;
0472   typedef typename _NodeTypes::__next_pointer __next_pointer;
0473 
0474   __next_pointer __node_;
0475   size_t __bucket_;
0476   size_t __bucket_count_;
0477 
0478   typedef pointer_traits<__node_pointer> __pointer_traits;
0479   typedef typename __pointer_traits::element_type __node;
0480   typedef __remove_const_t<__node> __non_const_node;
0481   typedef __rebind_pointer_t<__node_pointer, __non_const_node> __non_const_node_pointer;
0482 
0483 public:
0484   typedef __hash_local_iterator<__non_const_node_pointer> __non_const_iterator;
0485 
0486   typedef forward_iterator_tag iterator_category;
0487   typedef typename _NodeTypes::__node_value_type value_type;
0488   typedef typename _NodeTypes::difference_type difference_type;
0489   typedef const value_type& reference;
0490   typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
0491 
0492   _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {}
0493 
0494   _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
0495       : __node_(__x.__node_),
0496         __bucket_(__x.__bucket_),
0497         __bucket_count_(__x.__bucket_count_) {}
0498 
0499   _LIBCPP_HIDE_FROM_ABI reference operator*() const {
0500     _LIBCPP_ASSERT_NON_NULL(
0501         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
0502     return __node_->__upcast()->__get_value();
0503   }
0504 
0505   _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
0506     _LIBCPP_ASSERT_NON_NULL(
0507         __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
0508     return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__get_value());
0509   }
0510 
0511   _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator& operator++() {
0512     _LIBCPP_ASSERT_NON_NULL(
0513         __node_ != nullptr, "Attempted to increment a non-incrementable unordered container const_local_iterator");
0514     __node_ = __node_->__next_;
0515     if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
0516       __node_ = nullptr;
0517     return *this;
0518   }
0519 
0520   _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator operator++(int) {
0521     __hash_const_local_iterator __t(*this);
0522     ++(*this);
0523     return __t;
0524   }
0525 
0526   friend _LIBCPP_HIDE_FROM_ABI bool
0527   operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) {
0528     return __x.__node_ == __y.__node_;
0529   }
0530   friend _LIBCPP_HIDE_FROM_ABI bool
0531   operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) {
0532     return !(__x == __y);
0533   }
0534 
0535 private:
0536   _LIBCPP_HIDE_FROM_ABI explicit __hash_const_local_iterator(
0537       __next_pointer __node_ptr, size_t __bucket, size_t __bucket_count) _NOEXCEPT
0538       : __node_(__node_ptr),
0539         __bucket_(__bucket),
0540         __bucket_count_(__bucket_count) {
0541     if (__node_ != nullptr)
0542       __node_ = __node_->__next_;
0543   }
0544 
0545   template <class, class, class, class>
0546   friend class __hash_table;
0547   template <class>
0548   friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
0549 };
0550 
0551 template <class _Alloc>
0552 class __bucket_list_deallocator {
0553   typedef _Alloc allocator_type;
0554   typedef allocator_traits<allocator_type> __alloc_traits;
0555   typedef typename __alloc_traits::size_type size_type;
0556 
0557   __compressed_pair<size_type, allocator_type> __data_;
0558 
0559 public:
0560   typedef typename __alloc_traits::pointer pointer;
0561 
0562   _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
0563       : __data_(0, __default_init_tag()) {}
0564 
0565   _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(const allocator_type& __a, size_type __size)
0566       _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
0567       : __data_(__size, __a) {}
0568 
0569   _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x)
0570       _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
0571       : __data_(std::move(__x.__data_)) {
0572     __x.size() = 0;
0573   }
0574 
0575   _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __data_.first(); }
0576   _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __data_.first(); }
0577 
0578   _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __data_.second(); }
0579   _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __data_.second(); }
0580 
0581   _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { __alloc_traits::deallocate(__alloc(), __p, size()); }
0582 };
0583 
0584 template <class _Alloc>
0585 class __hash_map_node_destructor;
0586 
0587 template <class _Alloc>
0588 class __hash_node_destructor {
0589   typedef _Alloc allocator_type;
0590   typedef allocator_traits<allocator_type> __alloc_traits;
0591 
0592 public:
0593   typedef typename __alloc_traits::pointer pointer;
0594 
0595 private:
0596   typedef __hash_node_types<pointer> _NodeTypes;
0597 
0598   allocator_type& __na_;
0599 
0600 public:
0601   bool __value_constructed;
0602 
0603   _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&)            = default;
0604   _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
0605 
0606   _LIBCPP_HIDE_FROM_ABI explicit __hash_node_destructor(allocator_type& __na, bool __constructed = false) _NOEXCEPT
0607       : __na_(__na),
0608         __value_constructed(__constructed) {}
0609 
0610   _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
0611     if (__value_constructed) {
0612       __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__get_value()));
0613       std::__destroy_at(std::addressof(*__p));
0614     }
0615     if (__p)
0616       __alloc_traits::deallocate(__na_, __p, 1);
0617   }
0618 
0619   template <class>
0620   friend class __hash_map_node_destructor;
0621 };
0622 
0623 #if _LIBCPP_STD_VER >= 17
0624 template <class _NodeType, class _Alloc>
0625 struct __generic_container_node_destructor;
0626 
0627 template <class _Tp, class _VoidPtr, class _Alloc>
0628 struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> : __hash_node_destructor<_Alloc> {
0629   using __hash_node_destructor<_Alloc>::__hash_node_destructor;
0630 };
0631 #endif
0632 
0633 template <class _Key, class _Hash, class _Equal>
0634 struct __enforce_unordered_container_requirements {
0635 #ifndef _LIBCPP_CXX03_LANG
0636   static_assert(__check_hash_requirements<_Key, _Hash>::value,
0637                 "the specified hash does not meet the Hash requirements");
0638   static_assert(is_copy_constructible<_Equal>::value, "the specified comparator is required to be copy constructible");
0639 #endif
0640   typedef int type;
0641 };
0642 
0643 template <class _Key, class _Hash, class _Equal>
0644 #ifndef _LIBCPP_CXX03_LANG
0645 _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
0646                          "the specified comparator type does not provide a viable const call operator")
0647 _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
0648                          "the specified hash functor does not provide a viable const call operator")
0649 #endif
0650     typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
0651     __diagnose_unordered_container_requirements(int);
0652 
0653 // This dummy overload is used so that the compiler won't emit a spurious
0654 // "no matching function for call to __diagnose_unordered_xxx" diagnostic
0655 // when the overload above causes a hard error.
0656 template <class _Key, class _Hash, class _Equal>
0657 int __diagnose_unordered_container_requirements(void*);
0658 
0659 template <class _Tp, class _Hash, class _Equal, class _Alloc>
0660 class __hash_table {
0661 public:
0662   typedef _Tp value_type;
0663   typedef _Hash hasher;
0664   typedef _Equal key_equal;
0665   typedef _Alloc allocator_type;
0666 
0667 private:
0668   typedef allocator_traits<allocator_type> __alloc_traits;
0669   typedef typename __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type _NodeTypes;
0670 
0671 public:
0672   typedef typename _NodeTypes::__node_value_type __node_value_type;
0673   typedef typename _NodeTypes::__container_value_type __container_value_type;
0674   typedef typename _NodeTypes::key_type key_type;
0675   typedef value_type& reference;
0676   typedef const value_type& const_reference;
0677   typedef typename __alloc_traits::pointer pointer;
0678   typedef typename __alloc_traits::const_pointer const_pointer;
0679 #ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
0680   typedef typename __alloc_traits::size_type size_type;
0681 #else
0682   typedef typename _NodeTypes::size_type size_type;
0683 #endif
0684   typedef typename _NodeTypes::difference_type difference_type;
0685 
0686 public:
0687   // Create __node
0688 
0689   typedef typename _NodeTypes::__node_type __node;
0690   typedef __rebind_alloc<__alloc_traits, __node> __node_allocator;
0691   typedef allocator_traits<__node_allocator> __node_traits;
0692   typedef typename _NodeTypes::__void_pointer __void_pointer;
0693   typedef typename _NodeTypes::__node_pointer __node_pointer;
0694   typedef typename _NodeTypes::__node_pointer __node_const_pointer;
0695   typedef typename _NodeTypes::__node_base_type __first_node;
0696   typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
0697   typedef typename _NodeTypes::__next_pointer __next_pointer;
0698 
0699 private:
0700   // check for sane allocator pointer rebinding semantics. Rebinding the
0701   // allocator for a new pointer type should be exactly the same as rebinding
0702   // the pointer using 'pointer_traits'.
0703   static_assert(is_same<__node_pointer, typename __node_traits::pointer>::value,
0704                 "Allocator does not rebind pointers in a sane manner.");
0705   typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator;
0706   typedef allocator_traits<__node_base_allocator> __node_base_traits;
0707   static_assert(is_same<__node_base_pointer, typename __node_base_traits::pointer>::value,
0708                 "Allocator does not rebind pointers in a sane manner.");
0709 
0710 private:
0711   typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator;
0712   typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
0713   typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
0714   typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits;
0715   typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;
0716 
0717   // --- Member data begin ---
0718   __bucket_list __bucket_list_;
0719   __compressed_pair<__first_node, __node_allocator> __p1_;
0720   __compressed_pair<size_type, hasher> __p2_;
0721   __compressed_pair<float, key_equal> __p3_;
0722   // --- Member data end ---
0723 
0724   _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __p2_.first(); }
0725 
0726 public:
0727   _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __p2_.first(); }
0728 
0729   _LIBCPP_HIDE_FROM_ABI hasher& hash_function() _NOEXCEPT { return __p2_.second(); }
0730   _LIBCPP_HIDE_FROM_ABI const hasher& hash_function() const _NOEXCEPT { return __p2_.second(); }
0731 
0732   _LIBCPP_HIDE_FROM_ABI float& max_load_factor() _NOEXCEPT { return __p3_.first(); }
0733   _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __p3_.first(); }
0734 
0735   _LIBCPP_HIDE_FROM_ABI key_equal& key_eq() _NOEXCEPT { return __p3_.second(); }
0736   _LIBCPP_HIDE_FROM_ABI const key_equal& key_eq() const _NOEXCEPT { return __p3_.second(); }
0737 
0738   _LIBCPP_HIDE_FROM_ABI __node_allocator& __node_alloc() _NOEXCEPT { return __p1_.second(); }
0739   _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __p1_.second(); }
0740 
0741 public:
0742   typedef __hash_iterator<__node_pointer> iterator;
0743   typedef __hash_const_iterator<__node_pointer> const_iterator;
0744   typedef __hash_local_iterator<__node_pointer> local_iterator;
0745   typedef __hash_const_local_iterator<__node_pointer> const_local_iterator;
0746 
0747   _LIBCPP_HIDE_FROM_ABI __hash_table() _NOEXCEPT_(
0748       is_nothrow_default_constructible<__bucket_list>::value&& is_nothrow_default_constructible<__first_node>::value&&
0749           is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_default_constructible<hasher>::value&&
0750               is_nothrow_default_constructible<key_equal>::value);
0751   _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql);
0752   _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql, const allocator_type& __a);
0753   _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a);
0754   _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u);
0755   _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a);
0756   _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) _NOEXCEPT_(
0757       is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&&
0758           is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<hasher>::value&&
0759               is_nothrow_move_constructible<key_equal>::value);
0760   _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a);
0761   _LIBCPP_HIDE_FROM_ABI ~__hash_table();
0762 
0763   _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u);
0764   _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(__hash_table&& __u)
0765       _NOEXCEPT_(__node_traits::propagate_on_container_move_assignment::value&&
0766                      is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable<hasher>::value&&
0767                          is_nothrow_move_assignable<key_equal>::value);
0768   template <class _InputIterator>
0769   _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
0770   template <class _InputIterator>
0771   _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
0772 
0773   _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
0774     return std::min<size_type>(__node_traits::max_size(__node_alloc()), numeric_limits<difference_type >::max());
0775   }
0776 
0777 private:
0778   _LIBCPP_HIDE_FROM_ABI __next_pointer __node_insert_multi_prepare(size_t __cp_hash, value_type& __cp_val);
0779   _LIBCPP_HIDE_FROM_ABI void __node_insert_multi_perform(__node_pointer __cp, __next_pointer __pn) _NOEXCEPT;
0780 
0781   _LIBCPP_HIDE_FROM_ABI __next_pointer __node_insert_unique_prepare(size_t __nd_hash, value_type& __nd_val);
0782   _LIBCPP_HIDE_FROM_ABI void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
0783 
0784 public:
0785   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
0786   _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd);
0787   _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
0788 
0789   template <class _Key, class... _Args>
0790   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
0791 
0792   template <class... _Args>
0793   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
0794 
0795   template <class _Pp>
0796   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Pp&& __x) {
0797     return __emplace_unique_extract_key(std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>());
0798   }
0799 
0800   template <class _First,
0801             class _Second,
0802             __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, int> = 0>
0803   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_First&& __f, _Second&& __s) {
0804     return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s));
0805   }
0806 
0807   template <class... _Args>
0808   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Args&&... __args) {
0809     return __emplace_unique_impl(std::forward<_Args>(__args)...);
0810   }
0811 
0812   template <class _Pp>
0813   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
0814     return __emplace_unique_impl(std::forward<_Pp>(__x));
0815   }
0816   template <class _Pp>
0817   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
0818     return __emplace_unique_key_args(__x, std::forward<_Pp>(__x));
0819   }
0820   template <class _Pp>
0821   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
0822     return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x));
0823   }
0824 
0825   template <class... _Args>
0826   _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
0827   template <class... _Args>
0828   _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
0829 
0830   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(__container_value_type&& __x) {
0831     return __emplace_unique_key_args(_NodeTypes::__get_key(__x), std::move(__x));
0832   }
0833 
0834   template <class _Pp, __enable_if_t<!__is_same_uncvref<_Pp, __container_value_type>::value, int> = 0>
0835   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(_Pp&& __x) {
0836     return __emplace_unique(std::forward<_Pp>(__x));
0837   }
0838 
0839   template <class _Pp>
0840   _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(_Pp&& __x) {
0841     return __emplace_multi(std::forward<_Pp>(__x));
0842   }
0843 
0844   template <class _Pp>
0845   _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(const_iterator __p, _Pp&& __x) {
0846     return __emplace_hint_multi(__p, std::forward<_Pp>(__x));
0847   }
0848 
0849   _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(const __container_value_type& __x) {
0850     return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
0851   }
0852 
0853 #if _LIBCPP_STD_VER >= 17
0854   template <class _NodeHandle, class _InsertReturnType>
0855   _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
0856   template <class _NodeHandle>
0857   _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator __hint, _NodeHandle&& __nh);
0858   template <class _Table>
0859   _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(_Table& __source);
0860 
0861   template <class _NodeHandle>
0862   _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&& __nh);
0863   template <class _NodeHandle>
0864   _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
0865   template <class _Table>
0866   _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Table& __source);
0867 
0868   template <class _NodeHandle>
0869   _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const& __key);
0870   template <class _NodeHandle>
0871   _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator __it);
0872 #endif
0873 
0874   _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
0875   _LIBCPP_HIDE_FROM_ABI void __rehash_unique(size_type __n) { __rehash<true>(__n); }
0876   _LIBCPP_HIDE_FROM_ABI void __rehash_multi(size_type __n) { __rehash<false>(__n); }
0877   _LIBCPP_HIDE_FROM_ABI void __reserve_unique(size_type __n) {
0878     __rehash_unique(static_cast<size_type>(std::ceil(__n / max_load_factor())));
0879   }
0880   _LIBCPP_HIDE_FROM_ABI void __reserve_multi(size_type __n) {
0881     __rehash_multi(static_cast<size_type>(std::ceil(__n / max_load_factor())));
0882   }
0883 
0884   _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __bucket_list_.get_deleter().size(); }
0885 
0886   _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT;
0887   _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT;
0888   _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT;
0889   _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT;
0890 
0891   template <class _Key>
0892   _LIBCPP_HIDE_FROM_ABI size_type bucket(const _Key& __k) const {
0893     _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0894         bucket_count() > 0, "unordered container::bucket(key) called when bucket_count() == 0");
0895     return std::__constrain_hash(hash_function()(__k), bucket_count());
0896   }
0897 
0898   template <class _Key>
0899   _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __x);
0900   template <class _Key>
0901   _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const;
0902 
0903   typedef __hash_node_destructor<__node_allocator> _Dp;
0904   typedef unique_ptr<__node, _Dp> __node_holder;
0905 
0906   _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
0907   _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
0908   template <class _Key>
0909   _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
0910   template <class _Key>
0911   _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);
0912   _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
0913 
0914   template <class _Key>
0915   _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
0916   template <class _Key>
0917   _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
0918 
0919   template <class _Key>
0920   _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_unique(const _Key& __k);
0921   template <class _Key>
0922   _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_unique(const _Key& __k) const;
0923 
0924   template <class _Key>
0925   _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_multi(const _Key& __k);
0926   template <class _Key>
0927   _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const;
0928 
0929   _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u)
0930 #if _LIBCPP_STD_VER <= 11
0931       _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal> &&
0932                  (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
0933                   __is_nothrow_swappable_v<__pointer_allocator>) &&
0934                  (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>));
0935 #else
0936       _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>);
0937 #endif
0938 
0939   _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return max_size(); }
0940   _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const;
0941   _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT {
0942     size_type __bc = bucket_count();
0943     return __bc != 0 ? (float)size() / __bc : 0.f;
0944   }
0945   _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) _NOEXCEPT {
0946     // While passing a non-positive load factor is undefined behavior, in practice the result will be benign (the
0947     // call will be equivalent to `max_load_factor(load_factor())`, which is also the case for passing a valid value
0948     // less than the current `load_factor`).
0949     _LIBCPP_ASSERT_PEDANTIC(__mlf > 0, "unordered container::max_load_factor(lf) called with lf <= 0");
0950     max_load_factor() = std::max(__mlf, load_factor());
0951   }
0952 
0953   _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) {
0954     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0955         __n < bucket_count(), "unordered container::begin(n) called with n >= bucket_count()");
0956     return local_iterator(__bucket_list_[__n], __n, bucket_count());
0957   }
0958 
0959   _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) {
0960     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0961         __n < bucket_count(), "unordered container::end(n) called with n >= bucket_count()");
0962     return local_iterator(nullptr, __n, bucket_count());
0963   }
0964 
0965   _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const {
0966     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0967         __n < bucket_count(), "unordered container::cbegin(n) called with n >= bucket_count()");
0968     return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
0969   }
0970 
0971   _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const {
0972     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0973         __n < bucket_count(), "unordered container::cend(n) called with n >= bucket_count()");
0974     return const_local_iterator(nullptr, __n, bucket_count());
0975   }
0976 
0977 private:
0978   template <bool _UniqueKeys>
0979   _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n);
0980   template <bool _UniqueKeys>
0981   _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n);
0982 
0983   template <class... _Args>
0984   _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args);
0985 
0986   template <class _First, class... _Rest>
0987   _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
0988 
0989   _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u) {
0990     __copy_assign_alloc(__u, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
0991   }
0992   _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type);
0993   _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table&, false_type) {}
0994 
0995   _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type);
0996   _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type)
0997       _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable<hasher>::value&&
0998                      is_nothrow_move_assignable<key_equal>::value);
0999   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u) _NOEXCEPT_(
1000       !__node_traits::propagate_on_container_move_assignment::value ||
1001       (is_nothrow_move_assignable<__pointer_allocator>::value && is_nothrow_move_assignable<__node_allocator>::value)) {
1002     __move_assign_alloc(__u, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
1003   }
1004   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u, true_type) _NOEXCEPT_(
1005       is_nothrow_move_assignable<__pointer_allocator>::value&& is_nothrow_move_assignable<__node_allocator>::value) {
1006     __bucket_list_.get_deleter().__alloc() = std::move(__u.__bucket_list_.get_deleter().__alloc());
1007     __node_alloc()                         = std::move(__u.__node_alloc());
1008   }
1009   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
1010 
1011   _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT;
1012   _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT;
1013 
1014   template <class, class, class, class, class>
1015   friend class _LIBCPP_TEMPLATE_VIS unordered_map;
1016   template <class, class, class, class, class>
1017   friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
1018 };
1019 
1020 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1021 inline __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() _NOEXCEPT_(
1022     is_nothrow_default_constructible<__bucket_list>::value&& is_nothrow_default_constructible<__first_node>::value&&
1023         is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_default_constructible<hasher>::value&&
1024             is_nothrow_default_constructible<key_equal>::value)
1025     : __p2_(0, __default_init_tag()), __p3_(1.0f, __default_init_tag()) {}
1026 
1027 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1028 inline __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, const key_equal& __eql)
1029     : __bucket_list_(nullptr, __bucket_list_deleter()), __p1_(), __p2_(0, __hf), __p3_(1.0f, __eql) {}
1030 
1031 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1032 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(
1033     const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
1034     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1035       __p1_(__default_init_tag(), __node_allocator(__a)),
1036       __p2_(0, __hf),
1037       __p3_(1.0f, __eql) {}
1038 
1039 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1040 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
1041     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1042       __p1_(__default_init_tag(), __node_allocator(__a)),
1043       __p2_(0, __default_init_tag()),
1044       __p3_(1.0f, __default_init_tag()) {}
1045 
1046 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1047 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
1048     : __bucket_list_(nullptr,
1049                      __bucket_list_deleter(allocator_traits<__pointer_allocator>::select_on_container_copy_construction(
1050                                                __u.__bucket_list_.get_deleter().__alloc()),
1051                                            0)),
1052       __p1_(__default_init_tag(),
1053             allocator_traits<__node_allocator>::select_on_container_copy_construction(__u.__node_alloc())),
1054       __p2_(0, __u.hash_function()),
1055       __p3_(__u.__p3_) {}
1056 
1057 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1058 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, const allocator_type& __a)
1059     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1060       __p1_(__default_init_tag(), __node_allocator(__a)),
1061       __p2_(0, __u.hash_function()),
1062       __p3_(__u.__p3_) {}
1063 
1064 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1065 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) _NOEXCEPT_(
1066     is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&&
1067         is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<hasher>::value&&
1068             is_nothrow_move_constructible<key_equal>::value)
1069     : __bucket_list_(std::move(__u.__bucket_list_)),
1070       __p1_(std::move(__u.__p1_)),
1071       __p2_(std::move(__u.__p2_)),
1072       __p3_(std::move(__u.__p3_)) {
1073   if (size() > 0) {
1074     __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr();
1075     __u.__p1_.first().__next_                                                              = nullptr;
1076     __u.size()                                                                             = 0;
1077   }
1078 }
1079 
1080 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1081 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, const allocator_type& __a)
1082     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1083       __p1_(__default_init_tag(), __node_allocator(__a)),
1084       __p2_(0, std::move(__u.hash_function())),
1085       __p3_(std::move(__u.__p3_)) {
1086   if (__a == allocator_type(__u.__node_alloc())) {
1087     __bucket_list_.reset(__u.__bucket_list_.release());
1088     __bucket_list_.get_deleter().size()     = __u.__bucket_list_.get_deleter().size();
1089     __u.__bucket_list_.get_deleter().size() = 0;
1090     if (__u.size() > 0) {
1091       __p1_.first().__next_     = __u.__p1_.first().__next_;
1092       __u.__p1_.first().__next_ = nullptr;
1093       __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr();
1094       size()                                                                                 = __u.size();
1095       __u.size()                                                                             = 0;
1096     }
1097   }
1098 }
1099 
1100 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1101 __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() {
1102 #if defined(_LIBCPP_CXX03_LANG)
1103   static_assert(is_copy_constructible<key_equal>::value, "Predicate must be copy-constructible.");
1104   static_assert(is_copy_constructible<hasher>::value, "Hasher must be copy-constructible.");
1105 #endif
1106 
1107   __deallocate_node(__p1_.first().__next_);
1108 }
1109 
1110 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1111 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(const __hash_table& __u, true_type) {
1112   if (__node_alloc() != __u.__node_alloc()) {
1113     clear();
1114     __bucket_list_.reset();
1115     __bucket_list_.get_deleter().size() = 0;
1116   }
1117   __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();
1118   __node_alloc()                         = __u.__node_alloc();
1119 }
1120 
1121 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1122 __hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) {
1123   if (this != std::addressof(__u)) {
1124     __copy_assign_alloc(__u);
1125     hash_function()   = __u.hash_function();
1126     key_eq()          = __u.key_eq();
1127     max_load_factor() = __u.max_load_factor();
1128     __assign_multi(__u.begin(), __u.end());
1129   }
1130   return *this;
1131 }
1132 
1133 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1134 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) _NOEXCEPT {
1135   __node_allocator& __na = __node_alloc();
1136   while (__np != nullptr) {
1137     __next_pointer __next    = __np->__next_;
1138     __node_pointer __real_np = __np->__upcast();
1139     __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__get_value()));
1140     std::__destroy_at(std::addressof(*__real_np));
1141     __node_traits::deallocate(__na, __real_np, 1);
1142     __np = __next;
1143   }
1144 }
1145 
1146 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1147 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1148 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT {
1149   size_type __bc = bucket_count();
1150   for (size_type __i = 0; __i < __bc; ++__i)
1151     __bucket_list_[__i] = nullptr;
1152   size()                 = 0;
1153   __next_pointer __cache = __p1_.first().__next_;
1154   __p1_.first().__next_  = nullptr;
1155   return __cache;
1156 }
1157 
1158 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1159 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, true_type)
1160     _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable<hasher>::value&&
1161                    is_nothrow_move_assignable<key_equal>::value) {
1162   clear();
1163   __bucket_list_.reset(__u.__bucket_list_.release());
1164   __bucket_list_.get_deleter().size()     = __u.__bucket_list_.get_deleter().size();
1165   __u.__bucket_list_.get_deleter().size() = 0;
1166   __move_assign_alloc(__u);
1167   size()                = __u.size();
1168   hash_function()       = std::move(__u.hash_function());
1169   max_load_factor()     = __u.max_load_factor();
1170   key_eq()              = std::move(__u.key_eq());
1171   __p1_.first().__next_ = __u.__p1_.first().__next_;
1172   if (size() > 0) {
1173     __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr();
1174     __u.__p1_.first().__next_                                                              = nullptr;
1175     __u.size()                                                                             = 0;
1176   }
1177 }
1178 
1179 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1180 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, false_type) {
1181   if (__node_alloc() == __u.__node_alloc())
1182     __move_assign(__u, true_type());
1183   else {
1184     hash_function()   = std::move(__u.hash_function());
1185     key_eq()          = std::move(__u.key_eq());
1186     max_load_factor() = __u.max_load_factor();
1187     if (bucket_count() != 0) {
1188       __next_pointer __cache = __detach();
1189 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1190       try {
1191 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1192         const_iterator __i = __u.begin();
1193         while (__cache != nullptr && __u.size() != 0) {
1194           __cache->__upcast()->__get_value() = std::move(__u.remove(__i++)->__get_value());
1195           __next_pointer __next              = __cache->__next_;
1196           __node_insert_multi(__cache->__upcast());
1197           __cache = __next;
1198         }
1199 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1200       } catch (...) {
1201         __deallocate_node(__cache);
1202         throw;
1203       }
1204 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1205       __deallocate_node(__cache);
1206     }
1207     const_iterator __i = __u.begin();
1208     while (__u.size() != 0) {
1209       __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__get_value()));
1210       __node_insert_multi(__h.get());
1211       __h.release();
1212     }
1213   }
1214 }
1215 
1216 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1217 inline __hash_table<_Tp, _Hash, _Equal, _Alloc>&
1218 __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) _NOEXCEPT_(
1219     __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<__node_allocator>::value&&
1220         is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value) {
1221   __move_assign(__u, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
1222   return *this;
1223 }
1224 
1225 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1226 template <class _InputIterator>
1227 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, _InputIterator __last) {
1228   typedef iterator_traits<_InputIterator> _ITraits;
1229   typedef typename _ITraits::value_type _ItValueType;
1230   static_assert(is_same<_ItValueType, __container_value_type>::value,
1231                 "__assign_unique may only be called with the containers value type");
1232 
1233   if (bucket_count() != 0) {
1234     __next_pointer __cache = __detach();
1235 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1236     try {
1237 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1238       for (; __cache != nullptr && __first != __last; ++__first) {
1239         __cache->__upcast()->__get_value() = *__first;
1240         __next_pointer __next              = __cache->__next_;
1241         __node_insert_unique(__cache->__upcast());
1242         __cache = __next;
1243       }
1244 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1245     } catch (...) {
1246       __deallocate_node(__cache);
1247       throw;
1248     }
1249 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1250     __deallocate_node(__cache);
1251   }
1252   for (; __first != __last; ++__first)
1253     __insert_unique(*__first);
1254 }
1255 
1256 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1257 template <class _InputIterator>
1258 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, _InputIterator __last) {
1259   typedef iterator_traits<_InputIterator> _ITraits;
1260   typedef typename _ITraits::value_type _ItValueType;
1261   static_assert(
1262       (is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value),
1263       "__assign_multi may only be called with the containers value type"
1264       " or the nodes value type");
1265   if (bucket_count() != 0) {
1266     __next_pointer __cache = __detach();
1267 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1268     try {
1269 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1270       for (; __cache != nullptr && __first != __last; ++__first) {
1271         __cache->__upcast()->__get_value() = *__first;
1272         __next_pointer __next              = __cache->__next_;
1273         __node_insert_multi(__cache->__upcast());
1274         __cache = __next;
1275       }
1276 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1277     } catch (...) {
1278       __deallocate_node(__cache);
1279       throw;
1280     }
1281 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1282     __deallocate_node(__cache);
1283   }
1284   for (; __first != __last; ++__first)
1285     __insert_multi(_NodeTypes::__get_value(*__first));
1286 }
1287 
1288 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1289 inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1290 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT {
1291   return iterator(__p1_.first().__next_);
1292 }
1293 
1294 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1295 inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1296 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT {
1297   return iterator(nullptr);
1298 }
1299 
1300 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1301 inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
1302 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT {
1303   return const_iterator(__p1_.first().__next_);
1304 }
1305 
1306 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1307 inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
1308 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT {
1309   return const_iterator(nullptr);
1310 }
1311 
1312 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1313 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT {
1314   if (size() > 0) {
1315     __deallocate_node(__p1_.first().__next_);
1316     __p1_.first().__next_ = nullptr;
1317     size_type __bc        = bucket_count();
1318     for (size_type __i = 0; __i < __bc; ++__i)
1319       __bucket_list_[__i] = nullptr;
1320     size() = 0;
1321   }
1322 }
1323 
1324 // Prepare the container for an insertion of the value __value with the hash
1325 // __hash. This does a lookup into the container to see if __value is already
1326 // present, and performs a rehash if necessary. Returns a pointer to the
1327 // existing element if it exists, otherwise nullptr.
1328 //
1329 // Note that this function does forward exceptions if key_eq() throws, and never
1330 // mutates __value or actually inserts into the map.
1331 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1332 _LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1333 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(size_t __hash, value_type& __value) {
1334   size_type __bc = bucket_count();
1335 
1336   if (__bc != 0) {
1337     size_t __chash         = std::__constrain_hash(__hash, __bc);
1338     __next_pointer __ndptr = __bucket_list_[__chash];
1339     if (__ndptr != nullptr) {
1340       for (__ndptr = __ndptr->__next_;
1341            __ndptr != nullptr &&
1342            (__ndptr->__hash() == __hash || std::__constrain_hash(__ndptr->__hash(), __bc) == __chash);
1343            __ndptr = __ndptr->__next_) {
1344         if ((__ndptr->__hash() == __hash) && key_eq()(__ndptr->__upcast()->__get_value(), __value))
1345           return __ndptr;
1346       }
1347     }
1348   }
1349   if (size() + 1 > __bc * max_load_factor() || __bc == 0) {
1350     __rehash_unique(std::max<size_type>(
1351         2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1352   }
1353   return nullptr;
1354 }
1355 
1356 // Insert the node __nd into the container by pushing it into the right bucket,
1357 // and updating size(). Assumes that __nd->__hash is up-to-date, and that
1358 // rehashing has already occurred and that no element with the same key exists
1359 // in the map.
1360 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1361 _LIBCPP_HIDE_FROM_ABI void
1362 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(__node_pointer __nd) _NOEXCEPT {
1363   size_type __bc = bucket_count();
1364   size_t __chash = std::__constrain_hash(__nd->__hash(), __bc);
1365   // insert_after __bucket_list_[__chash], or __first_node if bucket is null
1366   __next_pointer __pn = __bucket_list_[__chash];
1367   if (__pn == nullptr) {
1368     __pn          = __p1_.first().__ptr();
1369     __nd->__next_ = __pn->__next_;
1370     __pn->__next_ = __nd->__ptr();
1371     // fix up __bucket_list_
1372     __bucket_list_[__chash] = __pn;
1373     if (__nd->__next_ != nullptr)
1374       __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
1375   } else {
1376     __nd->__next_ = __pn->__next_;
1377     __pn->__next_ = __nd->__ptr();
1378   }
1379   ++size();
1380 }
1381 
1382 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1383 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1384 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) {
1385   __nd->__hash_                  = hash_function()(__nd->__get_value());
1386   __next_pointer __existing_node = __node_insert_unique_prepare(__nd->__hash(), __nd->__get_value());
1387 
1388   // Insert the node, unless it already exists in the container.
1389   bool __inserted = false;
1390   if (__existing_node == nullptr) {
1391     __node_insert_unique_perform(__nd);
1392     __existing_node = __nd->__ptr();
1393     __inserted      = true;
1394   }
1395   return pair<iterator, bool>(iterator(__existing_node), __inserted);
1396 }
1397 
1398 // Prepare the container for an insertion of the value __cp_val with the hash
1399 // __cp_hash. This does a lookup into the container to see if __cp_value is
1400 // already present, and performs a rehash if necessary. Returns a pointer to the
1401 // last occurrence of __cp_val in the map.
1402 //
1403 // Note that this function does forward exceptions if key_eq() throws, and never
1404 // mutates __value or actually inserts into the map.
1405 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1406 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1407 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(size_t __cp_hash, value_type& __cp_val) {
1408   size_type __bc = bucket_count();
1409   if (size() + 1 > __bc * max_load_factor() || __bc == 0) {
1410     __rehash_multi(std::max<size_type>(
1411         2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1412     __bc = bucket_count();
1413   }
1414   size_t __chash      = std::__constrain_hash(__cp_hash, __bc);
1415   __next_pointer __pn = __bucket_list_[__chash];
1416   if (__pn != nullptr) {
1417     for (bool __found = false;
1418          __pn->__next_ != nullptr && std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
1419          __pn = __pn->__next_) {
1420       //      __found    key_eq()     action
1421       //      false       false       loop
1422       //      true        true        loop
1423       //      false       true        set __found to true
1424       //      true        false       break
1425       if (__found !=
1426           (__pn->__next_->__hash() == __cp_hash && key_eq()(__pn->__next_->__upcast()->__get_value(), __cp_val))) {
1427         if (!__found)
1428           __found = true;
1429         else
1430           break;
1431       }
1432     }
1433   }
1434   return __pn;
1435 }
1436 
1437 // Insert the node __cp into the container after __pn (which is the last node in
1438 // the bucket that compares equal to __cp). Rehashing, and checking for
1439 // uniqueness has already been performed (in __node_insert_multi_prepare), so
1440 // all we need to do is update the bucket and size(). Assumes that __cp->__hash
1441 // is up-to-date.
1442 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1443 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
1444     __node_pointer __cp, __next_pointer __pn) _NOEXCEPT {
1445   size_type __bc = bucket_count();
1446   size_t __chash = std::__constrain_hash(__cp->__hash_, __bc);
1447   if (__pn == nullptr) {
1448     __pn          = __p1_.first().__ptr();
1449     __cp->__next_ = __pn->__next_;
1450     __pn->__next_ = __cp->__ptr();
1451     // fix up __bucket_list_
1452     __bucket_list_[__chash] = __pn;
1453     if (__cp->__next_ != nullptr)
1454       __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] = __cp->__ptr();
1455   } else {
1456     __cp->__next_ = __pn->__next_;
1457     __pn->__next_ = __cp->__ptr();
1458     if (__cp->__next_ != nullptr) {
1459       size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc);
1460       if (__nhash != __chash)
1461         __bucket_list_[__nhash] = __cp->__ptr();
1462     }
1463   }
1464   ++size();
1465 }
1466 
1467 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1468 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1469 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) {
1470   __cp->__hash_       = hash_function()(__cp->__get_value());
1471   __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__get_value());
1472   __node_insert_multi_perform(__cp, __pn);
1473 
1474   return iterator(__cp->__ptr());
1475 }
1476 
1477 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1478 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1479 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(const_iterator __p, __node_pointer __cp) {
1480   if (__p != end() && key_eq()(*__p, __cp->__get_value())) {
1481     __next_pointer __np = __p.__node_;
1482     __cp->__hash_       = __np->__hash();
1483     size_type __bc      = bucket_count();
1484     if (size() + 1 > __bc * max_load_factor() || __bc == 0) {
1485       __rehash_multi(std::max<size_type>(
1486           2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1487       __bc = bucket_count();
1488     }
1489     size_t __chash      = std::__constrain_hash(__cp->__hash_, __bc);
1490     __next_pointer __pp = __bucket_list_[__chash];
1491     while (__pp->__next_ != __np)
1492       __pp = __pp->__next_;
1493     __cp->__next_ = __np;
1494     __pp->__next_ = static_cast<__next_pointer>(__cp);
1495     ++size();
1496     return iterator(static_cast<__next_pointer>(__cp));
1497   }
1498   return __node_insert_multi(__cp);
1499 }
1500 
1501 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1502 template <class _Key, class... _Args>
1503 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1504 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) {
1505   size_t __hash   = hash_function()(__k);
1506   size_type __bc  = bucket_count();
1507   bool __inserted = false;
1508   __next_pointer __nd;
1509   size_t __chash;
1510   if (__bc != 0) {
1511     __chash = std::__constrain_hash(__hash, __bc);
1512     __nd    = __bucket_list_[__chash];
1513     if (__nd != nullptr) {
1514       for (__nd = __nd->__next_;
1515            __nd != nullptr && (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
1516            __nd = __nd->__next_) {
1517         if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k))
1518           goto __done;
1519       }
1520     }
1521   }
1522   {
1523     __node_holder __h = __construct_node_hash(__hash, std::forward<_Args>(__args)...);
1524     if (size() + 1 > __bc * max_load_factor() || __bc == 0) {
1525       __rehash_unique(std::max<size_type>(
1526           2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1527       __bc    = bucket_count();
1528       __chash = std::__constrain_hash(__hash, __bc);
1529     }
1530     // insert_after __bucket_list_[__chash], or __first_node if bucket is null
1531     __next_pointer __pn = __bucket_list_[__chash];
1532     if (__pn == nullptr) {
1533       __pn          = __p1_.first().__ptr();
1534       __h->__next_  = __pn->__next_;
1535       __pn->__next_ = __h.get()->__ptr();
1536       // fix up __bucket_list_
1537       __bucket_list_[__chash] = __pn;
1538       if (__h->__next_ != nullptr)
1539         __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] = __h.get()->__ptr();
1540     } else {
1541       __h->__next_  = __pn->__next_;
1542       __pn->__next_ = static_cast<__next_pointer>(__h.get());
1543     }
1544     __nd = static_cast<__next_pointer>(__h.release());
1545     // increment size
1546     ++size();
1547     __inserted = true;
1548   }
1549 __done:
1550   return pair<iterator, bool>(iterator(__nd), __inserted);
1551 }
1552 
1553 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1554 template <class... _Args>
1555 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1556 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) {
1557   __node_holder __h        = __construct_node(std::forward<_Args>(__args)...);
1558   pair<iterator, bool> __r = __node_insert_unique(__h.get());
1559   if (__r.second)
1560     __h.release();
1561   return __r;
1562 }
1563 
1564 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1565 template <class... _Args>
1566 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1567 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) {
1568   __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1569   iterator __r      = __node_insert_multi(__h.get());
1570   __h.release();
1571   return __r;
1572 }
1573 
1574 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1575 template <class... _Args>
1576 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1577 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) {
1578   __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
1579   iterator __r      = __node_insert_multi(__p, __h.get());
1580   __h.release();
1581   return __r;
1582 }
1583 
1584 #if _LIBCPP_STD_VER >= 17
1585 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1586 template <class _NodeHandle, class _InsertReturnType>
1587 _LIBCPP_HIDE_FROM_ABI _InsertReturnType
1588 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(_NodeHandle&& __nh) {
1589   if (__nh.empty())
1590     return _InsertReturnType{end(), false, _NodeHandle()};
1591   pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
1592   if (__result.second)
1593     __nh.__release_ptr();
1594   return _InsertReturnType{__result.first, __result.second, std::move(__nh)};
1595 }
1596 
1597 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1598 template <class _NodeHandle>
1599 _LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1600 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(const_iterator, _NodeHandle&& __nh) {
1601   if (__nh.empty())
1602     return end();
1603   pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
1604   if (__result.second)
1605     __nh.__release_ptr();
1606   return __result.first;
1607 }
1608 
1609 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1610 template <class _NodeHandle>
1611 _LIBCPP_HIDE_FROM_ABI _NodeHandle
1612 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(key_type const& __key) {
1613   iterator __i = find(__key);
1614   if (__i == end())
1615     return _NodeHandle();
1616   return __node_handle_extract<_NodeHandle>(__i);
1617 }
1618 
1619 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1620 template <class _NodeHandle>
1621 _LIBCPP_HIDE_FROM_ABI _NodeHandle __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(const_iterator __p) {
1622   allocator_type __alloc(__node_alloc());
1623   return _NodeHandle(remove(__p).release(), __alloc);
1624 }
1625 
1626 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1627 template <class _Table>
1628 _LIBCPP_HIDE_FROM_ABI void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(_Table& __source) {
1629   static_assert(is_same<__node, typename _Table::__node>::value, "");
1630 
1631   for (typename _Table::iterator __it = __source.begin(); __it != __source.end();) {
1632     __node_pointer __src_ptr       = __it.__node_->__upcast();
1633     size_t __hash                  = hash_function()(__src_ptr->__get_value());
1634     __next_pointer __existing_node = __node_insert_unique_prepare(__hash, __src_ptr->__get_value());
1635     auto __prev_iter               = __it++;
1636     if (__existing_node == nullptr) {
1637       (void)__source.remove(__prev_iter).release();
1638       __src_ptr->__hash_ = __hash;
1639       __node_insert_unique_perform(__src_ptr);
1640     }
1641   }
1642 }
1643 
1644 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1645 template <class _NodeHandle>
1646 _LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1647 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(_NodeHandle&& __nh) {
1648   if (__nh.empty())
1649     return end();
1650   iterator __result = __node_insert_multi(__nh.__ptr_);
1651   __nh.__release_ptr();
1652   return __result;
1653 }
1654 
1655 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1656 template <class _NodeHandle>
1657 _LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1658 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh) {
1659   if (__nh.empty())
1660     return end();
1661   iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
1662   __nh.__release_ptr();
1663   return __result;
1664 }
1665 
1666 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1667 template <class _Table>
1668 _LIBCPP_HIDE_FROM_ABI void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(_Table& __source) {
1669   static_assert(is_same<typename _Table::__node, __node>::value, "");
1670 
1671   for (typename _Table::iterator __it = __source.begin(); __it != __source.end();) {
1672     __node_pointer __src_ptr = __it.__node_->__upcast();
1673     size_t __src_hash        = hash_function()(__src_ptr->__get_value());
1674     __next_pointer __pn      = __node_insert_multi_prepare(__src_hash, __src_ptr->__get_value());
1675     (void)__source.remove(__it++).release();
1676     __src_ptr->__hash_ = __src_hash;
1677     __node_insert_multi_perform(__src_ptr, __pn);
1678   }
1679 }
1680 #endif // _LIBCPP_STD_VER >= 17
1681 
1682 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1683 template <bool _UniqueKeys>
1684 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {
1685   if (__n == 1)
1686     __n = 2;
1687   else if (__n & (__n - 1))
1688     __n = std::__next_prime(__n);
1689   size_type __bc = bucket_count();
1690   if (__n > __bc)
1691     __do_rehash<_UniqueKeys>(__n);
1692   else if (__n < __bc) {
1693     __n = std::max<size_type>(
1694         __n,
1695         std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor())))
1696                                     : std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor()))));
1697     if (__n < __bc)
1698       __do_rehash<_UniqueKeys>(__n);
1699   }
1700 }
1701 
1702 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1703 template <bool _UniqueKeys>
1704 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) {
1705   __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
1706   __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
1707   __bucket_list_.get_deleter().size() = __nbc;
1708   if (__nbc > 0) {
1709     for (size_type __i = 0; __i < __nbc; ++__i)
1710       __bucket_list_[__i] = nullptr;
1711     __next_pointer __pp = __p1_.first().__ptr();
1712     __next_pointer __cp = __pp->__next_;
1713     if (__cp != nullptr) {
1714       size_type __chash       = std::__constrain_hash(__cp->__hash(), __nbc);
1715       __bucket_list_[__chash] = __pp;
1716       size_type __phash       = __chash;
1717       for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) {
1718         __chash = std::__constrain_hash(__cp->__hash(), __nbc);
1719         if (__chash == __phash)
1720           __pp = __cp;
1721         else {
1722           if (__bucket_list_[__chash] == nullptr) {
1723             __bucket_list_[__chash] = __pp;
1724             __pp                    = __cp;
1725             __phash                 = __chash;
1726           } else {
1727             __next_pointer __np = __cp;
1728             if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) {
1729               for (; __np->__next_ != nullptr &&
1730                      key_eq()(__cp->__upcast()->__get_value(), __np->__next_->__upcast()->__get_value());
1731                    __np = __np->__next_)
1732                 ;
1733             }
1734             __pp->__next_                    = __np->__next_;
1735             __np->__next_                    = __bucket_list_[__chash]->__next_;
1736             __bucket_list_[__chash]->__next_ = __cp;
1737           }
1738         }
1739       }
1740     }
1741   }
1742 }
1743 
1744 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1745 template <class _Key>
1746 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1747 __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) {
1748   size_t __hash  = hash_function()(__k);
1749   size_type __bc = bucket_count();
1750   if (__bc != 0) {
1751     size_t __chash      = std::__constrain_hash(__hash, __bc);
1752     __next_pointer __nd = __bucket_list_[__chash];
1753     if (__nd != nullptr) {
1754       for (__nd = __nd->__next_;
1755            __nd != nullptr && (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
1756            __nd = __nd->__next_) {
1757         if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k))
1758           return iterator(__nd);
1759       }
1760     }
1761   }
1762   return end();
1763 }
1764 
1765 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1766 template <class _Key>
1767 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
1768 __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const {
1769   size_t __hash  = hash_function()(__k);
1770   size_type __bc = bucket_count();
1771   if (__bc != 0) {
1772     size_t __chash      = std::__constrain_hash(__hash, __bc);
1773     __next_pointer __nd = __bucket_list_[__chash];
1774     if (__nd != nullptr) {
1775       for (__nd = __nd->__next_;
1776            __nd != nullptr && (__hash == __nd->__hash() || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
1777            __nd = __nd->__next_) {
1778         if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k))
1779           return const_iterator(__nd);
1780       }
1781     }
1782   }
1783   return end();
1784 }
1785 
1786 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1787 template <class... _Args>
1788 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
1789 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) {
1790   static_assert(!__is_hash_value_type<_Args...>::value, "Construct cannot be called with a hash value type");
1791   __node_allocator& __na = __node_alloc();
1792   __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1793 
1794   // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value
1795   // held inside the node, since we need to use the allocator's construct() method for that.
1796   //
1797   // We don't use the allocator's construct() method to construct the node itself since the
1798   // Cpp17FooInsertable named requirements don't require the allocator's construct() method
1799   // to work on anything other than the value_type.
1800   std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ 0);
1801 
1802   // Now construct the value_type using the allocator's construct() method.
1803   __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_Args>(__args)...);
1804   __h.get_deleter().__value_constructed = true;
1805 
1806   __h->__hash_ = hash_function()(__h->__get_value());
1807   return __h;
1808 }
1809 
1810 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1811 template <class _First, class... _Rest>
1812 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
1813 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest) {
1814   static_assert(!__is_hash_value_type<_First, _Rest...>::value, "Construct cannot be called with a hash value type");
1815   __node_allocator& __na = __node_alloc();
1816   __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1817   std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ __hash);
1818   __node_traits::construct(
1819       __na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...);
1820   __h.get_deleter().__value_constructed = true;
1821   return __h;
1822 }
1823 
1824 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1825 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1826 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) {
1827   __next_pointer __np = __p.__node_;
1828   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1829       __p != end(), "unordered container::erase(iterator) called with a non-dereferenceable iterator");
1830   iterator __r(__np);
1831   ++__r;
1832   remove(__p);
1833   return __r;
1834 }
1835 
1836 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1837 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1838 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) {
1839   for (const_iterator __p = __first; __first != __last; __p = __first) {
1840     ++__first;
1841     erase(__p);
1842   }
1843   __next_pointer __np = __last.__node_;
1844   return iterator(__np);
1845 }
1846 
1847 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1848 template <class _Key>
1849 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
1850 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) {
1851   iterator __i = find(__k);
1852   if (__i == end())
1853     return 0;
1854   erase(__i);
1855   return 1;
1856 }
1857 
1858 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1859 template <class _Key>
1860 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
1861 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) {
1862   size_type __r = 0;
1863   iterator __i  = find(__k);
1864   if (__i != end()) {
1865     iterator __e = end();
1866     do {
1867       erase(__i++);
1868       ++__r;
1869     } while (__i != __e && key_eq()(*__i, __k));
1870   }
1871   return __r;
1872 }
1873 
1874 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1875 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
1876 __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT {
1877   // current node
1878   __next_pointer __cn = __p.__node_;
1879   size_type __bc      = bucket_count();
1880   size_t __chash      = std::__constrain_hash(__cn->__hash(), __bc);
1881   // find previous node
1882   __next_pointer __pn = __bucket_list_[__chash];
1883   for (; __pn->__next_ != __cn; __pn = __pn->__next_)
1884     ;
1885   // Fix up __bucket_list_
1886   // if __pn is not in same bucket (before begin is not in same bucket) &&
1887   //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
1888   if (__pn == __p1_.first().__ptr() || std::__constrain_hash(__pn->__hash(), __bc) != __chash) {
1889     if (__cn->__next_ == nullptr || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
1890       __bucket_list_[__chash] = nullptr;
1891   }
1892   // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
1893   if (__cn->__next_ != nullptr) {
1894     size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc);
1895     if (__nhash != __chash)
1896       __bucket_list_[__nhash] = __pn;
1897   }
1898   // remove __cn
1899   __pn->__next_ = __cn->__next_;
1900   __cn->__next_ = nullptr;
1901   --size();
1902   return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
1903 }
1904 
1905 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1906 template <class _Key>
1907 inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
1908 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const {
1909   return static_cast<size_type>(find(__k) != end());
1910 }
1911 
1912 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1913 template <class _Key>
1914 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
1915 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const {
1916   size_type __r      = 0;
1917   const_iterator __i = find(__k);
1918   if (__i != end()) {
1919     const_iterator __e = end();
1920     do {
1921       ++__i;
1922       ++__r;
1923     } while (__i != __e && key_eq()(*__i, __k));
1924   }
1925   return __r;
1926 }
1927 
1928 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1929 template <class _Key>
1930 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
1931      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
1932 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(const _Key& __k) {
1933   iterator __i = find(__k);
1934   iterator __j = __i;
1935   if (__i != end())
1936     ++__j;
1937   return pair<iterator, iterator>(__i, __j);
1938 }
1939 
1940 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1941 template <class _Key>
1942 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
1943      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
1944 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(const _Key& __k) const {
1945   const_iterator __i = find(__k);
1946   const_iterator __j = __i;
1947   if (__i != end())
1948     ++__j;
1949   return pair<const_iterator, const_iterator>(__i, __j);
1950 }
1951 
1952 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1953 template <class _Key>
1954 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
1955      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
1956 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) {
1957   iterator __i = find(__k);
1958   iterator __j = __i;
1959   if (__i != end()) {
1960     iterator __e = end();
1961     do {
1962       ++__j;
1963     } while (__j != __e && key_eq()(*__j, __k));
1964   }
1965   return pair<iterator, iterator>(__i, __j);
1966 }
1967 
1968 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1969 template <class _Key>
1970 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
1971      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
1972 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) const {
1973   const_iterator __i = find(__k);
1974   const_iterator __j = __i;
1975   if (__i != end()) {
1976     const_iterator __e = end();
1977     do {
1978       ++__j;
1979     } while (__j != __e && key_eq()(*__j, __k));
1980   }
1981   return pair<const_iterator, const_iterator>(__i, __j);
1982 }
1983 
1984 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1985 void __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
1986 #if _LIBCPP_STD_VER <= 11
1987     _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal> &&
1988                (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
1989                 __is_nothrow_swappable_v<__pointer_allocator>) &&
1990                (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>))
1991 #else
1992     _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>)
1993 #endif
1994 {
1995   _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
1996       __node_traits::propagate_on_container_swap::value || this->__node_alloc() == __u.__node_alloc(),
1997       "unordered container::swap: Either propagate_on_container_swap "
1998       "must be true or the allocators must compare equal");
1999   {
2000     __node_pointer_pointer __npp = __bucket_list_.release();
2001     __bucket_list_.reset(__u.__bucket_list_.release());
2002     __u.__bucket_list_.reset(__npp);
2003   }
2004   std::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
2005   std::__swap_allocator(__bucket_list_.get_deleter().__alloc(), __u.__bucket_list_.get_deleter().__alloc());
2006   std::__swap_allocator(__node_alloc(), __u.__node_alloc());
2007   std::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
2008   __p2_.swap(__u.__p2_);
2009   __p3_.swap(__u.__p3_);
2010   if (size() > 0)
2011     __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr();
2012   if (__u.size() > 0)
2013     __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
2014         __u.__p1_.first().__ptr();
2015 }
2016 
2017 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2018 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2019 __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const {
2020   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
2021       __n < bucket_count(), "unordered container::bucket_size(n) called with n >= bucket_count()");
2022   __next_pointer __np = __bucket_list_[__n];
2023   size_type __bc      = bucket_count();
2024   size_type __r       = 0;
2025   if (__np != nullptr) {
2026     for (__np = __np->__next_; __np != nullptr && std::__constrain_hash(__np->__hash(), __bc) == __n;
2027          __np = __np->__next_, (void)++__r)
2028       ;
2029   }
2030   return __r;
2031 }
2032 
2033 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2034 inline _LIBCPP_HIDE_FROM_ABI void
2035 swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)
2036     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
2037   __x.swap(__y);
2038 }
2039 
2040 _LIBCPP_END_NAMESPACE_STD
2041 
2042 _LIBCPP_POP_MACROS
2043 
2044 #endif // _LIBCPP___CXX03___HASH_TABLE