13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
10cc82a1b0SLouis Dionne#ifndef _LIBCPP___HASH_TABLE
11cc82a1b0SLouis Dionne#define _LIBCPP___HASH_TABLE
123e519524SHoward Hinnant
132e2f3158SNikolas Klauser#include <__algorithm/max.h>
142e2f3158SNikolas Klauser#include <__algorithm/min.h>
15f87aa19bSLouis Dionne#include <__assert>
16bfbd73f8SArthur O'Dwyer#include <__bits> // __libcpp_clz
173e519524SHoward Hinnant#include <__config>
18bfbd73f8SArthur O'Dwyer#include <__debug>
192e2f3158SNikolas Klauser#include <__functional/hash.h>
203cd4531bSNikolas Klauser#include <__iterator/iterator_traits.h>
21*f4fb72e6SNikolas Klauser#include <__memory/swap_allocator.h>
2252915d78SNikolas Klauser#include <__utility/swap.h>
233e519524SHoward Hinnant#include <cmath>
24bfbd73f8SArthur O'Dwyer#include <initializer_list>
25bfbd73f8SArthur O'Dwyer#include <memory>
2604333f9bSEric Fiselier#include <type_traits>
2752915d78SNikolas Klauser
28073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
293e519524SHoward Hinnant#  pragma GCC system_header
30073458b1SHoward Hinnant#endif
313e519524SHoward Hinnant
32a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS
33a016efb1SEric Fiselier#include <__undef_macros>
343e519524SHoward Hinnant
35fcd02211SEric Fiselier
36a016efb1SEric Fiselier_LIBCPP_BEGIN_NAMESPACE_STD
37a016efb1SEric Fiselier
38fcd02211SEric Fiseliertemplate <class _Key, class _Tp>
39fcd02211SEric Fiselierstruct __hash_value_type;
40fcd02211SEric Fiselier
41fcd02211SEric Fiseliertemplate <class _Tp>
42fcd02211SEric Fiselierstruct __is_hash_value_type_imp : false_type {};
43fcd02211SEric Fiselier
44fcd02211SEric Fiseliertemplate <class _Key, class _Value>
45fcd02211SEric Fiselierstruct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {};
46fcd02211SEric Fiselier
47fcd02211SEric Fiseliertemplate <class ..._Args>
48fcd02211SEric Fiselierstruct __is_hash_value_type : false_type {};
49fcd02211SEric Fiselier
50fcd02211SEric Fiseliertemplate <class _One>
51f7558068SNikolas Klauserstruct __is_hash_value_type<_One> : __is_hash_value_type_imp<__uncvref_t<_One> > {};
52fcd02211SEric Fiselier
536e41256fSHoward Hinnant_LIBCPP_FUNC_VIS
54ce53420eSHoward Hinnantsize_t __next_prime(size_t __n);
553e519524SHoward Hinnant
563e519524SHoward Hinnanttemplate <class _NodePtr>
573e519524SHoward Hinnantstruct __hash_node_base
583e519524SHoward Hinnant{
5940492ba4SEric Fiselier    typedef typename pointer_traits<_NodePtr>::element_type __node_type;
603e519524SHoward Hinnant    typedef __hash_node_base __first_node;
6140492ba4SEric Fiselier    typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer;
6240492ba4SEric Fiselier    typedef _NodePtr __node_pointer;
633e519524SHoward Hinnant
6440492ba4SEric Fiselier#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
6540492ba4SEric Fiselier  typedef __node_base_pointer __next_pointer;
6640492ba4SEric Fiselier#else
6740492ba4SEric Fiselier  typedef typename conditional<
6840492ba4SEric Fiselier      is_pointer<__node_pointer>::value,
6940492ba4SEric Fiselier      __node_base_pointer,
7040492ba4SEric Fiselier      __node_pointer>::type   __next_pointer;
7140492ba4SEric Fiselier#endif
7240492ba4SEric Fiselier
7340492ba4SEric Fiselier    __next_pointer    __next_;
7440492ba4SEric Fiselier
7540492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
7640492ba4SEric Fiselier    __next_pointer __ptr() _NOEXCEPT {
7740492ba4SEric Fiselier        return static_cast<__next_pointer>(
7840492ba4SEric Fiselier            pointer_traits<__node_base_pointer>::pointer_to(*this));
7940492ba4SEric Fiselier    }
8040492ba4SEric Fiselier
8140492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
8240492ba4SEric Fiselier    __node_pointer __upcast() _NOEXCEPT {
8340492ba4SEric Fiselier        return static_cast<__node_pointer>(
8440492ba4SEric Fiselier            pointer_traits<__node_base_pointer>::pointer_to(*this));
8540492ba4SEric Fiselier    }
8640492ba4SEric Fiselier
8740492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
8840492ba4SEric Fiselier    size_t __hash() const _NOEXCEPT {
8940492ba4SEric Fiselier        return static_cast<__node_type const&>(*this).__hash_;
9040492ba4SEric Fiselier    }
913e519524SHoward Hinnant
923714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
933e519524SHoward Hinnant};
943e519524SHoward Hinnant
953e519524SHoward Hinnanttemplate <class _Tp, class _VoidPtr>
967c2f5827SAmy Huangstruct _LIBCPP_STANDALONE_DEBUG __hash_node
973e519524SHoward Hinnant    : public __hash_node_base
983e519524SHoward Hinnant             <
99934b0921SEric Fiselier                 typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type
1003e519524SHoward Hinnant             >
1013e519524SHoward Hinnant{
10275d0dcfdSEric Fiselier    typedef _Tp __node_value_type;
1033e519524SHoward Hinnant
1043e519524SHoward Hinnant    size_t            __hash_;
10575d0dcfdSEric Fiselier    __node_value_type __value_;
1063e519524SHoward Hinnant};
1073e519524SHoward Hinnant
1084cb38a82SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1094cb38a82SHoward Hinnantbool
1109ba5c11bSEric Fiselier__is_hash_power2(size_t __bc)
1114cb38a82SHoward Hinnant{
1124cb38a82SHoward Hinnant    return __bc > 2 && !(__bc & (__bc - 1));
1134cb38a82SHoward Hinnant}
1144cb38a82SHoward Hinnant
1154cb38a82SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1164cb38a82SHoward Hinnantsize_t
1174cb38a82SHoward Hinnant__constrain_hash(size_t __h, size_t __bc)
1184cb38a82SHoward Hinnant{
119118cb418SEric Fiselier    return !(__bc & (__bc - 1)) ? __h & (__bc - 1) :
120118cb418SEric Fiselier        (__h < __bc ? __h : __h % __bc);
1214cb38a82SHoward Hinnant}
1224cb38a82SHoward Hinnant
1234cb38a82SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1244cb38a82SHoward Hinnantsize_t
1259ba5c11bSEric Fiselier__next_hash_pow2(size_t __n)
1264cb38a82SHoward Hinnant{
127d586f92cSArthur O'Dwyer    return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1)));
1284cb38a82SHoward Hinnant}
1294cb38a82SHoward Hinnant
130fde79b40SDuncan P. N. Exon Smith
131ce53420eSHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
13275d0dcfdSEric Fiselier
133e2f2d1edSEric Fiseliertemplate <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_iterator;
134e2f2d1edSEric Fiseliertemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
135e2f2d1edSEric Fiseliertemplate <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_local_iterator;
136e2f2d1edSEric Fiseliertemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
137e2f2d1edSEric Fiseliertemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
138e2f2d1edSEric Fiseliertemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
1393e519524SHoward Hinnant
14075d0dcfdSEric Fiseliertemplate <class _Tp>
14143b121dfSEric Fiselierstruct __hash_key_value_types {
14275d0dcfdSEric Fiselier  static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
14375d0dcfdSEric Fiselier  typedef _Tp key_type;
14475d0dcfdSEric Fiselier  typedef _Tp __node_value_type;
14575d0dcfdSEric Fiselier  typedef _Tp __container_value_type;
14675d0dcfdSEric Fiselier  static const bool __is_map = false;
147fcd02211SEric Fiselier
148fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
149fcd02211SEric Fiselier  static key_type const& __get_key(_Tp const& __v) {
150fcd02211SEric Fiselier    return __v;
151fcd02211SEric Fiselier  }
152fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
153fcd02211SEric Fiselier  static __container_value_type const& __get_value(__node_value_type const& __v) {
154fcd02211SEric Fiselier    return __v;
155fcd02211SEric Fiselier  }
156fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
157fcd02211SEric Fiselier  static __container_value_type* __get_ptr(__node_value_type& __n) {
158fcd02211SEric Fiselier    return _VSTD::addressof(__n);
159fcd02211SEric Fiselier  }
160fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
161fcd02211SEric Fiselier  static __container_value_type&& __move(__node_value_type& __v) {
162fcd02211SEric Fiselier    return _VSTD::move(__v);
163fcd02211SEric Fiselier  }
16475d0dcfdSEric Fiselier};
16575d0dcfdSEric Fiselier
16675d0dcfdSEric Fiseliertemplate <class _Key, class _Tp>
16743b121dfSEric Fiselierstruct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
16875d0dcfdSEric Fiselier  typedef _Key                                         key_type;
16975d0dcfdSEric Fiselier  typedef _Tp                                          mapped_type;
17075d0dcfdSEric Fiselier  typedef __hash_value_type<_Key, _Tp>                 __node_value_type;
17175d0dcfdSEric Fiselier  typedef pair<const _Key, _Tp>                        __container_value_type;
17275d0dcfdSEric Fiselier  typedef __container_value_type                       __map_value_type;
17375d0dcfdSEric Fiselier  static const bool __is_map = true;
174fcd02211SEric Fiselier
175fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
176fcd02211SEric Fiselier  static key_type const& __get_key(__container_value_type const& __v) {
177fcd02211SEric Fiselier    return __v.first;
178fcd02211SEric Fiselier  }
179fcd02211SEric Fiselier
180fcd02211SEric Fiselier  template <class _Up>
181fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
1824887d047SNikolas Klauser  static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&>
183fcd02211SEric Fiselier  __get_value(_Up& __t) {
184f52318b4SErik Pilkington    return __t.__get_value();
185fcd02211SEric Fiselier  }
186fcd02211SEric Fiselier
187fcd02211SEric Fiselier  template <class _Up>
188fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
1894887d047SNikolas Klauser  static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&>
190fcd02211SEric Fiselier  __get_value(_Up& __t) {
191fcd02211SEric Fiselier    return __t;
192fcd02211SEric Fiselier  }
193fcd02211SEric Fiselier
194fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
195fcd02211SEric Fiselier  static __container_value_type* __get_ptr(__node_value_type& __n) {
196f52318b4SErik Pilkington    return _VSTD::addressof(__n.__get_value());
197fcd02211SEric Fiselier  }
198fcd02211SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
199f52318b4SErik Pilkington  static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
200f52318b4SErik Pilkington    return __v.__move();
201fcd02211SEric Fiselier  }
20275d0dcfdSEric Fiselier};
20375d0dcfdSEric Fiselier
20443b121dfSEric Fiseliertemplate <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>,
20575d0dcfdSEric Fiselier          bool = _KVTypes::__is_map>
20643b121dfSEric Fiselierstruct __hash_map_pointer_types {};
20775d0dcfdSEric Fiselier
20875d0dcfdSEric Fiseliertemplate <class _Tp, class _AllocPtr, class _KVTypes>
20943b121dfSEric Fiselierstruct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
21075d0dcfdSEric Fiselier  typedef typename _KVTypes::__map_value_type   _Mv;
21175d0dcfdSEric Fiselier  typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
21275d0dcfdSEric Fiselier                                                       __map_value_type_pointer;
21375d0dcfdSEric Fiselier  typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
21475d0dcfdSEric Fiselier                                                 __const_map_value_type_pointer;
21575d0dcfdSEric Fiselier};
21675d0dcfdSEric Fiselier
21775d0dcfdSEric Fiseliertemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
21875d0dcfdSEric Fiselierstruct __hash_node_types;
21975d0dcfdSEric Fiselier
22075d0dcfdSEric Fiseliertemplate <class _NodePtr, class _Tp, class _VoidPtr>
22175d0dcfdSEric Fiselierstruct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> >
22243b121dfSEric Fiselier    : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr>
22375d0dcfdSEric Fiselier
22475d0dcfdSEric Fiselier{
22543b121dfSEric Fiselier  typedef __hash_key_value_types<_Tp>           __base;
22675d0dcfdSEric Fiselier
22775d0dcfdSEric Fiselierpublic:
22875d0dcfdSEric Fiselier  typedef ptrdiff_t difference_type;
22975d0dcfdSEric Fiselier  typedef size_t size_type;
23075d0dcfdSEric Fiselier
23175d0dcfdSEric Fiselier  typedef typename __rebind_pointer<_NodePtr, void>::type       __void_pointer;
23275d0dcfdSEric Fiselier
23375d0dcfdSEric Fiselier  typedef typename pointer_traits<_NodePtr>::element_type       __node_type;
23475d0dcfdSEric Fiselier  typedef _NodePtr                                              __node_pointer;
23575d0dcfdSEric Fiselier
23675d0dcfdSEric Fiselier  typedef __hash_node_base<__node_pointer>                      __node_base_type;
23775d0dcfdSEric Fiselier  typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type
23875d0dcfdSEric Fiselier                                                             __node_base_pointer;
23975d0dcfdSEric Fiselier
24040492ba4SEric Fiselier  typedef typename __node_base_type::__next_pointer          __next_pointer;
24140492ba4SEric Fiselier
24275d0dcfdSEric Fiselier  typedef _Tp                                                 __node_value_type;
24375d0dcfdSEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
24475d0dcfdSEric Fiselier                                                      __node_value_type_pointer;
24575d0dcfdSEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
24675d0dcfdSEric Fiselier                                                __const_node_value_type_pointer;
24740492ba4SEric Fiselier
24875d0dcfdSEric Fiselierprivate:
24975d0dcfdSEric Fiselier    static_assert(!is_const<__node_type>::value,
25075d0dcfdSEric Fiselier                "_NodePtr should never be a pointer to const");
25175d0dcfdSEric Fiselier    static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
25275d0dcfdSEric Fiselier                  "_VoidPtr does not point to unqualified void type");
25375d0dcfdSEric Fiselier    static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
25475d0dcfdSEric Fiselier                          _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
25575d0dcfdSEric Fiselier};
25675d0dcfdSEric Fiselier
25775d0dcfdSEric Fiseliertemplate <class _HashIterator>
25875d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator;
25975d0dcfdSEric Fiseliertemplate <class _NodePtr>
26075d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
26175d0dcfdSEric Fiseliertemplate <class _NodePtr>
26275d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
26375d0dcfdSEric Fiseliertemplate <class _NodePtr>
26475d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
26575d0dcfdSEric Fiseliertemplate <class _NodePtr>
26675d0dcfdSEric Fiselierstruct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
26775d0dcfdSEric Fiselier
26875d0dcfdSEric Fiselier
26975d0dcfdSEric Fiseliertemplate <class _NodeValueTp, class _VoidPtr>
27075d0dcfdSEric Fiselierstruct __make_hash_node_types {
27175d0dcfdSEric Fiselier  typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp;
27275d0dcfdSEric Fiselier  typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr;
27375d0dcfdSEric Fiselier  typedef __hash_node_types<_NodePtr> type;
27475d0dcfdSEric Fiselier};
27575d0dcfdSEric Fiselier
2763e519524SHoward Hinnanttemplate <class _NodePtr>
277e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_iterator
2783e519524SHoward Hinnant{
27975d0dcfdSEric Fiselier    typedef __hash_node_types<_NodePtr> _NodeTypes;
2803e519524SHoward Hinnant    typedef _NodePtr                            __node_pointer;
28140492ba4SEric Fiselier    typedef typename _NodeTypes::__next_pointer __next_pointer;
2823e519524SHoward Hinnant
28340492ba4SEric Fiselier    __next_pointer            __node_;
2843e519524SHoward Hinnant
2853e519524SHoward Hinnantpublic:
2863e519524SHoward Hinnant    typedef forward_iterator_tag                           iterator_category;
28775d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_value_type         value_type;
28875d0dcfdSEric Fiselier    typedef typename _NodeTypes::difference_type           difference_type;
2893e519524SHoward Hinnant    typedef value_type&                                    reference;
29075d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_value_type_pointer pointer;
2913e519524SHoward Hinnant
29240492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) {
293caf5548cSNikolas Klauser        _VSTD::__debug_db_insert_i(this);
294b24c8024SHoward Hinnant    }
295b24c8024SHoward Hinnant
296f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
29743d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
298b24c8024SHoward Hinnant    __hash_iterator(const __hash_iterator& __i)
299b24c8024SHoward Hinnant        : __node_(__i.__node_)
300b24c8024SHoward Hinnant    {
301968e2739SMark de Wever        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
302b24c8024SHoward Hinnant    }
303b24c8024SHoward Hinnant
30443d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
305b24c8024SHoward Hinnant    ~__hash_iterator()
306b24c8024SHoward Hinnant    {
307b24c8024SHoward Hinnant        __get_db()->__erase_i(this);
308b24c8024SHoward Hinnant    }
309b24c8024SHoward Hinnant
310b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
311b24c8024SHoward Hinnant    __hash_iterator& operator=(const __hash_iterator& __i)
312b24c8024SHoward Hinnant    {
313d6e2c95dSMark de Wever        if (this != _VSTD::addressof(__i))
314b24c8024SHoward Hinnant        {
315d6e2c95dSMark de Wever            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
316b24c8024SHoward Hinnant            __node_ = __i.__node_;
317b24c8024SHoward Hinnant        }
318b24c8024SHoward Hinnant        return *this;
319b24c8024SHoward Hinnant    }
320f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE
321b24c8024SHoward Hinnant
322b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
32340492ba4SEric Fiselier    reference operator*() const {
32440492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
325b24c8024SHoward Hinnant                             "Attempted to dereference a non-dereferenceable unordered container iterator");
32640492ba4SEric Fiselier        return __node_->__upcast()->__value_;
327b24c8024SHoward Hinnant    }
3283e519524SHoward Hinnant
32943d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
33040492ba4SEric Fiselier    pointer operator->() const {
33140492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
33240492ba4SEric Fiselier                           "Attempted to dereference a non-dereferenceable unordered container iterator");
33340492ba4SEric Fiselier        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
33440492ba4SEric Fiselier    }
33540492ba4SEric Fiselier
33640492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
33740492ba4SEric Fiselier    __hash_iterator& operator++() {
33840492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
33996100f15SKristina Bessonova                       "Attempted to increment a non-incrementable unordered container iterator");
3403e519524SHoward Hinnant        __node_ = __node_->__next_;
3413e519524SHoward Hinnant        return *this;
3423e519524SHoward Hinnant    }
3433e519524SHoward Hinnant
34443d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
3453e519524SHoward Hinnant    __hash_iterator operator++(int)
3463e519524SHoward Hinnant    {
3473e519524SHoward Hinnant        __hash_iterator __t(*this);
3483e519524SHoward Hinnant        ++(*this);
3493e519524SHoward Hinnant        return __t;
3503e519524SHoward Hinnant    }
3513e519524SHoward Hinnant
35243d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
35343d99238SHoward Hinnant    bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)
354b24c8024SHoward Hinnant    {
355b24c8024SHoward Hinnant        return __x.__node_ == __y.__node_;
356b24c8024SHoward Hinnant    }
35743d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
35843d99238SHoward Hinnant    bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)
359b24c8024SHoward Hinnant        {return !(__x == __y);}
3603e519524SHoward Hinnant
3613e519524SHoward Hinnantprivate:
362b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
363f86c2b6fSArthur O'Dwyer    explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
364b24c8024SHoward Hinnant        : __node_(__node)
365b24c8024SHoward Hinnant        {
3664eab04f8SLouis Dionne            (void)__c;
367f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
368b24c8024SHoward Hinnant            __get_db()->__insert_ic(this, __c);
369b24c8024SHoward Hinnant#endif
3704eab04f8SLouis Dionne        }
3713e519524SHoward Hinnant    template <class, class, class, class> friend class __hash_table;
372e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
373e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
374e2f2d1edSEric Fiselier    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
375e2f2d1edSEric Fiselier    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
3763e519524SHoward Hinnant};
3773e519524SHoward Hinnant
37875d0dcfdSEric Fiseliertemplate <class _NodePtr>
379e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_const_iterator
3803e519524SHoward Hinnant{
38175d0dcfdSEric Fiselier    static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, "");
38275d0dcfdSEric Fiselier    typedef __hash_node_types<_NodePtr> _NodeTypes;
38375d0dcfdSEric Fiselier    typedef _NodePtr                            __node_pointer;
38440492ba4SEric Fiselier    typedef typename _NodeTypes::__next_pointer __next_pointer;
385757373e6SEric Fiselier
38640492ba4SEric Fiselier    __next_pointer __node_;
3873e519524SHoward Hinnant
3883e519524SHoward Hinnantpublic:
389757373e6SEric Fiselier    typedef __hash_iterator<_NodePtr> __non_const_iterator;
390757373e6SEric Fiselier
3913e519524SHoward Hinnant    typedef forward_iterator_tag                                 iterator_category;
39275d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_value_type               value_type;
39375d0dcfdSEric Fiselier    typedef typename _NodeTypes::difference_type                 difference_type;
3943e519524SHoward Hinnant    typedef const value_type&                                    reference;
39575d0dcfdSEric Fiselier    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
39675d0dcfdSEric Fiselier
3973e519524SHoward Hinnant
39840492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {
399caf5548cSNikolas Klauser        _VSTD::__debug_db_insert_i(this);
400b24c8024SHoward Hinnant    }
40140492ba4SEric Fiselier
40243d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
4033714107eSHoward Hinnant    __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
4043e519524SHoward Hinnant        : __node_(__x.__node_)
405b24c8024SHoward Hinnant    {
406f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
407d6e2c95dSMark de Wever        __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
408870827f6SLouis Dionne#endif
409b24c8024SHoward Hinnant    }
410b24c8024SHoward Hinnant
411f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
41243d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
413b24c8024SHoward Hinnant    __hash_const_iterator(const __hash_const_iterator& __i)
414b24c8024SHoward Hinnant        : __node_(__i.__node_)
415b24c8024SHoward Hinnant    {
416d6e2c95dSMark de Wever        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
417b24c8024SHoward Hinnant    }
418b24c8024SHoward Hinnant
41943d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
420b24c8024SHoward Hinnant    ~__hash_const_iterator()
421b24c8024SHoward Hinnant    {
422b24c8024SHoward Hinnant        __get_db()->__erase_i(this);
423b24c8024SHoward Hinnant    }
424b24c8024SHoward Hinnant
425b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
426b24c8024SHoward Hinnant    __hash_const_iterator& operator=(const __hash_const_iterator& __i)
427b24c8024SHoward Hinnant    {
428d6e2c95dSMark de Wever        if (this != _VSTD::addressof(__i))
429b24c8024SHoward Hinnant        {
430d6e2c95dSMark de Wever            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
431b24c8024SHoward Hinnant            __node_ = __i.__node_;
432b24c8024SHoward Hinnant        }
433b24c8024SHoward Hinnant        return *this;
434b24c8024SHoward Hinnant    }
435f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE
436b24c8024SHoward Hinnant
437b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
43840492ba4SEric Fiselier    reference operator*() const {
43940492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
440b24c8024SHoward Hinnant                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
44140492ba4SEric Fiselier        return __node_->__upcast()->__value_;
442b24c8024SHoward Hinnant    }
443b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
44440492ba4SEric Fiselier    pointer operator->() const {
44540492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
446b24c8024SHoward Hinnant                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
44740492ba4SEric Fiselier        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
448b24c8024SHoward Hinnant    }
4493e519524SHoward Hinnant
45043d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
45140492ba4SEric Fiselier    __hash_const_iterator& operator++() {
45240492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
45396100f15SKristina Bessonova                             "Attempted to increment a non-incrementable unordered container const_iterator");
4543e519524SHoward Hinnant        __node_ = __node_->__next_;
4553e519524SHoward Hinnant        return *this;
4563e519524SHoward Hinnant    }
4573e519524SHoward Hinnant
45843d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
4593e519524SHoward Hinnant    __hash_const_iterator operator++(int)
4603e519524SHoward Hinnant    {
4613e519524SHoward Hinnant        __hash_const_iterator __t(*this);
4623e519524SHoward Hinnant        ++(*this);
4633e519524SHoward Hinnant        return __t;
4643e519524SHoward Hinnant    }
4653e519524SHoward Hinnant
46643d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
46743d99238SHoward Hinnant    bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
468b24c8024SHoward Hinnant    {
469b24c8024SHoward Hinnant        return __x.__node_ == __y.__node_;
470b24c8024SHoward Hinnant    }
47143d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
47243d99238SHoward Hinnant    bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
473b24c8024SHoward Hinnant        {return !(__x == __y);}
4743e519524SHoward Hinnant
4753e519524SHoward Hinnantprivate:
476b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
477f86c2b6fSArthur O'Dwyer    explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
478b24c8024SHoward Hinnant        : __node_(__node)
479b24c8024SHoward Hinnant        {
4804eab04f8SLouis Dionne            (void)__c;
481f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
482b24c8024SHoward Hinnant            __get_db()->__insert_ic(this, __c);
483b24c8024SHoward Hinnant#endif
4844eab04f8SLouis Dionne        }
4853e519524SHoward Hinnant    template <class, class, class, class> friend class __hash_table;
486e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
487e2f2d1edSEric Fiselier    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
488e2f2d1edSEric Fiselier    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
4893e519524SHoward Hinnant};
4903e519524SHoward Hinnant
4913e519524SHoward Hinnanttemplate <class _NodePtr>
492e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_local_iterator
4933e519524SHoward Hinnant{
49475d0dcfdSEric Fiselier    typedef __hash_node_types<_NodePtr> _NodeTypes;
4953e519524SHoward Hinnant    typedef _NodePtr                            __node_pointer;
49640492ba4SEric Fiselier    typedef typename _NodeTypes::__next_pointer __next_pointer;
4973e519524SHoward Hinnant
49840492ba4SEric Fiselier    __next_pointer         __node_;
4993e519524SHoward Hinnant    size_t                 __bucket_;
5003e519524SHoward Hinnant    size_t                 __bucket_count_;
5013e519524SHoward Hinnant
5023e519524SHoward Hinnantpublic:
5033e519524SHoward Hinnant    typedef forward_iterator_tag                                iterator_category;
50475d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_value_type              value_type;
50575d0dcfdSEric Fiselier    typedef typename _NodeTypes::difference_type                difference_type;
5063e519524SHoward Hinnant    typedef value_type&                                         reference;
50775d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_value_type_pointer      pointer;
5083e519524SHoward Hinnant
50940492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {
510caf5548cSNikolas Klauser        _VSTD::__debug_db_insert_i(this);
511b24c8024SHoward Hinnant    }
512b24c8024SHoward Hinnant
513f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
51443d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
515b24c8024SHoward Hinnant    __hash_local_iterator(const __hash_local_iterator& __i)
516b24c8024SHoward Hinnant        : __node_(__i.__node_),
517b24c8024SHoward Hinnant          __bucket_(__i.__bucket_),
518b24c8024SHoward Hinnant          __bucket_count_(__i.__bucket_count_)
519b24c8024SHoward Hinnant    {
520d6e2c95dSMark de Wever        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
521b24c8024SHoward Hinnant    }
522b24c8024SHoward Hinnant
52343d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
524b24c8024SHoward Hinnant    ~__hash_local_iterator()
525b24c8024SHoward Hinnant    {
526b24c8024SHoward Hinnant        __get_db()->__erase_i(this);
527b24c8024SHoward Hinnant    }
528b24c8024SHoward Hinnant
529b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
530b24c8024SHoward Hinnant    __hash_local_iterator& operator=(const __hash_local_iterator& __i)
531b24c8024SHoward Hinnant    {
532d6e2c95dSMark de Wever        if (this != _VSTD::addressof(__i))
533b24c8024SHoward Hinnant        {
534d6e2c95dSMark de Wever            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
535b24c8024SHoward Hinnant            __node_ = __i.__node_;
536b24c8024SHoward Hinnant            __bucket_ = __i.__bucket_;
537b24c8024SHoward Hinnant            __bucket_count_ = __i.__bucket_count_;
538b24c8024SHoward Hinnant        }
539b24c8024SHoward Hinnant        return *this;
540b24c8024SHoward Hinnant    }
541f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE
542b24c8024SHoward Hinnant
543b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
54440492ba4SEric Fiselier    reference operator*() const {
54540492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
546b24c8024SHoward Hinnant                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
54740492ba4SEric Fiselier        return __node_->__upcast()->__value_;
548b24c8024SHoward Hinnant    }
5493e519524SHoward Hinnant
55043d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
55140492ba4SEric Fiselier    pointer operator->() const {
55240492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
55340492ba4SEric Fiselier                             "Attempted to dereference a non-dereferenceable unordered container local_iterator");
55440492ba4SEric Fiselier        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
55540492ba4SEric Fiselier    }
55640492ba4SEric Fiselier
55740492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
55840492ba4SEric Fiselier    __hash_local_iterator& operator++() {
55940492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
56096100f15SKristina Bessonova                       "Attempted to increment a non-incrementable unordered container local_iterator");
5613e519524SHoward Hinnant        __node_ = __node_->__next_;
56240492ba4SEric Fiselier        if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
5633e519524SHoward Hinnant            __node_ = nullptr;
5643e519524SHoward Hinnant        return *this;
5653e519524SHoward Hinnant    }
5663e519524SHoward Hinnant
56743d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5683e519524SHoward Hinnant    __hash_local_iterator operator++(int)
5693e519524SHoward Hinnant    {
5703e519524SHoward Hinnant        __hash_local_iterator __t(*this);
5713e519524SHoward Hinnant        ++(*this);
5723e519524SHoward Hinnant        return __t;
5733e519524SHoward Hinnant    }
5743e519524SHoward Hinnant
57543d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
57643d99238SHoward Hinnant    bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
577b24c8024SHoward Hinnant    {
578b24c8024SHoward Hinnant        return __x.__node_ == __y.__node_;
579b24c8024SHoward Hinnant    }
58043d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
58143d99238SHoward Hinnant    bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
582b24c8024SHoward Hinnant        {return !(__x == __y);}
5833e519524SHoward Hinnant
5843e519524SHoward Hinnantprivate:
585b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
586f86c2b6fSArthur O'Dwyer    explicit __hash_local_iterator(__next_pointer __node, size_t __bucket,
587b24c8024SHoward Hinnant                                   size_t __bucket_count, const void* __c) _NOEXCEPT
588b24c8024SHoward Hinnant        : __node_(__node),
589b24c8024SHoward Hinnant          __bucket_(__bucket),
590b24c8024SHoward Hinnant          __bucket_count_(__bucket_count)
591b24c8024SHoward Hinnant        {
5924eab04f8SLouis Dionne            (void)__c;
593f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
594b24c8024SHoward Hinnant            __get_db()->__insert_ic(this, __c);
595b24c8024SHoward Hinnant#endif
5964eab04f8SLouis Dionne            if (__node_ != nullptr)
5974eab04f8SLouis Dionne                __node_ = __node_->__next_;
5984eab04f8SLouis Dionne        }
5993e519524SHoward Hinnant    template <class, class, class, class> friend class __hash_table;
600e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
601e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
6023e519524SHoward Hinnant};
6033e519524SHoward Hinnant
6043e519524SHoward Hinnanttemplate <class _ConstNodePtr>
605e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator
6063e519524SHoward Hinnant{
60775d0dcfdSEric Fiselier    typedef __hash_node_types<_ConstNodePtr> _NodeTypes;
6083e519524SHoward Hinnant    typedef _ConstNodePtr                       __node_pointer;
60940492ba4SEric Fiselier    typedef typename _NodeTypes::__next_pointer __next_pointer;
6103e519524SHoward Hinnant
61140492ba4SEric Fiselier    __next_pointer         __node_;
6123e519524SHoward Hinnant    size_t                 __bucket_;
6133e519524SHoward Hinnant    size_t                 __bucket_count_;
6143e519524SHoward Hinnant
6153e519524SHoward Hinnant    typedef pointer_traits<__node_pointer>          __pointer_traits;
6163e519524SHoward Hinnant    typedef typename __pointer_traits::element_type __node;
6173e519524SHoward Hinnant    typedef typename remove_const<__node>::type     __non_const_node;
618934b0921SEric Fiselier    typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type
6193e519524SHoward Hinnant        __non_const_node_pointer;
620757373e6SEric Fiselierpublic:
6213e519524SHoward Hinnant    typedef __hash_local_iterator<__non_const_node_pointer>
6223e519524SHoward Hinnant                                                    __non_const_iterator;
623757373e6SEric Fiselier
6243e519524SHoward Hinnant    typedef forward_iterator_tag                                 iterator_category;
62575d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_value_type               value_type;
62675d0dcfdSEric Fiselier    typedef typename _NodeTypes::difference_type                 difference_type;
6273e519524SHoward Hinnant    typedef const value_type&                                    reference;
62875d0dcfdSEric Fiselier    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
6293e519524SHoward Hinnant
630934b0921SEric Fiselier
63140492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {
632caf5548cSNikolas Klauser        _VSTD::__debug_db_insert_i(this);
633b24c8024SHoward Hinnant    }
634b24c8024SHoward Hinnant
63543d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
6363714107eSHoward Hinnant    __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
6373e519524SHoward Hinnant        : __node_(__x.__node_),
6383e519524SHoward Hinnant          __bucket_(__x.__bucket_),
6393e519524SHoward Hinnant          __bucket_count_(__x.__bucket_count_)
640b24c8024SHoward Hinnant    {
641f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
642d6e2c95dSMark de Wever        __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
643870827f6SLouis Dionne#endif
644b24c8024SHoward Hinnant    }
645b24c8024SHoward Hinnant
646f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
64743d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
648b24c8024SHoward Hinnant    __hash_const_local_iterator(const __hash_const_local_iterator& __i)
649b24c8024SHoward Hinnant        : __node_(__i.__node_),
650b24c8024SHoward Hinnant          __bucket_(__i.__bucket_),
651b24c8024SHoward Hinnant          __bucket_count_(__i.__bucket_count_)
652b24c8024SHoward Hinnant    {
653d6e2c95dSMark de Wever        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
654b24c8024SHoward Hinnant    }
655b24c8024SHoward Hinnant
65643d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
657b24c8024SHoward Hinnant    ~__hash_const_local_iterator()
658b24c8024SHoward Hinnant    {
659b24c8024SHoward Hinnant        __get_db()->__erase_i(this);
660b24c8024SHoward Hinnant    }
661b24c8024SHoward Hinnant
662b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
663b24c8024SHoward Hinnant    __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)
664b24c8024SHoward Hinnant    {
665d6e2c95dSMark de Wever        if (this != _VSTD::addressof(__i))
666b24c8024SHoward Hinnant        {
667d6e2c95dSMark de Wever            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
668b24c8024SHoward Hinnant            __node_ = __i.__node_;
669b24c8024SHoward Hinnant            __bucket_ = __i.__bucket_;
670b24c8024SHoward Hinnant            __bucket_count_ = __i.__bucket_count_;
671b24c8024SHoward Hinnant        }
672b24c8024SHoward Hinnant        return *this;
673b24c8024SHoward Hinnant    }
674f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE
675b24c8024SHoward Hinnant
676b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
67740492ba4SEric Fiselier    reference operator*() const {
67840492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
679b24c8024SHoward Hinnant                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
68040492ba4SEric Fiselier        return __node_->__upcast()->__value_;
681b24c8024SHoward Hinnant    }
6823e519524SHoward Hinnant
68343d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
68440492ba4SEric Fiselier    pointer operator->() const {
68540492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
68640492ba4SEric Fiselier                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
68740492ba4SEric Fiselier        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
68840492ba4SEric Fiselier    }
68940492ba4SEric Fiselier
69040492ba4SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
69140492ba4SEric Fiselier    __hash_const_local_iterator& operator++() {
69240492ba4SEric Fiselier        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
69396100f15SKristina Bessonova                       "Attempted to increment a non-incrementable unordered container const_local_iterator");
6943e519524SHoward Hinnant        __node_ = __node_->__next_;
69540492ba4SEric Fiselier        if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
6963e519524SHoward Hinnant            __node_ = nullptr;
6973e519524SHoward Hinnant        return *this;
6983e519524SHoward Hinnant    }
6993e519524SHoward Hinnant
70043d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7013e519524SHoward Hinnant    __hash_const_local_iterator operator++(int)
7023e519524SHoward Hinnant    {
7033e519524SHoward Hinnant        __hash_const_local_iterator __t(*this);
7043e519524SHoward Hinnant        ++(*this);
7053e519524SHoward Hinnant        return __t;
7063e519524SHoward Hinnant    }
7073e519524SHoward Hinnant
70843d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
70943d99238SHoward Hinnant    bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
710b24c8024SHoward Hinnant    {
711b24c8024SHoward Hinnant        return __x.__node_ == __y.__node_;
712b24c8024SHoward Hinnant    }
71343d99238SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
71443d99238SHoward Hinnant    bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
715b24c8024SHoward Hinnant        {return !(__x == __y);}
7163e519524SHoward Hinnant
7173e519524SHoward Hinnantprivate:
718b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
719f86c2b6fSArthur O'Dwyer    explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
720b24c8024SHoward Hinnant                                         size_t __bucket_count, const void* __c) _NOEXCEPT
7212e4755ffSLouis Dionne        : __node_(__node_ptr),
722b24c8024SHoward Hinnant          __bucket_(__bucket),
723b24c8024SHoward Hinnant          __bucket_count_(__bucket_count)
724b24c8024SHoward Hinnant        {
7254eab04f8SLouis Dionne            (void)__c;
726f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
727b24c8024SHoward Hinnant            __get_db()->__insert_ic(this, __c);
728b24c8024SHoward Hinnant#endif
7294eab04f8SLouis Dionne            if (__node_ != nullptr)
7304eab04f8SLouis Dionne                __node_ = __node_->__next_;
7314eab04f8SLouis Dionne        }
7323e519524SHoward Hinnant    template <class, class, class, class> friend class __hash_table;
733e2f2d1edSEric Fiselier    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
7343e519524SHoward Hinnant};
7353e519524SHoward Hinnant
7363e519524SHoward Hinnanttemplate <class _Alloc>
7373e519524SHoward Hinnantclass __bucket_list_deallocator
7383e519524SHoward Hinnant{
7393e519524SHoward Hinnant    typedef _Alloc                                          allocator_type;
7403e519524SHoward Hinnant    typedef allocator_traits<allocator_type>                __alloc_traits;
7413e519524SHoward Hinnant    typedef typename __alloc_traits::size_type              size_type;
7423e519524SHoward Hinnant
7433e519524SHoward Hinnant    __compressed_pair<size_type, allocator_type> __data_;
7443e519524SHoward Hinnantpublic:
7453e519524SHoward Hinnant    typedef typename __alloc_traits::pointer pointer;
7463e519524SHoward Hinnant
74743d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7483e519524SHoward Hinnant    __bucket_list_deallocator()
7493714107eSHoward Hinnant        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
750549545b6SEric Fiselier        : __data_(0, __default_init_tag()) {}
75143d99238SHoward Hinnant
75243d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7533e519524SHoward Hinnant    __bucket_list_deallocator(const allocator_type& __a, size_type __size)
7543714107eSHoward Hinnant        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
7553e519524SHoward Hinnant        : __data_(__size, __a) {}
7563e519524SHoward Hinnant
75743d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7583e519524SHoward Hinnant    __bucket_list_deallocator(__bucket_list_deallocator&& __x)
7593714107eSHoward Hinnant        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
760ce48a113SHoward Hinnant        : __data_(_VSTD::move(__x.__data_))
7613e519524SHoward Hinnant    {
7623e519524SHoward Hinnant        __x.size() = 0;
7633e519524SHoward Hinnant    }
7643e519524SHoward Hinnant
7653714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7663714107eSHoward Hinnant    size_type& size() _NOEXCEPT {return __data_.first();}
7673714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7683714107eSHoward Hinnant    size_type  size() const _NOEXCEPT {return __data_.first();}
7693e519524SHoward Hinnant
77043d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7713714107eSHoward Hinnant    allocator_type& __alloc() _NOEXCEPT {return __data_.second();}
7723714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7733714107eSHoward Hinnant    const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();}
7743714107eSHoward Hinnant
7753714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7763714107eSHoward Hinnant    void operator()(pointer __p) _NOEXCEPT
7773e519524SHoward Hinnant    {
7783e519524SHoward Hinnant        __alloc_traits::deallocate(__alloc(), __p, size());
7793e519524SHoward Hinnant    }
7803e519524SHoward Hinnant};
7813e519524SHoward Hinnant
782ce53420eSHoward Hinnanttemplate <class _Alloc> class __hash_map_node_destructor;
7833e519524SHoward Hinnant
7843e519524SHoward Hinnanttemplate <class _Alloc>
7853e519524SHoward Hinnantclass __hash_node_destructor
7863e519524SHoward Hinnant{
7873e519524SHoward Hinnant    typedef _Alloc                                          allocator_type;
7883e519524SHoward Hinnant    typedef allocator_traits<allocator_type>                __alloc_traits;
78975d0dcfdSEric Fiselier
7903e519524SHoward Hinnantpublic:
7913e519524SHoward Hinnant    typedef typename __alloc_traits::pointer                pointer;
7923e519524SHoward Hinnantprivate:
793fcd02211SEric Fiselier    typedef __hash_node_types<pointer> _NodeTypes;
7943e519524SHoward Hinnant
7953e519524SHoward Hinnant    allocator_type& __na_;
7963e519524SHoward Hinnant
7973e519524SHoward Hinnantpublic:
7983e519524SHoward Hinnant    bool __value_constructed;
7993e519524SHoward Hinnant
800f97936faSEric Fiselier    __hash_node_destructor(__hash_node_destructor const&) = default;
801f97936faSEric Fiselier    __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
802f97936faSEric Fiselier
803f97936faSEric Fiselier
80443d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
805f622b58cSHoward Hinnant    explicit __hash_node_destructor(allocator_type& __na,
806f622b58cSHoward Hinnant                                    bool __constructed = false) _NOEXCEPT
8073e519524SHoward Hinnant        : __na_(__na),
808f622b58cSHoward Hinnant          __value_constructed(__constructed)
8093e519524SHoward Hinnant        {}
8103e519524SHoward Hinnant
81143d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8123714107eSHoward Hinnant    void operator()(pointer __p) _NOEXCEPT
8133e519524SHoward Hinnant    {
8143e519524SHoward Hinnant        if (__value_constructed)
815fcd02211SEric Fiselier            __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
8163e519524SHoward Hinnant        if (__p)
8173e519524SHoward Hinnant            __alloc_traits::deallocate(__na_, __p, 1);
8183e519524SHoward Hinnant    }
8193e519524SHoward Hinnant
8203e519524SHoward Hinnant    template <class> friend class __hash_map_node_destructor;
8213e519524SHoward Hinnant};
8223e519524SHoward Hinnant
823b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14
824b0386a51SErik Pilkingtontemplate <class _NodeType, class _Alloc>
825b0386a51SErik Pilkingtonstruct __generic_container_node_destructor;
826b0386a51SErik Pilkington
827b0386a51SErik Pilkingtontemplate <class _Tp, class _VoidPtr, class _Alloc>
828b0386a51SErik Pilkingtonstruct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
829b0386a51SErik Pilkington    : __hash_node_destructor<_Alloc>
830b0386a51SErik Pilkington{
831b0386a51SErik Pilkington    using __hash_node_destructor<_Alloc>::__hash_node_destructor;
832b0386a51SErik Pilkington};
833b0386a51SErik Pilkington#endif
83404333f9bSEric Fiselier
8353560fbf3SLouis Dionnetemplate <class _Key, class _Hash, class _Equal>
8363560fbf3SLouis Dionnestruct __enforce_unordered_container_requirements {
83704333f9bSEric Fiselier#ifndef _LIBCPP_CXX03_LANG
838bd6a2d85SEric Fiselier    static_assert(__check_hash_requirements<_Key, _Hash>::value,
839bd6a2d85SEric Fiselier    "the specified hash does not meet the Hash requirements");
840acb21581SEric Fiselier    static_assert(is_copy_constructible<_Equal>::value,
841acb21581SEric Fiselier    "the specified comparator is required to be copy constructible");
8423560fbf3SLouis Dionne#endif
8433560fbf3SLouis Dionne    typedef int type;
84404333f9bSEric Fiselier};
84504333f9bSEric Fiselier
8463560fbf3SLouis Dionnetemplate <class _Key, class _Hash, class _Equal>
8473560fbf3SLouis Dionne#ifndef _LIBCPP_CXX03_LANG
8483560fbf3SLouis Dionne    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
8497c142fccSLouis Dionne    "the specified comparator type does not provide a viable const call operator")
8503560fbf3SLouis Dionne    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
8517c142fccSLouis Dionne    "the specified hash functor does not provide a viable const call operator")
8523560fbf3SLouis Dionne#endif
8533560fbf3SLouis Dionnetypename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
8543560fbf3SLouis Dionne__diagnose_unordered_container_requirements(int);
8553560fbf3SLouis Dionne
8563560fbf3SLouis Dionne// This dummy overload is used so that the compiler won't emit a spurious
8573560fbf3SLouis Dionne// "no matching function for call to __diagnose_unordered_xxx" diagnostic
8583560fbf3SLouis Dionne// when the overload above causes a hard error.
8593560fbf3SLouis Dionnetemplate <class _Key, class _Hash, class _Equal>
8603560fbf3SLouis Dionneint __diagnose_unordered_container_requirements(void*);
86104333f9bSEric Fiselier
8623e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
8633e519524SHoward Hinnantclass __hash_table
8643e519524SHoward Hinnant{
8653e519524SHoward Hinnantpublic:
8663e519524SHoward Hinnant    typedef _Tp    value_type;
8673e519524SHoward Hinnant    typedef _Hash  hasher;
8683e519524SHoward Hinnant    typedef _Equal key_equal;
8693e519524SHoward Hinnant    typedef _Alloc allocator_type;
8703e519524SHoward Hinnant
8713e519524SHoward Hinnantprivate:
8723e519524SHoward Hinnant    typedef allocator_traits<allocator_type> __alloc_traits;
87375d0dcfdSEric Fiselier    typedef typename
87475d0dcfdSEric Fiselier      __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type
87575d0dcfdSEric Fiselier                                                                     _NodeTypes;
8763e519524SHoward Hinnantpublic:
877fcd02211SEric Fiselier
878fcd02211SEric Fiselier    typedef typename _NodeTypes::__node_value_type           __node_value_type;
879fcd02211SEric Fiselier    typedef typename _NodeTypes::__container_value_type      __container_value_type;
880fde79b40SDuncan P. N. Exon Smith    typedef typename _NodeTypes::key_type                    key_type;
8813e519524SHoward Hinnant    typedef value_type&                              reference;
8823e519524SHoward Hinnant    typedef const value_type&                        const_reference;
8833e519524SHoward Hinnant    typedef typename __alloc_traits::pointer         pointer;
8843e519524SHoward Hinnant    typedef typename __alloc_traits::const_pointer   const_pointer;
88575d0dcfdSEric Fiselier#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
8863e519524SHoward Hinnant    typedef typename __alloc_traits::size_type       size_type;
88775d0dcfdSEric Fiselier#else
88875d0dcfdSEric Fiselier    typedef typename _NodeTypes::size_type           size_type;
88975d0dcfdSEric Fiselier#endif
89075d0dcfdSEric Fiselier    typedef typename _NodeTypes::difference_type     difference_type;
8913e519524SHoward Hinnantpublic:
8923e519524SHoward Hinnant    // Create __node
89375d0dcfdSEric Fiselier
89475d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_type __node;
8951f508014SMarshall Clow    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
8963e519524SHoward Hinnant    typedef allocator_traits<__node_allocator>       __node_traits;
8978e39768cSEric Fiselier    typedef typename _NodeTypes::__void_pointer      __void_pointer;
89875d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_pointer      __node_pointer;
89975d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_pointer      __node_const_pointer;
90075d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_base_type    __first_node;
90175d0dcfdSEric Fiselier    typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
90240492ba4SEric Fiselier    typedef typename _NodeTypes::__next_pointer      __next_pointer;
90375d0dcfdSEric Fiselier
90475d0dcfdSEric Fiselierprivate:
90575d0dcfdSEric Fiselier    // check for sane allocator pointer rebinding semantics. Rebinding the
90675d0dcfdSEric Fiselier    // allocator for a new pointer type should be exactly the same as rebinding
90775d0dcfdSEric Fiselier    // the pointer using 'pointer_traits'.
90875d0dcfdSEric Fiselier    static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
90975d0dcfdSEric Fiselier                  "Allocator does not rebind pointers in a sane manner.");
91075d0dcfdSEric Fiselier    typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type
91175d0dcfdSEric Fiselier        __node_base_allocator;
91275d0dcfdSEric Fiselier    typedef allocator_traits<__node_base_allocator> __node_base_traits;
91375d0dcfdSEric Fiselier    static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
91475d0dcfdSEric Fiselier                 "Allocator does not rebind pointers in a sane manner.");
9153e519524SHoward Hinnant
9163e519524SHoward Hinnantprivate:
9173e519524SHoward Hinnant
91840492ba4SEric Fiselier    typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator;
9193e519524SHoward Hinnant    typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
92040492ba4SEric Fiselier    typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
9213e519524SHoward Hinnant    typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
9223e519524SHoward Hinnant    typedef typename __bucket_list_deleter::pointer       __node_pointer_pointer;
9233e519524SHoward Hinnant
9243e519524SHoward Hinnant    // --- Member data begin ---
9253e519524SHoward Hinnant    __bucket_list                                         __bucket_list_;
9263e519524SHoward Hinnant    __compressed_pair<__first_node, __node_allocator>     __p1_;
9273e519524SHoward Hinnant    __compressed_pair<size_type, hasher>                  __p2_;
9283e519524SHoward Hinnant    __compressed_pair<float, key_equal>                   __p3_;
9293e519524SHoward Hinnant    // --- Member data end ---
9303e519524SHoward Hinnant
9313714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9323714107eSHoward Hinnant    size_type& size() _NOEXCEPT {return __p2_.first();}
9333e519524SHoward Hinnantpublic:
9343714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9353714107eSHoward Hinnant    size_type  size() const _NOEXCEPT {return __p2_.first();}
9363e519524SHoward Hinnant
9373714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9383714107eSHoward Hinnant    hasher& hash_function() _NOEXCEPT {return __p2_.second();}
9393714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9403714107eSHoward Hinnant    const hasher& hash_function() const _NOEXCEPT {return __p2_.second();}
9413e519524SHoward Hinnant
9423714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9433714107eSHoward Hinnant    float& max_load_factor() _NOEXCEPT {return __p3_.first();}
9443714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9453714107eSHoward Hinnant    float  max_load_factor() const _NOEXCEPT {return __p3_.first();}
9463e519524SHoward Hinnant
9473714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9483714107eSHoward Hinnant    key_equal& key_eq() _NOEXCEPT {return __p3_.second();}
9493714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9503714107eSHoward Hinnant    const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();}
9513e519524SHoward Hinnant
9523714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9533714107eSHoward Hinnant    __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();}
9543714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
9553714107eSHoward Hinnant    const __node_allocator& __node_alloc() const _NOEXCEPT
9563714107eSHoward Hinnant        {return __p1_.second();}
9573e519524SHoward Hinnant
9583e519524SHoward Hinnantpublic:
9593e519524SHoward Hinnant    typedef __hash_iterator<__node_pointer>                   iterator;
960307f8143SHoward Hinnant    typedef __hash_const_iterator<__node_pointer>             const_iterator;
9613e519524SHoward Hinnant    typedef __hash_local_iterator<__node_pointer>             local_iterator;
962307f8143SHoward Hinnant    typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;
9633e519524SHoward Hinnant
964906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
9653714107eSHoward Hinnant    __hash_table()
9663714107eSHoward Hinnant        _NOEXCEPT_(
9673714107eSHoward Hinnant            is_nothrow_default_constructible<__bucket_list>::value &&
9683714107eSHoward Hinnant            is_nothrow_default_constructible<__first_node>::value &&
9693714107eSHoward Hinnant            is_nothrow_default_constructible<__node_allocator>::value &&
9703714107eSHoward Hinnant            is_nothrow_default_constructible<hasher>::value &&
9713714107eSHoward Hinnant            is_nothrow_default_constructible<key_equal>::value);
972906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
9733e519524SHoward Hinnant    __hash_table(const hasher& __hf, const key_equal& __eql);
9743e519524SHoward Hinnant    __hash_table(const hasher& __hf, const key_equal& __eql,
9753e519524SHoward Hinnant                 const allocator_type& __a);
9763e519524SHoward Hinnant    explicit __hash_table(const allocator_type& __a);
9773e519524SHoward Hinnant    __hash_table(const __hash_table& __u);
9783e519524SHoward Hinnant    __hash_table(const __hash_table& __u, const allocator_type& __a);
9793714107eSHoward Hinnant    __hash_table(__hash_table&& __u)
9803714107eSHoward Hinnant        _NOEXCEPT_(
9813714107eSHoward Hinnant            is_nothrow_move_constructible<__bucket_list>::value &&
9823714107eSHoward Hinnant            is_nothrow_move_constructible<__first_node>::value &&
9833714107eSHoward Hinnant            is_nothrow_move_constructible<__node_allocator>::value &&
9843714107eSHoward Hinnant            is_nothrow_move_constructible<hasher>::value &&
9853714107eSHoward Hinnant            is_nothrow_move_constructible<key_equal>::value);
9863e519524SHoward Hinnant    __hash_table(__hash_table&& __u, const allocator_type& __a);
9873e519524SHoward Hinnant    ~__hash_table();
9883e519524SHoward Hinnant
9893e519524SHoward Hinnant    __hash_table& operator=(const __hash_table& __u);
990906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
9913714107eSHoward Hinnant    __hash_table& operator=(__hash_table&& __u)
9923714107eSHoward Hinnant        _NOEXCEPT_(
9933714107eSHoward Hinnant            __node_traits::propagate_on_container_move_assignment::value &&
9943714107eSHoward Hinnant            is_nothrow_move_assignable<__node_allocator>::value &&
9953714107eSHoward Hinnant            is_nothrow_move_assignable<hasher>::value &&
9963714107eSHoward Hinnant            is_nothrow_move_assignable<key_equal>::value);
9973e519524SHoward Hinnant    template <class _InputIterator>
9983e519524SHoward Hinnant        void __assign_unique(_InputIterator __first, _InputIterator __last);
9993e519524SHoward Hinnant    template <class _InputIterator>
10003e519524SHoward Hinnant        void __assign_multi(_InputIterator __first, _InputIterator __last);
10013e519524SHoward Hinnant
100243d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
10033714107eSHoward Hinnant    size_type max_size() const _NOEXCEPT
10043e519524SHoward Hinnant    {
1005d586f92cSArthur O'Dwyer        return _VSTD::min<size_type>(
1006341c9dd9SEric Fiselier            __node_traits::max_size(__node_alloc()),
100755b31b4eSEric Fiselier            numeric_limits<difference_type >::max()
100855b31b4eSEric Fiselier        );
10093e519524SHoward Hinnant    }
10103e519524SHoward Hinnant
10115c4e07aeSErik Pilkingtonprivate:
10125c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
10135c4e07aeSErik Pilkington    __next_pointer __node_insert_multi_prepare(size_t __cp_hash,
10145c4e07aeSErik Pilkington                                               value_type& __cp_val);
10155c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
10165c4e07aeSErik Pilkington    void __node_insert_multi_perform(__node_pointer __cp,
10175c4e07aeSErik Pilkington                                     __next_pointer __pn) _NOEXCEPT;
10185c4e07aeSErik Pilkington
10195c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
10205c4e07aeSErik Pilkington    __next_pointer __node_insert_unique_prepare(size_t __nd_hash,
10215c4e07aeSErik Pilkington                                                value_type& __nd_val);
10225c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
10235c4e07aeSErik Pilkington    void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
10245c4e07aeSErik Pilkington
10255c4e07aeSErik Pilkingtonpublic:
10265c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
10273e519524SHoward Hinnant    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
10285c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
10293e519524SHoward Hinnant    iterator             __node_insert_multi(__node_pointer __nd);
10305c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
10313e519524SHoward Hinnant    iterator             __node_insert_multi(const_iterator __p,
10323e519524SHoward Hinnant                                             __node_pointer __nd);
10333e519524SHoward Hinnant
1034fcd02211SEric Fiselier    template <class _Key, class ..._Args>
1035fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
1036fcd02211SEric Fiselier    pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
1037fcd02211SEric Fiselier
10383e519524SHoward Hinnant    template <class... _Args>
1039fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
1040fde79b40SDuncan P. N. Exon Smith    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
1041fde79b40SDuncan P. N. Exon Smith
1042fde79b40SDuncan P. N. Exon Smith    template <class _Pp>
1043fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
1044fde79b40SDuncan P. N. Exon Smith    pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1045fde79b40SDuncan P. N. Exon Smith      return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1046fde79b40SDuncan P. N. Exon Smith                                          __can_extract_key<_Pp, key_type>());
1047fde79b40SDuncan P. N. Exon Smith    }
104850088684SEric Fiselier
104950088684SEric Fiselier    template <class _First, class _Second>
105050088684SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
10514887d047SNikolas Klauser    __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair<iterator, bool> >
10524887d047SNikolas Klauser    __emplace_unique(_First&& __f, _Second&& __s) {
105350088684SEric Fiselier        return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
105450088684SEric Fiselier                                              _VSTD::forward<_Second>(__s));
105550088684SEric Fiselier    }
105650088684SEric Fiselier
10573e519524SHoward Hinnant    template <class... _Args>
1058fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
1059fde79b40SDuncan P. N. Exon Smith    pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1060fde79b40SDuncan P. N. Exon Smith      return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1061fde79b40SDuncan P. N. Exon Smith    }
1062fde79b40SDuncan P. N. Exon Smith
1063fde79b40SDuncan P. N. Exon Smith    template <class _Pp>
1064fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
1065fde79b40SDuncan P. N. Exon Smith    pair<iterator, bool>
1066fde79b40SDuncan P. N. Exon Smith    __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1067fde79b40SDuncan P. N. Exon Smith      return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1068fde79b40SDuncan P. N. Exon Smith    }
1069fde79b40SDuncan P. N. Exon Smith    template <class _Pp>
1070fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
1071fde79b40SDuncan P. N. Exon Smith    pair<iterator, bool>
1072fde79b40SDuncan P. N. Exon Smith    __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1073fde79b40SDuncan P. N. Exon Smith      return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1074fde79b40SDuncan P. N. Exon Smith    }
1075fde79b40SDuncan P. N. Exon Smith    template <class _Pp>
1076fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
1077fde79b40SDuncan P. N. Exon Smith    pair<iterator, bool>
1078fde79b40SDuncan P. N. Exon Smith    __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1079fde79b40SDuncan P. N. Exon Smith      return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1080fde79b40SDuncan P. N. Exon Smith    }
1081fde79b40SDuncan P. N. Exon Smith
1082fde79b40SDuncan P. N. Exon Smith    template <class... _Args>
1083fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
10843e519524SHoward Hinnant    iterator __emplace_multi(_Args&&... __args);
10853e519524SHoward Hinnant    template <class... _Args>
1086fde79b40SDuncan P. N. Exon Smith    _LIBCPP_INLINE_VISIBILITY
10873e519524SHoward Hinnant    iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
10883e519524SHoward Hinnant
1089fcd02211SEric Fiselier
1090de3f2b39SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1091fcd02211SEric Fiselier    pair<iterator, bool>
1092fcd02211SEric Fiselier    __insert_unique(__container_value_type&& __x) {
1093fcd02211SEric Fiselier      return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x));
1094fcd02211SEric Fiselier    }
1095fcd02211SEric Fiselier
10964887d047SNikolas Klauser    template <class _Pp, class = __enable_if_t<!__is_same_uncvref<_Pp, __container_value_type>::value> >
1097de3f2b39SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1098fcd02211SEric Fiselier    pair<iterator, bool> __insert_unique(_Pp&& __x) {
1099fcd02211SEric Fiselier      return __emplace_unique(_VSTD::forward<_Pp>(__x));
1100fcd02211SEric Fiselier    }
1101fcd02211SEric Fiselier
1102fcd02211SEric Fiselier    template <class _Pp>
1103fcd02211SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1104fcd02211SEric Fiselier    iterator __insert_multi(_Pp&& __x) {
1105fcd02211SEric Fiselier      return __emplace_multi(_VSTD::forward<_Pp>(__x));
1106fcd02211SEric Fiselier    }
1107fcd02211SEric Fiselier
1108fcd02211SEric Fiselier    template <class _Pp>
1109fcd02211SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1110fcd02211SEric Fiselier    iterator __insert_multi(const_iterator __p, _Pp&& __x) {
1111fcd02211SEric Fiselier        return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x));
1112fcd02211SEric Fiselier    }
1113fcd02211SEric Fiselier
1114fcd02211SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
1115fcd02211SEric Fiselier    pair<iterator, bool> __insert_unique(const __container_value_type& __x) {
1116fcd02211SEric Fiselier        return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
1117fcd02211SEric Fiselier    }
11183e519524SHoward Hinnant
1119b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14
1120b0386a51SErik Pilkington    template <class _NodeHandle, class _InsertReturnType>
1121b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1122b0386a51SErik Pilkington    _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
1123b0386a51SErik Pilkington    template <class _NodeHandle>
1124b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1125b0386a51SErik Pilkington    iterator __node_handle_insert_unique(const_iterator __hint,
1126b0386a51SErik Pilkington                                         _NodeHandle&& __nh);
11275c4e07aeSErik Pilkington    template <class _Table>
11285c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
11295c4e07aeSErik Pilkington    void __node_handle_merge_unique(_Table& __source);
1130b0386a51SErik Pilkington
1131b0386a51SErik Pilkington    template <class _NodeHandle>
1132b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1133b0386a51SErik Pilkington    iterator __node_handle_insert_multi(_NodeHandle&& __nh);
1134b0386a51SErik Pilkington    template <class _NodeHandle>
1135b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1136b0386a51SErik Pilkington    iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
11375c4e07aeSErik Pilkington    template <class _Table>
11385c4e07aeSErik Pilkington    _LIBCPP_INLINE_VISIBILITY
11395c4e07aeSErik Pilkington    void __node_handle_merge_multi(_Table& __source);
1140b0386a51SErik Pilkington
1141b0386a51SErik Pilkington    template <class _NodeHandle>
1142b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1143b0386a51SErik Pilkington    _NodeHandle __node_handle_extract(key_type const& __key);
1144b0386a51SErik Pilkington    template <class _NodeHandle>
1145b0386a51SErik Pilkington    _LIBCPP_INLINE_VISIBILITY
1146b0386a51SErik Pilkington    _NodeHandle __node_handle_extract(const_iterator __it);
1147b0386a51SErik Pilkington#endif
1148b0386a51SErik Pilkington
11493714107eSHoward Hinnant    void clear() _NOEXCEPT;
11503085e42fSIvan Trofimov    _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); }
11513085e42fSIvan Trofimov    _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); }
11523085e42fSIvan Trofimov    _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n)
11533085e42fSIvan Trofimov    {
11543085e42fSIvan Trofimov        __rehash_unique(static_cast<size_type>(ceil(__n / max_load_factor())));
11553085e42fSIvan Trofimov    }
11563085e42fSIvan Trofimov    _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n)
11573085e42fSIvan Trofimov    {
11583085e42fSIvan Trofimov        __rehash_multi(static_cast<size_type>(ceil(__n / max_load_factor())));
11593085e42fSIvan Trofimov    }
116043d99238SHoward Hinnant
116143d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
11623714107eSHoward Hinnant    size_type bucket_count() const _NOEXCEPT
11633e519524SHoward Hinnant    {
11643e519524SHoward Hinnant        return __bucket_list_.get_deleter().size();
11653e519524SHoward Hinnant    }
11663e519524SHoward Hinnant
1167906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
11683714107eSHoward Hinnant    iterator       begin() _NOEXCEPT;
1169906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
11703714107eSHoward Hinnant    iterator       end() _NOEXCEPT;
1171906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
11723714107eSHoward Hinnant    const_iterator begin() const _NOEXCEPT;
1173906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
11743714107eSHoward Hinnant    const_iterator end() const _NOEXCEPT;
11753e519524SHoward Hinnant
11763e519524SHoward Hinnant    template <class _Key>
117743d99238SHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
11783e519524SHoward Hinnant        size_type bucket(const _Key& __k) const
1179e5c13decSHoward Hinnant        {
1180e5c13decSHoward Hinnant            _LIBCPP_ASSERT(bucket_count() > 0,
1181e5c13decSHoward Hinnant                "unordered container::bucket(key) called when bucket_count() == 0");
1182e5c13decSHoward Hinnant            return __constrain_hash(hash_function()(__k), bucket_count());
1183e5c13decSHoward Hinnant        }
11843e519524SHoward Hinnant
11853e519524SHoward Hinnant    template <class _Key>
11863e519524SHoward Hinnant        iterator       find(const _Key& __x);
11873e519524SHoward Hinnant    template <class _Key>
11883e519524SHoward Hinnant        const_iterator find(const _Key& __x) const;
11893e519524SHoward Hinnant
1190c003db1fSHoward Hinnant    typedef __hash_node_destructor<__node_allocator> _Dp;
1191c003db1fSHoward Hinnant    typedef unique_ptr<__node, _Dp> __node_holder;
11923e519524SHoward Hinnant
11933e519524SHoward Hinnant    iterator erase(const_iterator __p);
11943e519524SHoward Hinnant    iterator erase(const_iterator __first, const_iterator __last);
11953e519524SHoward Hinnant    template <class _Key>
11963e519524SHoward Hinnant        size_type __erase_unique(const _Key& __k);
11973e519524SHoward Hinnant    template <class _Key>
11983e519524SHoward Hinnant        size_type __erase_multi(const _Key& __k);
11993714107eSHoward Hinnant    __node_holder remove(const_iterator __p) _NOEXCEPT;
12003e519524SHoward Hinnant
12013e519524SHoward Hinnant    template <class _Key>
1202906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
12033e519524SHoward Hinnant        size_type __count_unique(const _Key& __k) const;
12043e519524SHoward Hinnant    template <class _Key>
12053e519524SHoward Hinnant        size_type __count_multi(const _Key& __k) const;
12063e519524SHoward Hinnant
12073e519524SHoward Hinnant    template <class _Key>
12083e519524SHoward Hinnant        pair<iterator, iterator>
12093e519524SHoward Hinnant        __equal_range_unique(const _Key& __k);
12103e519524SHoward Hinnant    template <class _Key>
12113e519524SHoward Hinnant        pair<const_iterator, const_iterator>
12123e519524SHoward Hinnant        __equal_range_unique(const _Key& __k) const;
12133e519524SHoward Hinnant
12143e519524SHoward Hinnant    template <class _Key>
12153e519524SHoward Hinnant        pair<iterator, iterator>
12163e519524SHoward Hinnant        __equal_range_multi(const _Key& __k);
12173e519524SHoward Hinnant    template <class _Key>
12183e519524SHoward Hinnant        pair<const_iterator, const_iterator>
12193e519524SHoward Hinnant        __equal_range_multi(const _Key& __k) const;
12203e519524SHoward Hinnant
12213714107eSHoward Hinnant    void swap(__hash_table& __u)
122287a82490SEric Fiselier#if _LIBCPP_STD_VER <= 11
122361b302f9SEric Fiselier        _NOEXCEPT_(
1224e3fbe143SMarshall Clow            __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
1225e3fbe143SMarshall Clow            && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
1226e3fbe143SMarshall Clow                  || __is_nothrow_swappable<__pointer_allocator>::value)
1227e3fbe143SMarshall Clow            && (!__node_traits::propagate_on_container_swap::value
1228e3fbe143SMarshall Clow                  || __is_nothrow_swappable<__node_allocator>::value)
1229e3fbe143SMarshall Clow            );
123087a82490SEric Fiselier#else
123161b302f9SEric Fiselier     _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
123287a82490SEric Fiselier#endif
12333e519524SHoward Hinnant
123443d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
12353714107eSHoward Hinnant    size_type max_bucket_count() const _NOEXCEPT
123655b31b4eSEric Fiselier        {return max_size(); }
12373e519524SHoward Hinnant    size_type bucket_size(size_type __n) const;
12383714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
12393e519524SHoward Hinnant    {
12403e519524SHoward Hinnant        size_type __bc = bucket_count();
12413e519524SHoward Hinnant        return __bc != 0 ? (float)size() / __bc : 0.f;
12423e519524SHoward Hinnant    }
12433714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
1244e5c13decSHoward Hinnant    {
1245e5c13decSHoward Hinnant        _LIBCPP_ASSERT(__mlf > 0,
1246e5c13decSHoward Hinnant            "unordered container::max_load_factor(lf) called with lf <= 0");
1247e5c13decSHoward Hinnant        max_load_factor() = _VSTD::max(__mlf, load_factor());
1248e5c13decSHoward Hinnant    }
12493e519524SHoward Hinnant
1250b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1251b24c8024SHoward Hinnant    local_iterator
1252b24c8024SHoward Hinnant    begin(size_type __n)
1253b24c8024SHoward Hinnant    {
1254e5c13decSHoward Hinnant        _LIBCPP_ASSERT(__n < bucket_count(),
1255e5c13decSHoward Hinnant            "unordered container::begin(n) called with n >= bucket_count()");
1256b24c8024SHoward Hinnant        return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
1257b24c8024SHoward Hinnant    }
1258b24c8024SHoward Hinnant
1259b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1260b24c8024SHoward Hinnant    local_iterator
1261b24c8024SHoward Hinnant    end(size_type __n)
1262b24c8024SHoward Hinnant    {
1263e5c13decSHoward Hinnant        _LIBCPP_ASSERT(__n < bucket_count(),
1264e5c13decSHoward Hinnant            "unordered container::end(n) called with n >= bucket_count()");
1265b24c8024SHoward Hinnant        return local_iterator(nullptr, __n, bucket_count(), this);
1266b24c8024SHoward Hinnant    }
1267b24c8024SHoward Hinnant
1268b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1269b24c8024SHoward Hinnant    const_local_iterator
1270b24c8024SHoward Hinnant    cbegin(size_type __n) const
1271b24c8024SHoward Hinnant    {
1272e5c13decSHoward Hinnant        _LIBCPP_ASSERT(__n < bucket_count(),
1273e5c13decSHoward Hinnant            "unordered container::cbegin(n) called with n >= bucket_count()");
1274b24c8024SHoward Hinnant        return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
1275b24c8024SHoward Hinnant    }
1276b24c8024SHoward Hinnant
1277b24c8024SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1278b24c8024SHoward Hinnant    const_local_iterator
1279b24c8024SHoward Hinnant    cend(size_type __n) const
1280b24c8024SHoward Hinnant    {
1281e5c13decSHoward Hinnant        _LIBCPP_ASSERT(__n < bucket_count(),
1282e5c13decSHoward Hinnant            "unordered container::cend(n) called with n >= bucket_count()");
1283b24c8024SHoward Hinnant        return const_local_iterator(nullptr, __n, bucket_count(), this);
1284b24c8024SHoward Hinnant    }
1285b24c8024SHoward Hinnant
1286f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1287b24c8024SHoward Hinnant
1288b24c8024SHoward Hinnant    bool __dereferenceable(const const_iterator* __i) const;
1289b24c8024SHoward Hinnant    bool __decrementable(const const_iterator* __i) const;
1290b24c8024SHoward Hinnant    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1291b24c8024SHoward Hinnant    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1292b24c8024SHoward Hinnant
1293f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE
1294b24c8024SHoward Hinnant
12953e519524SHoward Hinnantprivate:
12963085e42fSIvan Trofimov    template <bool _UniqueKeys> void __rehash(size_type __n);
12973085e42fSIvan Trofimov    template <bool _UniqueKeys> void __do_rehash(size_type __n);
12983e519524SHoward Hinnant
12993e519524SHoward Hinnant    template <class ..._Args>
13003e519524SHoward Hinnant    __node_holder __construct_node(_Args&& ...__args);
1301fcd02211SEric Fiselier
1302fcd02211SEric Fiselier    template <class _First, class ..._Rest>
1303fcd02211SEric Fiselier    __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
1304fcd02211SEric Fiselier
13053e519524SHoward Hinnant
130643d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
13073e519524SHoward Hinnant    void __copy_assign_alloc(const __hash_table& __u)
13083e519524SHoward Hinnant        {__copy_assign_alloc(__u, integral_constant<bool,
13093e519524SHoward Hinnant             __node_traits::propagate_on_container_copy_assignment::value>());}
13103e519524SHoward Hinnant    void __copy_assign_alloc(const __hash_table& __u, true_type);
131143d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1312c206366fSHoward Hinnant        void __copy_assign_alloc(const __hash_table&, false_type) {}
13133e519524SHoward Hinnant
13143e519524SHoward Hinnant    void __move_assign(__hash_table& __u, false_type);
13153714107eSHoward Hinnant    void __move_assign(__hash_table& __u, true_type)
13163714107eSHoward Hinnant        _NOEXCEPT_(
13173714107eSHoward Hinnant            is_nothrow_move_assignable<__node_allocator>::value &&
13183714107eSHoward Hinnant            is_nothrow_move_assignable<hasher>::value &&
13193714107eSHoward Hinnant            is_nothrow_move_assignable<key_equal>::value);
13203714107eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
13213714107eSHoward Hinnant    void __move_assign_alloc(__hash_table& __u)
13223714107eSHoward Hinnant        _NOEXCEPT_(
13233714107eSHoward Hinnant            !__node_traits::propagate_on_container_move_assignment::value ||
13243714107eSHoward Hinnant            (is_nothrow_move_assignable<__pointer_allocator>::value &&
13253714107eSHoward Hinnant             is_nothrow_move_assignable<__node_allocator>::value))
13263e519524SHoward Hinnant        {__move_assign_alloc(__u, integral_constant<bool,
13273e519524SHoward Hinnant             __node_traits::propagate_on_container_move_assignment::value>());}
132843d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
13293e519524SHoward Hinnant    void __move_assign_alloc(__hash_table& __u, true_type)
13303714107eSHoward Hinnant        _NOEXCEPT_(
13313714107eSHoward Hinnant            is_nothrow_move_assignable<__pointer_allocator>::value &&
13323714107eSHoward Hinnant            is_nothrow_move_assignable<__node_allocator>::value)
13333e519524SHoward Hinnant    {
13343e519524SHoward Hinnant        __bucket_list_.get_deleter().__alloc() =
1335ce48a113SHoward Hinnant                _VSTD::move(__u.__bucket_list_.get_deleter().__alloc());
1336ce48a113SHoward Hinnant        __node_alloc() = _VSTD::move(__u.__node_alloc());
13373e519524SHoward Hinnant    }
133843d99238SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
13393714107eSHoward Hinnant        void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
13403e519524SHoward Hinnant
1341cd71f447SEric Fiselier    void __deallocate_node(__next_pointer __np) _NOEXCEPT;
134240492ba4SEric Fiselier    __next_pointer __detach() _NOEXCEPT;
1343307f8143SHoward Hinnant
1344e2f2d1edSEric Fiselier    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
1345e2f2d1edSEric Fiselier    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
13463e519524SHoward Hinnant};
13473e519524SHoward Hinnant
13483e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1349906c872dSEvgeniy Stepanovinline
13503e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()
13513714107eSHoward Hinnant    _NOEXCEPT_(
13523714107eSHoward Hinnant        is_nothrow_default_constructible<__bucket_list>::value &&
13533714107eSHoward Hinnant        is_nothrow_default_constructible<__first_node>::value &&
1354e2e332a5SEric Fiselier        is_nothrow_default_constructible<__node_allocator>::value &&
13553714107eSHoward Hinnant        is_nothrow_default_constructible<hasher>::value &&
13563714107eSHoward Hinnant        is_nothrow_default_constructible<key_equal>::value)
1357549545b6SEric Fiselier    : __p2_(0, __default_init_tag()),
1358549545b6SEric Fiselier      __p3_(1.0f, __default_init_tag())
13593e519524SHoward Hinnant{
13603e519524SHoward Hinnant}
13613e519524SHoward Hinnant
13623e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1363906c872dSEvgeniy Stepanovinline
13643e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
13653e519524SHoward Hinnant                                                       const key_equal& __eql)
13663e519524SHoward Hinnant    : __bucket_list_(nullptr, __bucket_list_deleter()),
13673e519524SHoward Hinnant      __p1_(),
13683e519524SHoward Hinnant      __p2_(0, __hf),
13693e519524SHoward Hinnant      __p3_(1.0f, __eql)
13703e519524SHoward Hinnant{
13713e519524SHoward Hinnant}
13723e519524SHoward Hinnant
13733e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
13743e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
13753e519524SHoward Hinnant                                                       const key_equal& __eql,
13763e519524SHoward Hinnant                                                       const allocator_type& __a)
13773e519524SHoward Hinnant    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1378549545b6SEric Fiselier      __p1_(__default_init_tag(), __node_allocator(__a)),
13793e519524SHoward Hinnant      __p2_(0, __hf),
13803e519524SHoward Hinnant      __p3_(1.0f, __eql)
13813e519524SHoward Hinnant{
13823e519524SHoward Hinnant}
13833e519524SHoward Hinnant
13843e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
13853e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
13863e519524SHoward Hinnant    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1387549545b6SEric Fiselier      __p1_(__default_init_tag(), __node_allocator(__a)),
1388549545b6SEric Fiselier      __p2_(0, __default_init_tag()),
1389549545b6SEric Fiselier      __p3_(1.0f, __default_init_tag())
13903e519524SHoward Hinnant{
13913e519524SHoward Hinnant}
13923e519524SHoward Hinnant
13933e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
13943e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
13953e519524SHoward Hinnant    : __bucket_list_(nullptr,
13963e519524SHoward Hinnant          __bucket_list_deleter(allocator_traits<__pointer_allocator>::
13973e519524SHoward Hinnant              select_on_container_copy_construction(
13983e519524SHoward Hinnant                  __u.__bucket_list_.get_deleter().__alloc()), 0)),
1399549545b6SEric Fiselier      __p1_(__default_init_tag(), allocator_traits<__node_allocator>::
14003e519524SHoward Hinnant          select_on_container_copy_construction(__u.__node_alloc())),
14013e519524SHoward Hinnant      __p2_(0, __u.hash_function()),
14023e519524SHoward Hinnant      __p3_(__u.__p3_)
14033e519524SHoward Hinnant{
14043e519524SHoward Hinnant}
14053e519524SHoward Hinnant
14063e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
14073e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
14083e519524SHoward Hinnant                                                       const allocator_type& __a)
14093e519524SHoward Hinnant    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1410549545b6SEric Fiselier      __p1_(__default_init_tag(), __node_allocator(__a)),
14113e519524SHoward Hinnant      __p2_(0, __u.hash_function()),
14123e519524SHoward Hinnant      __p3_(__u.__p3_)
14133e519524SHoward Hinnant{
14143e519524SHoward Hinnant}
14153e519524SHoward Hinnant
14163e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
14173e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
14183714107eSHoward Hinnant        _NOEXCEPT_(
14193714107eSHoward Hinnant            is_nothrow_move_constructible<__bucket_list>::value &&
14203714107eSHoward Hinnant            is_nothrow_move_constructible<__first_node>::value &&
1421e2e332a5SEric Fiselier            is_nothrow_move_constructible<__node_allocator>::value &&
14223714107eSHoward Hinnant            is_nothrow_move_constructible<hasher>::value &&
14233714107eSHoward Hinnant            is_nothrow_move_constructible<key_equal>::value)
1424ce48a113SHoward Hinnant    : __bucket_list_(_VSTD::move(__u.__bucket_list_)),
1425ce48a113SHoward Hinnant      __p1_(_VSTD::move(__u.__p1_)),
1426ce48a113SHoward Hinnant      __p2_(_VSTD::move(__u.__p2_)),
1427ce48a113SHoward Hinnant      __p3_(_VSTD::move(__u.__p3_))
14283e519524SHoward Hinnant{
14293e519524SHoward Hinnant    if (size() > 0)
14303e519524SHoward Hinnant    {
143140492ba4SEric Fiselier        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
143240492ba4SEric Fiselier            __p1_.first().__ptr();
14333e519524SHoward Hinnant        __u.__p1_.first().__next_ = nullptr;
14343e519524SHoward Hinnant        __u.size() = 0;
14353e519524SHoward Hinnant    }
14363e519524SHoward Hinnant}
14373e519524SHoward Hinnant
14383e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
14393e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
14403e519524SHoward Hinnant                                                       const allocator_type& __a)
14413e519524SHoward Hinnant    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1442549545b6SEric Fiselier      __p1_(__default_init_tag(), __node_allocator(__a)),
1443ce48a113SHoward Hinnant      __p2_(0, _VSTD::move(__u.hash_function())),
1444ce48a113SHoward Hinnant      __p3_(_VSTD::move(__u.__p3_))
14453e519524SHoward Hinnant{
14463e519524SHoward Hinnant    if (__a == allocator_type(__u.__node_alloc()))
14473e519524SHoward Hinnant    {
14483e519524SHoward Hinnant        __bucket_list_.reset(__u.__bucket_list_.release());
14493e519524SHoward Hinnant        __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
14503e519524SHoward Hinnant        __u.__bucket_list_.get_deleter().size() = 0;
14513e519524SHoward Hinnant        if (__u.size() > 0)
14523e519524SHoward Hinnant        {
14533e519524SHoward Hinnant            __p1_.first().__next_ = __u.__p1_.first().__next_;
14543e519524SHoward Hinnant            __u.__p1_.first().__next_ = nullptr;
145540492ba4SEric Fiselier            __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
145640492ba4SEric Fiselier                __p1_.first().__ptr();
14573e519524SHoward Hinnant            size() = __u.size();
14583e519524SHoward Hinnant            __u.size() = 0;
14593e519524SHoward Hinnant        }
14603e519524SHoward Hinnant    }
14613e519524SHoward Hinnant}
14623e519524SHoward Hinnant
14633e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
14643e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
14653e519524SHoward Hinnant{
1466acb21581SEric Fiselier#if defined(_LIBCPP_CXX03_LANG)
14673b8669edSMarshall Clow    static_assert((is_copy_constructible<key_equal>::value),
14683b8669edSMarshall Clow                 "Predicate must be copy-constructible.");
14693b8669edSMarshall Clow    static_assert((is_copy_constructible<hasher>::value),
14703b8669edSMarshall Clow                 "Hasher must be copy-constructible.");
147104333f9bSEric Fiselier#endif
1472acb21581SEric Fiselier
1473cd71f447SEric Fiselier    __deallocate_node(__p1_.first().__next_);
147408f68dfeSNikolas Klauser    std::__debug_db_erase_c(this);
14753e519524SHoward Hinnant}
14763e519524SHoward Hinnant
14773e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
14783e519524SHoward Hinnantvoid
14793e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(
14803e519524SHoward Hinnant        const __hash_table& __u, true_type)
14813e519524SHoward Hinnant{
14823e519524SHoward Hinnant    if (__node_alloc() != __u.__node_alloc())
14833e519524SHoward Hinnant    {
14843e519524SHoward Hinnant        clear();
14853e519524SHoward Hinnant        __bucket_list_.reset();
14863e519524SHoward Hinnant        __bucket_list_.get_deleter().size() = 0;
14873e519524SHoward Hinnant    }
14883e519524SHoward Hinnant    __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();
14893e519524SHoward Hinnant    __node_alloc() = __u.__node_alloc();
14903e519524SHoward Hinnant}
14913e519524SHoward Hinnant
14923e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
14933e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>&
14943e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u)
14953e519524SHoward Hinnant{
1496b8608b87SMark de Wever    if (this != _VSTD::addressof(__u))
14973e519524SHoward Hinnant    {
14983e519524SHoward Hinnant        __copy_assign_alloc(__u);
14993e519524SHoward Hinnant        hash_function() = __u.hash_function();
15003e519524SHoward Hinnant        key_eq() = __u.key_eq();
15013e519524SHoward Hinnant        max_load_factor() = __u.max_load_factor();
15023e519524SHoward Hinnant        __assign_multi(__u.begin(), __u.end());
15033e519524SHoward Hinnant    }
15043e519524SHoward Hinnant    return *this;
15053e519524SHoward Hinnant}
15063e519524SHoward Hinnant
15073e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
15083e519524SHoward Hinnantvoid
1509cd71f447SEric Fiselier__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
15103714107eSHoward Hinnant    _NOEXCEPT
15113e519524SHoward Hinnant{
15123e519524SHoward Hinnant    __node_allocator& __na = __node_alloc();
15133e519524SHoward Hinnant    while (__np != nullptr)
15143e519524SHoward Hinnant    {
151540492ba4SEric Fiselier        __next_pointer __next = __np->__next_;
1516f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1517b24c8024SHoward Hinnant        __c_node* __c = __get_db()->__find_c_and_lock(this);
1518b24c8024SHoward Hinnant        for (__i_node** __p = __c->end_; __p != __c->beg_; )
1519b24c8024SHoward Hinnant        {
1520b24c8024SHoward Hinnant            --__p;
1521b24c8024SHoward Hinnant            iterator* __i = static_cast<iterator*>((*__p)->__i_);
1522b24c8024SHoward Hinnant            if (__i->__node_ == __np)
1523b24c8024SHoward Hinnant            {
1524b24c8024SHoward Hinnant                (*__p)->__c_ = nullptr;
1525b24c8024SHoward Hinnant                if (--__c->end_ != __p)
15263696227cSArthur O'Dwyer                    _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1527b24c8024SHoward Hinnant            }
1528b24c8024SHoward Hinnant        }
1529b24c8024SHoward Hinnant        __get_db()->unlock();
1530b24c8024SHoward Hinnant#endif
153140492ba4SEric Fiselier        __node_pointer __real_np = __np->__upcast();
153240492ba4SEric Fiselier        __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_));
153340492ba4SEric Fiselier        __node_traits::deallocate(__na, __real_np, 1);
15343e519524SHoward Hinnant        __np = __next;
15353e519524SHoward Hinnant    }
15363e519524SHoward Hinnant}
15373e519524SHoward Hinnant
15383e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
153940492ba4SEric Fiseliertypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
15403714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT
15413e519524SHoward Hinnant{
15423e519524SHoward Hinnant    size_type __bc = bucket_count();
15433e519524SHoward Hinnant    for (size_type __i = 0; __i < __bc; ++__i)
15443e519524SHoward Hinnant        __bucket_list_[__i] = nullptr;
15453e519524SHoward Hinnant    size() = 0;
154640492ba4SEric Fiselier    __next_pointer __cache = __p1_.first().__next_;
15473e519524SHoward Hinnant    __p1_.first().__next_ = nullptr;
15483e519524SHoward Hinnant    return __cache;
15493e519524SHoward Hinnant}
15503e519524SHoward Hinnant
15513e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
15523e519524SHoward Hinnantvoid
15533e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
15543e519524SHoward Hinnant        __hash_table& __u, true_type)
15553714107eSHoward Hinnant    _NOEXCEPT_(
15563714107eSHoward Hinnant        is_nothrow_move_assignable<__node_allocator>::value &&
15573714107eSHoward Hinnant        is_nothrow_move_assignable<hasher>::value &&
15583714107eSHoward Hinnant        is_nothrow_move_assignable<key_equal>::value)
15593e519524SHoward Hinnant{
15603e519524SHoward Hinnant    clear();
15613e519524SHoward Hinnant    __bucket_list_.reset(__u.__bucket_list_.release());
15623e519524SHoward Hinnant    __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
15633e519524SHoward Hinnant    __u.__bucket_list_.get_deleter().size() = 0;
15643e519524SHoward Hinnant    __move_assign_alloc(__u);
15653e519524SHoward Hinnant    size() = __u.size();
1566ce48a113SHoward Hinnant    hash_function() = _VSTD::move(__u.hash_function());
15673e519524SHoward Hinnant    max_load_factor() = __u.max_load_factor();
1568ce48a113SHoward Hinnant    key_eq() = _VSTD::move(__u.key_eq());
15693e519524SHoward Hinnant    __p1_.first().__next_ = __u.__p1_.first().__next_;
15703e519524SHoward Hinnant    if (size() > 0)
15713e519524SHoward Hinnant    {
157240492ba4SEric Fiselier        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
157340492ba4SEric Fiselier            __p1_.first().__ptr();
15743e519524SHoward Hinnant        __u.__p1_.first().__next_ = nullptr;
15753e519524SHoward Hinnant        __u.size() = 0;
15763e519524SHoward Hinnant    }
157708f68dfeSNikolas Klauser    std::__debug_db_swap(this, std::addressof(__u));
15783e519524SHoward Hinnant}
15793e519524SHoward Hinnant
15803e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
15813e519524SHoward Hinnantvoid
15823e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
15833e519524SHoward Hinnant        __hash_table& __u, false_type)
15843e519524SHoward Hinnant{
15853e519524SHoward Hinnant    if (__node_alloc() == __u.__node_alloc())
15863e519524SHoward Hinnant        __move_assign(__u, true_type());
15873e519524SHoward Hinnant    else
15883e519524SHoward Hinnant    {
1589ce48a113SHoward Hinnant        hash_function() = _VSTD::move(__u.hash_function());
1590ce48a113SHoward Hinnant        key_eq() = _VSTD::move(__u.key_eq());
15913e519524SHoward Hinnant        max_load_factor() = __u.max_load_factor();
15923e519524SHoward Hinnant        if (bucket_count() != 0)
15933e519524SHoward Hinnant        {
159440492ba4SEric Fiselier            __next_pointer __cache = __detach();
15953e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
15963e519524SHoward Hinnant            try
15973e519524SHoward Hinnant            {
1598b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
15993e519524SHoward Hinnant                const_iterator __i = __u.begin();
16003e519524SHoward Hinnant                while (__cache != nullptr && __u.size() != 0)
16013e519524SHoward Hinnant                {
160240492ba4SEric Fiselier                    __cache->__upcast()->__value_ =
160340492ba4SEric Fiselier                        _VSTD::move(__u.remove(__i++)->__value_);
160440492ba4SEric Fiselier                    __next_pointer __next = __cache->__next_;
160540492ba4SEric Fiselier                    __node_insert_multi(__cache->__upcast());
16063e519524SHoward Hinnant                    __cache = __next;
16073e519524SHoward Hinnant                }
16083e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
16093e519524SHoward Hinnant            }
16103e519524SHoward Hinnant            catch (...)
16113e519524SHoward Hinnant            {
1612cd71f447SEric Fiselier                __deallocate_node(__cache);
16133e519524SHoward Hinnant                throw;
16143e519524SHoward Hinnant            }
1615b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
1616cd71f447SEric Fiselier            __deallocate_node(__cache);
16173e519524SHoward Hinnant        }
16183e519524SHoward Hinnant        const_iterator __i = __u.begin();
16193e519524SHoward Hinnant        while (__u.size() != 0)
16203e519524SHoward Hinnant        {
1621fcd02211SEric Fiselier            __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_));
16223e519524SHoward Hinnant            __node_insert_multi(__h.get());
16233e519524SHoward Hinnant            __h.release();
16243e519524SHoward Hinnant        }
16253e519524SHoward Hinnant    }
16263e519524SHoward Hinnant}
16273e519524SHoward Hinnant
16283e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1629906c872dSEvgeniy Stepanovinline
16303e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>&
16313e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
16323714107eSHoward Hinnant    _NOEXCEPT_(
16333714107eSHoward Hinnant        __node_traits::propagate_on_container_move_assignment::value &&
16343714107eSHoward Hinnant        is_nothrow_move_assignable<__node_allocator>::value &&
16353714107eSHoward Hinnant        is_nothrow_move_assignable<hasher>::value &&
16363714107eSHoward Hinnant        is_nothrow_move_assignable<key_equal>::value)
16373e519524SHoward Hinnant{
16383e519524SHoward Hinnant    __move_assign(__u, integral_constant<bool,
16393e519524SHoward Hinnant                  __node_traits::propagate_on_container_move_assignment::value>());
16403e519524SHoward Hinnant    return *this;
16413e519524SHoward Hinnant}
16423e519524SHoward Hinnant
16433e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
16443e519524SHoward Hinnanttemplate <class _InputIterator>
16453e519524SHoward Hinnantvoid
16463e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,
16473e519524SHoward Hinnant                                                          _InputIterator __last)
16483e519524SHoward Hinnant{
1649fcd02211SEric Fiselier    typedef iterator_traits<_InputIterator> _ITraits;
1650fcd02211SEric Fiselier    typedef typename _ITraits::value_type _ItValueType;
1651fcd02211SEric Fiselier    static_assert((is_same<_ItValueType, __container_value_type>::value),
1652fcd02211SEric Fiselier                  "__assign_unique may only be called with the containers value type");
1653fcd02211SEric Fiselier
16543e519524SHoward Hinnant    if (bucket_count() != 0)
16553e519524SHoward Hinnant    {
165640492ba4SEric Fiselier        __next_pointer __cache = __detach();
16573e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
16583e519524SHoward Hinnant        try
16593e519524SHoward Hinnant        {
1660b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
16613e519524SHoward Hinnant            for (; __cache != nullptr && __first != __last; ++__first)
16623e519524SHoward Hinnant            {
166340492ba4SEric Fiselier                __cache->__upcast()->__value_ = *__first;
166440492ba4SEric Fiselier                __next_pointer __next = __cache->__next_;
166540492ba4SEric Fiselier                __node_insert_unique(__cache->__upcast());
16663e519524SHoward Hinnant                __cache = __next;
16673e519524SHoward Hinnant            }
16683e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
16693e519524SHoward Hinnant        }
16703e519524SHoward Hinnant        catch (...)
16713e519524SHoward Hinnant        {
1672cd71f447SEric Fiselier            __deallocate_node(__cache);
16733e519524SHoward Hinnant            throw;
16743e519524SHoward Hinnant        }
1675b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
1676cd71f447SEric Fiselier        __deallocate_node(__cache);
16773e519524SHoward Hinnant    }
16783e519524SHoward Hinnant    for (; __first != __last; ++__first)
16793e519524SHoward Hinnant        __insert_unique(*__first);
16803e519524SHoward Hinnant}
16813e519524SHoward Hinnant
16823e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
16833e519524SHoward Hinnanttemplate <class _InputIterator>
16843e519524SHoward Hinnantvoid
16853e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
16863e519524SHoward Hinnant                                                         _InputIterator __last)
16873e519524SHoward Hinnant{
1688fcd02211SEric Fiselier    typedef iterator_traits<_InputIterator> _ITraits;
1689fcd02211SEric Fiselier    typedef typename _ITraits::value_type _ItValueType;
1690fcd02211SEric Fiselier    static_assert((is_same<_ItValueType, __container_value_type>::value ||
1691fcd02211SEric Fiselier                  is_same<_ItValueType, __node_value_type>::value),
1692fcd02211SEric Fiselier                  "__assign_multi may only be called with the containers value type"
1693fcd02211SEric Fiselier                  " or the nodes value type");
16943e519524SHoward Hinnant    if (bucket_count() != 0)
16953e519524SHoward Hinnant    {
169640492ba4SEric Fiselier        __next_pointer __cache = __detach();
16973e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
16983e519524SHoward Hinnant        try
16993e519524SHoward Hinnant        {
1700b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
17013e519524SHoward Hinnant            for (; __cache != nullptr && __first != __last; ++__first)
17023e519524SHoward Hinnant            {
170340492ba4SEric Fiselier                __cache->__upcast()->__value_ = *__first;
170440492ba4SEric Fiselier                __next_pointer __next = __cache->__next_;
170540492ba4SEric Fiselier                __node_insert_multi(__cache->__upcast());
17063e519524SHoward Hinnant                __cache = __next;
17073e519524SHoward Hinnant            }
17083e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
17093e519524SHoward Hinnant        }
17103e519524SHoward Hinnant        catch (...)
17113e519524SHoward Hinnant        {
1712cd71f447SEric Fiselier            __deallocate_node(__cache);
17133e519524SHoward Hinnant            throw;
17143e519524SHoward Hinnant        }
1715b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
1716cd71f447SEric Fiselier        __deallocate_node(__cache);
17173e519524SHoward Hinnant    }
17183e519524SHoward Hinnant    for (; __first != __last; ++__first)
1719fcd02211SEric Fiselier        __insert_multi(_NodeTypes::__get_value(*__first));
17203e519524SHoward Hinnant}
17213e519524SHoward Hinnant
17223e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1723906c872dSEvgeniy Stepanovinline
17243e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
17253714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
17263e519524SHoward Hinnant{
1727b24c8024SHoward Hinnant    return iterator(__p1_.first().__next_, this);
17283e519524SHoward Hinnant}
17293e519524SHoward Hinnant
17303e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1731906c872dSEvgeniy Stepanovinline
17323e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
17333714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
17343e519524SHoward Hinnant{
1735b24c8024SHoward Hinnant    return iterator(nullptr, this);
17363e519524SHoward Hinnant}
17373e519524SHoward Hinnant
17383e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1739906c872dSEvgeniy Stepanovinline
17403e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
17413714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
17423e519524SHoward Hinnant{
1743b24c8024SHoward Hinnant    return const_iterator(__p1_.first().__next_, this);
17443e519524SHoward Hinnant}
17453e519524SHoward Hinnant
17463e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1747906c872dSEvgeniy Stepanovinline
17483e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
17493714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
17503e519524SHoward Hinnant{
1751b24c8024SHoward Hinnant    return const_iterator(nullptr, this);
17523e519524SHoward Hinnant}
17533e519524SHoward Hinnant
17543e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
17553e519524SHoward Hinnantvoid
17563714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
17573e519524SHoward Hinnant{
17583e519524SHoward Hinnant    if (size() > 0)
17593e519524SHoward Hinnant    {
1760cd71f447SEric Fiselier        __deallocate_node(__p1_.first().__next_);
17613e519524SHoward Hinnant        __p1_.first().__next_ = nullptr;
17623e519524SHoward Hinnant        size_type __bc = bucket_count();
17631f8da84bSHoward Hinnant        for (size_type __i = 0; __i < __bc; ++__i)
17643e519524SHoward Hinnant            __bucket_list_[__i] = nullptr;
17653e519524SHoward Hinnant        size() = 0;
17663e519524SHoward Hinnant    }
17673e519524SHoward Hinnant}
17683e519524SHoward Hinnant
17695c4e07aeSErik Pilkington
17705c4e07aeSErik Pilkington// Prepare the container for an insertion of the value __value with the hash
17715c4e07aeSErik Pilkington// __hash. This does a lookup into the container to see if __value is already
17725c4e07aeSErik Pilkington// present, and performs a rehash if necessary. Returns a pointer to the
17735c4e07aeSErik Pilkington// existing element if it exists, otherwise nullptr.
17745c4e07aeSErik Pilkington//
17755c4e07aeSErik Pilkington// Note that this function does forward exceptions if key_eq() throws, and never
17765c4e07aeSErik Pilkington// mutates __value or actually inserts into the map.
17773e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
17785c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY
17795c4e07aeSErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
17805c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
17815c4e07aeSErik Pilkington    size_t __hash, value_type& __value)
17823e519524SHoward Hinnant{
17833e519524SHoward Hinnant    size_type __bc = bucket_count();
17845c4e07aeSErik Pilkington
17853e519524SHoward Hinnant    if (__bc != 0)
17863e519524SHoward Hinnant    {
17875c4e07aeSErik Pilkington        size_t __chash = __constrain_hash(__hash, __bc);
17885c4e07aeSErik Pilkington        __next_pointer __ndptr = __bucket_list_[__chash];
17893e519524SHoward Hinnant        if (__ndptr != nullptr)
17903e519524SHoward Hinnant        {
17913e519524SHoward Hinnant            for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
179240492ba4SEric Fiselier                                             __constrain_hash(__ndptr->__hash(), __bc) == __chash;
17933e519524SHoward Hinnant                                                     __ndptr = __ndptr->__next_)
17943e519524SHoward Hinnant            {
17955c4e07aeSErik Pilkington                if (key_eq()(__ndptr->__upcast()->__value_, __value))
17965c4e07aeSErik Pilkington                    return __ndptr;
17973e519524SHoward Hinnant            }
17983e519524SHoward Hinnant        }
17993e519524SHoward Hinnant    }
18003e519524SHoward Hinnant    if (size()+1 > __bc * max_load_factor() || __bc == 0)
18013e519524SHoward Hinnant    {
18023085e42fSIvan Trofimov        __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
18033e519524SHoward Hinnant                                     size_type(ceil(float(size() + 1) / max_load_factor()))));
18043e519524SHoward Hinnant    }
18055c4e07aeSErik Pilkington    return nullptr;
18065c4e07aeSErik Pilkington}
18075c4e07aeSErik Pilkington
18085c4e07aeSErik Pilkington// Insert the node __nd into the container by pushing it into the right bucket,
18095c4e07aeSErik Pilkington// and updating size(). Assumes that __nd->__hash is up-to-date, and that
18105c4e07aeSErik Pilkington// rehashing has already occurred and that no element with the same key exists
18115c4e07aeSErik Pilkington// in the map.
18125c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
18135c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY
18145c4e07aeSErik Pilkingtonvoid
18155c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
18165c4e07aeSErik Pilkington    __node_pointer __nd) _NOEXCEPT
18175c4e07aeSErik Pilkington{
18185c4e07aeSErik Pilkington    size_type __bc = bucket_count();
18195c4e07aeSErik Pilkington    size_t __chash = __constrain_hash(__nd->__hash(), __bc);
18203e519524SHoward Hinnant    // insert_after __bucket_list_[__chash], or __first_node if bucket is null
182140492ba4SEric Fiselier    __next_pointer __pn = __bucket_list_[__chash];
18223e519524SHoward Hinnant    if (__pn == nullptr)
18233e519524SHoward Hinnant    {
182440492ba4SEric Fiselier        __pn =__p1_.first().__ptr();
18253e519524SHoward Hinnant        __nd->__next_ = __pn->__next_;
182640492ba4SEric Fiselier        __pn->__next_ = __nd->__ptr();
18273e519524SHoward Hinnant        // fix up __bucket_list_
18283e519524SHoward Hinnant        __bucket_list_[__chash] = __pn;
18293e519524SHoward Hinnant        if (__nd->__next_ != nullptr)
183040492ba4SEric Fiselier            __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
18313e519524SHoward Hinnant    }
18323e519524SHoward Hinnant    else
18333e519524SHoward Hinnant    {
18343e519524SHoward Hinnant        __nd->__next_ = __pn->__next_;
183540492ba4SEric Fiselier        __pn->__next_ = __nd->__ptr();
18363e519524SHoward Hinnant    }
18373e519524SHoward Hinnant    ++size();
18383e519524SHoward Hinnant}
18393e519524SHoward Hinnant
18403e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
18415c4e07aeSErik Pilkingtonpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
18425c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
18433e519524SHoward Hinnant{
18445c4e07aeSErik Pilkington    __nd->__hash_ = hash_function()(__nd->__value_);
18455c4e07aeSErik Pilkington    __next_pointer __existing_node =
18465c4e07aeSErik Pilkington        __node_insert_unique_prepare(__nd->__hash(), __nd->__value_);
18475c4e07aeSErik Pilkington
18485c4e07aeSErik Pilkington    // Insert the node, unless it already exists in the container.
18495c4e07aeSErik Pilkington    bool __inserted = false;
18505c4e07aeSErik Pilkington    if (__existing_node == nullptr)
18515c4e07aeSErik Pilkington    {
18525c4e07aeSErik Pilkington        __node_insert_unique_perform(__nd);
18535c4e07aeSErik Pilkington        __existing_node = __nd->__ptr();
18545c4e07aeSErik Pilkington        __inserted = true;
18555c4e07aeSErik Pilkington    }
18565c4e07aeSErik Pilkington    return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
18575c4e07aeSErik Pilkington}
18585c4e07aeSErik Pilkington
18595c4e07aeSErik Pilkington// Prepare the container for an insertion of the value __cp_val with the hash
18605c4e07aeSErik Pilkington// __cp_hash. This does a lookup into the container to see if __cp_value is
18615c4e07aeSErik Pilkington// already present, and performs a rehash if necessary. Returns a pointer to the
1862b6f19174SArthur O'Dwyer// last occurrence of __cp_val in the map.
18635c4e07aeSErik Pilkington//
18645c4e07aeSErik Pilkington// Note that this function does forward exceptions if key_eq() throws, and never
18655c4e07aeSErik Pilkington// mutates __value or actually inserts into the map.
18665c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
18675c4e07aeSErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
18685c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
18695c4e07aeSErik Pilkington    size_t __cp_hash, value_type& __cp_val)
18705c4e07aeSErik Pilkington{
18713e519524SHoward Hinnant    size_type __bc = bucket_count();
18723e519524SHoward Hinnant    if (size()+1 > __bc * max_load_factor() || __bc == 0)
18733e519524SHoward Hinnant    {
18743085e42fSIvan Trofimov        __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
18753e519524SHoward Hinnant                       size_type(ceil(float(size() + 1) / max_load_factor()))));
18763e519524SHoward Hinnant        __bc = bucket_count();
18773e519524SHoward Hinnant    }
18785c4e07aeSErik Pilkington    size_t __chash = __constrain_hash(__cp_hash, __bc);
187940492ba4SEric Fiselier    __next_pointer __pn = __bucket_list_[__chash];
18805c4e07aeSErik Pilkington    if (__pn != nullptr)
18815c4e07aeSErik Pilkington    {
18825c4e07aeSErik Pilkington        for (bool __found = false; __pn->__next_ != nullptr &&
18835c4e07aeSErik Pilkington                                   __constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
18845c4e07aeSErik Pilkington                                                           __pn = __pn->__next_)
18855c4e07aeSErik Pilkington        {
18865c4e07aeSErik Pilkington            //      __found    key_eq()     action
18875c4e07aeSErik Pilkington            //      false       false       loop
18885c4e07aeSErik Pilkington            //      true        true        loop
18895c4e07aeSErik Pilkington            //      false       true        set __found to true
18905c4e07aeSErik Pilkington            //      true        false       break
18915c4e07aeSErik Pilkington            if (__found != (__pn->__next_->__hash() == __cp_hash &&
18925c4e07aeSErik Pilkington                            key_eq()(__pn->__next_->__upcast()->__value_, __cp_val)))
18935c4e07aeSErik Pilkington            {
18945c4e07aeSErik Pilkington                if (!__found)
18955c4e07aeSErik Pilkington                    __found = true;
18965c4e07aeSErik Pilkington                else
18975c4e07aeSErik Pilkington                    break;
18985c4e07aeSErik Pilkington            }
18995c4e07aeSErik Pilkington        }
19005c4e07aeSErik Pilkington    }
19015c4e07aeSErik Pilkington    return __pn;
19025c4e07aeSErik Pilkington}
19035c4e07aeSErik Pilkington
19045c4e07aeSErik Pilkington// Insert the node __cp into the container after __pn (which is the last node in
19055c4e07aeSErik Pilkington// the bucket that compares equal to __cp). Rehashing, and checking for
19065c4e07aeSErik Pilkington// uniqueness has already been performed (in __node_insert_multi_prepare), so
19075c4e07aeSErik Pilkington// all we need to do is update the bucket and size(). Assumes that __cp->__hash
19085c4e07aeSErik Pilkington// is up-to-date.
19095c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
19105c4e07aeSErik Pilkingtonvoid
19115c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
19125c4e07aeSErik Pilkington    __node_pointer __cp, __next_pointer __pn) _NOEXCEPT
19135c4e07aeSErik Pilkington{
19145c4e07aeSErik Pilkington    size_type __bc = bucket_count();
19155c4e07aeSErik Pilkington    size_t __chash = __constrain_hash(__cp->__hash_, __bc);
19163e519524SHoward Hinnant    if (__pn == nullptr)
19173e519524SHoward Hinnant    {
191840492ba4SEric Fiselier        __pn =__p1_.first().__ptr();
19193e519524SHoward Hinnant        __cp->__next_ = __pn->__next_;
192040492ba4SEric Fiselier        __pn->__next_ = __cp->__ptr();
19213e519524SHoward Hinnant        // fix up __bucket_list_
19223e519524SHoward Hinnant        __bucket_list_[__chash] = __pn;
19233e519524SHoward Hinnant        if (__cp->__next_ != nullptr)
192440492ba4SEric Fiselier            __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)]
192540492ba4SEric Fiselier                = __cp->__ptr();
19263e519524SHoward Hinnant    }
19273e519524SHoward Hinnant    else
19283e519524SHoward Hinnant    {
19293e519524SHoward Hinnant        __cp->__next_ = __pn->__next_;
193040492ba4SEric Fiselier        __pn->__next_ = __cp->__ptr();
19313e519524SHoward Hinnant        if (__cp->__next_ != nullptr)
19323e519524SHoward Hinnant        {
193340492ba4SEric Fiselier            size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc);
19343e519524SHoward Hinnant            if (__nhash != __chash)
193540492ba4SEric Fiselier                __bucket_list_[__nhash] = __cp->__ptr();
19363e519524SHoward Hinnant        }
19373e519524SHoward Hinnant    }
19383e519524SHoward Hinnant    ++size();
19395c4e07aeSErik Pilkington}
19405c4e07aeSErik Pilkington
19415c4e07aeSErik Pilkington
19425c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
19435c4e07aeSErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
19445c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
19455c4e07aeSErik Pilkington{
19465c4e07aeSErik Pilkington    __cp->__hash_ = hash_function()(__cp->__value_);
19475c4e07aeSErik Pilkington    __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
19485c4e07aeSErik Pilkington    __node_insert_multi_perform(__cp, __pn);
19495c4e07aeSErik Pilkington
195040492ba4SEric Fiselier    return iterator(__cp->__ptr(), this);
19513e519524SHoward Hinnant}
19523e519524SHoward Hinnant
19533e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
19543e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
19553e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
19563e519524SHoward Hinnant        const_iterator __p, __node_pointer __cp)
19573e519524SHoward Hinnant{
1958d6e2c95dSMark de Wever    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
19592f51de56SHoward Hinnant                         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
19602f51de56SHoward Hinnant                         " referring to this unordered container");
19613e519524SHoward Hinnant    if (__p != end() && key_eq()(*__p, __cp->__value_))
19623e519524SHoward Hinnant    {
196340492ba4SEric Fiselier        __next_pointer __np = __p.__node_;
196440492ba4SEric Fiselier        __cp->__hash_ = __np->__hash();
19653e519524SHoward Hinnant        size_type __bc = bucket_count();
19663e519524SHoward Hinnant        if (size()+1 > __bc * max_load_factor() || __bc == 0)
19673e519524SHoward Hinnant        {
19683085e42fSIvan Trofimov            __rehash_multi(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
19693e519524SHoward Hinnant                           size_type(ceil(float(size() + 1) / max_load_factor()))));
19703e519524SHoward Hinnant            __bc = bucket_count();
19713e519524SHoward Hinnant        }
19724cb38a82SHoward Hinnant        size_t __chash = __constrain_hash(__cp->__hash_, __bc);
197340492ba4SEric Fiselier        __next_pointer __pp = __bucket_list_[__chash];
19743e519524SHoward Hinnant        while (__pp->__next_ != __np)
19753e519524SHoward Hinnant            __pp = __pp->__next_;
19763e519524SHoward Hinnant        __cp->__next_ = __np;
197740492ba4SEric Fiselier        __pp->__next_ = static_cast<__next_pointer>(__cp);
19783e519524SHoward Hinnant        ++size();
197940492ba4SEric Fiselier        return iterator(static_cast<__next_pointer>(__cp), this);
19803e519524SHoward Hinnant    }
19813e519524SHoward Hinnant    return __node_insert_multi(__cp);
19823e519524SHoward Hinnant}
19833e519524SHoward Hinnant
1984de3f2b39SEric Fiselier
1985de3f2b39SEric Fiselier
1986de3f2b39SEric Fiseliertemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1987fcd02211SEric Fiseliertemplate <class _Key, class ..._Args>
1988de3f2b39SEric Fiselierpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1989fcd02211SEric Fiselier__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
1990de3f2b39SEric Fiselier{
1991fcd02211SEric Fiselier
1992fcd02211SEric Fiselier    size_t __hash = hash_function()(__k);
19933e519524SHoward Hinnant    size_type __bc = bucket_count();
19943e519524SHoward Hinnant    bool __inserted = false;
199540492ba4SEric Fiselier    __next_pointer __nd;
19963e519524SHoward Hinnant    size_t __chash;
19973e519524SHoward Hinnant    if (__bc != 0)
19983e519524SHoward Hinnant    {
19994cb38a82SHoward Hinnant        __chash = __constrain_hash(__hash, __bc);
20003e519524SHoward Hinnant        __nd = __bucket_list_[__chash];
20013e519524SHoward Hinnant        if (__nd != nullptr)
20023e519524SHoward Hinnant        {
20033e519524SHoward Hinnant            for (__nd = __nd->__next_; __nd != nullptr &&
20041a06fe5fSEric Fiselier                (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash);
20053e519524SHoward Hinnant                                                           __nd = __nd->__next_)
20063e519524SHoward Hinnant            {
200740492ba4SEric Fiselier                if (key_eq()(__nd->__upcast()->__value_, __k))
20083e519524SHoward Hinnant                    goto __done;
20093e519524SHoward Hinnant            }
20103e519524SHoward Hinnant        }
20113e519524SHoward Hinnant    }
20123e519524SHoward Hinnant    {
2013fcd02211SEric Fiselier        __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...);
20143e519524SHoward Hinnant        if (size()+1 > __bc * max_load_factor() || __bc == 0)
20153e519524SHoward Hinnant        {
20163085e42fSIvan Trofimov            __rehash_unique(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
20173e519524SHoward Hinnant                           size_type(ceil(float(size() + 1) / max_load_factor()))));
20183e519524SHoward Hinnant            __bc = bucket_count();
20194cb38a82SHoward Hinnant            __chash = __constrain_hash(__hash, __bc);
20203e519524SHoward Hinnant        }
20213e519524SHoward Hinnant        // insert_after __bucket_list_[__chash], or __first_node if bucket is null
202240492ba4SEric Fiselier        __next_pointer __pn = __bucket_list_[__chash];
20233e519524SHoward Hinnant        if (__pn == nullptr)
20243e519524SHoward Hinnant        {
202540492ba4SEric Fiselier            __pn = __p1_.first().__ptr();
20263e519524SHoward Hinnant            __h->__next_ = __pn->__next_;
202740492ba4SEric Fiselier            __pn->__next_ = __h.get()->__ptr();
20283e519524SHoward Hinnant            // fix up __bucket_list_
20293e519524SHoward Hinnant            __bucket_list_[__chash] = __pn;
20303e519524SHoward Hinnant            if (__h->__next_ != nullptr)
203140492ba4SEric Fiselier                __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)]
203240492ba4SEric Fiselier                    = __h.get()->__ptr();
20333e519524SHoward Hinnant        }
20343e519524SHoward Hinnant        else
20353e519524SHoward Hinnant        {
20363e519524SHoward Hinnant            __h->__next_ = __pn->__next_;
203740492ba4SEric Fiselier            __pn->__next_ = static_cast<__next_pointer>(__h.get());
20383e519524SHoward Hinnant        }
203940492ba4SEric Fiselier        __nd = static_cast<__next_pointer>(__h.release());
20403e519524SHoward Hinnant        // increment size
20413e519524SHoward Hinnant        ++size();
20423e519524SHoward Hinnant        __inserted = true;
20433e519524SHoward Hinnant    }
20443e519524SHoward Hinnant__done:
2045b24c8024SHoward Hinnant    return pair<iterator, bool>(iterator(__nd, this), __inserted);
20463e519524SHoward Hinnant}
20473e519524SHoward Hinnant
20483e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
20493e519524SHoward Hinnanttemplate <class... _Args>
20503e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
2051fde79b40SDuncan P. N. Exon Smith__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args)
20523e519524SHoward Hinnant{
2053ce48a113SHoward Hinnant    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
20543e519524SHoward Hinnant    pair<iterator, bool> __r = __node_insert_unique(__h.get());
20553e519524SHoward Hinnant    if (__r.second)
20563e519524SHoward Hinnant        __h.release();
20573e519524SHoward Hinnant    return __r;
20583e519524SHoward Hinnant}
20593e519524SHoward Hinnant
20603e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
20613e519524SHoward Hinnanttemplate <class... _Args>
20623e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
20633e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args)
20643e519524SHoward Hinnant{
2065ce48a113SHoward Hinnant    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
20663e519524SHoward Hinnant    iterator __r = __node_insert_multi(__h.get());
20673e519524SHoward Hinnant    __h.release();
20683e519524SHoward Hinnant    return __r;
20693e519524SHoward Hinnant}
20703e519524SHoward Hinnant
20713e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
20723e519524SHoward Hinnanttemplate <class... _Args>
20733e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
20743e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
20753e519524SHoward Hinnant        const_iterator __p, _Args&&... __args)
20763e519524SHoward Hinnant{
2077d6e2c95dSMark de Wever    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
2078e5c13decSHoward Hinnant                         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
2079e5c13decSHoward Hinnant                         " referring to this unordered container");
2080ce48a113SHoward Hinnant    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
20813e519524SHoward Hinnant    iterator __r = __node_insert_multi(__p, __h.get());
20823e519524SHoward Hinnant    __h.release();
20833e519524SHoward Hinnant    return __r;
20843e519524SHoward Hinnant}
20853e519524SHoward Hinnant
2086b0386a51SErik Pilkington#if _LIBCPP_STD_VER > 14
2087b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2088b0386a51SErik Pilkingtontemplate <class _NodeHandle, class _InsertReturnType>
2089b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2090b0386a51SErik Pilkington_InsertReturnType
2091b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
2092b0386a51SErik Pilkington    _NodeHandle&& __nh)
2093b0386a51SErik Pilkington{
2094b0386a51SErik Pilkington    if (__nh.empty())
2095b0386a51SErik Pilkington        return _InsertReturnType{end(), false, _NodeHandle()};
2096b0386a51SErik Pilkington    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
2097b0386a51SErik Pilkington    if (__result.second)
20986886f1e3SEric Fiselier        __nh.__release_ptr();
2099b0386a51SErik Pilkington    return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
2100b0386a51SErik Pilkington}
2101b0386a51SErik Pilkington
2102b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2103b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2104b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2105b0386a51SErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2106b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
2107b0386a51SErik Pilkington    const_iterator, _NodeHandle&& __nh)
2108b0386a51SErik Pilkington{
2109b0386a51SErik Pilkington    if (__nh.empty())
2110b0386a51SErik Pilkington        return end();
2111b0386a51SErik Pilkington    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
2112b0386a51SErik Pilkington    if (__result.second)
21136886f1e3SEric Fiselier        __nh.__release_ptr();
2114b0386a51SErik Pilkington    return __result.first;
2115b0386a51SErik Pilkington}
2116b0386a51SErik Pilkington
2117b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2118b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2119b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2120b0386a51SErik Pilkington_NodeHandle
2121b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
2122b0386a51SErik Pilkington    key_type const& __key)
2123b0386a51SErik Pilkington{
2124b0386a51SErik Pilkington    iterator __i = find(__key);
2125b0386a51SErik Pilkington    if (__i == end())
2126b0386a51SErik Pilkington        return _NodeHandle();
2127b0386a51SErik Pilkington    return __node_handle_extract<_NodeHandle>(__i);
2128b0386a51SErik Pilkington}
2129b0386a51SErik Pilkington
2130b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2131b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2132b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2133b0386a51SErik Pilkington_NodeHandle
2134b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
2135b0386a51SErik Pilkington    const_iterator __p)
2136b0386a51SErik Pilkington{
2137b0386a51SErik Pilkington    allocator_type __alloc(__node_alloc());
2138b0386a51SErik Pilkington    return _NodeHandle(remove(__p).release(), __alloc);
2139b0386a51SErik Pilkington}
2140b0386a51SErik Pilkington
2141b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
21425c4e07aeSErik Pilkingtontemplate <class _Table>
21435c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY
21445c4e07aeSErik Pilkingtonvoid
21455c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
21465c4e07aeSErik Pilkington    _Table& __source)
21475c4e07aeSErik Pilkington{
21485c4e07aeSErik Pilkington    static_assert(is_same<__node, typename _Table::__node>::value, "");
21495c4e07aeSErik Pilkington
21505c4e07aeSErik Pilkington    for (typename _Table::iterator __it = __source.begin();
21515c4e07aeSErik Pilkington         __it != __source.end();)
21525c4e07aeSErik Pilkington    {
21535c4e07aeSErik Pilkington        __node_pointer __src_ptr = __it.__node_->__upcast();
21545c4e07aeSErik Pilkington        size_t __hash = hash_function()(__src_ptr->__value_);
21555c4e07aeSErik Pilkington        __next_pointer __existing_node =
21565c4e07aeSErik Pilkington            __node_insert_unique_prepare(__hash, __src_ptr->__value_);
21575c4e07aeSErik Pilkington        auto __prev_iter = __it++;
21585c4e07aeSErik Pilkington        if (__existing_node == nullptr)
21595c4e07aeSErik Pilkington        {
21605c4e07aeSErik Pilkington            (void)__source.remove(__prev_iter).release();
21615c4e07aeSErik Pilkington            __src_ptr->__hash_ = __hash;
21625c4e07aeSErik Pilkington            __node_insert_unique_perform(__src_ptr);
21635c4e07aeSErik Pilkington        }
21645c4e07aeSErik Pilkington    }
21655c4e07aeSErik Pilkington}
21665c4e07aeSErik Pilkington
21675c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2168b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2169b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2170b0386a51SErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2171b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
2172b0386a51SErik Pilkington    _NodeHandle&& __nh)
2173b0386a51SErik Pilkington{
2174b0386a51SErik Pilkington    if (__nh.empty())
2175b0386a51SErik Pilkington        return end();
2176b0386a51SErik Pilkington    iterator __result = __node_insert_multi(__nh.__ptr_);
21776886f1e3SEric Fiselier    __nh.__release_ptr();
2178b0386a51SErik Pilkington    return __result;
2179b0386a51SErik Pilkington}
2180b0386a51SErik Pilkington
2181b0386a51SErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2182b0386a51SErik Pilkingtontemplate <class _NodeHandle>
2183b0386a51SErik Pilkington_LIBCPP_INLINE_VISIBILITY
2184b0386a51SErik Pilkingtontypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2185b0386a51SErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
2186b0386a51SErik Pilkington    const_iterator __hint, _NodeHandle&& __nh)
2187b0386a51SErik Pilkington{
2188b0386a51SErik Pilkington    if (__nh.empty())
2189b0386a51SErik Pilkington        return end();
2190b0386a51SErik Pilkington    iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
21916886f1e3SEric Fiselier    __nh.__release_ptr();
2192b0386a51SErik Pilkington    return __result;
2193b0386a51SErik Pilkington}
2194b0386a51SErik Pilkington
21955c4e07aeSErik Pilkingtontemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
21965c4e07aeSErik Pilkingtontemplate <class _Table>
21975c4e07aeSErik Pilkington_LIBCPP_INLINE_VISIBILITY
21985c4e07aeSErik Pilkingtonvoid
21995c4e07aeSErik Pilkington__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
22005c4e07aeSErik Pilkington    _Table& __source)
22015c4e07aeSErik Pilkington{
22025c4e07aeSErik Pilkington    static_assert(is_same<typename _Table::__node, __node>::value, "");
22035c4e07aeSErik Pilkington
22045c4e07aeSErik Pilkington    for (typename _Table::iterator __it = __source.begin();
22055c4e07aeSErik Pilkington         __it != __source.end();)
22065c4e07aeSErik Pilkington    {
22075c4e07aeSErik Pilkington        __node_pointer __src_ptr = __it.__node_->__upcast();
22085c4e07aeSErik Pilkington        size_t __src_hash = hash_function()(__src_ptr->__value_);
22095c4e07aeSErik Pilkington        __next_pointer __pn =
22105c4e07aeSErik Pilkington            __node_insert_multi_prepare(__src_hash, __src_ptr->__value_);
22115c4e07aeSErik Pilkington        (void)__source.remove(__it++).release();
22125c4e07aeSErik Pilkington        __src_ptr->__hash_ = __src_hash;
22135c4e07aeSErik Pilkington        __node_insert_multi_perform(__src_ptr, __pn);
22145c4e07aeSErik Pilkington    }
22155c4e07aeSErik Pilkington}
2216b0386a51SErik Pilkington#endif // _LIBCPP_STD_VER > 14
2217b0386a51SErik Pilkington
22183e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
22193085e42fSIvan Trofimovtemplate <bool _UniqueKeys>
22203e519524SHoward Hinnantvoid
22213085e42fSIvan Trofimov__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n)
2222954966c1SMarshall Clow_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
22233e519524SHoward Hinnant{
2224553b09b5SDan Albert    if (__n == 1)
22254cb38a82SHoward Hinnant        __n = 2;
22264cb38a82SHoward Hinnant    else if (__n & (__n - 1))
22274cb38a82SHoward Hinnant        __n = __next_prime(__n);
22283e519524SHoward Hinnant    size_type __bc = bucket_count();
22293e519524SHoward Hinnant    if (__n > __bc)
22303085e42fSIvan Trofimov        __do_rehash<_UniqueKeys>(__n);
22314cb38a82SHoward Hinnant    else if (__n < __bc)
22323e519524SHoward Hinnant    {
2233ce48a113SHoward Hinnant        __n = _VSTD::max<size_type>
22343e519524SHoward Hinnant              (
22353e519524SHoward Hinnant                  __n,
22369ba5c11bSEric Fiselier                  __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
22373e519524SHoward Hinnant                                           __next_prime(size_t(ceil(float(size()) / max_load_factor())))
22383e519524SHoward Hinnant              );
22393e519524SHoward Hinnant        if (__n < __bc)
22403085e42fSIvan Trofimov            __do_rehash<_UniqueKeys>(__n);
22413e519524SHoward Hinnant    }
22423e519524SHoward Hinnant}
22433e519524SHoward Hinnant
22443e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
22453085e42fSIvan Trofimovtemplate <bool _UniqueKeys>
22463e519524SHoward Hinnantvoid
22473085e42fSIvan Trofimov__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
22483e519524SHoward Hinnant{
224908f68dfeSNikolas Klauser    std::__debug_db_invalidate_all(this);
22503e519524SHoward Hinnant    __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
22513e519524SHoward Hinnant    __bucket_list_.reset(__nbc > 0 ?
22523e519524SHoward Hinnant                      __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
22533e519524SHoward Hinnant    __bucket_list_.get_deleter().size() = __nbc;
22543e519524SHoward Hinnant    if (__nbc > 0)
22553e519524SHoward Hinnant    {
22563e519524SHoward Hinnant        for (size_type __i = 0; __i < __nbc; ++__i)
22573e519524SHoward Hinnant            __bucket_list_[__i] = nullptr;
225840492ba4SEric Fiselier        __next_pointer __pp = __p1_.first().__ptr();
225940492ba4SEric Fiselier        __next_pointer __cp = __pp->__next_;
22603e519524SHoward Hinnant        if (__cp != nullptr)
22613e519524SHoward Hinnant        {
226240492ba4SEric Fiselier            size_type __chash = __constrain_hash(__cp->__hash(), __nbc);
22633e519524SHoward Hinnant            __bucket_list_[__chash] = __pp;
22643e519524SHoward Hinnant            size_type __phash = __chash;
226516bf4339SArthur O'Dwyer            for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr;
22663e519524SHoward Hinnant                                                           __cp = __pp->__next_)
22673e519524SHoward Hinnant            {
226840492ba4SEric Fiselier                __chash = __constrain_hash(__cp->__hash(), __nbc);
22693e519524SHoward Hinnant                if (__chash == __phash)
22703e519524SHoward Hinnant                    __pp = __cp;
22713e519524SHoward Hinnant                else
22723e519524SHoward Hinnant                {
22733e519524SHoward Hinnant                    if (__bucket_list_[__chash] == nullptr)
22743e519524SHoward Hinnant                    {
22753e519524SHoward Hinnant                        __bucket_list_[__chash] = __pp;
22763e519524SHoward Hinnant                        __pp = __cp;
22773e519524SHoward Hinnant                        __phash = __chash;
22783e519524SHoward Hinnant                    }
22793e519524SHoward Hinnant                    else
22803e519524SHoward Hinnant                    {
228140492ba4SEric Fiselier                        __next_pointer __np = __cp;
22823085e42fSIvan Trofimov                        if _LIBCPP_CONSTEXPR_AFTER_CXX14 (!_UniqueKeys)
22833085e42fSIvan Trofimov                        {
22843e519524SHoward Hinnant                            for (; __np->__next_ != nullptr &&
228540492ba4SEric Fiselier                                   key_eq()(__cp->__upcast()->__value_,
228640492ba4SEric Fiselier                                            __np->__next_->__upcast()->__value_);
22873e519524SHoward Hinnant                                                               __np = __np->__next_)
22883e519524SHoward Hinnant                                ;
22893085e42fSIvan Trofimov                        }
22903e519524SHoward Hinnant                        __pp->__next_ = __np->__next_;
22913e519524SHoward Hinnant                        __np->__next_ = __bucket_list_[__chash]->__next_;
22923e519524SHoward Hinnant                        __bucket_list_[__chash]->__next_ = __cp;
22933e519524SHoward Hinnant
22943e519524SHoward Hinnant                    }
22953e519524SHoward Hinnant                }
22963e519524SHoward Hinnant            }
22973e519524SHoward Hinnant        }
22983e519524SHoward Hinnant    }
22993e519524SHoward Hinnant}
23003e519524SHoward Hinnant
23013e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
23023e519524SHoward Hinnanttemplate <class _Key>
23033e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
23043e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
23053e519524SHoward Hinnant{
23063e519524SHoward Hinnant    size_t __hash = hash_function()(__k);
23073e519524SHoward Hinnant    size_type __bc = bucket_count();
23083e519524SHoward Hinnant    if (__bc != 0)
23093e519524SHoward Hinnant    {
23104cb38a82SHoward Hinnant        size_t __chash = __constrain_hash(__hash, __bc);
231140492ba4SEric Fiselier        __next_pointer __nd = __bucket_list_[__chash];
23123e519524SHoward Hinnant        if (__nd != nullptr)
23133e519524SHoward Hinnant        {
23143e519524SHoward Hinnant            for (__nd = __nd->__next_; __nd != nullptr &&
231540492ba4SEric Fiselier                (__nd->__hash() == __hash
231640492ba4SEric Fiselier                  || __constrain_hash(__nd->__hash(), __bc) == __chash);
23173e519524SHoward Hinnant                                                           __nd = __nd->__next_)
23183e519524SHoward Hinnant            {
231940492ba4SEric Fiselier                if ((__nd->__hash() == __hash)
232040492ba4SEric Fiselier                    && key_eq()(__nd->__upcast()->__value_, __k))
2321b24c8024SHoward Hinnant                    return iterator(__nd, this);
23223e519524SHoward Hinnant            }
23233e519524SHoward Hinnant        }
23243e519524SHoward Hinnant    }
23253e519524SHoward Hinnant    return end();
23263e519524SHoward Hinnant}
23273e519524SHoward Hinnant
23283e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
23293e519524SHoward Hinnanttemplate <class _Key>
23303e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
23313e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
23323e519524SHoward Hinnant{
23333e519524SHoward Hinnant    size_t __hash = hash_function()(__k);
23343e519524SHoward Hinnant    size_type __bc = bucket_count();
23353e519524SHoward Hinnant    if (__bc != 0)
23363e519524SHoward Hinnant    {
23374cb38a82SHoward Hinnant        size_t __chash = __constrain_hash(__hash, __bc);
233840492ba4SEric Fiselier        __next_pointer __nd = __bucket_list_[__chash];
23393e519524SHoward Hinnant        if (__nd != nullptr)
23403e519524SHoward Hinnant        {
23413e519524SHoward Hinnant            for (__nd = __nd->__next_; __nd != nullptr &&
234240492ba4SEric Fiselier                (__hash == __nd->__hash()
234340492ba4SEric Fiselier                    || __constrain_hash(__nd->__hash(), __bc) == __chash);
23443e519524SHoward Hinnant                                                           __nd = __nd->__next_)
23453e519524SHoward Hinnant            {
234640492ba4SEric Fiselier                if ((__nd->__hash() == __hash)
234740492ba4SEric Fiselier                    && key_eq()(__nd->__upcast()->__value_, __k))
2348b24c8024SHoward Hinnant                    return const_iterator(__nd, this);
23493e519524SHoward Hinnant            }
23503e519524SHoward Hinnant        }
23513e519524SHoward Hinnant
23523e519524SHoward Hinnant    }
23533e519524SHoward Hinnant    return end();
23543e519524SHoward Hinnant}
23553e519524SHoward Hinnant
23563e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
23573e519524SHoward Hinnanttemplate <class ..._Args>
23583e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
23593e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
23603e519524SHoward Hinnant{
2361fcd02211SEric Fiselier    static_assert(!__is_hash_value_type<_Args...>::value,
2362fcd02211SEric Fiselier                  "Construct cannot be called with a hash value type");
23633e519524SHoward Hinnant    __node_allocator& __na = __node_alloc();
2364c003db1fSHoward Hinnant    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
2365fcd02211SEric Fiselier    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
23663e519524SHoward Hinnant    __h.get_deleter().__value_constructed = true;
23673e519524SHoward Hinnant    __h->__hash_ = hash_function()(__h->__value_);
23683e519524SHoward Hinnant    __h->__next_ = nullptr;
23693e519524SHoward Hinnant    return __h;
23703e519524SHoward Hinnant}
23713e519524SHoward Hinnant
23723e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2373fcd02211SEric Fiseliertemplate <class _First, class ..._Rest>
23743e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
2375fcd02211SEric Fiselier__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(
2376fcd02211SEric Fiselier    size_t __hash, _First&& __f, _Rest&& ...__rest)
23773e519524SHoward Hinnant{
2378fcd02211SEric Fiselier    static_assert(!__is_hash_value_type<_First, _Rest...>::value,
2379fcd02211SEric Fiselier                  "Construct cannot be called with a hash value type");
23803e519524SHoward Hinnant    __node_allocator& __na = __node_alloc();
2381c003db1fSHoward Hinnant    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
2382fcd02211SEric Fiselier    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_),
2383fcd02211SEric Fiselier                             _VSTD::forward<_First>(__f),
2384fcd02211SEric Fiselier                             _VSTD::forward<_Rest>(__rest)...);
23853e519524SHoward Hinnant    __h.get_deleter().__value_constructed = true;
23863e519524SHoward Hinnant    __h->__hash_ = __hash;
23873e519524SHoward Hinnant    __h->__next_ = nullptr;
2388179b1f8cSHoward Hinnant    return __h;
23893e519524SHoward Hinnant}
23903e519524SHoward Hinnant
23913e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
23923e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
23933e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
23943e519524SHoward Hinnant{
239540492ba4SEric Fiselier    __next_pointer __np = __p.__node_;
2396d6e2c95dSMark de Wever    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
2397b24c8024SHoward Hinnant                         "unordered container erase(iterator) called with an iterator not"
2398b24c8024SHoward Hinnant                         " referring to this container");
2399c87c8917SLouis Dionne    _LIBCPP_ASSERT(__p != end(),
2400b24c8024SHoward Hinnant                   "unordered container erase(iterator) called with a non-dereferenceable iterator");
2401b24c8024SHoward Hinnant    iterator __r(__np, this);
24023e519524SHoward Hinnant    ++__r;
24033e519524SHoward Hinnant    remove(__p);
24043e519524SHoward Hinnant    return __r;
24053e519524SHoward Hinnant}
24063e519524SHoward Hinnant
24073e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
24083e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
24093e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
24103e519524SHoward Hinnant                                                const_iterator __last)
24113e519524SHoward Hinnant{
2412d6e2c95dSMark de Wever    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this,
24138a867878SKristina Bessonova                         "unordered container::erase(iterator, iterator) called with an iterator not"
24148a867878SKristina Bessonova                         " referring to this container");
2415d6e2c95dSMark de Wever    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this,
24168a867878SKristina Bessonova                         "unordered container::erase(iterator, iterator) called with an iterator not"
24178a867878SKristina Bessonova                         " referring to this container");
24183e519524SHoward Hinnant    for (const_iterator __p = __first; __first != __last; __p = __first)
24193e519524SHoward Hinnant    {
24203e519524SHoward Hinnant        ++__first;
24213e519524SHoward Hinnant        erase(__p);
24223e519524SHoward Hinnant    }
242340492ba4SEric Fiselier    __next_pointer __np = __last.__node_;
2424b24c8024SHoward Hinnant    return iterator (__np, this);
24253e519524SHoward Hinnant}
24263e519524SHoward Hinnant
24273e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
24283e519524SHoward Hinnanttemplate <class _Key>
24293e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
24303e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k)
24313e519524SHoward Hinnant{
24323e519524SHoward Hinnant    iterator __i = find(__k);
24333e519524SHoward Hinnant    if (__i == end())
24343e519524SHoward Hinnant        return 0;
24353e519524SHoward Hinnant    erase(__i);
24363e519524SHoward Hinnant    return 1;
24373e519524SHoward Hinnant}
24383e519524SHoward Hinnant
24393e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
24403e519524SHoward Hinnanttemplate <class _Key>
24413e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
24423e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k)
24433e519524SHoward Hinnant{
24443e519524SHoward Hinnant    size_type __r = 0;
24453e519524SHoward Hinnant    iterator __i = find(__k);
24463e519524SHoward Hinnant    if (__i != end())
24473e519524SHoward Hinnant    {
24483e519524SHoward Hinnant        iterator __e = end();
24493e519524SHoward Hinnant        do
24503e519524SHoward Hinnant        {
24513e519524SHoward Hinnant            erase(__i++);
24523e519524SHoward Hinnant            ++__r;
24533e519524SHoward Hinnant        } while (__i != __e && key_eq()(*__i, __k));
24543e519524SHoward Hinnant    }
24553e519524SHoward Hinnant    return __r;
24563e519524SHoward Hinnant}
24573e519524SHoward Hinnant
24583e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
24593e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
24603714107eSHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
24613e519524SHoward Hinnant{
24623e519524SHoward Hinnant    // current node
246340492ba4SEric Fiselier    __next_pointer __cn = __p.__node_;
24643e519524SHoward Hinnant    size_type __bc = bucket_count();
246540492ba4SEric Fiselier    size_t __chash = __constrain_hash(__cn->__hash(), __bc);
24663e519524SHoward Hinnant    // find previous node
246740492ba4SEric Fiselier    __next_pointer __pn = __bucket_list_[__chash];
24683e519524SHoward Hinnant    for (; __pn->__next_ != __cn; __pn = __pn->__next_)
24693e519524SHoward Hinnant        ;
24703e519524SHoward Hinnant    // Fix up __bucket_list_
24713e519524SHoward Hinnant        // if __pn is not in same bucket (before begin is not in same bucket) &&
24723e519524SHoward Hinnant        //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
247340492ba4SEric Fiselier    if (__pn == __p1_.first().__ptr()
247440492ba4SEric Fiselier            || __constrain_hash(__pn->__hash(), __bc) != __chash)
24753e519524SHoward Hinnant    {
247640492ba4SEric Fiselier        if (__cn->__next_ == nullptr
247740492ba4SEric Fiselier            || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
24783e519524SHoward Hinnant            __bucket_list_[__chash] = nullptr;
24793e519524SHoward Hinnant    }
24803e519524SHoward Hinnant        // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
24813e519524SHoward Hinnant    if (__cn->__next_ != nullptr)
24823e519524SHoward Hinnant    {
248340492ba4SEric Fiselier        size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc);
24843e519524SHoward Hinnant        if (__nhash != __chash)
24853e519524SHoward Hinnant            __bucket_list_[__nhash] = __pn;
24863e519524SHoward Hinnant    }
24873e519524SHoward Hinnant    // remove __cn
24883e519524SHoward Hinnant    __pn->__next_ = __cn->__next_;
24893e519524SHoward Hinnant    __cn->__next_ = nullptr;
24903e519524SHoward Hinnant    --size();
2491f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2492b24c8024SHoward Hinnant    __c_node* __c = __get_db()->__find_c_and_lock(this);
2493780b51dfSEric Fiselier    for (__i_node** __dp = __c->end_; __dp != __c->beg_; )
2494b24c8024SHoward Hinnant    {
2495780b51dfSEric Fiselier        --__dp;
2496780b51dfSEric Fiselier        iterator* __i = static_cast<iterator*>((*__dp)->__i_);
2497b24c8024SHoward Hinnant        if (__i->__node_ == __cn)
2498b24c8024SHoward Hinnant        {
2499780b51dfSEric Fiselier            (*__dp)->__c_ = nullptr;
2500780b51dfSEric Fiselier            if (--__c->end_ != __dp)
25013696227cSArthur O'Dwyer                _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*));
2502b24c8024SHoward Hinnant        }
2503b24c8024SHoward Hinnant    }
2504b24c8024SHoward Hinnant    __get_db()->unlock();
2505b24c8024SHoward Hinnant#endif
250640492ba4SEric Fiselier    return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
25073e519524SHoward Hinnant}
25083e519524SHoward Hinnant
25093e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
25103e519524SHoward Hinnanttemplate <class _Key>
2511906c872dSEvgeniy Stepanovinline
25123e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
25133e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const
25143e519524SHoward Hinnant{
25153e519524SHoward Hinnant    return static_cast<size_type>(find(__k) != end());
25163e519524SHoward Hinnant}
25173e519524SHoward Hinnant
25183e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
25193e519524SHoward Hinnanttemplate <class _Key>
25203e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
25213e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const
25223e519524SHoward Hinnant{
25233e519524SHoward Hinnant    size_type __r = 0;
25243e519524SHoward Hinnant    const_iterator __i = find(__k);
25253e519524SHoward Hinnant    if (__i != end())
25263e519524SHoward Hinnant    {
25273e519524SHoward Hinnant        const_iterator __e = end();
25283e519524SHoward Hinnant        do
25293e519524SHoward Hinnant        {
25303e519524SHoward Hinnant            ++__i;
25313e519524SHoward Hinnant            ++__r;
25323e519524SHoward Hinnant        } while (__i != __e && key_eq()(*__i, __k));
25333e519524SHoward Hinnant    }
25343e519524SHoward Hinnant    return __r;
25353e519524SHoward Hinnant}
25363e519524SHoward Hinnant
25373e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
25383e519524SHoward Hinnanttemplate <class _Key>
25393e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
25403e519524SHoward Hinnant     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
25413e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
25423e519524SHoward Hinnant        const _Key& __k)
25433e519524SHoward Hinnant{
25443e519524SHoward Hinnant    iterator __i = find(__k);
25453e519524SHoward Hinnant    iterator __j = __i;
25463e519524SHoward Hinnant    if (__i != end())
25473e519524SHoward Hinnant        ++__j;
25483e519524SHoward Hinnant    return pair<iterator, iterator>(__i, __j);
25493e519524SHoward Hinnant}
25503e519524SHoward Hinnant
25513e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
25523e519524SHoward Hinnanttemplate <class _Key>
25533e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
25543e519524SHoward Hinnant     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
25553e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
25563e519524SHoward Hinnant        const _Key& __k) const
25573e519524SHoward Hinnant{
25583e519524SHoward Hinnant    const_iterator __i = find(__k);
25593e519524SHoward Hinnant    const_iterator __j = __i;
25603e519524SHoward Hinnant    if (__i != end())
25613e519524SHoward Hinnant        ++__j;
25623e519524SHoward Hinnant    return pair<const_iterator, const_iterator>(__i, __j);
25633e519524SHoward Hinnant}
25643e519524SHoward Hinnant
25653e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
25663e519524SHoward Hinnanttemplate <class _Key>
25673e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
25683e519524SHoward Hinnant     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
25693e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
25703e519524SHoward Hinnant        const _Key& __k)
25713e519524SHoward Hinnant{
25723e519524SHoward Hinnant    iterator __i = find(__k);
25733e519524SHoward Hinnant    iterator __j = __i;
25743e519524SHoward Hinnant    if (__i != end())
25753e519524SHoward Hinnant    {
25763e519524SHoward Hinnant        iterator __e = end();
25773e519524SHoward Hinnant        do
25783e519524SHoward Hinnant        {
25793e519524SHoward Hinnant            ++__j;
25803e519524SHoward Hinnant        } while (__j != __e && key_eq()(*__j, __k));
25813e519524SHoward Hinnant    }
25823e519524SHoward Hinnant    return pair<iterator, iterator>(__i, __j);
25833e519524SHoward Hinnant}
25843e519524SHoward Hinnant
25853e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
25863e519524SHoward Hinnanttemplate <class _Key>
25873e519524SHoward Hinnantpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
25883e519524SHoward Hinnant     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
25893e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
25903e519524SHoward Hinnant        const _Key& __k) const
25913e519524SHoward Hinnant{
25923e519524SHoward Hinnant    const_iterator __i = find(__k);
25933e519524SHoward Hinnant    const_iterator __j = __i;
25943e519524SHoward Hinnant    if (__i != end())
25953e519524SHoward Hinnant    {
25963e519524SHoward Hinnant        const_iterator __e = end();
25973e519524SHoward Hinnant        do
25983e519524SHoward Hinnant        {
25993e519524SHoward Hinnant            ++__j;
26003e519524SHoward Hinnant        } while (__j != __e && key_eq()(*__j, __k));
26013e519524SHoward Hinnant    }
26023e519524SHoward Hinnant    return pair<const_iterator, const_iterator>(__i, __j);
26033e519524SHoward Hinnant}
26043e519524SHoward Hinnant
26053e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
26063e519524SHoward Hinnantvoid
26073e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
260887a82490SEric Fiselier#if _LIBCPP_STD_VER <= 11
260961b302f9SEric Fiselier    _NOEXCEPT_(
2610e3fbe143SMarshall Clow        __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
2611e3fbe143SMarshall Clow        && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
2612e3fbe143SMarshall Clow              || __is_nothrow_swappable<__pointer_allocator>::value)
2613e3fbe143SMarshall Clow        && (!__node_traits::propagate_on_container_swap::value
2614e3fbe143SMarshall Clow              || __is_nothrow_swappable<__node_allocator>::value)
2615e3fbe143SMarshall Clow            )
261687a82490SEric Fiselier#else
261761b302f9SEric Fiselier  _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
261887a82490SEric Fiselier#endif
26193e519524SHoward Hinnant{
2620780b51dfSEric Fiselier    _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value ||
2621780b51dfSEric Fiselier                   this->__node_alloc() == __u.__node_alloc(),
2622780b51dfSEric Fiselier                   "list::swap: Either propagate_on_container_swap must be true"
2623780b51dfSEric Fiselier                   " or the allocators must compare equal");
26243e519524SHoward Hinnant    {
26253e519524SHoward Hinnant    __node_pointer_pointer __npp = __bucket_list_.release();
26263e519524SHoward Hinnant    __bucket_list_.reset(__u.__bucket_list_.release());
26273e519524SHoward Hinnant    __u.__bucket_list_.reset(__npp);
26283e519524SHoward Hinnant    }
2629ce48a113SHoward Hinnant    _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
26306e965df6SArthur O'Dwyer    _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(),
26313e519524SHoward Hinnant             __u.__bucket_list_.get_deleter().__alloc());
26326e965df6SArthur O'Dwyer    _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc());
2633ce48a113SHoward Hinnant    _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
26343e519524SHoward Hinnant    __p2_.swap(__u.__p2_);
26353e519524SHoward Hinnant    __p3_.swap(__u.__p3_);
26363e519524SHoward Hinnant    if (size() > 0)
263740492ba4SEric Fiselier        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
263840492ba4SEric Fiselier            __p1_.first().__ptr();
26393e519524SHoward Hinnant    if (__u.size() > 0)
264040492ba4SEric Fiselier        __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
264140492ba4SEric Fiselier            __u.__p1_.first().__ptr();
264208f68dfeSNikolas Klauser    std::__debug_db_swap(this, std::addressof(__u));
26433e519524SHoward Hinnant}
26443e519524SHoward Hinnant
26453e519524SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
26463e519524SHoward Hinnanttypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
26473e519524SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
26483e519524SHoward Hinnant{
2649e5c13decSHoward Hinnant    _LIBCPP_ASSERT(__n < bucket_count(),
2650e5c13decSHoward Hinnant        "unordered container::bucket_size(n) called with n >= bucket_count()");
265140492ba4SEric Fiselier    __next_pointer __np = __bucket_list_[__n];
26523e519524SHoward Hinnant    size_type __bc = bucket_count();
26533e519524SHoward Hinnant    size_type __r = 0;
26543e519524SHoward Hinnant    if (__np != nullptr)
26553e519524SHoward Hinnant    {
26563e519524SHoward Hinnant        for (__np = __np->__next_; __np != nullptr &&
265740492ba4SEric Fiselier                                   __constrain_hash(__np->__hash(), __bc) == __n;
265816bf4339SArthur O'Dwyer                                                    __np = __np->__next_, (void) ++__r)
26593e519524SHoward Hinnant            ;
26603e519524SHoward Hinnant    }
26613e519524SHoward Hinnant    return __r;
26623e519524SHoward Hinnant}
26633e519524SHoward Hinnant
26643714107eSHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
26653714107eSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
26663714107eSHoward Hinnantvoid
26673714107eSHoward Hinnantswap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
26683714107eSHoward Hinnant     __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)
26693714107eSHoward Hinnant    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
26703714107eSHoward Hinnant{
26713714107eSHoward Hinnant    __x.swap(__y);
26723714107eSHoward Hinnant}
26733714107eSHoward Hinnant
2674f3966eafSLouis Dionne#ifdef _LIBCPP_ENABLE_DEBUG_MODE
2675b24c8024SHoward Hinnant
2676b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2677b24c8024SHoward Hinnantbool
2678b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const
2679b24c8024SHoward Hinnant{
2680b24c8024SHoward Hinnant    return __i->__node_ != nullptr;
2681b24c8024SHoward Hinnant}
2682b24c8024SHoward Hinnant
2683b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2684b24c8024SHoward Hinnantbool
2685b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const
2686b24c8024SHoward Hinnant{
2687b24c8024SHoward Hinnant    return false;
2688b24c8024SHoward Hinnant}
2689b24c8024SHoward Hinnant
2690b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2691b24c8024SHoward Hinnantbool
2692b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
2693b24c8024SHoward Hinnant{
2694b24c8024SHoward Hinnant    return false;
2695b24c8024SHoward Hinnant}
2696b24c8024SHoward Hinnant
2697b24c8024SHoward Hinnanttemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2698b24c8024SHoward Hinnantbool
2699b24c8024SHoward Hinnant__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
2700b24c8024SHoward Hinnant{
2701b24c8024SHoward Hinnant    return false;
2702b24c8024SHoward Hinnant}
2703b24c8024SHoward Hinnant
2704f3966eafSLouis Dionne#endif // _LIBCPP_ENABLE_DEBUG_MODE
2705a016efb1SEric Fiselier
27063e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
27073e519524SHoward Hinnant
2708a016efb1SEric Fiselier_LIBCPP_POP_MACROS
2709a016efb1SEric Fiselier
2710cc82a1b0SLouis Dionne#endif // _LIBCPP___HASH_TABLE
2711