Back to home page

EIC code displayed by LXR

 
 

    


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