xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/__hash_table (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1*4d6fc14bSjoerg// -*- C++ -*-
2*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
3*4d6fc14bSjoerg//
4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information.
6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4d6fc14bSjoerg//
8*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
9*4d6fc14bSjoerg
10*4d6fc14bSjoerg#ifndef _LIBCPP__HASH_TABLE
11*4d6fc14bSjoerg#define _LIBCPP__HASH_TABLE
12*4d6fc14bSjoerg
13*4d6fc14bSjoerg#include <__config>
14*4d6fc14bSjoerg#include <initializer_list>
15*4d6fc14bSjoerg#include <memory>
16*4d6fc14bSjoerg#include <iterator>
17*4d6fc14bSjoerg#include <algorithm>
18*4d6fc14bSjoerg#include <cmath>
19*4d6fc14bSjoerg#include <utility>
20*4d6fc14bSjoerg#include <type_traits>
21*4d6fc14bSjoerg
22*4d6fc14bSjoerg#include <__debug>
23*4d6fc14bSjoerg
24*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25*4d6fc14bSjoerg#pragma GCC system_header
26*4d6fc14bSjoerg#endif
27*4d6fc14bSjoerg
28*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS
29*4d6fc14bSjoerg#include <__undef_macros>
30*4d6fc14bSjoerg
31*4d6fc14bSjoerg
32*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD
33*4d6fc14bSjoerg
34*4d6fc14bSjoergtemplate <class _Key, class _Tp>
35*4d6fc14bSjoergstruct __hash_value_type;
36*4d6fc14bSjoerg
37*4d6fc14bSjoergtemplate <class _Tp>
38*4d6fc14bSjoergstruct __is_hash_value_type_imp : false_type {};
39*4d6fc14bSjoerg
40*4d6fc14bSjoergtemplate <class _Key, class _Value>
41*4d6fc14bSjoergstruct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {};
42*4d6fc14bSjoerg
43*4d6fc14bSjoergtemplate <class ..._Args>
44*4d6fc14bSjoergstruct __is_hash_value_type : false_type {};
45*4d6fc14bSjoerg
46*4d6fc14bSjoergtemplate <class _One>
47*4d6fc14bSjoergstruct __is_hash_value_type<_One> : __is_hash_value_type_imp<typename __uncvref<_One>::type> {};
48*4d6fc14bSjoerg
49*4d6fc14bSjoerg_LIBCPP_FUNC_VIS
50*4d6fc14bSjoergsize_t __next_prime(size_t __n);
51*4d6fc14bSjoerg
52*4d6fc14bSjoergtemplate <class _NodePtr>
53*4d6fc14bSjoergstruct __hash_node_base
54*4d6fc14bSjoerg{
55*4d6fc14bSjoerg    typedef typename pointer_traits<_NodePtr>::element_type __node_type;
56*4d6fc14bSjoerg    typedef __hash_node_base __first_node;
57*4d6fc14bSjoerg    typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer;
58*4d6fc14bSjoerg    typedef _NodePtr __node_pointer;
59*4d6fc14bSjoerg
60*4d6fc14bSjoerg#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
61*4d6fc14bSjoerg  typedef __node_base_pointer __next_pointer;
62*4d6fc14bSjoerg#else
63*4d6fc14bSjoerg  typedef typename conditional<
64*4d6fc14bSjoerg      is_pointer<__node_pointer>::value,
65*4d6fc14bSjoerg      __node_base_pointer,
66*4d6fc14bSjoerg      __node_pointer>::type   __next_pointer;
67*4d6fc14bSjoerg#endif
68*4d6fc14bSjoerg
69*4d6fc14bSjoerg    __next_pointer    __next_;
70*4d6fc14bSjoerg
71*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
72*4d6fc14bSjoerg    __next_pointer __ptr() _NOEXCEPT {
73*4d6fc14bSjoerg        return static_cast<__next_pointer>(
74*4d6fc14bSjoerg            pointer_traits<__node_base_pointer>::pointer_to(*this));
75*4d6fc14bSjoerg    }
76*4d6fc14bSjoerg
77*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
78*4d6fc14bSjoerg    __node_pointer __upcast() _NOEXCEPT {
79*4d6fc14bSjoerg        return static_cast<__node_pointer>(
80*4d6fc14bSjoerg            pointer_traits<__node_base_pointer>::pointer_to(*this));
81*4d6fc14bSjoerg    }
82*4d6fc14bSjoerg
83*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
84*4d6fc14bSjoerg    size_t __hash() const _NOEXCEPT {
85*4d6fc14bSjoerg        return static_cast<__node_type const&>(*this).__hash_;
86*4d6fc14bSjoerg    }
87*4d6fc14bSjoerg
88*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
89*4d6fc14bSjoerg};
90*4d6fc14bSjoerg
91*4d6fc14bSjoergtemplate <class _Tp, class _VoidPtr>
92*4d6fc14bSjoergstruct _LIBCPP_STANDALONE_DEBUG __hash_node
93*4d6fc14bSjoerg    : public __hash_node_base
94*4d6fc14bSjoerg             <
95*4d6fc14bSjoerg                 typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type
96*4d6fc14bSjoerg             >
97*4d6fc14bSjoerg{
98*4d6fc14bSjoerg    typedef _Tp __node_value_type;
99*4d6fc14bSjoerg
100*4d6fc14bSjoerg    size_t            __hash_;
101*4d6fc14bSjoerg    __node_value_type __value_;
102*4d6fc14bSjoerg};
103*4d6fc14bSjoerg
104*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
105*4d6fc14bSjoergbool
106*4d6fc14bSjoerg__is_hash_power2(size_t __bc)
107*4d6fc14bSjoerg{
108*4d6fc14bSjoerg    return __bc > 2 && !(__bc & (__bc - 1));
109*4d6fc14bSjoerg}
110*4d6fc14bSjoerg
111*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
112*4d6fc14bSjoergsize_t
113*4d6fc14bSjoerg__constrain_hash(size_t __h, size_t __bc)
114*4d6fc14bSjoerg{
115*4d6fc14bSjoerg    return !(__bc & (__bc - 1)) ? __h & (__bc - 1) :
116*4d6fc14bSjoerg        (__h < __bc ? __h : __h % __bc);
117*4d6fc14bSjoerg}
118*4d6fc14bSjoerg
119*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
120*4d6fc14bSjoergsize_t
121*4d6fc14bSjoerg__next_hash_pow2(size_t __n)
122*4d6fc14bSjoerg{
123*4d6fc14bSjoerg    return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1)));
124*4d6fc14bSjoerg}
125*4d6fc14bSjoerg
126*4d6fc14bSjoerg
127*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
128*4d6fc14bSjoerg
129*4d6fc14bSjoergtemplate <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_iterator;
130*4d6fc14bSjoergtemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
131*4d6fc14bSjoergtemplate <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_local_iterator;
132*4d6fc14bSjoergtemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
133*4d6fc14bSjoergtemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
134*4d6fc14bSjoergtemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
135*4d6fc14bSjoerg
136*4d6fc14bSjoergtemplate <class _Tp>
137*4d6fc14bSjoergstruct __hash_key_value_types {
138*4d6fc14bSjoerg  static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
139*4d6fc14bSjoerg  typedef _Tp key_type;
140*4d6fc14bSjoerg  typedef _Tp __node_value_type;
141*4d6fc14bSjoerg  typedef _Tp __container_value_type;
142*4d6fc14bSjoerg  static const bool __is_map = false;
143*4d6fc14bSjoerg
144*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
145*4d6fc14bSjoerg  static key_type const& __get_key(_Tp const& __v) {
146*4d6fc14bSjoerg    return __v;
147*4d6fc14bSjoerg  }
148*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
149*4d6fc14bSjoerg  static __container_value_type const& __get_value(__node_value_type const& __v) {
150*4d6fc14bSjoerg    return __v;
151*4d6fc14bSjoerg  }
152*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
153*4d6fc14bSjoerg  static __container_value_type* __get_ptr(__node_value_type& __n) {
154*4d6fc14bSjoerg    return _VSTD::addressof(__n);
155*4d6fc14bSjoerg  }
156*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
157*4d6fc14bSjoerg  static __container_value_type&& __move(__node_value_type& __v) {
158*4d6fc14bSjoerg    return _VSTD::move(__v);
159*4d6fc14bSjoerg  }
160*4d6fc14bSjoerg};
161*4d6fc14bSjoerg
162*4d6fc14bSjoergtemplate <class _Key, class _Tp>
163*4d6fc14bSjoergstruct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
164*4d6fc14bSjoerg  typedef _Key                                         key_type;
165*4d6fc14bSjoerg  typedef _Tp                                          mapped_type;
166*4d6fc14bSjoerg  typedef __hash_value_type<_Key, _Tp>                 __node_value_type;
167*4d6fc14bSjoerg  typedef pair<const _Key, _Tp>                        __container_value_type;
168*4d6fc14bSjoerg  typedef __container_value_type                       __map_value_type;
169*4d6fc14bSjoerg  static const bool __is_map = true;
170*4d6fc14bSjoerg
171*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
172*4d6fc14bSjoerg  static key_type const& __get_key(__container_value_type const& __v) {
173*4d6fc14bSjoerg    return __v.first;
174*4d6fc14bSjoerg  }
175*4d6fc14bSjoerg
176*4d6fc14bSjoerg  template <class _Up>
177*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
178*4d6fc14bSjoerg  static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value,
179*4d6fc14bSjoerg      __container_value_type const&>::type
180*4d6fc14bSjoerg  __get_value(_Up& __t) {
181*4d6fc14bSjoerg    return __t.__get_value();
182*4d6fc14bSjoerg  }
183*4d6fc14bSjoerg
184*4d6fc14bSjoerg  template <class _Up>
185*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
186*4d6fc14bSjoerg  static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value,
187*4d6fc14bSjoerg      __container_value_type const&>::type
188*4d6fc14bSjoerg  __get_value(_Up& __t) {
189*4d6fc14bSjoerg    return __t;
190*4d6fc14bSjoerg  }
191*4d6fc14bSjoerg
192*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
193*4d6fc14bSjoerg  static __container_value_type* __get_ptr(__node_value_type& __n) {
194*4d6fc14bSjoerg    return _VSTD::addressof(__n.__get_value());
195*4d6fc14bSjoerg  }
196*4d6fc14bSjoerg  _LIBCPP_INLINE_VISIBILITY
197*4d6fc14bSjoerg  static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
198*4d6fc14bSjoerg    return __v.__move();
199*4d6fc14bSjoerg  }
200*4d6fc14bSjoerg};
201*4d6fc14bSjoerg
202*4d6fc14bSjoergtemplate <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>,
203*4d6fc14bSjoerg          bool = _KVTypes::__is_map>
204*4d6fc14bSjoergstruct __hash_map_pointer_types {};
205*4d6fc14bSjoerg
206*4d6fc14bSjoergtemplate <class _Tp, class _AllocPtr, class _KVTypes>
207*4d6fc14bSjoergstruct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
208*4d6fc14bSjoerg  typedef typename _KVTypes::__map_value_type   _Mv;
209*4d6fc14bSjoerg  typedef typename __rebind_pointer<_AllocPtr, _Mv>::type
210*4d6fc14bSjoerg                                                       __map_value_type_pointer;
211*4d6fc14bSjoerg  typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type
212*4d6fc14bSjoerg                                                 __const_map_value_type_pointer;
213*4d6fc14bSjoerg};
214*4d6fc14bSjoerg
215*4d6fc14bSjoergtemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
216*4d6fc14bSjoergstruct __hash_node_types;
217*4d6fc14bSjoerg
218*4d6fc14bSjoergtemplate <class _NodePtr, class _Tp, class _VoidPtr>
219*4d6fc14bSjoergstruct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> >
220*4d6fc14bSjoerg    : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr>
221*4d6fc14bSjoerg
222*4d6fc14bSjoerg{
223*4d6fc14bSjoerg  typedef __hash_key_value_types<_Tp>           __base;
224*4d6fc14bSjoerg
225*4d6fc14bSjoergpublic:
226*4d6fc14bSjoerg  typedef ptrdiff_t difference_type;
227*4d6fc14bSjoerg  typedef size_t size_type;
228*4d6fc14bSjoerg
229*4d6fc14bSjoerg  typedef typename __rebind_pointer<_NodePtr, void>::type       __void_pointer;
230*4d6fc14bSjoerg
231*4d6fc14bSjoerg  typedef typename pointer_traits<_NodePtr>::element_type       __node_type;
232*4d6fc14bSjoerg  typedef _NodePtr                                              __node_pointer;
233*4d6fc14bSjoerg
234*4d6fc14bSjoerg  typedef __hash_node_base<__node_pointer>                      __node_base_type;
235*4d6fc14bSjoerg  typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type
236*4d6fc14bSjoerg                                                             __node_base_pointer;
237*4d6fc14bSjoerg
238*4d6fc14bSjoerg  typedef typename __node_base_type::__next_pointer          __next_pointer;
239*4d6fc14bSjoerg
240*4d6fc14bSjoerg  typedef _Tp                                                 __node_value_type;
241*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
242*4d6fc14bSjoerg                                                      __node_value_type_pointer;
243*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
244*4d6fc14bSjoerg                                                __const_node_value_type_pointer;
245*4d6fc14bSjoerg
246*4d6fc14bSjoergprivate:
247*4d6fc14bSjoerg    static_assert(!is_const<__node_type>::value,
248*4d6fc14bSjoerg                "_NodePtr should never be a pointer to const");
249*4d6fc14bSjoerg    static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
250*4d6fc14bSjoerg                  "_VoidPtr does not point to unqualified void type");
251*4d6fc14bSjoerg    static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type,
252*4d6fc14bSjoerg                          _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
253*4d6fc14bSjoerg};
254*4d6fc14bSjoerg
255*4d6fc14bSjoergtemplate <class _HashIterator>
256*4d6fc14bSjoergstruct __hash_node_types_from_iterator;
257*4d6fc14bSjoergtemplate <class _NodePtr>
258*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
259*4d6fc14bSjoergtemplate <class _NodePtr>
260*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
261*4d6fc14bSjoergtemplate <class _NodePtr>
262*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
263*4d6fc14bSjoergtemplate <class _NodePtr>
264*4d6fc14bSjoergstruct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
265*4d6fc14bSjoerg
266*4d6fc14bSjoerg
267*4d6fc14bSjoergtemplate <class _NodeValueTp, class _VoidPtr>
268*4d6fc14bSjoergstruct __make_hash_node_types {
269*4d6fc14bSjoerg  typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp;
270*4d6fc14bSjoerg  typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr;
271*4d6fc14bSjoerg  typedef __hash_node_types<_NodePtr> type;
272*4d6fc14bSjoerg};
273*4d6fc14bSjoerg
274*4d6fc14bSjoergtemplate <class _NodePtr>
275*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_iterator
276*4d6fc14bSjoerg{
277*4d6fc14bSjoerg    typedef __hash_node_types<_NodePtr> _NodeTypes;
278*4d6fc14bSjoerg    typedef _NodePtr                            __node_pointer;
279*4d6fc14bSjoerg    typedef typename _NodeTypes::__next_pointer __next_pointer;
280*4d6fc14bSjoerg
281*4d6fc14bSjoerg    __next_pointer            __node_;
282*4d6fc14bSjoerg
283*4d6fc14bSjoergpublic:
284*4d6fc14bSjoerg    typedef forward_iterator_tag                           iterator_category;
285*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type         value_type;
286*4d6fc14bSjoerg    typedef typename _NodeTypes::difference_type           difference_type;
287*4d6fc14bSjoerg    typedef value_type&                                    reference;
288*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type_pointer pointer;
289*4d6fc14bSjoerg
290*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) {
291*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
292*4d6fc14bSjoerg        __get_db()->__insert_i(this);
293*4d6fc14bSjoerg#endif
294*4d6fc14bSjoerg    }
295*4d6fc14bSjoerg
296*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
297*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
298*4d6fc14bSjoerg    __hash_iterator(const __hash_iterator& __i)
299*4d6fc14bSjoerg        : __node_(__i.__node_)
300*4d6fc14bSjoerg    {
301*4d6fc14bSjoerg        __get_db()->__iterator_copy(this, &__i);
302*4d6fc14bSjoerg    }
303*4d6fc14bSjoerg
304*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
305*4d6fc14bSjoerg    ~__hash_iterator()
306*4d6fc14bSjoerg    {
307*4d6fc14bSjoerg        __get_db()->__erase_i(this);
308*4d6fc14bSjoerg    }
309*4d6fc14bSjoerg
310*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
311*4d6fc14bSjoerg    __hash_iterator& operator=(const __hash_iterator& __i)
312*4d6fc14bSjoerg    {
313*4d6fc14bSjoerg        if (this != &__i)
314*4d6fc14bSjoerg        {
315*4d6fc14bSjoerg            __get_db()->__iterator_copy(this, &__i);
316*4d6fc14bSjoerg            __node_ = __i.__node_;
317*4d6fc14bSjoerg        }
318*4d6fc14bSjoerg        return *this;
319*4d6fc14bSjoerg    }
320*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2
321*4d6fc14bSjoerg
322*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
323*4d6fc14bSjoerg    reference operator*() const {
324*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
325*4d6fc14bSjoerg                             "Attempted to dereference a non-dereferenceable unordered container iterator");
326*4d6fc14bSjoerg        return __node_->__upcast()->__value_;
327*4d6fc14bSjoerg    }
328*4d6fc14bSjoerg
329*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
330*4d6fc14bSjoerg    pointer operator->() const {
331*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
332*4d6fc14bSjoerg                           "Attempted to dereference a non-dereferenceable unordered container iterator");
333*4d6fc14bSjoerg        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
334*4d6fc14bSjoerg    }
335*4d6fc14bSjoerg
336*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
337*4d6fc14bSjoerg    __hash_iterator& operator++() {
338*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
339*4d6fc14bSjoerg                       "Attempted to increment a non-incrementable unordered container iterator");
340*4d6fc14bSjoerg        __node_ = __node_->__next_;
341*4d6fc14bSjoerg        return *this;
342*4d6fc14bSjoerg    }
343*4d6fc14bSjoerg
344*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
345*4d6fc14bSjoerg    __hash_iterator operator++(int)
346*4d6fc14bSjoerg    {
347*4d6fc14bSjoerg        __hash_iterator __t(*this);
348*4d6fc14bSjoerg        ++(*this);
349*4d6fc14bSjoerg        return __t;
350*4d6fc14bSjoerg    }
351*4d6fc14bSjoerg
352*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
353*4d6fc14bSjoerg    bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)
354*4d6fc14bSjoerg    {
355*4d6fc14bSjoerg        return __x.__node_ == __y.__node_;
356*4d6fc14bSjoerg    }
357*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
358*4d6fc14bSjoerg    bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)
359*4d6fc14bSjoerg        {return !(__x == __y);}
360*4d6fc14bSjoerg
361*4d6fc14bSjoergprivate:
362*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
363*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
364*4d6fc14bSjoerg    __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
365*4d6fc14bSjoerg        : __node_(__node)
366*4d6fc14bSjoerg        {
367*4d6fc14bSjoerg            __get_db()->__insert_ic(this, __c);
368*4d6fc14bSjoerg        }
369*4d6fc14bSjoerg#else
370*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
371*4d6fc14bSjoerg    __hash_iterator(__next_pointer __node) _NOEXCEPT
372*4d6fc14bSjoerg        : __node_(__node)
373*4d6fc14bSjoerg        {}
374*4d6fc14bSjoerg#endif
375*4d6fc14bSjoerg    template <class, class, class, class> friend class __hash_table;
376*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
377*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
378*4d6fc14bSjoerg    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
379*4d6fc14bSjoerg    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
380*4d6fc14bSjoerg};
381*4d6fc14bSjoerg
382*4d6fc14bSjoergtemplate <class _NodePtr>
383*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_const_iterator
384*4d6fc14bSjoerg{
385*4d6fc14bSjoerg    static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, "");
386*4d6fc14bSjoerg    typedef __hash_node_types<_NodePtr> _NodeTypes;
387*4d6fc14bSjoerg    typedef _NodePtr                            __node_pointer;
388*4d6fc14bSjoerg    typedef typename _NodeTypes::__next_pointer __next_pointer;
389*4d6fc14bSjoerg
390*4d6fc14bSjoerg    __next_pointer __node_;
391*4d6fc14bSjoerg
392*4d6fc14bSjoergpublic:
393*4d6fc14bSjoerg    typedef __hash_iterator<_NodePtr> __non_const_iterator;
394*4d6fc14bSjoerg
395*4d6fc14bSjoerg    typedef forward_iterator_tag                                 iterator_category;
396*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type               value_type;
397*4d6fc14bSjoerg    typedef typename _NodeTypes::difference_type                 difference_type;
398*4d6fc14bSjoerg    typedef const value_type&                                    reference;
399*4d6fc14bSjoerg    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
400*4d6fc14bSjoerg
401*4d6fc14bSjoerg
402*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {
403*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
404*4d6fc14bSjoerg        __get_db()->__insert_i(this);
405*4d6fc14bSjoerg#endif
406*4d6fc14bSjoerg    }
407*4d6fc14bSjoerg
408*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
409*4d6fc14bSjoerg    __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
410*4d6fc14bSjoerg        : __node_(__x.__node_)
411*4d6fc14bSjoerg    {
412*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
413*4d6fc14bSjoerg        __get_db()->__iterator_copy(this, &__x);
414*4d6fc14bSjoerg#endif
415*4d6fc14bSjoerg    }
416*4d6fc14bSjoerg
417*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
418*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
419*4d6fc14bSjoerg    __hash_const_iterator(const __hash_const_iterator& __i)
420*4d6fc14bSjoerg        : __node_(__i.__node_)
421*4d6fc14bSjoerg    {
422*4d6fc14bSjoerg        __get_db()->__iterator_copy(this, &__i);
423*4d6fc14bSjoerg    }
424*4d6fc14bSjoerg
425*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
426*4d6fc14bSjoerg    ~__hash_const_iterator()
427*4d6fc14bSjoerg    {
428*4d6fc14bSjoerg        __get_db()->__erase_i(this);
429*4d6fc14bSjoerg    }
430*4d6fc14bSjoerg
431*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
432*4d6fc14bSjoerg    __hash_const_iterator& operator=(const __hash_const_iterator& __i)
433*4d6fc14bSjoerg    {
434*4d6fc14bSjoerg        if (this != &__i)
435*4d6fc14bSjoerg        {
436*4d6fc14bSjoerg            __get_db()->__iterator_copy(this, &__i);
437*4d6fc14bSjoerg            __node_ = __i.__node_;
438*4d6fc14bSjoerg        }
439*4d6fc14bSjoerg        return *this;
440*4d6fc14bSjoerg    }
441*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2
442*4d6fc14bSjoerg
443*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
444*4d6fc14bSjoerg    reference operator*() const {
445*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
446*4d6fc14bSjoerg                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
447*4d6fc14bSjoerg        return __node_->__upcast()->__value_;
448*4d6fc14bSjoerg    }
449*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
450*4d6fc14bSjoerg    pointer operator->() const {
451*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
452*4d6fc14bSjoerg                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
453*4d6fc14bSjoerg        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
454*4d6fc14bSjoerg    }
455*4d6fc14bSjoerg
456*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
457*4d6fc14bSjoerg    __hash_const_iterator& operator++() {
458*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
459*4d6fc14bSjoerg                             "Attempted to increment a non-incrementable unordered container const_iterator");
460*4d6fc14bSjoerg        __node_ = __node_->__next_;
461*4d6fc14bSjoerg        return *this;
462*4d6fc14bSjoerg    }
463*4d6fc14bSjoerg
464*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
465*4d6fc14bSjoerg    __hash_const_iterator operator++(int)
466*4d6fc14bSjoerg    {
467*4d6fc14bSjoerg        __hash_const_iterator __t(*this);
468*4d6fc14bSjoerg        ++(*this);
469*4d6fc14bSjoerg        return __t;
470*4d6fc14bSjoerg    }
471*4d6fc14bSjoerg
472*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
473*4d6fc14bSjoerg    bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
474*4d6fc14bSjoerg    {
475*4d6fc14bSjoerg        return __x.__node_ == __y.__node_;
476*4d6fc14bSjoerg    }
477*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
478*4d6fc14bSjoerg    bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
479*4d6fc14bSjoerg        {return !(__x == __y);}
480*4d6fc14bSjoerg
481*4d6fc14bSjoergprivate:
482*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
483*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
484*4d6fc14bSjoerg    __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
485*4d6fc14bSjoerg        : __node_(__node)
486*4d6fc14bSjoerg        {
487*4d6fc14bSjoerg            __get_db()->__insert_ic(this, __c);
488*4d6fc14bSjoerg        }
489*4d6fc14bSjoerg#else
490*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
491*4d6fc14bSjoerg    __hash_const_iterator(__next_pointer __node) _NOEXCEPT
492*4d6fc14bSjoerg        : __node_(__node)
493*4d6fc14bSjoerg        {}
494*4d6fc14bSjoerg#endif
495*4d6fc14bSjoerg    template <class, class, class, class> friend class __hash_table;
496*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
497*4d6fc14bSjoerg    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
498*4d6fc14bSjoerg    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
499*4d6fc14bSjoerg};
500*4d6fc14bSjoerg
501*4d6fc14bSjoergtemplate <class _NodePtr>
502*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_local_iterator
503*4d6fc14bSjoerg{
504*4d6fc14bSjoerg    typedef __hash_node_types<_NodePtr> _NodeTypes;
505*4d6fc14bSjoerg    typedef _NodePtr                            __node_pointer;
506*4d6fc14bSjoerg    typedef typename _NodeTypes::__next_pointer __next_pointer;
507*4d6fc14bSjoerg
508*4d6fc14bSjoerg    __next_pointer         __node_;
509*4d6fc14bSjoerg    size_t                 __bucket_;
510*4d6fc14bSjoerg    size_t                 __bucket_count_;
511*4d6fc14bSjoerg
512*4d6fc14bSjoergpublic:
513*4d6fc14bSjoerg    typedef forward_iterator_tag                                iterator_category;
514*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type              value_type;
515*4d6fc14bSjoerg    typedef typename _NodeTypes::difference_type                difference_type;
516*4d6fc14bSjoerg    typedef value_type&                                         reference;
517*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type_pointer      pointer;
518*4d6fc14bSjoerg
519*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {
520*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
521*4d6fc14bSjoerg        __get_db()->__insert_i(this);
522*4d6fc14bSjoerg#endif
523*4d6fc14bSjoerg    }
524*4d6fc14bSjoerg
525*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
526*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
527*4d6fc14bSjoerg    __hash_local_iterator(const __hash_local_iterator& __i)
528*4d6fc14bSjoerg        : __node_(__i.__node_),
529*4d6fc14bSjoerg          __bucket_(__i.__bucket_),
530*4d6fc14bSjoerg          __bucket_count_(__i.__bucket_count_)
531*4d6fc14bSjoerg    {
532*4d6fc14bSjoerg        __get_db()->__iterator_copy(this, &__i);
533*4d6fc14bSjoerg    }
534*4d6fc14bSjoerg
535*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
536*4d6fc14bSjoerg    ~__hash_local_iterator()
537*4d6fc14bSjoerg    {
538*4d6fc14bSjoerg        __get_db()->__erase_i(this);
539*4d6fc14bSjoerg    }
540*4d6fc14bSjoerg
541*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
542*4d6fc14bSjoerg    __hash_local_iterator& operator=(const __hash_local_iterator& __i)
543*4d6fc14bSjoerg    {
544*4d6fc14bSjoerg        if (this != &__i)
545*4d6fc14bSjoerg        {
546*4d6fc14bSjoerg            __get_db()->__iterator_copy(this, &__i);
547*4d6fc14bSjoerg            __node_ = __i.__node_;
548*4d6fc14bSjoerg            __bucket_ = __i.__bucket_;
549*4d6fc14bSjoerg            __bucket_count_ = __i.__bucket_count_;
550*4d6fc14bSjoerg        }
551*4d6fc14bSjoerg        return *this;
552*4d6fc14bSjoerg    }
553*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2
554*4d6fc14bSjoerg
555*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
556*4d6fc14bSjoerg    reference operator*() const {
557*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
558*4d6fc14bSjoerg                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
559*4d6fc14bSjoerg        return __node_->__upcast()->__value_;
560*4d6fc14bSjoerg    }
561*4d6fc14bSjoerg
562*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
563*4d6fc14bSjoerg    pointer operator->() const {
564*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
565*4d6fc14bSjoerg                             "Attempted to dereference a non-dereferenceable unordered container local_iterator");
566*4d6fc14bSjoerg        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
567*4d6fc14bSjoerg    }
568*4d6fc14bSjoerg
569*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
570*4d6fc14bSjoerg    __hash_local_iterator& operator++() {
571*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
572*4d6fc14bSjoerg                       "Attempted to increment a non-incrementable unordered container local_iterator");
573*4d6fc14bSjoerg        __node_ = __node_->__next_;
574*4d6fc14bSjoerg        if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
575*4d6fc14bSjoerg            __node_ = nullptr;
576*4d6fc14bSjoerg        return *this;
577*4d6fc14bSjoerg    }
578*4d6fc14bSjoerg
579*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
580*4d6fc14bSjoerg    __hash_local_iterator operator++(int)
581*4d6fc14bSjoerg    {
582*4d6fc14bSjoerg        __hash_local_iterator __t(*this);
583*4d6fc14bSjoerg        ++(*this);
584*4d6fc14bSjoerg        return __t;
585*4d6fc14bSjoerg    }
586*4d6fc14bSjoerg
587*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
588*4d6fc14bSjoerg    bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
589*4d6fc14bSjoerg    {
590*4d6fc14bSjoerg        return __x.__node_ == __y.__node_;
591*4d6fc14bSjoerg    }
592*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
593*4d6fc14bSjoerg    bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
594*4d6fc14bSjoerg        {return !(__x == __y);}
595*4d6fc14bSjoerg
596*4d6fc14bSjoergprivate:
597*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
598*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
599*4d6fc14bSjoerg    __hash_local_iterator(__next_pointer __node, size_t __bucket,
600*4d6fc14bSjoerg                          size_t __bucket_count, const void* __c) _NOEXCEPT
601*4d6fc14bSjoerg        : __node_(__node),
602*4d6fc14bSjoerg          __bucket_(__bucket),
603*4d6fc14bSjoerg          __bucket_count_(__bucket_count)
604*4d6fc14bSjoerg        {
605*4d6fc14bSjoerg            __get_db()->__insert_ic(this, __c);
606*4d6fc14bSjoerg            if (__node_ != nullptr)
607*4d6fc14bSjoerg                __node_ = __node_->__next_;
608*4d6fc14bSjoerg        }
609*4d6fc14bSjoerg#else
610*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
611*4d6fc14bSjoerg    __hash_local_iterator(__next_pointer __node, size_t __bucket,
612*4d6fc14bSjoerg                          size_t __bucket_count) _NOEXCEPT
613*4d6fc14bSjoerg        : __node_(__node),
614*4d6fc14bSjoerg          __bucket_(__bucket),
615*4d6fc14bSjoerg          __bucket_count_(__bucket_count)
616*4d6fc14bSjoerg        {
617*4d6fc14bSjoerg            if (__node_ != nullptr)
618*4d6fc14bSjoerg                __node_ = __node_->__next_;
619*4d6fc14bSjoerg        }
620*4d6fc14bSjoerg#endif
621*4d6fc14bSjoerg    template <class, class, class, class> friend class __hash_table;
622*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
623*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
624*4d6fc14bSjoerg};
625*4d6fc14bSjoerg
626*4d6fc14bSjoergtemplate <class _ConstNodePtr>
627*4d6fc14bSjoergclass _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator
628*4d6fc14bSjoerg{
629*4d6fc14bSjoerg    typedef __hash_node_types<_ConstNodePtr> _NodeTypes;
630*4d6fc14bSjoerg    typedef _ConstNodePtr                       __node_pointer;
631*4d6fc14bSjoerg    typedef typename _NodeTypes::__next_pointer __next_pointer;
632*4d6fc14bSjoerg
633*4d6fc14bSjoerg    __next_pointer         __node_;
634*4d6fc14bSjoerg    size_t                 __bucket_;
635*4d6fc14bSjoerg    size_t                 __bucket_count_;
636*4d6fc14bSjoerg
637*4d6fc14bSjoerg    typedef pointer_traits<__node_pointer>          __pointer_traits;
638*4d6fc14bSjoerg    typedef typename __pointer_traits::element_type __node;
639*4d6fc14bSjoerg    typedef typename remove_const<__node>::type     __non_const_node;
640*4d6fc14bSjoerg    typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type
641*4d6fc14bSjoerg        __non_const_node_pointer;
642*4d6fc14bSjoergpublic:
643*4d6fc14bSjoerg    typedef __hash_local_iterator<__non_const_node_pointer>
644*4d6fc14bSjoerg                                                    __non_const_iterator;
645*4d6fc14bSjoerg
646*4d6fc14bSjoerg    typedef forward_iterator_tag                                 iterator_category;
647*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type               value_type;
648*4d6fc14bSjoerg    typedef typename _NodeTypes::difference_type                 difference_type;
649*4d6fc14bSjoerg    typedef const value_type&                                    reference;
650*4d6fc14bSjoerg    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
651*4d6fc14bSjoerg
652*4d6fc14bSjoerg
653*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {
654*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
655*4d6fc14bSjoerg        __get_db()->__insert_i(this);
656*4d6fc14bSjoerg#endif
657*4d6fc14bSjoerg    }
658*4d6fc14bSjoerg
659*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
660*4d6fc14bSjoerg    __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
661*4d6fc14bSjoerg        : __node_(__x.__node_),
662*4d6fc14bSjoerg          __bucket_(__x.__bucket_),
663*4d6fc14bSjoerg          __bucket_count_(__x.__bucket_count_)
664*4d6fc14bSjoerg    {
665*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
666*4d6fc14bSjoerg        __get_db()->__iterator_copy(this, &__x);
667*4d6fc14bSjoerg#endif
668*4d6fc14bSjoerg    }
669*4d6fc14bSjoerg
670*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
671*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
672*4d6fc14bSjoerg    __hash_const_local_iterator(const __hash_const_local_iterator& __i)
673*4d6fc14bSjoerg        : __node_(__i.__node_),
674*4d6fc14bSjoerg          __bucket_(__i.__bucket_),
675*4d6fc14bSjoerg          __bucket_count_(__i.__bucket_count_)
676*4d6fc14bSjoerg    {
677*4d6fc14bSjoerg        __get_db()->__iterator_copy(this, &__i);
678*4d6fc14bSjoerg    }
679*4d6fc14bSjoerg
680*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
681*4d6fc14bSjoerg    ~__hash_const_local_iterator()
682*4d6fc14bSjoerg    {
683*4d6fc14bSjoerg        __get_db()->__erase_i(this);
684*4d6fc14bSjoerg    }
685*4d6fc14bSjoerg
686*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
687*4d6fc14bSjoerg    __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)
688*4d6fc14bSjoerg    {
689*4d6fc14bSjoerg        if (this != &__i)
690*4d6fc14bSjoerg        {
691*4d6fc14bSjoerg            __get_db()->__iterator_copy(this, &__i);
692*4d6fc14bSjoerg            __node_ = __i.__node_;
693*4d6fc14bSjoerg            __bucket_ = __i.__bucket_;
694*4d6fc14bSjoerg            __bucket_count_ = __i.__bucket_count_;
695*4d6fc14bSjoerg        }
696*4d6fc14bSjoerg        return *this;
697*4d6fc14bSjoerg    }
698*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2
699*4d6fc14bSjoerg
700*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
701*4d6fc14bSjoerg    reference operator*() const {
702*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
703*4d6fc14bSjoerg                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
704*4d6fc14bSjoerg        return __node_->__upcast()->__value_;
705*4d6fc14bSjoerg    }
706*4d6fc14bSjoerg
707*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
708*4d6fc14bSjoerg    pointer operator->() const {
709*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
710*4d6fc14bSjoerg                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
711*4d6fc14bSjoerg        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
712*4d6fc14bSjoerg    }
713*4d6fc14bSjoerg
714*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
715*4d6fc14bSjoerg    __hash_const_local_iterator& operator++() {
716*4d6fc14bSjoerg        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
717*4d6fc14bSjoerg                       "Attempted to increment a non-incrementable unordered container const_local_iterator");
718*4d6fc14bSjoerg        __node_ = __node_->__next_;
719*4d6fc14bSjoerg        if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
720*4d6fc14bSjoerg            __node_ = nullptr;
721*4d6fc14bSjoerg        return *this;
722*4d6fc14bSjoerg    }
723*4d6fc14bSjoerg
724*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
725*4d6fc14bSjoerg    __hash_const_local_iterator operator++(int)
726*4d6fc14bSjoerg    {
727*4d6fc14bSjoerg        __hash_const_local_iterator __t(*this);
728*4d6fc14bSjoerg        ++(*this);
729*4d6fc14bSjoerg        return __t;
730*4d6fc14bSjoerg    }
731*4d6fc14bSjoerg
732*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
733*4d6fc14bSjoerg    bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
734*4d6fc14bSjoerg    {
735*4d6fc14bSjoerg        return __x.__node_ == __y.__node_;
736*4d6fc14bSjoerg    }
737*4d6fc14bSjoerg    friend _LIBCPP_INLINE_VISIBILITY
738*4d6fc14bSjoerg    bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
739*4d6fc14bSjoerg        {return !(__x == __y);}
740*4d6fc14bSjoerg
741*4d6fc14bSjoergprivate:
742*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
743*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
744*4d6fc14bSjoerg    __hash_const_local_iterator(__next_pointer __node, size_t __bucket,
745*4d6fc14bSjoerg                                size_t __bucket_count, const void* __c) _NOEXCEPT
746*4d6fc14bSjoerg        : __node_(__node),
747*4d6fc14bSjoerg          __bucket_(__bucket),
748*4d6fc14bSjoerg          __bucket_count_(__bucket_count)
749*4d6fc14bSjoerg        {
750*4d6fc14bSjoerg            __get_db()->__insert_ic(this, __c);
751*4d6fc14bSjoerg            if (__node_ != nullptr)
752*4d6fc14bSjoerg                __node_ = __node_->__next_;
753*4d6fc14bSjoerg        }
754*4d6fc14bSjoerg#else
755*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
756*4d6fc14bSjoerg    __hash_const_local_iterator(__next_pointer __node, size_t __bucket,
757*4d6fc14bSjoerg                                size_t __bucket_count) _NOEXCEPT
758*4d6fc14bSjoerg        : __node_(__node),
759*4d6fc14bSjoerg          __bucket_(__bucket),
760*4d6fc14bSjoerg          __bucket_count_(__bucket_count)
761*4d6fc14bSjoerg        {
762*4d6fc14bSjoerg            if (__node_ != nullptr)
763*4d6fc14bSjoerg                __node_ = __node_->__next_;
764*4d6fc14bSjoerg        }
765*4d6fc14bSjoerg#endif
766*4d6fc14bSjoerg    template <class, class, class, class> friend class __hash_table;
767*4d6fc14bSjoerg    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
768*4d6fc14bSjoerg};
769*4d6fc14bSjoerg
770*4d6fc14bSjoergtemplate <class _Alloc>
771*4d6fc14bSjoergclass __bucket_list_deallocator
772*4d6fc14bSjoerg{
773*4d6fc14bSjoerg    typedef _Alloc                                          allocator_type;
774*4d6fc14bSjoerg    typedef allocator_traits<allocator_type>                __alloc_traits;
775*4d6fc14bSjoerg    typedef typename __alloc_traits::size_type              size_type;
776*4d6fc14bSjoerg
777*4d6fc14bSjoerg    __compressed_pair<size_type, allocator_type> __data_;
778*4d6fc14bSjoergpublic:
779*4d6fc14bSjoerg    typedef typename __alloc_traits::pointer pointer;
780*4d6fc14bSjoerg
781*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
782*4d6fc14bSjoerg    __bucket_list_deallocator()
783*4d6fc14bSjoerg        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
784*4d6fc14bSjoerg        : __data_(0, __default_init_tag()) {}
785*4d6fc14bSjoerg
786*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
787*4d6fc14bSjoerg    __bucket_list_deallocator(const allocator_type& __a, size_type __size)
788*4d6fc14bSjoerg        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
789*4d6fc14bSjoerg        : __data_(__size, __a) {}
790*4d6fc14bSjoerg
791*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
792*4d6fc14bSjoerg    __bucket_list_deallocator(__bucket_list_deallocator&& __x)
793*4d6fc14bSjoerg        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
794*4d6fc14bSjoerg        : __data_(_VSTD::move(__x.__data_))
795*4d6fc14bSjoerg    {
796*4d6fc14bSjoerg        __x.size() = 0;
797*4d6fc14bSjoerg    }
798*4d6fc14bSjoerg
799*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
800*4d6fc14bSjoerg    size_type& size() _NOEXCEPT {return __data_.first();}
801*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
802*4d6fc14bSjoerg    size_type  size() const _NOEXCEPT {return __data_.first();}
803*4d6fc14bSjoerg
804*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
805*4d6fc14bSjoerg    allocator_type& __alloc() _NOEXCEPT {return __data_.second();}
806*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
807*4d6fc14bSjoerg    const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();}
808*4d6fc14bSjoerg
809*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
810*4d6fc14bSjoerg    void operator()(pointer __p) _NOEXCEPT
811*4d6fc14bSjoerg    {
812*4d6fc14bSjoerg        __alloc_traits::deallocate(__alloc(), __p, size());
813*4d6fc14bSjoerg    }
814*4d6fc14bSjoerg};
815*4d6fc14bSjoerg
816*4d6fc14bSjoergtemplate <class _Alloc> class __hash_map_node_destructor;
817*4d6fc14bSjoerg
818*4d6fc14bSjoergtemplate <class _Alloc>
819*4d6fc14bSjoergclass __hash_node_destructor
820*4d6fc14bSjoerg{
821*4d6fc14bSjoerg    typedef _Alloc                                          allocator_type;
822*4d6fc14bSjoerg    typedef allocator_traits<allocator_type>                __alloc_traits;
823*4d6fc14bSjoerg
824*4d6fc14bSjoergpublic:
825*4d6fc14bSjoerg    typedef typename __alloc_traits::pointer                pointer;
826*4d6fc14bSjoergprivate:
827*4d6fc14bSjoerg    typedef __hash_node_types<pointer> _NodeTypes;
828*4d6fc14bSjoerg
829*4d6fc14bSjoerg    allocator_type& __na_;
830*4d6fc14bSjoerg
831*4d6fc14bSjoergpublic:
832*4d6fc14bSjoerg    bool __value_constructed;
833*4d6fc14bSjoerg
834*4d6fc14bSjoerg    __hash_node_destructor(__hash_node_destructor const&) = default;
835*4d6fc14bSjoerg    __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
836*4d6fc14bSjoerg
837*4d6fc14bSjoerg
838*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
839*4d6fc14bSjoerg    explicit __hash_node_destructor(allocator_type& __na,
840*4d6fc14bSjoerg                                    bool __constructed = false) _NOEXCEPT
841*4d6fc14bSjoerg        : __na_(__na),
842*4d6fc14bSjoerg          __value_constructed(__constructed)
843*4d6fc14bSjoerg        {}
844*4d6fc14bSjoerg
845*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
846*4d6fc14bSjoerg    void operator()(pointer __p) _NOEXCEPT
847*4d6fc14bSjoerg    {
848*4d6fc14bSjoerg        if (__value_constructed)
849*4d6fc14bSjoerg            __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
850*4d6fc14bSjoerg        if (__p)
851*4d6fc14bSjoerg            __alloc_traits::deallocate(__na_, __p, 1);
852*4d6fc14bSjoerg    }
853*4d6fc14bSjoerg
854*4d6fc14bSjoerg    template <class> friend class __hash_map_node_destructor;
855*4d6fc14bSjoerg};
856*4d6fc14bSjoerg
857*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14
858*4d6fc14bSjoergtemplate <class _NodeType, class _Alloc>
859*4d6fc14bSjoergstruct __generic_container_node_destructor;
860*4d6fc14bSjoerg
861*4d6fc14bSjoergtemplate <class _Tp, class _VoidPtr, class _Alloc>
862*4d6fc14bSjoergstruct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
863*4d6fc14bSjoerg    : __hash_node_destructor<_Alloc>
864*4d6fc14bSjoerg{
865*4d6fc14bSjoerg    using __hash_node_destructor<_Alloc>::__hash_node_destructor;
866*4d6fc14bSjoerg};
867*4d6fc14bSjoerg#endif
868*4d6fc14bSjoerg
869*4d6fc14bSjoergtemplate <class _Key, class _Hash, class _Equal>
870*4d6fc14bSjoergstruct __enforce_unordered_container_requirements {
871*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
872*4d6fc14bSjoerg    static_assert(__check_hash_requirements<_Key, _Hash>::value,
873*4d6fc14bSjoerg    "the specified hash does not meet the Hash requirements");
874*4d6fc14bSjoerg    static_assert(is_copy_constructible<_Equal>::value,
875*4d6fc14bSjoerg    "the specified comparator is required to be copy constructible");
876*4d6fc14bSjoerg#endif
877*4d6fc14bSjoerg    typedef int type;
878*4d6fc14bSjoerg};
879*4d6fc14bSjoerg
880*4d6fc14bSjoergtemplate <class _Key, class _Hash, class _Equal>
881*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
882*4d6fc14bSjoerg    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
883*4d6fc14bSjoerg    "the specified comparator type does not provide a viable const call operator")
884*4d6fc14bSjoerg    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
885*4d6fc14bSjoerg    "the specified hash functor does not provide a viable const call operator")
886*4d6fc14bSjoerg#endif
887*4d6fc14bSjoergtypename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
888*4d6fc14bSjoerg__diagnose_unordered_container_requirements(int);
889*4d6fc14bSjoerg
890*4d6fc14bSjoerg// This dummy overload is used so that the compiler won't emit a spurious
891*4d6fc14bSjoerg// "no matching function for call to __diagnose_unordered_xxx" diagnostic
892*4d6fc14bSjoerg// when the overload above causes a hard error.
893*4d6fc14bSjoergtemplate <class _Key, class _Hash, class _Equal>
894*4d6fc14bSjoergint __diagnose_unordered_container_requirements(void*);
895*4d6fc14bSjoerg
896*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
897*4d6fc14bSjoergclass __hash_table
898*4d6fc14bSjoerg{
899*4d6fc14bSjoergpublic:
900*4d6fc14bSjoerg    typedef _Tp    value_type;
901*4d6fc14bSjoerg    typedef _Hash  hasher;
902*4d6fc14bSjoerg    typedef _Equal key_equal;
903*4d6fc14bSjoerg    typedef _Alloc allocator_type;
904*4d6fc14bSjoerg
905*4d6fc14bSjoergprivate:
906*4d6fc14bSjoerg    typedef allocator_traits<allocator_type> __alloc_traits;
907*4d6fc14bSjoerg    typedef typename
908*4d6fc14bSjoerg      __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type
909*4d6fc14bSjoerg                                                                     _NodeTypes;
910*4d6fc14bSjoergpublic:
911*4d6fc14bSjoerg
912*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_value_type           __node_value_type;
913*4d6fc14bSjoerg    typedef typename _NodeTypes::__container_value_type      __container_value_type;
914*4d6fc14bSjoerg    typedef typename _NodeTypes::key_type                    key_type;
915*4d6fc14bSjoerg    typedef value_type&                              reference;
916*4d6fc14bSjoerg    typedef const value_type&                        const_reference;
917*4d6fc14bSjoerg    typedef typename __alloc_traits::pointer         pointer;
918*4d6fc14bSjoerg    typedef typename __alloc_traits::const_pointer   const_pointer;
919*4d6fc14bSjoerg#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
920*4d6fc14bSjoerg    typedef typename __alloc_traits::size_type       size_type;
921*4d6fc14bSjoerg#else
922*4d6fc14bSjoerg    typedef typename _NodeTypes::size_type           size_type;
923*4d6fc14bSjoerg#endif
924*4d6fc14bSjoerg    typedef typename _NodeTypes::difference_type     difference_type;
925*4d6fc14bSjoergpublic:
926*4d6fc14bSjoerg    // Create __node
927*4d6fc14bSjoerg
928*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_type __node;
929*4d6fc14bSjoerg    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
930*4d6fc14bSjoerg    typedef allocator_traits<__node_allocator>       __node_traits;
931*4d6fc14bSjoerg    typedef typename _NodeTypes::__void_pointer      __void_pointer;
932*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_pointer      __node_pointer;
933*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_pointer      __node_const_pointer;
934*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_base_type    __first_node;
935*4d6fc14bSjoerg    typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
936*4d6fc14bSjoerg    typedef typename _NodeTypes::__next_pointer      __next_pointer;
937*4d6fc14bSjoerg
938*4d6fc14bSjoergprivate:
939*4d6fc14bSjoerg    // check for sane allocator pointer rebinding semantics. Rebinding the
940*4d6fc14bSjoerg    // allocator for a new pointer type should be exactly the same as rebinding
941*4d6fc14bSjoerg    // the pointer using 'pointer_traits'.
942*4d6fc14bSjoerg    static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
943*4d6fc14bSjoerg                  "Allocator does not rebind pointers in a sane manner.");
944*4d6fc14bSjoerg    typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type
945*4d6fc14bSjoerg        __node_base_allocator;
946*4d6fc14bSjoerg    typedef allocator_traits<__node_base_allocator> __node_base_traits;
947*4d6fc14bSjoerg    static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
948*4d6fc14bSjoerg                 "Allocator does not rebind pointers in a sane manner.");
949*4d6fc14bSjoerg
950*4d6fc14bSjoergprivate:
951*4d6fc14bSjoerg
952*4d6fc14bSjoerg    typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator;
953*4d6fc14bSjoerg    typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
954*4d6fc14bSjoerg    typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
955*4d6fc14bSjoerg    typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
956*4d6fc14bSjoerg    typedef typename __bucket_list_deleter::pointer       __node_pointer_pointer;
957*4d6fc14bSjoerg
958*4d6fc14bSjoerg    // --- Member data begin ---
959*4d6fc14bSjoerg    __bucket_list                                         __bucket_list_;
960*4d6fc14bSjoerg    __compressed_pair<__first_node, __node_allocator>     __p1_;
961*4d6fc14bSjoerg    __compressed_pair<size_type, hasher>                  __p2_;
962*4d6fc14bSjoerg    __compressed_pair<float, key_equal>                   __p3_;
963*4d6fc14bSjoerg    // --- Member data end ---
964*4d6fc14bSjoerg
965*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
966*4d6fc14bSjoerg    size_type& size() _NOEXCEPT {return __p2_.first();}
967*4d6fc14bSjoergpublic:
968*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
969*4d6fc14bSjoerg    size_type  size() const _NOEXCEPT {return __p2_.first();}
970*4d6fc14bSjoerg
971*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
972*4d6fc14bSjoerg    hasher& hash_function() _NOEXCEPT {return __p2_.second();}
973*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
974*4d6fc14bSjoerg    const hasher& hash_function() const _NOEXCEPT {return __p2_.second();}
975*4d6fc14bSjoerg
976*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
977*4d6fc14bSjoerg    float& max_load_factor() _NOEXCEPT {return __p3_.first();}
978*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
979*4d6fc14bSjoerg    float  max_load_factor() const _NOEXCEPT {return __p3_.first();}
980*4d6fc14bSjoerg
981*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
982*4d6fc14bSjoerg    key_equal& key_eq() _NOEXCEPT {return __p3_.second();}
983*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
984*4d6fc14bSjoerg    const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();}
985*4d6fc14bSjoerg
986*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
987*4d6fc14bSjoerg    __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();}
988*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
989*4d6fc14bSjoerg    const __node_allocator& __node_alloc() const _NOEXCEPT
990*4d6fc14bSjoerg        {return __p1_.second();}
991*4d6fc14bSjoerg
992*4d6fc14bSjoergpublic:
993*4d6fc14bSjoerg    typedef __hash_iterator<__node_pointer>                   iterator;
994*4d6fc14bSjoerg    typedef __hash_const_iterator<__node_pointer>             const_iterator;
995*4d6fc14bSjoerg    typedef __hash_local_iterator<__node_pointer>             local_iterator;
996*4d6fc14bSjoerg    typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;
997*4d6fc14bSjoerg
998*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
999*4d6fc14bSjoerg    __hash_table()
1000*4d6fc14bSjoerg        _NOEXCEPT_(
1001*4d6fc14bSjoerg            is_nothrow_default_constructible<__bucket_list>::value &&
1002*4d6fc14bSjoerg            is_nothrow_default_constructible<__first_node>::value &&
1003*4d6fc14bSjoerg            is_nothrow_default_constructible<__node_allocator>::value &&
1004*4d6fc14bSjoerg            is_nothrow_default_constructible<hasher>::value &&
1005*4d6fc14bSjoerg            is_nothrow_default_constructible<key_equal>::value);
1006*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1007*4d6fc14bSjoerg    __hash_table(const hasher& __hf, const key_equal& __eql);
1008*4d6fc14bSjoerg    __hash_table(const hasher& __hf, const key_equal& __eql,
1009*4d6fc14bSjoerg                 const allocator_type& __a);
1010*4d6fc14bSjoerg    explicit __hash_table(const allocator_type& __a);
1011*4d6fc14bSjoerg    __hash_table(const __hash_table& __u);
1012*4d6fc14bSjoerg    __hash_table(const __hash_table& __u, const allocator_type& __a);
1013*4d6fc14bSjoerg    __hash_table(__hash_table&& __u)
1014*4d6fc14bSjoerg        _NOEXCEPT_(
1015*4d6fc14bSjoerg            is_nothrow_move_constructible<__bucket_list>::value &&
1016*4d6fc14bSjoerg            is_nothrow_move_constructible<__first_node>::value &&
1017*4d6fc14bSjoerg            is_nothrow_move_constructible<__node_allocator>::value &&
1018*4d6fc14bSjoerg            is_nothrow_move_constructible<hasher>::value &&
1019*4d6fc14bSjoerg            is_nothrow_move_constructible<key_equal>::value);
1020*4d6fc14bSjoerg    __hash_table(__hash_table&& __u, const allocator_type& __a);
1021*4d6fc14bSjoerg    ~__hash_table();
1022*4d6fc14bSjoerg
1023*4d6fc14bSjoerg    __hash_table& operator=(const __hash_table& __u);
1024*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1025*4d6fc14bSjoerg    __hash_table& operator=(__hash_table&& __u)
1026*4d6fc14bSjoerg        _NOEXCEPT_(
1027*4d6fc14bSjoerg            __node_traits::propagate_on_container_move_assignment::value &&
1028*4d6fc14bSjoerg            is_nothrow_move_assignable<__node_allocator>::value &&
1029*4d6fc14bSjoerg            is_nothrow_move_assignable<hasher>::value &&
1030*4d6fc14bSjoerg            is_nothrow_move_assignable<key_equal>::value);
1031*4d6fc14bSjoerg    template <class _InputIterator>
1032*4d6fc14bSjoerg        void __assign_unique(_InputIterator __first, _InputIterator __last);
1033*4d6fc14bSjoerg    template <class _InputIterator>
1034*4d6fc14bSjoerg        void __assign_multi(_InputIterator __first, _InputIterator __last);
1035*4d6fc14bSjoerg
1036*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1037*4d6fc14bSjoerg    size_type max_size() const _NOEXCEPT
1038*4d6fc14bSjoerg    {
1039*4d6fc14bSjoerg        return _VSTD::min<size_type>(
1040*4d6fc14bSjoerg            __node_traits::max_size(__node_alloc()),
1041*4d6fc14bSjoerg            numeric_limits<difference_type >::max()
1042*4d6fc14bSjoerg        );
1043*4d6fc14bSjoerg    }
1044*4d6fc14bSjoerg
1045*4d6fc14bSjoergprivate:
1046*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1047*4d6fc14bSjoerg    __next_pointer __node_insert_multi_prepare(size_t __cp_hash,
1048*4d6fc14bSjoerg                                               value_type& __cp_val);
1049*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1050*4d6fc14bSjoerg    void __node_insert_multi_perform(__node_pointer __cp,
1051*4d6fc14bSjoerg                                     __next_pointer __pn) _NOEXCEPT;
1052*4d6fc14bSjoerg
1053*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1054*4d6fc14bSjoerg    __next_pointer __node_insert_unique_prepare(size_t __nd_hash,
1055*4d6fc14bSjoerg                                                value_type& __nd_val);
1056*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1057*4d6fc14bSjoerg    void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
1058*4d6fc14bSjoerg
1059*4d6fc14bSjoergpublic:
1060*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1061*4d6fc14bSjoerg    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
1062*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1063*4d6fc14bSjoerg    iterator             __node_insert_multi(__node_pointer __nd);
1064*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1065*4d6fc14bSjoerg    iterator             __node_insert_multi(const_iterator __p,
1066*4d6fc14bSjoerg                                             __node_pointer __nd);
1067*4d6fc14bSjoerg
1068*4d6fc14bSjoerg    template <class _Key, class ..._Args>
1069*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1070*4d6fc14bSjoerg    pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
1071*4d6fc14bSjoerg
1072*4d6fc14bSjoerg    template <class... _Args>
1073*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1074*4d6fc14bSjoerg    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
1075*4d6fc14bSjoerg
1076*4d6fc14bSjoerg    template <class _Pp>
1077*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1078*4d6fc14bSjoerg    pair<iterator, bool> __emplace_unique(_Pp&& __x) {
1079*4d6fc14bSjoerg      return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
1080*4d6fc14bSjoerg                                          __can_extract_key<_Pp, key_type>());
1081*4d6fc14bSjoerg    }
1082*4d6fc14bSjoerg
1083*4d6fc14bSjoerg    template <class _First, class _Second>
1084*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1085*4d6fc14bSjoerg    typename enable_if<
1086*4d6fc14bSjoerg        __can_extract_map_key<_First, key_type, __container_value_type>::value,
1087*4d6fc14bSjoerg        pair<iterator, bool>
1088*4d6fc14bSjoerg    >::type __emplace_unique(_First&& __f, _Second&& __s) {
1089*4d6fc14bSjoerg        return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
1090*4d6fc14bSjoerg                                              _VSTD::forward<_Second>(__s));
1091*4d6fc14bSjoerg    }
1092*4d6fc14bSjoerg
1093*4d6fc14bSjoerg    template <class... _Args>
1094*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1095*4d6fc14bSjoerg    pair<iterator, bool> __emplace_unique(_Args&&... __args) {
1096*4d6fc14bSjoerg      return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
1097*4d6fc14bSjoerg    }
1098*4d6fc14bSjoerg
1099*4d6fc14bSjoerg    template <class _Pp>
1100*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1101*4d6fc14bSjoerg    pair<iterator, bool>
1102*4d6fc14bSjoerg    __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
1103*4d6fc14bSjoerg      return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
1104*4d6fc14bSjoerg    }
1105*4d6fc14bSjoerg    template <class _Pp>
1106*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1107*4d6fc14bSjoerg    pair<iterator, bool>
1108*4d6fc14bSjoerg    __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
1109*4d6fc14bSjoerg      return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
1110*4d6fc14bSjoerg    }
1111*4d6fc14bSjoerg    template <class _Pp>
1112*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1113*4d6fc14bSjoerg    pair<iterator, bool>
1114*4d6fc14bSjoerg    __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
1115*4d6fc14bSjoerg      return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
1116*4d6fc14bSjoerg    }
1117*4d6fc14bSjoerg
1118*4d6fc14bSjoerg    template <class... _Args>
1119*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1120*4d6fc14bSjoerg    iterator __emplace_multi(_Args&&... __args);
1121*4d6fc14bSjoerg    template <class... _Args>
1122*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1123*4d6fc14bSjoerg    iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
1124*4d6fc14bSjoerg
1125*4d6fc14bSjoerg
1126*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1127*4d6fc14bSjoerg    pair<iterator, bool>
1128*4d6fc14bSjoerg    __insert_unique(__container_value_type&& __x) {
1129*4d6fc14bSjoerg      return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x));
1130*4d6fc14bSjoerg    }
1131*4d6fc14bSjoerg
1132*4d6fc14bSjoerg    template <class _Pp, class = typename enable_if<
1133*4d6fc14bSjoerg            !__is_same_uncvref<_Pp, __container_value_type>::value
1134*4d6fc14bSjoerg        >::type>
1135*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1136*4d6fc14bSjoerg    pair<iterator, bool> __insert_unique(_Pp&& __x) {
1137*4d6fc14bSjoerg      return __emplace_unique(_VSTD::forward<_Pp>(__x));
1138*4d6fc14bSjoerg    }
1139*4d6fc14bSjoerg
1140*4d6fc14bSjoerg    template <class _Pp>
1141*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1142*4d6fc14bSjoerg    iterator __insert_multi(_Pp&& __x) {
1143*4d6fc14bSjoerg      return __emplace_multi(_VSTD::forward<_Pp>(__x));
1144*4d6fc14bSjoerg    }
1145*4d6fc14bSjoerg
1146*4d6fc14bSjoerg    template <class _Pp>
1147*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1148*4d6fc14bSjoerg    iterator __insert_multi(const_iterator __p, _Pp&& __x) {
1149*4d6fc14bSjoerg        return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x));
1150*4d6fc14bSjoerg    }
1151*4d6fc14bSjoerg
1152*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1153*4d6fc14bSjoerg    pair<iterator, bool> __insert_unique(const __container_value_type& __x) {
1154*4d6fc14bSjoerg        return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
1155*4d6fc14bSjoerg    }
1156*4d6fc14bSjoerg
1157*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14
1158*4d6fc14bSjoerg    template <class _NodeHandle, class _InsertReturnType>
1159*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1160*4d6fc14bSjoerg    _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
1161*4d6fc14bSjoerg    template <class _NodeHandle>
1162*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1163*4d6fc14bSjoerg    iterator __node_handle_insert_unique(const_iterator __hint,
1164*4d6fc14bSjoerg                                         _NodeHandle&& __nh);
1165*4d6fc14bSjoerg    template <class _Table>
1166*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1167*4d6fc14bSjoerg    void __node_handle_merge_unique(_Table& __source);
1168*4d6fc14bSjoerg
1169*4d6fc14bSjoerg    template <class _NodeHandle>
1170*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1171*4d6fc14bSjoerg    iterator __node_handle_insert_multi(_NodeHandle&& __nh);
1172*4d6fc14bSjoerg    template <class _NodeHandle>
1173*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1174*4d6fc14bSjoerg    iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
1175*4d6fc14bSjoerg    template <class _Table>
1176*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1177*4d6fc14bSjoerg    void __node_handle_merge_multi(_Table& __source);
1178*4d6fc14bSjoerg
1179*4d6fc14bSjoerg    template <class _NodeHandle>
1180*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1181*4d6fc14bSjoerg    _NodeHandle __node_handle_extract(key_type const& __key);
1182*4d6fc14bSjoerg    template <class _NodeHandle>
1183*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1184*4d6fc14bSjoerg    _NodeHandle __node_handle_extract(const_iterator __it);
1185*4d6fc14bSjoerg#endif
1186*4d6fc14bSjoerg
1187*4d6fc14bSjoerg    void clear() _NOEXCEPT;
1188*4d6fc14bSjoerg    void rehash(size_type __n);
1189*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)
1190*4d6fc14bSjoerg        {rehash(static_cast<size_type>(ceil(__n / max_load_factor())));}
1191*4d6fc14bSjoerg
1192*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1193*4d6fc14bSjoerg    size_type bucket_count() const _NOEXCEPT
1194*4d6fc14bSjoerg    {
1195*4d6fc14bSjoerg        return __bucket_list_.get_deleter().size();
1196*4d6fc14bSjoerg    }
1197*4d6fc14bSjoerg
1198*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1199*4d6fc14bSjoerg    iterator       begin() _NOEXCEPT;
1200*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1201*4d6fc14bSjoerg    iterator       end() _NOEXCEPT;
1202*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1203*4d6fc14bSjoerg    const_iterator begin() const _NOEXCEPT;
1204*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1205*4d6fc14bSjoerg    const_iterator end() const _NOEXCEPT;
1206*4d6fc14bSjoerg
1207*4d6fc14bSjoerg    template <class _Key>
1208*4d6fc14bSjoerg        _LIBCPP_INLINE_VISIBILITY
1209*4d6fc14bSjoerg        size_type bucket(const _Key& __k) const
1210*4d6fc14bSjoerg        {
1211*4d6fc14bSjoerg            _LIBCPP_ASSERT(bucket_count() > 0,
1212*4d6fc14bSjoerg                "unordered container::bucket(key) called when bucket_count() == 0");
1213*4d6fc14bSjoerg            return __constrain_hash(hash_function()(__k), bucket_count());
1214*4d6fc14bSjoerg        }
1215*4d6fc14bSjoerg
1216*4d6fc14bSjoerg    template <class _Key>
1217*4d6fc14bSjoerg        iterator       find(const _Key& __x);
1218*4d6fc14bSjoerg    template <class _Key>
1219*4d6fc14bSjoerg        const_iterator find(const _Key& __x) const;
1220*4d6fc14bSjoerg
1221*4d6fc14bSjoerg    typedef __hash_node_destructor<__node_allocator> _Dp;
1222*4d6fc14bSjoerg    typedef unique_ptr<__node, _Dp> __node_holder;
1223*4d6fc14bSjoerg
1224*4d6fc14bSjoerg    iterator erase(const_iterator __p);
1225*4d6fc14bSjoerg    iterator erase(const_iterator __first, const_iterator __last);
1226*4d6fc14bSjoerg    template <class _Key>
1227*4d6fc14bSjoerg        size_type __erase_unique(const _Key& __k);
1228*4d6fc14bSjoerg    template <class _Key>
1229*4d6fc14bSjoerg        size_type __erase_multi(const _Key& __k);
1230*4d6fc14bSjoerg    __node_holder remove(const_iterator __p) _NOEXCEPT;
1231*4d6fc14bSjoerg
1232*4d6fc14bSjoerg    template <class _Key>
1233*4d6fc14bSjoerg        _LIBCPP_INLINE_VISIBILITY
1234*4d6fc14bSjoerg        size_type __count_unique(const _Key& __k) const;
1235*4d6fc14bSjoerg    template <class _Key>
1236*4d6fc14bSjoerg        size_type __count_multi(const _Key& __k) const;
1237*4d6fc14bSjoerg
1238*4d6fc14bSjoerg    template <class _Key>
1239*4d6fc14bSjoerg        pair<iterator, iterator>
1240*4d6fc14bSjoerg        __equal_range_unique(const _Key& __k);
1241*4d6fc14bSjoerg    template <class _Key>
1242*4d6fc14bSjoerg        pair<const_iterator, const_iterator>
1243*4d6fc14bSjoerg        __equal_range_unique(const _Key& __k) const;
1244*4d6fc14bSjoerg
1245*4d6fc14bSjoerg    template <class _Key>
1246*4d6fc14bSjoerg        pair<iterator, iterator>
1247*4d6fc14bSjoerg        __equal_range_multi(const _Key& __k);
1248*4d6fc14bSjoerg    template <class _Key>
1249*4d6fc14bSjoerg        pair<const_iterator, const_iterator>
1250*4d6fc14bSjoerg        __equal_range_multi(const _Key& __k) const;
1251*4d6fc14bSjoerg
1252*4d6fc14bSjoerg    void swap(__hash_table& __u)
1253*4d6fc14bSjoerg#if _LIBCPP_STD_VER <= 11
1254*4d6fc14bSjoerg        _NOEXCEPT_(
1255*4d6fc14bSjoerg            __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
1256*4d6fc14bSjoerg            && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
1257*4d6fc14bSjoerg                  || __is_nothrow_swappable<__pointer_allocator>::value)
1258*4d6fc14bSjoerg            && (!__node_traits::propagate_on_container_swap::value
1259*4d6fc14bSjoerg                  || __is_nothrow_swappable<__node_allocator>::value)
1260*4d6fc14bSjoerg            );
1261*4d6fc14bSjoerg#else
1262*4d6fc14bSjoerg     _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
1263*4d6fc14bSjoerg#endif
1264*4d6fc14bSjoerg
1265*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1266*4d6fc14bSjoerg    size_type max_bucket_count() const _NOEXCEPT
1267*4d6fc14bSjoerg        {return max_size(); }
1268*4d6fc14bSjoerg    size_type bucket_size(size_type __n) const;
1269*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
1270*4d6fc14bSjoerg    {
1271*4d6fc14bSjoerg        size_type __bc = bucket_count();
1272*4d6fc14bSjoerg        return __bc != 0 ? (float)size() / __bc : 0.f;
1273*4d6fc14bSjoerg    }
1274*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
1275*4d6fc14bSjoerg    {
1276*4d6fc14bSjoerg        _LIBCPP_ASSERT(__mlf > 0,
1277*4d6fc14bSjoerg            "unordered container::max_load_factor(lf) called with lf <= 0");
1278*4d6fc14bSjoerg        max_load_factor() = _VSTD::max(__mlf, load_factor());
1279*4d6fc14bSjoerg    }
1280*4d6fc14bSjoerg
1281*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1282*4d6fc14bSjoerg    local_iterator
1283*4d6fc14bSjoerg    begin(size_type __n)
1284*4d6fc14bSjoerg    {
1285*4d6fc14bSjoerg        _LIBCPP_ASSERT(__n < bucket_count(),
1286*4d6fc14bSjoerg            "unordered container::begin(n) called with n >= bucket_count()");
1287*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1288*4d6fc14bSjoerg        return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
1289*4d6fc14bSjoerg#else
1290*4d6fc14bSjoerg        return local_iterator(__bucket_list_[__n], __n, bucket_count());
1291*4d6fc14bSjoerg#endif
1292*4d6fc14bSjoerg    }
1293*4d6fc14bSjoerg
1294*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1295*4d6fc14bSjoerg    local_iterator
1296*4d6fc14bSjoerg    end(size_type __n)
1297*4d6fc14bSjoerg    {
1298*4d6fc14bSjoerg        _LIBCPP_ASSERT(__n < bucket_count(),
1299*4d6fc14bSjoerg            "unordered container::end(n) called with n >= bucket_count()");
1300*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1301*4d6fc14bSjoerg        return local_iterator(nullptr, __n, bucket_count(), this);
1302*4d6fc14bSjoerg#else
1303*4d6fc14bSjoerg        return local_iterator(nullptr, __n, bucket_count());
1304*4d6fc14bSjoerg#endif
1305*4d6fc14bSjoerg    }
1306*4d6fc14bSjoerg
1307*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1308*4d6fc14bSjoerg    const_local_iterator
1309*4d6fc14bSjoerg    cbegin(size_type __n) const
1310*4d6fc14bSjoerg    {
1311*4d6fc14bSjoerg        _LIBCPP_ASSERT(__n < bucket_count(),
1312*4d6fc14bSjoerg            "unordered container::cbegin(n) called with n >= bucket_count()");
1313*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1314*4d6fc14bSjoerg        return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
1315*4d6fc14bSjoerg#else
1316*4d6fc14bSjoerg        return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
1317*4d6fc14bSjoerg#endif
1318*4d6fc14bSjoerg    }
1319*4d6fc14bSjoerg
1320*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1321*4d6fc14bSjoerg    const_local_iterator
1322*4d6fc14bSjoerg    cend(size_type __n) const
1323*4d6fc14bSjoerg    {
1324*4d6fc14bSjoerg        _LIBCPP_ASSERT(__n < bucket_count(),
1325*4d6fc14bSjoerg            "unordered container::cend(n) called with n >= bucket_count()");
1326*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1327*4d6fc14bSjoerg        return const_local_iterator(nullptr, __n, bucket_count(), this);
1328*4d6fc14bSjoerg#else
1329*4d6fc14bSjoerg        return const_local_iterator(nullptr, __n, bucket_count());
1330*4d6fc14bSjoerg#endif
1331*4d6fc14bSjoerg    }
1332*4d6fc14bSjoerg
1333*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1334*4d6fc14bSjoerg
1335*4d6fc14bSjoerg    bool __dereferenceable(const const_iterator* __i) const;
1336*4d6fc14bSjoerg    bool __decrementable(const const_iterator* __i) const;
1337*4d6fc14bSjoerg    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
1338*4d6fc14bSjoerg    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
1339*4d6fc14bSjoerg
1340*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2
1341*4d6fc14bSjoerg
1342*4d6fc14bSjoergprivate:
1343*4d6fc14bSjoerg    void __rehash(size_type __n);
1344*4d6fc14bSjoerg
1345*4d6fc14bSjoerg    template <class ..._Args>
1346*4d6fc14bSjoerg    __node_holder __construct_node(_Args&& ...__args);
1347*4d6fc14bSjoerg
1348*4d6fc14bSjoerg    template <class _First, class ..._Rest>
1349*4d6fc14bSjoerg    __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
1350*4d6fc14bSjoerg
1351*4d6fc14bSjoerg
1352*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1353*4d6fc14bSjoerg    void __copy_assign_alloc(const __hash_table& __u)
1354*4d6fc14bSjoerg        {__copy_assign_alloc(__u, integral_constant<bool,
1355*4d6fc14bSjoerg             __node_traits::propagate_on_container_copy_assignment::value>());}
1356*4d6fc14bSjoerg    void __copy_assign_alloc(const __hash_table& __u, true_type);
1357*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1358*4d6fc14bSjoerg        void __copy_assign_alloc(const __hash_table&, false_type) {}
1359*4d6fc14bSjoerg
1360*4d6fc14bSjoerg    void __move_assign(__hash_table& __u, false_type);
1361*4d6fc14bSjoerg    void __move_assign(__hash_table& __u, true_type)
1362*4d6fc14bSjoerg        _NOEXCEPT_(
1363*4d6fc14bSjoerg            is_nothrow_move_assignable<__node_allocator>::value &&
1364*4d6fc14bSjoerg            is_nothrow_move_assignable<hasher>::value &&
1365*4d6fc14bSjoerg            is_nothrow_move_assignable<key_equal>::value);
1366*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1367*4d6fc14bSjoerg    void __move_assign_alloc(__hash_table& __u)
1368*4d6fc14bSjoerg        _NOEXCEPT_(
1369*4d6fc14bSjoerg            !__node_traits::propagate_on_container_move_assignment::value ||
1370*4d6fc14bSjoerg            (is_nothrow_move_assignable<__pointer_allocator>::value &&
1371*4d6fc14bSjoerg             is_nothrow_move_assignable<__node_allocator>::value))
1372*4d6fc14bSjoerg        {__move_assign_alloc(__u, integral_constant<bool,
1373*4d6fc14bSjoerg             __node_traits::propagate_on_container_move_assignment::value>());}
1374*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1375*4d6fc14bSjoerg    void __move_assign_alloc(__hash_table& __u, true_type)
1376*4d6fc14bSjoerg        _NOEXCEPT_(
1377*4d6fc14bSjoerg            is_nothrow_move_assignable<__pointer_allocator>::value &&
1378*4d6fc14bSjoerg            is_nothrow_move_assignable<__node_allocator>::value)
1379*4d6fc14bSjoerg    {
1380*4d6fc14bSjoerg        __bucket_list_.get_deleter().__alloc() =
1381*4d6fc14bSjoerg                _VSTD::move(__u.__bucket_list_.get_deleter().__alloc());
1382*4d6fc14bSjoerg        __node_alloc() = _VSTD::move(__u.__node_alloc());
1383*4d6fc14bSjoerg    }
1384*4d6fc14bSjoerg    _LIBCPP_INLINE_VISIBILITY
1385*4d6fc14bSjoerg        void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
1386*4d6fc14bSjoerg
1387*4d6fc14bSjoerg    void __deallocate_node(__next_pointer __np) _NOEXCEPT;
1388*4d6fc14bSjoerg    __next_pointer __detach() _NOEXCEPT;
1389*4d6fc14bSjoerg
1390*4d6fc14bSjoerg    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
1391*4d6fc14bSjoerg    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
1392*4d6fc14bSjoerg};
1393*4d6fc14bSjoerg
1394*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1395*4d6fc14bSjoerginline
1396*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()
1397*4d6fc14bSjoerg    _NOEXCEPT_(
1398*4d6fc14bSjoerg        is_nothrow_default_constructible<__bucket_list>::value &&
1399*4d6fc14bSjoerg        is_nothrow_default_constructible<__first_node>::value &&
1400*4d6fc14bSjoerg        is_nothrow_default_constructible<__node_allocator>::value &&
1401*4d6fc14bSjoerg        is_nothrow_default_constructible<hasher>::value &&
1402*4d6fc14bSjoerg        is_nothrow_default_constructible<key_equal>::value)
1403*4d6fc14bSjoerg    : __p2_(0, __default_init_tag()),
1404*4d6fc14bSjoerg      __p3_(1.0f, __default_init_tag())
1405*4d6fc14bSjoerg{
1406*4d6fc14bSjoerg}
1407*4d6fc14bSjoerg
1408*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1409*4d6fc14bSjoerginline
1410*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
1411*4d6fc14bSjoerg                                                       const key_equal& __eql)
1412*4d6fc14bSjoerg    : __bucket_list_(nullptr, __bucket_list_deleter()),
1413*4d6fc14bSjoerg      __p1_(),
1414*4d6fc14bSjoerg      __p2_(0, __hf),
1415*4d6fc14bSjoerg      __p3_(1.0f, __eql)
1416*4d6fc14bSjoerg{
1417*4d6fc14bSjoerg}
1418*4d6fc14bSjoerg
1419*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1420*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
1421*4d6fc14bSjoerg                                                       const key_equal& __eql,
1422*4d6fc14bSjoerg                                                       const allocator_type& __a)
1423*4d6fc14bSjoerg    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1424*4d6fc14bSjoerg      __p1_(__default_init_tag(), __node_allocator(__a)),
1425*4d6fc14bSjoerg      __p2_(0, __hf),
1426*4d6fc14bSjoerg      __p3_(1.0f, __eql)
1427*4d6fc14bSjoerg{
1428*4d6fc14bSjoerg}
1429*4d6fc14bSjoerg
1430*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1431*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
1432*4d6fc14bSjoerg    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1433*4d6fc14bSjoerg      __p1_(__default_init_tag(), __node_allocator(__a)),
1434*4d6fc14bSjoerg      __p2_(0, __default_init_tag()),
1435*4d6fc14bSjoerg      __p3_(1.0f, __default_init_tag())
1436*4d6fc14bSjoerg{
1437*4d6fc14bSjoerg}
1438*4d6fc14bSjoerg
1439*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1440*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
1441*4d6fc14bSjoerg    : __bucket_list_(nullptr,
1442*4d6fc14bSjoerg          __bucket_list_deleter(allocator_traits<__pointer_allocator>::
1443*4d6fc14bSjoerg              select_on_container_copy_construction(
1444*4d6fc14bSjoerg                  __u.__bucket_list_.get_deleter().__alloc()), 0)),
1445*4d6fc14bSjoerg      __p1_(__default_init_tag(), allocator_traits<__node_allocator>::
1446*4d6fc14bSjoerg          select_on_container_copy_construction(__u.__node_alloc())),
1447*4d6fc14bSjoerg      __p2_(0, __u.hash_function()),
1448*4d6fc14bSjoerg      __p3_(__u.__p3_)
1449*4d6fc14bSjoerg{
1450*4d6fc14bSjoerg}
1451*4d6fc14bSjoerg
1452*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1453*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
1454*4d6fc14bSjoerg                                                       const allocator_type& __a)
1455*4d6fc14bSjoerg    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1456*4d6fc14bSjoerg      __p1_(__default_init_tag(), __node_allocator(__a)),
1457*4d6fc14bSjoerg      __p2_(0, __u.hash_function()),
1458*4d6fc14bSjoerg      __p3_(__u.__p3_)
1459*4d6fc14bSjoerg{
1460*4d6fc14bSjoerg}
1461*4d6fc14bSjoerg
1462*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1463*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
1464*4d6fc14bSjoerg        _NOEXCEPT_(
1465*4d6fc14bSjoerg            is_nothrow_move_constructible<__bucket_list>::value &&
1466*4d6fc14bSjoerg            is_nothrow_move_constructible<__first_node>::value &&
1467*4d6fc14bSjoerg            is_nothrow_move_constructible<__node_allocator>::value &&
1468*4d6fc14bSjoerg            is_nothrow_move_constructible<hasher>::value &&
1469*4d6fc14bSjoerg            is_nothrow_move_constructible<key_equal>::value)
1470*4d6fc14bSjoerg    : __bucket_list_(_VSTD::move(__u.__bucket_list_)),
1471*4d6fc14bSjoerg      __p1_(_VSTD::move(__u.__p1_)),
1472*4d6fc14bSjoerg      __p2_(_VSTD::move(__u.__p2_)),
1473*4d6fc14bSjoerg      __p3_(_VSTD::move(__u.__p3_))
1474*4d6fc14bSjoerg{
1475*4d6fc14bSjoerg    if (size() > 0)
1476*4d6fc14bSjoerg    {
1477*4d6fc14bSjoerg        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
1478*4d6fc14bSjoerg            __p1_.first().__ptr();
1479*4d6fc14bSjoerg        __u.__p1_.first().__next_ = nullptr;
1480*4d6fc14bSjoerg        __u.size() = 0;
1481*4d6fc14bSjoerg    }
1482*4d6fc14bSjoerg}
1483*4d6fc14bSjoerg
1484*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1485*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
1486*4d6fc14bSjoerg                                                       const allocator_type& __a)
1487*4d6fc14bSjoerg    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1488*4d6fc14bSjoerg      __p1_(__default_init_tag(), __node_allocator(__a)),
1489*4d6fc14bSjoerg      __p2_(0, _VSTD::move(__u.hash_function())),
1490*4d6fc14bSjoerg      __p3_(_VSTD::move(__u.__p3_))
1491*4d6fc14bSjoerg{
1492*4d6fc14bSjoerg    if (__a == allocator_type(__u.__node_alloc()))
1493*4d6fc14bSjoerg    {
1494*4d6fc14bSjoerg        __bucket_list_.reset(__u.__bucket_list_.release());
1495*4d6fc14bSjoerg        __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
1496*4d6fc14bSjoerg        __u.__bucket_list_.get_deleter().size() = 0;
1497*4d6fc14bSjoerg        if (__u.size() > 0)
1498*4d6fc14bSjoerg        {
1499*4d6fc14bSjoerg            __p1_.first().__next_ = __u.__p1_.first().__next_;
1500*4d6fc14bSjoerg            __u.__p1_.first().__next_ = nullptr;
1501*4d6fc14bSjoerg            __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
1502*4d6fc14bSjoerg                __p1_.first().__ptr();
1503*4d6fc14bSjoerg            size() = __u.size();
1504*4d6fc14bSjoerg            __u.size() = 0;
1505*4d6fc14bSjoerg        }
1506*4d6fc14bSjoerg    }
1507*4d6fc14bSjoerg}
1508*4d6fc14bSjoerg
1509*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1510*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
1511*4d6fc14bSjoerg{
1512*4d6fc14bSjoerg#if defined(_LIBCPP_CXX03_LANG)
1513*4d6fc14bSjoerg    static_assert((is_copy_constructible<key_equal>::value),
1514*4d6fc14bSjoerg                 "Predicate must be copy-constructible.");
1515*4d6fc14bSjoerg    static_assert((is_copy_constructible<hasher>::value),
1516*4d6fc14bSjoerg                 "Hasher must be copy-constructible.");
1517*4d6fc14bSjoerg#endif
1518*4d6fc14bSjoerg
1519*4d6fc14bSjoerg    __deallocate_node(__p1_.first().__next_);
1520*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1521*4d6fc14bSjoerg    __get_db()->__erase_c(this);
1522*4d6fc14bSjoerg#endif
1523*4d6fc14bSjoerg}
1524*4d6fc14bSjoerg
1525*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1526*4d6fc14bSjoergvoid
1527*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(
1528*4d6fc14bSjoerg        const __hash_table& __u, true_type)
1529*4d6fc14bSjoerg{
1530*4d6fc14bSjoerg    if (__node_alloc() != __u.__node_alloc())
1531*4d6fc14bSjoerg    {
1532*4d6fc14bSjoerg        clear();
1533*4d6fc14bSjoerg        __bucket_list_.reset();
1534*4d6fc14bSjoerg        __bucket_list_.get_deleter().size() = 0;
1535*4d6fc14bSjoerg    }
1536*4d6fc14bSjoerg    __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();
1537*4d6fc14bSjoerg    __node_alloc() = __u.__node_alloc();
1538*4d6fc14bSjoerg}
1539*4d6fc14bSjoerg
1540*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1541*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>&
1542*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u)
1543*4d6fc14bSjoerg{
1544*4d6fc14bSjoerg    if (this != &__u)
1545*4d6fc14bSjoerg    {
1546*4d6fc14bSjoerg        __copy_assign_alloc(__u);
1547*4d6fc14bSjoerg        hash_function() = __u.hash_function();
1548*4d6fc14bSjoerg        key_eq() = __u.key_eq();
1549*4d6fc14bSjoerg        max_load_factor() = __u.max_load_factor();
1550*4d6fc14bSjoerg        __assign_multi(__u.begin(), __u.end());
1551*4d6fc14bSjoerg    }
1552*4d6fc14bSjoerg    return *this;
1553*4d6fc14bSjoerg}
1554*4d6fc14bSjoerg
1555*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1556*4d6fc14bSjoergvoid
1557*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
1558*4d6fc14bSjoerg    _NOEXCEPT
1559*4d6fc14bSjoerg{
1560*4d6fc14bSjoerg    __node_allocator& __na = __node_alloc();
1561*4d6fc14bSjoerg    while (__np != nullptr)
1562*4d6fc14bSjoerg    {
1563*4d6fc14bSjoerg        __next_pointer __next = __np->__next_;
1564*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1565*4d6fc14bSjoerg        __c_node* __c = __get_db()->__find_c_and_lock(this);
1566*4d6fc14bSjoerg        for (__i_node** __p = __c->end_; __p != __c->beg_; )
1567*4d6fc14bSjoerg        {
1568*4d6fc14bSjoerg            --__p;
1569*4d6fc14bSjoerg            iterator* __i = static_cast<iterator*>((*__p)->__i_);
1570*4d6fc14bSjoerg            if (__i->__node_ == __np)
1571*4d6fc14bSjoerg            {
1572*4d6fc14bSjoerg                (*__p)->__c_ = nullptr;
1573*4d6fc14bSjoerg                if (--__c->end_ != __p)
1574*4d6fc14bSjoerg                    _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
1575*4d6fc14bSjoerg            }
1576*4d6fc14bSjoerg        }
1577*4d6fc14bSjoerg        __get_db()->unlock();
1578*4d6fc14bSjoerg#endif
1579*4d6fc14bSjoerg        __node_pointer __real_np = __np->__upcast();
1580*4d6fc14bSjoerg        __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_));
1581*4d6fc14bSjoerg        __node_traits::deallocate(__na, __real_np, 1);
1582*4d6fc14bSjoerg        __np = __next;
1583*4d6fc14bSjoerg    }
1584*4d6fc14bSjoerg}
1585*4d6fc14bSjoerg
1586*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1587*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1588*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT
1589*4d6fc14bSjoerg{
1590*4d6fc14bSjoerg    size_type __bc = bucket_count();
1591*4d6fc14bSjoerg    for (size_type __i = 0; __i < __bc; ++__i)
1592*4d6fc14bSjoerg        __bucket_list_[__i] = nullptr;
1593*4d6fc14bSjoerg    size() = 0;
1594*4d6fc14bSjoerg    __next_pointer __cache = __p1_.first().__next_;
1595*4d6fc14bSjoerg    __p1_.first().__next_ = nullptr;
1596*4d6fc14bSjoerg    return __cache;
1597*4d6fc14bSjoerg}
1598*4d6fc14bSjoerg
1599*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1600*4d6fc14bSjoergvoid
1601*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
1602*4d6fc14bSjoerg        __hash_table& __u, true_type)
1603*4d6fc14bSjoerg    _NOEXCEPT_(
1604*4d6fc14bSjoerg        is_nothrow_move_assignable<__node_allocator>::value &&
1605*4d6fc14bSjoerg        is_nothrow_move_assignable<hasher>::value &&
1606*4d6fc14bSjoerg        is_nothrow_move_assignable<key_equal>::value)
1607*4d6fc14bSjoerg{
1608*4d6fc14bSjoerg    clear();
1609*4d6fc14bSjoerg    __bucket_list_.reset(__u.__bucket_list_.release());
1610*4d6fc14bSjoerg    __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
1611*4d6fc14bSjoerg    __u.__bucket_list_.get_deleter().size() = 0;
1612*4d6fc14bSjoerg    __move_assign_alloc(__u);
1613*4d6fc14bSjoerg    size() = __u.size();
1614*4d6fc14bSjoerg    hash_function() = _VSTD::move(__u.hash_function());
1615*4d6fc14bSjoerg    max_load_factor() = __u.max_load_factor();
1616*4d6fc14bSjoerg    key_eq() = _VSTD::move(__u.key_eq());
1617*4d6fc14bSjoerg    __p1_.first().__next_ = __u.__p1_.first().__next_;
1618*4d6fc14bSjoerg    if (size() > 0)
1619*4d6fc14bSjoerg    {
1620*4d6fc14bSjoerg        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
1621*4d6fc14bSjoerg            __p1_.first().__ptr();
1622*4d6fc14bSjoerg        __u.__p1_.first().__next_ = nullptr;
1623*4d6fc14bSjoerg        __u.size() = 0;
1624*4d6fc14bSjoerg    }
1625*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1626*4d6fc14bSjoerg    __get_db()->swap(this, &__u);
1627*4d6fc14bSjoerg#endif
1628*4d6fc14bSjoerg}
1629*4d6fc14bSjoerg
1630*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1631*4d6fc14bSjoergvoid
1632*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
1633*4d6fc14bSjoerg        __hash_table& __u, false_type)
1634*4d6fc14bSjoerg{
1635*4d6fc14bSjoerg    if (__node_alloc() == __u.__node_alloc())
1636*4d6fc14bSjoerg        __move_assign(__u, true_type());
1637*4d6fc14bSjoerg    else
1638*4d6fc14bSjoerg    {
1639*4d6fc14bSjoerg        hash_function() = _VSTD::move(__u.hash_function());
1640*4d6fc14bSjoerg        key_eq() = _VSTD::move(__u.key_eq());
1641*4d6fc14bSjoerg        max_load_factor() = __u.max_load_factor();
1642*4d6fc14bSjoerg        if (bucket_count() != 0)
1643*4d6fc14bSjoerg        {
1644*4d6fc14bSjoerg            __next_pointer __cache = __detach();
1645*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS
1646*4d6fc14bSjoerg            try
1647*4d6fc14bSjoerg            {
1648*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS
1649*4d6fc14bSjoerg                const_iterator __i = __u.begin();
1650*4d6fc14bSjoerg                while (__cache != nullptr && __u.size() != 0)
1651*4d6fc14bSjoerg                {
1652*4d6fc14bSjoerg                    __cache->__upcast()->__value_ =
1653*4d6fc14bSjoerg                        _VSTD::move(__u.remove(__i++)->__value_);
1654*4d6fc14bSjoerg                    __next_pointer __next = __cache->__next_;
1655*4d6fc14bSjoerg                    __node_insert_multi(__cache->__upcast());
1656*4d6fc14bSjoerg                    __cache = __next;
1657*4d6fc14bSjoerg                }
1658*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS
1659*4d6fc14bSjoerg            }
1660*4d6fc14bSjoerg            catch (...)
1661*4d6fc14bSjoerg            {
1662*4d6fc14bSjoerg                __deallocate_node(__cache);
1663*4d6fc14bSjoerg                throw;
1664*4d6fc14bSjoerg            }
1665*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS
1666*4d6fc14bSjoerg            __deallocate_node(__cache);
1667*4d6fc14bSjoerg        }
1668*4d6fc14bSjoerg        const_iterator __i = __u.begin();
1669*4d6fc14bSjoerg        while (__u.size() != 0)
1670*4d6fc14bSjoerg        {
1671*4d6fc14bSjoerg            __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_));
1672*4d6fc14bSjoerg            __node_insert_multi(__h.get());
1673*4d6fc14bSjoerg            __h.release();
1674*4d6fc14bSjoerg        }
1675*4d6fc14bSjoerg    }
1676*4d6fc14bSjoerg}
1677*4d6fc14bSjoerg
1678*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1679*4d6fc14bSjoerginline
1680*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>&
1681*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
1682*4d6fc14bSjoerg    _NOEXCEPT_(
1683*4d6fc14bSjoerg        __node_traits::propagate_on_container_move_assignment::value &&
1684*4d6fc14bSjoerg        is_nothrow_move_assignable<__node_allocator>::value &&
1685*4d6fc14bSjoerg        is_nothrow_move_assignable<hasher>::value &&
1686*4d6fc14bSjoerg        is_nothrow_move_assignable<key_equal>::value)
1687*4d6fc14bSjoerg{
1688*4d6fc14bSjoerg    __move_assign(__u, integral_constant<bool,
1689*4d6fc14bSjoerg                  __node_traits::propagate_on_container_move_assignment::value>());
1690*4d6fc14bSjoerg    return *this;
1691*4d6fc14bSjoerg}
1692*4d6fc14bSjoerg
1693*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1694*4d6fc14bSjoergtemplate <class _InputIterator>
1695*4d6fc14bSjoergvoid
1696*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,
1697*4d6fc14bSjoerg                                                          _InputIterator __last)
1698*4d6fc14bSjoerg{
1699*4d6fc14bSjoerg    typedef iterator_traits<_InputIterator> _ITraits;
1700*4d6fc14bSjoerg    typedef typename _ITraits::value_type _ItValueType;
1701*4d6fc14bSjoerg    static_assert((is_same<_ItValueType, __container_value_type>::value),
1702*4d6fc14bSjoerg                  "__assign_unique may only be called with the containers value type");
1703*4d6fc14bSjoerg
1704*4d6fc14bSjoerg    if (bucket_count() != 0)
1705*4d6fc14bSjoerg    {
1706*4d6fc14bSjoerg        __next_pointer __cache = __detach();
1707*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS
1708*4d6fc14bSjoerg        try
1709*4d6fc14bSjoerg        {
1710*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS
1711*4d6fc14bSjoerg            for (; __cache != nullptr && __first != __last; ++__first)
1712*4d6fc14bSjoerg            {
1713*4d6fc14bSjoerg                __cache->__upcast()->__value_ = *__first;
1714*4d6fc14bSjoerg                __next_pointer __next = __cache->__next_;
1715*4d6fc14bSjoerg                __node_insert_unique(__cache->__upcast());
1716*4d6fc14bSjoerg                __cache = __next;
1717*4d6fc14bSjoerg            }
1718*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS
1719*4d6fc14bSjoerg        }
1720*4d6fc14bSjoerg        catch (...)
1721*4d6fc14bSjoerg        {
1722*4d6fc14bSjoerg            __deallocate_node(__cache);
1723*4d6fc14bSjoerg            throw;
1724*4d6fc14bSjoerg        }
1725*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS
1726*4d6fc14bSjoerg        __deallocate_node(__cache);
1727*4d6fc14bSjoerg    }
1728*4d6fc14bSjoerg    for (; __first != __last; ++__first)
1729*4d6fc14bSjoerg        __insert_unique(*__first);
1730*4d6fc14bSjoerg}
1731*4d6fc14bSjoerg
1732*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1733*4d6fc14bSjoergtemplate <class _InputIterator>
1734*4d6fc14bSjoergvoid
1735*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
1736*4d6fc14bSjoerg                                                         _InputIterator __last)
1737*4d6fc14bSjoerg{
1738*4d6fc14bSjoerg    typedef iterator_traits<_InputIterator> _ITraits;
1739*4d6fc14bSjoerg    typedef typename _ITraits::value_type _ItValueType;
1740*4d6fc14bSjoerg    static_assert((is_same<_ItValueType, __container_value_type>::value ||
1741*4d6fc14bSjoerg                  is_same<_ItValueType, __node_value_type>::value),
1742*4d6fc14bSjoerg                  "__assign_multi may only be called with the containers value type"
1743*4d6fc14bSjoerg                  " or the nodes value type");
1744*4d6fc14bSjoerg    if (bucket_count() != 0)
1745*4d6fc14bSjoerg    {
1746*4d6fc14bSjoerg        __next_pointer __cache = __detach();
1747*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS
1748*4d6fc14bSjoerg        try
1749*4d6fc14bSjoerg        {
1750*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS
1751*4d6fc14bSjoerg            for (; __cache != nullptr && __first != __last; ++__first)
1752*4d6fc14bSjoerg            {
1753*4d6fc14bSjoerg                __cache->__upcast()->__value_ = *__first;
1754*4d6fc14bSjoerg                __next_pointer __next = __cache->__next_;
1755*4d6fc14bSjoerg                __node_insert_multi(__cache->__upcast());
1756*4d6fc14bSjoerg                __cache = __next;
1757*4d6fc14bSjoerg            }
1758*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS
1759*4d6fc14bSjoerg        }
1760*4d6fc14bSjoerg        catch (...)
1761*4d6fc14bSjoerg        {
1762*4d6fc14bSjoerg            __deallocate_node(__cache);
1763*4d6fc14bSjoerg            throw;
1764*4d6fc14bSjoerg        }
1765*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS
1766*4d6fc14bSjoerg        __deallocate_node(__cache);
1767*4d6fc14bSjoerg    }
1768*4d6fc14bSjoerg    for (; __first != __last; ++__first)
1769*4d6fc14bSjoerg        __insert_multi(_NodeTypes::__get_value(*__first));
1770*4d6fc14bSjoerg}
1771*4d6fc14bSjoerg
1772*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1773*4d6fc14bSjoerginline
1774*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1775*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
1776*4d6fc14bSjoerg{
1777*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1778*4d6fc14bSjoerg    return iterator(__p1_.first().__next_, this);
1779*4d6fc14bSjoerg#else
1780*4d6fc14bSjoerg    return iterator(__p1_.first().__next_);
1781*4d6fc14bSjoerg#endif
1782*4d6fc14bSjoerg}
1783*4d6fc14bSjoerg
1784*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1785*4d6fc14bSjoerginline
1786*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1787*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
1788*4d6fc14bSjoerg{
1789*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1790*4d6fc14bSjoerg    return iterator(nullptr, this);
1791*4d6fc14bSjoerg#else
1792*4d6fc14bSjoerg    return iterator(nullptr);
1793*4d6fc14bSjoerg#endif
1794*4d6fc14bSjoerg}
1795*4d6fc14bSjoerg
1796*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1797*4d6fc14bSjoerginline
1798*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
1799*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
1800*4d6fc14bSjoerg{
1801*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1802*4d6fc14bSjoerg    return const_iterator(__p1_.first().__next_, this);
1803*4d6fc14bSjoerg#else
1804*4d6fc14bSjoerg    return const_iterator(__p1_.first().__next_);
1805*4d6fc14bSjoerg#endif
1806*4d6fc14bSjoerg}
1807*4d6fc14bSjoerg
1808*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1809*4d6fc14bSjoerginline
1810*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
1811*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
1812*4d6fc14bSjoerg{
1813*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1814*4d6fc14bSjoerg    return const_iterator(nullptr, this);
1815*4d6fc14bSjoerg#else
1816*4d6fc14bSjoerg    return const_iterator(nullptr);
1817*4d6fc14bSjoerg#endif
1818*4d6fc14bSjoerg}
1819*4d6fc14bSjoerg
1820*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1821*4d6fc14bSjoergvoid
1822*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
1823*4d6fc14bSjoerg{
1824*4d6fc14bSjoerg    if (size() > 0)
1825*4d6fc14bSjoerg    {
1826*4d6fc14bSjoerg        __deallocate_node(__p1_.first().__next_);
1827*4d6fc14bSjoerg        __p1_.first().__next_ = nullptr;
1828*4d6fc14bSjoerg        size_type __bc = bucket_count();
1829*4d6fc14bSjoerg        for (size_type __i = 0; __i < __bc; ++__i)
1830*4d6fc14bSjoerg            __bucket_list_[__i] = nullptr;
1831*4d6fc14bSjoerg        size() = 0;
1832*4d6fc14bSjoerg    }
1833*4d6fc14bSjoerg}
1834*4d6fc14bSjoerg
1835*4d6fc14bSjoerg
1836*4d6fc14bSjoerg// Prepare the container for an insertion of the value __value with the hash
1837*4d6fc14bSjoerg// __hash. This does a lookup into the container to see if __value is already
1838*4d6fc14bSjoerg// present, and performs a rehash if necessary. Returns a pointer to the
1839*4d6fc14bSjoerg// existing element if it exists, otherwise nullptr.
1840*4d6fc14bSjoerg//
1841*4d6fc14bSjoerg// Note that this function does forward exceptions if key_eq() throws, and never
1842*4d6fc14bSjoerg// mutates __value or actually inserts into the map.
1843*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1844*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
1845*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1846*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
1847*4d6fc14bSjoerg    size_t __hash, value_type& __value)
1848*4d6fc14bSjoerg{
1849*4d6fc14bSjoerg    size_type __bc = bucket_count();
1850*4d6fc14bSjoerg
1851*4d6fc14bSjoerg    if (__bc != 0)
1852*4d6fc14bSjoerg    {
1853*4d6fc14bSjoerg        size_t __chash = __constrain_hash(__hash, __bc);
1854*4d6fc14bSjoerg        __next_pointer __ndptr = __bucket_list_[__chash];
1855*4d6fc14bSjoerg        if (__ndptr != nullptr)
1856*4d6fc14bSjoerg        {
1857*4d6fc14bSjoerg            for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
1858*4d6fc14bSjoerg                                             __constrain_hash(__ndptr->__hash(), __bc) == __chash;
1859*4d6fc14bSjoerg                                                     __ndptr = __ndptr->__next_)
1860*4d6fc14bSjoerg            {
1861*4d6fc14bSjoerg                if (key_eq()(__ndptr->__upcast()->__value_, __value))
1862*4d6fc14bSjoerg                    return __ndptr;
1863*4d6fc14bSjoerg            }
1864*4d6fc14bSjoerg        }
1865*4d6fc14bSjoerg    }
1866*4d6fc14bSjoerg    if (size()+1 > __bc * max_load_factor() || __bc == 0)
1867*4d6fc14bSjoerg    {
1868*4d6fc14bSjoerg        rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
1869*4d6fc14bSjoerg                                     size_type(ceil(float(size() + 1) / max_load_factor()))));
1870*4d6fc14bSjoerg    }
1871*4d6fc14bSjoerg    return nullptr;
1872*4d6fc14bSjoerg}
1873*4d6fc14bSjoerg
1874*4d6fc14bSjoerg// Insert the node __nd into the container by pushing it into the right bucket,
1875*4d6fc14bSjoerg// and updating size(). Assumes that __nd->__hash is up-to-date, and that
1876*4d6fc14bSjoerg// rehashing has already occurred and that no element with the same key exists
1877*4d6fc14bSjoerg// in the map.
1878*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1879*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
1880*4d6fc14bSjoergvoid
1881*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
1882*4d6fc14bSjoerg    __node_pointer __nd) _NOEXCEPT
1883*4d6fc14bSjoerg{
1884*4d6fc14bSjoerg    size_type __bc = bucket_count();
1885*4d6fc14bSjoerg    size_t __chash = __constrain_hash(__nd->__hash(), __bc);
1886*4d6fc14bSjoerg    // insert_after __bucket_list_[__chash], or __first_node if bucket is null
1887*4d6fc14bSjoerg    __next_pointer __pn = __bucket_list_[__chash];
1888*4d6fc14bSjoerg    if (__pn == nullptr)
1889*4d6fc14bSjoerg    {
1890*4d6fc14bSjoerg        __pn =__p1_.first().__ptr();
1891*4d6fc14bSjoerg        __nd->__next_ = __pn->__next_;
1892*4d6fc14bSjoerg        __pn->__next_ = __nd->__ptr();
1893*4d6fc14bSjoerg        // fix up __bucket_list_
1894*4d6fc14bSjoerg        __bucket_list_[__chash] = __pn;
1895*4d6fc14bSjoerg        if (__nd->__next_ != nullptr)
1896*4d6fc14bSjoerg            __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
1897*4d6fc14bSjoerg    }
1898*4d6fc14bSjoerg    else
1899*4d6fc14bSjoerg    {
1900*4d6fc14bSjoerg        __nd->__next_ = __pn->__next_;
1901*4d6fc14bSjoerg        __pn->__next_ = __nd->__ptr();
1902*4d6fc14bSjoerg    }
1903*4d6fc14bSjoerg    ++size();
1904*4d6fc14bSjoerg}
1905*4d6fc14bSjoerg
1906*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1907*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1908*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
1909*4d6fc14bSjoerg{
1910*4d6fc14bSjoerg    __nd->__hash_ = hash_function()(__nd->__value_);
1911*4d6fc14bSjoerg    __next_pointer __existing_node =
1912*4d6fc14bSjoerg        __node_insert_unique_prepare(__nd->__hash(), __nd->__value_);
1913*4d6fc14bSjoerg
1914*4d6fc14bSjoerg    // Insert the node, unless it already exists in the container.
1915*4d6fc14bSjoerg    bool __inserted = false;
1916*4d6fc14bSjoerg    if (__existing_node == nullptr)
1917*4d6fc14bSjoerg    {
1918*4d6fc14bSjoerg        __node_insert_unique_perform(__nd);
1919*4d6fc14bSjoerg        __existing_node = __nd->__ptr();
1920*4d6fc14bSjoerg        __inserted = true;
1921*4d6fc14bSjoerg    }
1922*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
1923*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
1924*4d6fc14bSjoerg#else
1925*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__existing_node), __inserted);
1926*4d6fc14bSjoerg#endif
1927*4d6fc14bSjoerg}
1928*4d6fc14bSjoerg
1929*4d6fc14bSjoerg// Prepare the container for an insertion of the value __cp_val with the hash
1930*4d6fc14bSjoerg// __cp_hash. This does a lookup into the container to see if __cp_value is
1931*4d6fc14bSjoerg// already present, and performs a rehash if necessary. Returns a pointer to the
1932*4d6fc14bSjoerg// last occurrence of __cp_val in the map.
1933*4d6fc14bSjoerg//
1934*4d6fc14bSjoerg// Note that this function does forward exceptions if key_eq() throws, and never
1935*4d6fc14bSjoerg// mutates __value or actually inserts into the map.
1936*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1937*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1938*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
1939*4d6fc14bSjoerg    size_t __cp_hash, value_type& __cp_val)
1940*4d6fc14bSjoerg{
1941*4d6fc14bSjoerg    size_type __bc = bucket_count();
1942*4d6fc14bSjoerg    if (size()+1 > __bc * max_load_factor() || __bc == 0)
1943*4d6fc14bSjoerg    {
1944*4d6fc14bSjoerg        rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
1945*4d6fc14bSjoerg                       size_type(ceil(float(size() + 1) / max_load_factor()))));
1946*4d6fc14bSjoerg        __bc = bucket_count();
1947*4d6fc14bSjoerg    }
1948*4d6fc14bSjoerg    size_t __chash = __constrain_hash(__cp_hash, __bc);
1949*4d6fc14bSjoerg    __next_pointer __pn = __bucket_list_[__chash];
1950*4d6fc14bSjoerg    if (__pn != nullptr)
1951*4d6fc14bSjoerg    {
1952*4d6fc14bSjoerg        for (bool __found = false; __pn->__next_ != nullptr &&
1953*4d6fc14bSjoerg                                   __constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
1954*4d6fc14bSjoerg                                                           __pn = __pn->__next_)
1955*4d6fc14bSjoerg        {
1956*4d6fc14bSjoerg            //      __found    key_eq()     action
1957*4d6fc14bSjoerg            //      false       false       loop
1958*4d6fc14bSjoerg            //      true        true        loop
1959*4d6fc14bSjoerg            //      false       true        set __found to true
1960*4d6fc14bSjoerg            //      true        false       break
1961*4d6fc14bSjoerg            if (__found != (__pn->__next_->__hash() == __cp_hash &&
1962*4d6fc14bSjoerg                            key_eq()(__pn->__next_->__upcast()->__value_, __cp_val)))
1963*4d6fc14bSjoerg            {
1964*4d6fc14bSjoerg                if (!__found)
1965*4d6fc14bSjoerg                    __found = true;
1966*4d6fc14bSjoerg                else
1967*4d6fc14bSjoerg                    break;
1968*4d6fc14bSjoerg            }
1969*4d6fc14bSjoerg        }
1970*4d6fc14bSjoerg    }
1971*4d6fc14bSjoerg    return __pn;
1972*4d6fc14bSjoerg}
1973*4d6fc14bSjoerg
1974*4d6fc14bSjoerg// Insert the node __cp into the container after __pn (which is the last node in
1975*4d6fc14bSjoerg// the bucket that compares equal to __cp). Rehashing, and checking for
1976*4d6fc14bSjoerg// uniqueness has already been performed (in __node_insert_multi_prepare), so
1977*4d6fc14bSjoerg// all we need to do is update the bucket and size(). Assumes that __cp->__hash
1978*4d6fc14bSjoerg// is up-to-date.
1979*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
1980*4d6fc14bSjoergvoid
1981*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
1982*4d6fc14bSjoerg    __node_pointer __cp, __next_pointer __pn) _NOEXCEPT
1983*4d6fc14bSjoerg{
1984*4d6fc14bSjoerg    size_type __bc = bucket_count();
1985*4d6fc14bSjoerg    size_t __chash = __constrain_hash(__cp->__hash_, __bc);
1986*4d6fc14bSjoerg    if (__pn == nullptr)
1987*4d6fc14bSjoerg    {
1988*4d6fc14bSjoerg        __pn =__p1_.first().__ptr();
1989*4d6fc14bSjoerg        __cp->__next_ = __pn->__next_;
1990*4d6fc14bSjoerg        __pn->__next_ = __cp->__ptr();
1991*4d6fc14bSjoerg        // fix up __bucket_list_
1992*4d6fc14bSjoerg        __bucket_list_[__chash] = __pn;
1993*4d6fc14bSjoerg        if (__cp->__next_ != nullptr)
1994*4d6fc14bSjoerg            __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)]
1995*4d6fc14bSjoerg                = __cp->__ptr();
1996*4d6fc14bSjoerg    }
1997*4d6fc14bSjoerg    else
1998*4d6fc14bSjoerg    {
1999*4d6fc14bSjoerg        __cp->__next_ = __pn->__next_;
2000*4d6fc14bSjoerg        __pn->__next_ = __cp->__ptr();
2001*4d6fc14bSjoerg        if (__cp->__next_ != nullptr)
2002*4d6fc14bSjoerg        {
2003*4d6fc14bSjoerg            size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc);
2004*4d6fc14bSjoerg            if (__nhash != __chash)
2005*4d6fc14bSjoerg                __bucket_list_[__nhash] = __cp->__ptr();
2006*4d6fc14bSjoerg        }
2007*4d6fc14bSjoerg    }
2008*4d6fc14bSjoerg    ++size();
2009*4d6fc14bSjoerg}
2010*4d6fc14bSjoerg
2011*4d6fc14bSjoerg
2012*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2013*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2014*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
2015*4d6fc14bSjoerg{
2016*4d6fc14bSjoerg    __cp->__hash_ = hash_function()(__cp->__value_);
2017*4d6fc14bSjoerg    __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
2018*4d6fc14bSjoerg    __node_insert_multi_perform(__cp, __pn);
2019*4d6fc14bSjoerg
2020*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2021*4d6fc14bSjoerg    return iterator(__cp->__ptr(), this);
2022*4d6fc14bSjoerg#else
2023*4d6fc14bSjoerg    return iterator(__cp->__ptr());
2024*4d6fc14bSjoerg#endif
2025*4d6fc14bSjoerg}
2026*4d6fc14bSjoerg
2027*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2028*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2029*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
2030*4d6fc14bSjoerg        const_iterator __p, __node_pointer __cp)
2031*4d6fc14bSjoerg{
2032*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2033*4d6fc14bSjoerg    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
2034*4d6fc14bSjoerg        "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
2035*4d6fc14bSjoerg        " referring to this unordered container");
2036*4d6fc14bSjoerg#endif
2037*4d6fc14bSjoerg    if (__p != end() && key_eq()(*__p, __cp->__value_))
2038*4d6fc14bSjoerg    {
2039*4d6fc14bSjoerg        __next_pointer __np = __p.__node_;
2040*4d6fc14bSjoerg        __cp->__hash_ = __np->__hash();
2041*4d6fc14bSjoerg        size_type __bc = bucket_count();
2042*4d6fc14bSjoerg        if (size()+1 > __bc * max_load_factor() || __bc == 0)
2043*4d6fc14bSjoerg        {
2044*4d6fc14bSjoerg            rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
2045*4d6fc14bSjoerg                           size_type(ceil(float(size() + 1) / max_load_factor()))));
2046*4d6fc14bSjoerg            __bc = bucket_count();
2047*4d6fc14bSjoerg        }
2048*4d6fc14bSjoerg        size_t __chash = __constrain_hash(__cp->__hash_, __bc);
2049*4d6fc14bSjoerg        __next_pointer __pp = __bucket_list_[__chash];
2050*4d6fc14bSjoerg        while (__pp->__next_ != __np)
2051*4d6fc14bSjoerg            __pp = __pp->__next_;
2052*4d6fc14bSjoerg        __cp->__next_ = __np;
2053*4d6fc14bSjoerg        __pp->__next_ = static_cast<__next_pointer>(__cp);
2054*4d6fc14bSjoerg        ++size();
2055*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2056*4d6fc14bSjoerg        return iterator(static_cast<__next_pointer>(__cp), this);
2057*4d6fc14bSjoerg#else
2058*4d6fc14bSjoerg        return iterator(static_cast<__next_pointer>(__cp));
2059*4d6fc14bSjoerg#endif
2060*4d6fc14bSjoerg    }
2061*4d6fc14bSjoerg    return __node_insert_multi(__cp);
2062*4d6fc14bSjoerg}
2063*4d6fc14bSjoerg
2064*4d6fc14bSjoerg
2065*4d6fc14bSjoerg
2066*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2067*4d6fc14bSjoergtemplate <class _Key, class ..._Args>
2068*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
2069*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
2070*4d6fc14bSjoerg{
2071*4d6fc14bSjoerg
2072*4d6fc14bSjoerg    size_t __hash = hash_function()(__k);
2073*4d6fc14bSjoerg    size_type __bc = bucket_count();
2074*4d6fc14bSjoerg    bool __inserted = false;
2075*4d6fc14bSjoerg    __next_pointer __nd;
2076*4d6fc14bSjoerg    size_t __chash;
2077*4d6fc14bSjoerg    if (__bc != 0)
2078*4d6fc14bSjoerg    {
2079*4d6fc14bSjoerg        __chash = __constrain_hash(__hash, __bc);
2080*4d6fc14bSjoerg        __nd = __bucket_list_[__chash];
2081*4d6fc14bSjoerg        if (__nd != nullptr)
2082*4d6fc14bSjoerg        {
2083*4d6fc14bSjoerg            for (__nd = __nd->__next_; __nd != nullptr &&
2084*4d6fc14bSjoerg                (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash);
2085*4d6fc14bSjoerg                                                           __nd = __nd->__next_)
2086*4d6fc14bSjoerg            {
2087*4d6fc14bSjoerg                if (key_eq()(__nd->__upcast()->__value_, __k))
2088*4d6fc14bSjoerg                    goto __done;
2089*4d6fc14bSjoerg            }
2090*4d6fc14bSjoerg        }
2091*4d6fc14bSjoerg    }
2092*4d6fc14bSjoerg    {
2093*4d6fc14bSjoerg        __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...);
2094*4d6fc14bSjoerg        if (size()+1 > __bc * max_load_factor() || __bc == 0)
2095*4d6fc14bSjoerg        {
2096*4d6fc14bSjoerg            rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
2097*4d6fc14bSjoerg                           size_type(ceil(float(size() + 1) / max_load_factor()))));
2098*4d6fc14bSjoerg            __bc = bucket_count();
2099*4d6fc14bSjoerg            __chash = __constrain_hash(__hash, __bc);
2100*4d6fc14bSjoerg        }
2101*4d6fc14bSjoerg        // insert_after __bucket_list_[__chash], or __first_node if bucket is null
2102*4d6fc14bSjoerg        __next_pointer __pn = __bucket_list_[__chash];
2103*4d6fc14bSjoerg        if (__pn == nullptr)
2104*4d6fc14bSjoerg        {
2105*4d6fc14bSjoerg            __pn = __p1_.first().__ptr();
2106*4d6fc14bSjoerg            __h->__next_ = __pn->__next_;
2107*4d6fc14bSjoerg            __pn->__next_ = __h.get()->__ptr();
2108*4d6fc14bSjoerg            // fix up __bucket_list_
2109*4d6fc14bSjoerg            __bucket_list_[__chash] = __pn;
2110*4d6fc14bSjoerg            if (__h->__next_ != nullptr)
2111*4d6fc14bSjoerg                __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)]
2112*4d6fc14bSjoerg                    = __h.get()->__ptr();
2113*4d6fc14bSjoerg        }
2114*4d6fc14bSjoerg        else
2115*4d6fc14bSjoerg        {
2116*4d6fc14bSjoerg            __h->__next_ = __pn->__next_;
2117*4d6fc14bSjoerg            __pn->__next_ = static_cast<__next_pointer>(__h.get());
2118*4d6fc14bSjoerg        }
2119*4d6fc14bSjoerg        __nd = static_cast<__next_pointer>(__h.release());
2120*4d6fc14bSjoerg        // increment size
2121*4d6fc14bSjoerg        ++size();
2122*4d6fc14bSjoerg        __inserted = true;
2123*4d6fc14bSjoerg    }
2124*4d6fc14bSjoerg__done:
2125*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2126*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__nd, this), __inserted);
2127*4d6fc14bSjoerg#else
2128*4d6fc14bSjoerg    return pair<iterator, bool>(iterator(__nd), __inserted);
2129*4d6fc14bSjoerg#endif
2130*4d6fc14bSjoerg}
2131*4d6fc14bSjoerg
2132*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2133*4d6fc14bSjoergtemplate <class... _Args>
2134*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
2135*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args)
2136*4d6fc14bSjoerg{
2137*4d6fc14bSjoerg    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2138*4d6fc14bSjoerg    pair<iterator, bool> __r = __node_insert_unique(__h.get());
2139*4d6fc14bSjoerg    if (__r.second)
2140*4d6fc14bSjoerg        __h.release();
2141*4d6fc14bSjoerg    return __r;
2142*4d6fc14bSjoerg}
2143*4d6fc14bSjoerg
2144*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2145*4d6fc14bSjoergtemplate <class... _Args>
2146*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2147*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args)
2148*4d6fc14bSjoerg{
2149*4d6fc14bSjoerg    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2150*4d6fc14bSjoerg    iterator __r = __node_insert_multi(__h.get());
2151*4d6fc14bSjoerg    __h.release();
2152*4d6fc14bSjoerg    return __r;
2153*4d6fc14bSjoerg}
2154*4d6fc14bSjoerg
2155*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2156*4d6fc14bSjoergtemplate <class... _Args>
2157*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2158*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
2159*4d6fc14bSjoerg        const_iterator __p, _Args&&... __args)
2160*4d6fc14bSjoerg{
2161*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2162*4d6fc14bSjoerg    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
2163*4d6fc14bSjoerg        "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
2164*4d6fc14bSjoerg        " referring to this unordered container");
2165*4d6fc14bSjoerg#endif
2166*4d6fc14bSjoerg    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
2167*4d6fc14bSjoerg    iterator __r = __node_insert_multi(__p, __h.get());
2168*4d6fc14bSjoerg    __h.release();
2169*4d6fc14bSjoerg    return __r;
2170*4d6fc14bSjoerg}
2171*4d6fc14bSjoerg
2172*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14
2173*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2174*4d6fc14bSjoergtemplate <class _NodeHandle, class _InsertReturnType>
2175*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2176*4d6fc14bSjoerg_InsertReturnType
2177*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
2178*4d6fc14bSjoerg    _NodeHandle&& __nh)
2179*4d6fc14bSjoerg{
2180*4d6fc14bSjoerg    if (__nh.empty())
2181*4d6fc14bSjoerg        return _InsertReturnType{end(), false, _NodeHandle()};
2182*4d6fc14bSjoerg    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
2183*4d6fc14bSjoerg    if (__result.second)
2184*4d6fc14bSjoerg        __nh.__release_ptr();
2185*4d6fc14bSjoerg    return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
2186*4d6fc14bSjoerg}
2187*4d6fc14bSjoerg
2188*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2189*4d6fc14bSjoergtemplate <class _NodeHandle>
2190*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2191*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2192*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
2193*4d6fc14bSjoerg    const_iterator, _NodeHandle&& __nh)
2194*4d6fc14bSjoerg{
2195*4d6fc14bSjoerg    if (__nh.empty())
2196*4d6fc14bSjoerg        return end();
2197*4d6fc14bSjoerg    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
2198*4d6fc14bSjoerg    if (__result.second)
2199*4d6fc14bSjoerg        __nh.__release_ptr();
2200*4d6fc14bSjoerg    return __result.first;
2201*4d6fc14bSjoerg}
2202*4d6fc14bSjoerg
2203*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2204*4d6fc14bSjoergtemplate <class _NodeHandle>
2205*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2206*4d6fc14bSjoerg_NodeHandle
2207*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
2208*4d6fc14bSjoerg    key_type const& __key)
2209*4d6fc14bSjoerg{
2210*4d6fc14bSjoerg    iterator __i = find(__key);
2211*4d6fc14bSjoerg    if (__i == end())
2212*4d6fc14bSjoerg        return _NodeHandle();
2213*4d6fc14bSjoerg    return __node_handle_extract<_NodeHandle>(__i);
2214*4d6fc14bSjoerg}
2215*4d6fc14bSjoerg
2216*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2217*4d6fc14bSjoergtemplate <class _NodeHandle>
2218*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2219*4d6fc14bSjoerg_NodeHandle
2220*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
2221*4d6fc14bSjoerg    const_iterator __p)
2222*4d6fc14bSjoerg{
2223*4d6fc14bSjoerg    allocator_type __alloc(__node_alloc());
2224*4d6fc14bSjoerg    return _NodeHandle(remove(__p).release(), __alloc);
2225*4d6fc14bSjoerg}
2226*4d6fc14bSjoerg
2227*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2228*4d6fc14bSjoergtemplate <class _Table>
2229*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2230*4d6fc14bSjoergvoid
2231*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
2232*4d6fc14bSjoerg    _Table& __source)
2233*4d6fc14bSjoerg{
2234*4d6fc14bSjoerg    static_assert(is_same<__node, typename _Table::__node>::value, "");
2235*4d6fc14bSjoerg
2236*4d6fc14bSjoerg    for (typename _Table::iterator __it = __source.begin();
2237*4d6fc14bSjoerg         __it != __source.end();)
2238*4d6fc14bSjoerg    {
2239*4d6fc14bSjoerg        __node_pointer __src_ptr = __it.__node_->__upcast();
2240*4d6fc14bSjoerg        size_t __hash = hash_function()(__src_ptr->__value_);
2241*4d6fc14bSjoerg        __next_pointer __existing_node =
2242*4d6fc14bSjoerg            __node_insert_unique_prepare(__hash, __src_ptr->__value_);
2243*4d6fc14bSjoerg        auto __prev_iter = __it++;
2244*4d6fc14bSjoerg        if (__existing_node == nullptr)
2245*4d6fc14bSjoerg        {
2246*4d6fc14bSjoerg            (void)__source.remove(__prev_iter).release();
2247*4d6fc14bSjoerg            __src_ptr->__hash_ = __hash;
2248*4d6fc14bSjoerg            __node_insert_unique_perform(__src_ptr);
2249*4d6fc14bSjoerg        }
2250*4d6fc14bSjoerg    }
2251*4d6fc14bSjoerg}
2252*4d6fc14bSjoerg
2253*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2254*4d6fc14bSjoergtemplate <class _NodeHandle>
2255*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2256*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2257*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
2258*4d6fc14bSjoerg    _NodeHandle&& __nh)
2259*4d6fc14bSjoerg{
2260*4d6fc14bSjoerg    if (__nh.empty())
2261*4d6fc14bSjoerg        return end();
2262*4d6fc14bSjoerg    iterator __result = __node_insert_multi(__nh.__ptr_);
2263*4d6fc14bSjoerg    __nh.__release_ptr();
2264*4d6fc14bSjoerg    return __result;
2265*4d6fc14bSjoerg}
2266*4d6fc14bSjoerg
2267*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2268*4d6fc14bSjoergtemplate <class _NodeHandle>
2269*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2270*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2271*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
2272*4d6fc14bSjoerg    const_iterator __hint, _NodeHandle&& __nh)
2273*4d6fc14bSjoerg{
2274*4d6fc14bSjoerg    if (__nh.empty())
2275*4d6fc14bSjoerg        return end();
2276*4d6fc14bSjoerg    iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
2277*4d6fc14bSjoerg    __nh.__release_ptr();
2278*4d6fc14bSjoerg    return __result;
2279*4d6fc14bSjoerg}
2280*4d6fc14bSjoerg
2281*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2282*4d6fc14bSjoergtemplate <class _Table>
2283*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
2284*4d6fc14bSjoergvoid
2285*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
2286*4d6fc14bSjoerg    _Table& __source)
2287*4d6fc14bSjoerg{
2288*4d6fc14bSjoerg    static_assert(is_same<typename _Table::__node, __node>::value, "");
2289*4d6fc14bSjoerg
2290*4d6fc14bSjoerg    for (typename _Table::iterator __it = __source.begin();
2291*4d6fc14bSjoerg         __it != __source.end();)
2292*4d6fc14bSjoerg    {
2293*4d6fc14bSjoerg        __node_pointer __src_ptr = __it.__node_->__upcast();
2294*4d6fc14bSjoerg        size_t __src_hash = hash_function()(__src_ptr->__value_);
2295*4d6fc14bSjoerg        __next_pointer __pn =
2296*4d6fc14bSjoerg            __node_insert_multi_prepare(__src_hash, __src_ptr->__value_);
2297*4d6fc14bSjoerg        (void)__source.remove(__it++).release();
2298*4d6fc14bSjoerg        __src_ptr->__hash_ = __src_hash;
2299*4d6fc14bSjoerg        __node_insert_multi_perform(__src_ptr, __pn);
2300*4d6fc14bSjoerg    }
2301*4d6fc14bSjoerg}
2302*4d6fc14bSjoerg#endif // _LIBCPP_STD_VER > 14
2303*4d6fc14bSjoerg
2304*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2305*4d6fc14bSjoergvoid
2306*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)
2307*4d6fc14bSjoerg_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
2308*4d6fc14bSjoerg{
2309*4d6fc14bSjoerg    if (__n == 1)
2310*4d6fc14bSjoerg        __n = 2;
2311*4d6fc14bSjoerg    else if (__n & (__n - 1))
2312*4d6fc14bSjoerg        __n = __next_prime(__n);
2313*4d6fc14bSjoerg    size_type __bc = bucket_count();
2314*4d6fc14bSjoerg    if (__n > __bc)
2315*4d6fc14bSjoerg        __rehash(__n);
2316*4d6fc14bSjoerg    else if (__n < __bc)
2317*4d6fc14bSjoerg    {
2318*4d6fc14bSjoerg        __n = _VSTD::max<size_type>
2319*4d6fc14bSjoerg              (
2320*4d6fc14bSjoerg                  __n,
2321*4d6fc14bSjoerg                  __is_hash_power2(__bc) ? __next_hash_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
2322*4d6fc14bSjoerg                                           __next_prime(size_t(ceil(float(size()) / max_load_factor())))
2323*4d6fc14bSjoerg              );
2324*4d6fc14bSjoerg        if (__n < __bc)
2325*4d6fc14bSjoerg            __rehash(__n);
2326*4d6fc14bSjoerg    }
2327*4d6fc14bSjoerg}
2328*4d6fc14bSjoerg
2329*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2330*4d6fc14bSjoergvoid
2331*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
2332*4d6fc14bSjoerg{
2333*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2334*4d6fc14bSjoerg    __get_db()->__invalidate_all(this);
2335*4d6fc14bSjoerg#endif
2336*4d6fc14bSjoerg    __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
2337*4d6fc14bSjoerg    __bucket_list_.reset(__nbc > 0 ?
2338*4d6fc14bSjoerg                      __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
2339*4d6fc14bSjoerg    __bucket_list_.get_deleter().size() = __nbc;
2340*4d6fc14bSjoerg    if (__nbc > 0)
2341*4d6fc14bSjoerg    {
2342*4d6fc14bSjoerg        for (size_type __i = 0; __i < __nbc; ++__i)
2343*4d6fc14bSjoerg            __bucket_list_[__i] = nullptr;
2344*4d6fc14bSjoerg        __next_pointer __pp = __p1_.first().__ptr();
2345*4d6fc14bSjoerg        __next_pointer __cp = __pp->__next_;
2346*4d6fc14bSjoerg        if (__cp != nullptr)
2347*4d6fc14bSjoerg        {
2348*4d6fc14bSjoerg            size_type __chash = __constrain_hash(__cp->__hash(), __nbc);
2349*4d6fc14bSjoerg            __bucket_list_[__chash] = __pp;
2350*4d6fc14bSjoerg            size_type __phash = __chash;
2351*4d6fc14bSjoerg            for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr;
2352*4d6fc14bSjoerg                                                           __cp = __pp->__next_)
2353*4d6fc14bSjoerg            {
2354*4d6fc14bSjoerg                __chash = __constrain_hash(__cp->__hash(), __nbc);
2355*4d6fc14bSjoerg                if (__chash == __phash)
2356*4d6fc14bSjoerg                    __pp = __cp;
2357*4d6fc14bSjoerg                else
2358*4d6fc14bSjoerg                {
2359*4d6fc14bSjoerg                    if (__bucket_list_[__chash] == nullptr)
2360*4d6fc14bSjoerg                    {
2361*4d6fc14bSjoerg                        __bucket_list_[__chash] = __pp;
2362*4d6fc14bSjoerg                        __pp = __cp;
2363*4d6fc14bSjoerg                        __phash = __chash;
2364*4d6fc14bSjoerg                    }
2365*4d6fc14bSjoerg                    else
2366*4d6fc14bSjoerg                    {
2367*4d6fc14bSjoerg                        __next_pointer __np = __cp;
2368*4d6fc14bSjoerg                        for (; __np->__next_ != nullptr &&
2369*4d6fc14bSjoerg                               key_eq()(__cp->__upcast()->__value_,
2370*4d6fc14bSjoerg                                        __np->__next_->__upcast()->__value_);
2371*4d6fc14bSjoerg                                                           __np = __np->__next_)
2372*4d6fc14bSjoerg                            ;
2373*4d6fc14bSjoerg                        __pp->__next_ = __np->__next_;
2374*4d6fc14bSjoerg                        __np->__next_ = __bucket_list_[__chash]->__next_;
2375*4d6fc14bSjoerg                        __bucket_list_[__chash]->__next_ = __cp;
2376*4d6fc14bSjoerg
2377*4d6fc14bSjoerg                    }
2378*4d6fc14bSjoerg                }
2379*4d6fc14bSjoerg            }
2380*4d6fc14bSjoerg        }
2381*4d6fc14bSjoerg    }
2382*4d6fc14bSjoerg}
2383*4d6fc14bSjoerg
2384*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2385*4d6fc14bSjoergtemplate <class _Key>
2386*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2387*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
2388*4d6fc14bSjoerg{
2389*4d6fc14bSjoerg    size_t __hash = hash_function()(__k);
2390*4d6fc14bSjoerg    size_type __bc = bucket_count();
2391*4d6fc14bSjoerg    if (__bc != 0)
2392*4d6fc14bSjoerg    {
2393*4d6fc14bSjoerg        size_t __chash = __constrain_hash(__hash, __bc);
2394*4d6fc14bSjoerg        __next_pointer __nd = __bucket_list_[__chash];
2395*4d6fc14bSjoerg        if (__nd != nullptr)
2396*4d6fc14bSjoerg        {
2397*4d6fc14bSjoerg            for (__nd = __nd->__next_; __nd != nullptr &&
2398*4d6fc14bSjoerg                (__nd->__hash() == __hash
2399*4d6fc14bSjoerg                  || __constrain_hash(__nd->__hash(), __bc) == __chash);
2400*4d6fc14bSjoerg                                                           __nd = __nd->__next_)
2401*4d6fc14bSjoerg            {
2402*4d6fc14bSjoerg                if ((__nd->__hash() == __hash)
2403*4d6fc14bSjoerg                    && key_eq()(__nd->__upcast()->__value_, __k))
2404*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2405*4d6fc14bSjoerg                    return iterator(__nd, this);
2406*4d6fc14bSjoerg#else
2407*4d6fc14bSjoerg                    return iterator(__nd);
2408*4d6fc14bSjoerg#endif
2409*4d6fc14bSjoerg            }
2410*4d6fc14bSjoerg        }
2411*4d6fc14bSjoerg    }
2412*4d6fc14bSjoerg    return end();
2413*4d6fc14bSjoerg}
2414*4d6fc14bSjoerg
2415*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2416*4d6fc14bSjoergtemplate <class _Key>
2417*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
2418*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
2419*4d6fc14bSjoerg{
2420*4d6fc14bSjoerg    size_t __hash = hash_function()(__k);
2421*4d6fc14bSjoerg    size_type __bc = bucket_count();
2422*4d6fc14bSjoerg    if (__bc != 0)
2423*4d6fc14bSjoerg    {
2424*4d6fc14bSjoerg        size_t __chash = __constrain_hash(__hash, __bc);
2425*4d6fc14bSjoerg        __next_pointer __nd = __bucket_list_[__chash];
2426*4d6fc14bSjoerg        if (__nd != nullptr)
2427*4d6fc14bSjoerg        {
2428*4d6fc14bSjoerg            for (__nd = __nd->__next_; __nd != nullptr &&
2429*4d6fc14bSjoerg                (__hash == __nd->__hash()
2430*4d6fc14bSjoerg                    || __constrain_hash(__nd->__hash(), __bc) == __chash);
2431*4d6fc14bSjoerg                                                           __nd = __nd->__next_)
2432*4d6fc14bSjoerg            {
2433*4d6fc14bSjoerg                if ((__nd->__hash() == __hash)
2434*4d6fc14bSjoerg                    && key_eq()(__nd->__upcast()->__value_, __k))
2435*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2436*4d6fc14bSjoerg                    return const_iterator(__nd, this);
2437*4d6fc14bSjoerg#else
2438*4d6fc14bSjoerg                    return const_iterator(__nd);
2439*4d6fc14bSjoerg#endif
2440*4d6fc14bSjoerg            }
2441*4d6fc14bSjoerg        }
2442*4d6fc14bSjoerg
2443*4d6fc14bSjoerg    }
2444*4d6fc14bSjoerg    return end();
2445*4d6fc14bSjoerg}
2446*4d6fc14bSjoerg
2447*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2448*4d6fc14bSjoergtemplate <class ..._Args>
2449*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
2450*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
2451*4d6fc14bSjoerg{
2452*4d6fc14bSjoerg    static_assert(!__is_hash_value_type<_Args...>::value,
2453*4d6fc14bSjoerg                  "Construct cannot be called with a hash value type");
2454*4d6fc14bSjoerg    __node_allocator& __na = __node_alloc();
2455*4d6fc14bSjoerg    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
2456*4d6fc14bSjoerg    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
2457*4d6fc14bSjoerg    __h.get_deleter().__value_constructed = true;
2458*4d6fc14bSjoerg    __h->__hash_ = hash_function()(__h->__value_);
2459*4d6fc14bSjoerg    __h->__next_ = nullptr;
2460*4d6fc14bSjoerg    return __h;
2461*4d6fc14bSjoerg}
2462*4d6fc14bSjoerg
2463*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2464*4d6fc14bSjoergtemplate <class _First, class ..._Rest>
2465*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
2466*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(
2467*4d6fc14bSjoerg    size_t __hash, _First&& __f, _Rest&& ...__rest)
2468*4d6fc14bSjoerg{
2469*4d6fc14bSjoerg    static_assert(!__is_hash_value_type<_First, _Rest...>::value,
2470*4d6fc14bSjoerg                  "Construct cannot be called with a hash value type");
2471*4d6fc14bSjoerg    __node_allocator& __na = __node_alloc();
2472*4d6fc14bSjoerg    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
2473*4d6fc14bSjoerg    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_),
2474*4d6fc14bSjoerg                             _VSTD::forward<_First>(__f),
2475*4d6fc14bSjoerg                             _VSTD::forward<_Rest>(__rest)...);
2476*4d6fc14bSjoerg    __h.get_deleter().__value_constructed = true;
2477*4d6fc14bSjoerg    __h->__hash_ = __hash;
2478*4d6fc14bSjoerg    __h->__next_ = nullptr;
2479*4d6fc14bSjoerg    return __h;
2480*4d6fc14bSjoerg}
2481*4d6fc14bSjoerg
2482*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2483*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2484*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
2485*4d6fc14bSjoerg{
2486*4d6fc14bSjoerg    __next_pointer __np = __p.__node_;
2487*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2488*4d6fc14bSjoerg    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
2489*4d6fc14bSjoerg        "unordered container erase(iterator) called with an iterator not"
2490*4d6fc14bSjoerg        " referring to this container");
2491*4d6fc14bSjoerg    _LIBCPP_ASSERT(__p != end(),
2492*4d6fc14bSjoerg        "unordered container erase(iterator) called with a non-dereferenceable iterator");
2493*4d6fc14bSjoerg    iterator __r(__np, this);
2494*4d6fc14bSjoerg#else
2495*4d6fc14bSjoerg    iterator __r(__np);
2496*4d6fc14bSjoerg#endif
2497*4d6fc14bSjoerg    ++__r;
2498*4d6fc14bSjoerg    remove(__p);
2499*4d6fc14bSjoerg    return __r;
2500*4d6fc14bSjoerg}
2501*4d6fc14bSjoerg
2502*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2503*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2504*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
2505*4d6fc14bSjoerg                                                const_iterator __last)
2506*4d6fc14bSjoerg{
2507*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2508*4d6fc14bSjoerg    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
2509*4d6fc14bSjoerg        "unordered container::erase(iterator, iterator) called with an iterator not"
2510*4d6fc14bSjoerg        " referring to this container");
2511*4d6fc14bSjoerg    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,
2512*4d6fc14bSjoerg        "unordered container::erase(iterator, iterator) called with an iterator not"
2513*4d6fc14bSjoerg        " referring to this container");
2514*4d6fc14bSjoerg#endif
2515*4d6fc14bSjoerg    for (const_iterator __p = __first; __first != __last; __p = __first)
2516*4d6fc14bSjoerg    {
2517*4d6fc14bSjoerg        ++__first;
2518*4d6fc14bSjoerg        erase(__p);
2519*4d6fc14bSjoerg    }
2520*4d6fc14bSjoerg    __next_pointer __np = __last.__node_;
2521*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2522*4d6fc14bSjoerg    return iterator (__np, this);
2523*4d6fc14bSjoerg#else
2524*4d6fc14bSjoerg    return iterator (__np);
2525*4d6fc14bSjoerg#endif
2526*4d6fc14bSjoerg}
2527*4d6fc14bSjoerg
2528*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2529*4d6fc14bSjoergtemplate <class _Key>
2530*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2531*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k)
2532*4d6fc14bSjoerg{
2533*4d6fc14bSjoerg    iterator __i = find(__k);
2534*4d6fc14bSjoerg    if (__i == end())
2535*4d6fc14bSjoerg        return 0;
2536*4d6fc14bSjoerg    erase(__i);
2537*4d6fc14bSjoerg    return 1;
2538*4d6fc14bSjoerg}
2539*4d6fc14bSjoerg
2540*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2541*4d6fc14bSjoergtemplate <class _Key>
2542*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2543*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k)
2544*4d6fc14bSjoerg{
2545*4d6fc14bSjoerg    size_type __r = 0;
2546*4d6fc14bSjoerg    iterator __i = find(__k);
2547*4d6fc14bSjoerg    if (__i != end())
2548*4d6fc14bSjoerg    {
2549*4d6fc14bSjoerg        iterator __e = end();
2550*4d6fc14bSjoerg        do
2551*4d6fc14bSjoerg        {
2552*4d6fc14bSjoerg            erase(__i++);
2553*4d6fc14bSjoerg            ++__r;
2554*4d6fc14bSjoerg        } while (__i != __e && key_eq()(*__i, __k));
2555*4d6fc14bSjoerg    }
2556*4d6fc14bSjoerg    return __r;
2557*4d6fc14bSjoerg}
2558*4d6fc14bSjoerg
2559*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2560*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
2561*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
2562*4d6fc14bSjoerg{
2563*4d6fc14bSjoerg    // current node
2564*4d6fc14bSjoerg    __next_pointer __cn = __p.__node_;
2565*4d6fc14bSjoerg    size_type __bc = bucket_count();
2566*4d6fc14bSjoerg    size_t __chash = __constrain_hash(__cn->__hash(), __bc);
2567*4d6fc14bSjoerg    // find previous node
2568*4d6fc14bSjoerg    __next_pointer __pn = __bucket_list_[__chash];
2569*4d6fc14bSjoerg    for (; __pn->__next_ != __cn; __pn = __pn->__next_)
2570*4d6fc14bSjoerg        ;
2571*4d6fc14bSjoerg    // Fix up __bucket_list_
2572*4d6fc14bSjoerg        // if __pn is not in same bucket (before begin is not in same bucket) &&
2573*4d6fc14bSjoerg        //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
2574*4d6fc14bSjoerg    if (__pn == __p1_.first().__ptr()
2575*4d6fc14bSjoerg            || __constrain_hash(__pn->__hash(), __bc) != __chash)
2576*4d6fc14bSjoerg    {
2577*4d6fc14bSjoerg        if (__cn->__next_ == nullptr
2578*4d6fc14bSjoerg            || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
2579*4d6fc14bSjoerg            __bucket_list_[__chash] = nullptr;
2580*4d6fc14bSjoerg    }
2581*4d6fc14bSjoerg        // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
2582*4d6fc14bSjoerg    if (__cn->__next_ != nullptr)
2583*4d6fc14bSjoerg    {
2584*4d6fc14bSjoerg        size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc);
2585*4d6fc14bSjoerg        if (__nhash != __chash)
2586*4d6fc14bSjoerg            __bucket_list_[__nhash] = __pn;
2587*4d6fc14bSjoerg    }
2588*4d6fc14bSjoerg    // remove __cn
2589*4d6fc14bSjoerg    __pn->__next_ = __cn->__next_;
2590*4d6fc14bSjoerg    __cn->__next_ = nullptr;
2591*4d6fc14bSjoerg    --size();
2592*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2593*4d6fc14bSjoerg    __c_node* __c = __get_db()->__find_c_and_lock(this);
2594*4d6fc14bSjoerg    for (__i_node** __dp = __c->end_; __dp != __c->beg_; )
2595*4d6fc14bSjoerg    {
2596*4d6fc14bSjoerg        --__dp;
2597*4d6fc14bSjoerg        iterator* __i = static_cast<iterator*>((*__dp)->__i_);
2598*4d6fc14bSjoerg        if (__i->__node_ == __cn)
2599*4d6fc14bSjoerg        {
2600*4d6fc14bSjoerg            (*__dp)->__c_ = nullptr;
2601*4d6fc14bSjoerg            if (--__c->end_ != __dp)
2602*4d6fc14bSjoerg                _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*));
2603*4d6fc14bSjoerg        }
2604*4d6fc14bSjoerg    }
2605*4d6fc14bSjoerg    __get_db()->unlock();
2606*4d6fc14bSjoerg#endif
2607*4d6fc14bSjoerg    return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
2608*4d6fc14bSjoerg}
2609*4d6fc14bSjoerg
2610*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2611*4d6fc14bSjoergtemplate <class _Key>
2612*4d6fc14bSjoerginline
2613*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2614*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const
2615*4d6fc14bSjoerg{
2616*4d6fc14bSjoerg    return static_cast<size_type>(find(__k) != end());
2617*4d6fc14bSjoerg}
2618*4d6fc14bSjoerg
2619*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2620*4d6fc14bSjoergtemplate <class _Key>
2621*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2622*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const
2623*4d6fc14bSjoerg{
2624*4d6fc14bSjoerg    size_type __r = 0;
2625*4d6fc14bSjoerg    const_iterator __i = find(__k);
2626*4d6fc14bSjoerg    if (__i != end())
2627*4d6fc14bSjoerg    {
2628*4d6fc14bSjoerg        const_iterator __e = end();
2629*4d6fc14bSjoerg        do
2630*4d6fc14bSjoerg        {
2631*4d6fc14bSjoerg            ++__i;
2632*4d6fc14bSjoerg            ++__r;
2633*4d6fc14bSjoerg        } while (__i != __e && key_eq()(*__i, __k));
2634*4d6fc14bSjoerg    }
2635*4d6fc14bSjoerg    return __r;
2636*4d6fc14bSjoerg}
2637*4d6fc14bSjoerg
2638*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2639*4d6fc14bSjoergtemplate <class _Key>
2640*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
2641*4d6fc14bSjoerg     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
2642*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
2643*4d6fc14bSjoerg        const _Key& __k)
2644*4d6fc14bSjoerg{
2645*4d6fc14bSjoerg    iterator __i = find(__k);
2646*4d6fc14bSjoerg    iterator __j = __i;
2647*4d6fc14bSjoerg    if (__i != end())
2648*4d6fc14bSjoerg        ++__j;
2649*4d6fc14bSjoerg    return pair<iterator, iterator>(__i, __j);
2650*4d6fc14bSjoerg}
2651*4d6fc14bSjoerg
2652*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2653*4d6fc14bSjoergtemplate <class _Key>
2654*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
2655*4d6fc14bSjoerg     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
2656*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
2657*4d6fc14bSjoerg        const _Key& __k) const
2658*4d6fc14bSjoerg{
2659*4d6fc14bSjoerg    const_iterator __i = find(__k);
2660*4d6fc14bSjoerg    const_iterator __j = __i;
2661*4d6fc14bSjoerg    if (__i != end())
2662*4d6fc14bSjoerg        ++__j;
2663*4d6fc14bSjoerg    return pair<const_iterator, const_iterator>(__i, __j);
2664*4d6fc14bSjoerg}
2665*4d6fc14bSjoerg
2666*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2667*4d6fc14bSjoergtemplate <class _Key>
2668*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
2669*4d6fc14bSjoerg     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
2670*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
2671*4d6fc14bSjoerg        const _Key& __k)
2672*4d6fc14bSjoerg{
2673*4d6fc14bSjoerg    iterator __i = find(__k);
2674*4d6fc14bSjoerg    iterator __j = __i;
2675*4d6fc14bSjoerg    if (__i != end())
2676*4d6fc14bSjoerg    {
2677*4d6fc14bSjoerg        iterator __e = end();
2678*4d6fc14bSjoerg        do
2679*4d6fc14bSjoerg        {
2680*4d6fc14bSjoerg            ++__j;
2681*4d6fc14bSjoerg        } while (__j != __e && key_eq()(*__j, __k));
2682*4d6fc14bSjoerg    }
2683*4d6fc14bSjoerg    return pair<iterator, iterator>(__i, __j);
2684*4d6fc14bSjoerg}
2685*4d6fc14bSjoerg
2686*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2687*4d6fc14bSjoergtemplate <class _Key>
2688*4d6fc14bSjoergpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
2689*4d6fc14bSjoerg     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
2690*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
2691*4d6fc14bSjoerg        const _Key& __k) const
2692*4d6fc14bSjoerg{
2693*4d6fc14bSjoerg    const_iterator __i = find(__k);
2694*4d6fc14bSjoerg    const_iterator __j = __i;
2695*4d6fc14bSjoerg    if (__i != end())
2696*4d6fc14bSjoerg    {
2697*4d6fc14bSjoerg        const_iterator __e = end();
2698*4d6fc14bSjoerg        do
2699*4d6fc14bSjoerg        {
2700*4d6fc14bSjoerg            ++__j;
2701*4d6fc14bSjoerg        } while (__j != __e && key_eq()(*__j, __k));
2702*4d6fc14bSjoerg    }
2703*4d6fc14bSjoerg    return pair<const_iterator, const_iterator>(__i, __j);
2704*4d6fc14bSjoerg}
2705*4d6fc14bSjoerg
2706*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2707*4d6fc14bSjoergvoid
2708*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
2709*4d6fc14bSjoerg#if _LIBCPP_STD_VER <= 11
2710*4d6fc14bSjoerg    _NOEXCEPT_(
2711*4d6fc14bSjoerg        __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
2712*4d6fc14bSjoerg        && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
2713*4d6fc14bSjoerg              || __is_nothrow_swappable<__pointer_allocator>::value)
2714*4d6fc14bSjoerg        && (!__node_traits::propagate_on_container_swap::value
2715*4d6fc14bSjoerg              || __is_nothrow_swappable<__node_allocator>::value)
2716*4d6fc14bSjoerg            )
2717*4d6fc14bSjoerg#else
2718*4d6fc14bSjoerg  _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
2719*4d6fc14bSjoerg#endif
2720*4d6fc14bSjoerg{
2721*4d6fc14bSjoerg    _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value ||
2722*4d6fc14bSjoerg                   this->__node_alloc() == __u.__node_alloc(),
2723*4d6fc14bSjoerg                   "list::swap: Either propagate_on_container_swap must be true"
2724*4d6fc14bSjoerg                   " or the allocators must compare equal");
2725*4d6fc14bSjoerg    {
2726*4d6fc14bSjoerg    __node_pointer_pointer __npp = __bucket_list_.release();
2727*4d6fc14bSjoerg    __bucket_list_.reset(__u.__bucket_list_.release());
2728*4d6fc14bSjoerg    __u.__bucket_list_.reset(__npp);
2729*4d6fc14bSjoerg    }
2730*4d6fc14bSjoerg    _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
2731*4d6fc14bSjoerg    _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(),
2732*4d6fc14bSjoerg             __u.__bucket_list_.get_deleter().__alloc());
2733*4d6fc14bSjoerg    _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc());
2734*4d6fc14bSjoerg    _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
2735*4d6fc14bSjoerg    __p2_.swap(__u.__p2_);
2736*4d6fc14bSjoerg    __p3_.swap(__u.__p3_);
2737*4d6fc14bSjoerg    if (size() > 0)
2738*4d6fc14bSjoerg        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
2739*4d6fc14bSjoerg            __p1_.first().__ptr();
2740*4d6fc14bSjoerg    if (__u.size() > 0)
2741*4d6fc14bSjoerg        __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
2742*4d6fc14bSjoerg            __u.__p1_.first().__ptr();
2743*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2744*4d6fc14bSjoerg    __get_db()->swap(this, &__u);
2745*4d6fc14bSjoerg#endif
2746*4d6fc14bSjoerg}
2747*4d6fc14bSjoerg
2748*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2749*4d6fc14bSjoergtypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2750*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
2751*4d6fc14bSjoerg{
2752*4d6fc14bSjoerg    _LIBCPP_ASSERT(__n < bucket_count(),
2753*4d6fc14bSjoerg        "unordered container::bucket_size(n) called with n >= bucket_count()");
2754*4d6fc14bSjoerg    __next_pointer __np = __bucket_list_[__n];
2755*4d6fc14bSjoerg    size_type __bc = bucket_count();
2756*4d6fc14bSjoerg    size_type __r = 0;
2757*4d6fc14bSjoerg    if (__np != nullptr)
2758*4d6fc14bSjoerg    {
2759*4d6fc14bSjoerg        for (__np = __np->__next_; __np != nullptr &&
2760*4d6fc14bSjoerg                                   __constrain_hash(__np->__hash(), __bc) == __n;
2761*4d6fc14bSjoerg                                                    __np = __np->__next_, ++__r)
2762*4d6fc14bSjoerg            ;
2763*4d6fc14bSjoerg    }
2764*4d6fc14bSjoerg    return __r;
2765*4d6fc14bSjoerg}
2766*4d6fc14bSjoerg
2767*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2768*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
2769*4d6fc14bSjoergvoid
2770*4d6fc14bSjoergswap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
2771*4d6fc14bSjoerg     __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)
2772*4d6fc14bSjoerg    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2773*4d6fc14bSjoerg{
2774*4d6fc14bSjoerg    __x.swap(__y);
2775*4d6fc14bSjoerg}
2776*4d6fc14bSjoerg
2777*4d6fc14bSjoerg#if _LIBCPP_DEBUG_LEVEL == 2
2778*4d6fc14bSjoerg
2779*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2780*4d6fc14bSjoergbool
2781*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const
2782*4d6fc14bSjoerg{
2783*4d6fc14bSjoerg    return __i->__node_ != nullptr;
2784*4d6fc14bSjoerg}
2785*4d6fc14bSjoerg
2786*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2787*4d6fc14bSjoergbool
2788*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const
2789*4d6fc14bSjoerg{
2790*4d6fc14bSjoerg    return false;
2791*4d6fc14bSjoerg}
2792*4d6fc14bSjoerg
2793*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2794*4d6fc14bSjoergbool
2795*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
2796*4d6fc14bSjoerg{
2797*4d6fc14bSjoerg    return false;
2798*4d6fc14bSjoerg}
2799*4d6fc14bSjoerg
2800*4d6fc14bSjoergtemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2801*4d6fc14bSjoergbool
2802*4d6fc14bSjoerg__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
2803*4d6fc14bSjoerg{
2804*4d6fc14bSjoerg    return false;
2805*4d6fc14bSjoerg}
2806*4d6fc14bSjoerg
2807*4d6fc14bSjoerg#endif // _LIBCPP_DEBUG_LEVEL == 2
2808*4d6fc14bSjoerg
2809*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD
2810*4d6fc14bSjoerg
2811*4d6fc14bSjoerg_LIBCPP_POP_MACROS
2812*4d6fc14bSjoerg
2813*4d6fc14bSjoerg#endif // _LIBCPP__HASH_TABLE
2814