xref: /openbsd/gnu/llvm/libcxx/include/__hash_table (revision 4bdff4be)
146035553Spatrick// -*- C++ -*-
246035553Spatrick//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
10*4bdff4beSrobert#ifndef _LIBCPP___HASH_TABLE
11*4bdff4beSrobert#define _LIBCPP___HASH_TABLE
1246035553Spatrick
13*4bdff4beSrobert#include <__algorithm/max.h>
14*4bdff4beSrobert#include <__algorithm/min.h>
15*4bdff4beSrobert#include <__assert>
16*4bdff4beSrobert#include <__bit/countl.h>
1746035553Spatrick#include <__config>
1876d0caaeSpatrick#include <__debug>
19*4bdff4beSrobert#include <__functional/hash.h>
20*4bdff4beSrobert#include <__iterator/iterator_traits.h>
21*4bdff4beSrobert#include <__memory/addressof.h>
22*4bdff4beSrobert#include <__memory/allocator_traits.h>
23*4bdff4beSrobert#include <__memory/compressed_pair.h>
24*4bdff4beSrobert#include <__memory/pointer_traits.h>
25*4bdff4beSrobert#include <__memory/swap_allocator.h>
26*4bdff4beSrobert#include <__memory/unique_ptr.h>
27*4bdff4beSrobert#include <__type_traits/can_extract_key.h>
28*4bdff4beSrobert#include <__utility/forward.h>
29*4bdff4beSrobert#include <__utility/move.h>
30*4bdff4beSrobert#include <__utility/pair.h>
31*4bdff4beSrobert#include <__utility/swap.h>
3246035553Spatrick#include <cmath>
33*4bdff4beSrobert#include <cstring>
3476d0caaeSpatrick#include <initializer_list>
3546035553Spatrick#include <type_traits>
3646035553Spatrick
3746035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3846035553Spatrick#  pragma GCC system_header
3946035553Spatrick#endif
4046035553Spatrick
4146035553Spatrick_LIBCPP_PUSH_MACROS
4246035553Spatrick#include <__undef_macros>
4346035553Spatrick
4446035553Spatrick
4546035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
4646035553Spatrick
4746035553Spatricktemplate <class _Key, class _Tp>
4846035553Spatrickstruct __hash_value_type;
4946035553Spatrick
5046035553Spatricktemplate <class _Tp>
5146035553Spatrickstruct __is_hash_value_type_imp : false_type {};
5246035553Spatrick
5346035553Spatricktemplate <class _Key, class _Value>
5446035553Spatrickstruct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {};
5546035553Spatrick
5646035553Spatricktemplate <class ..._Args>
5746035553Spatrickstruct __is_hash_value_type : false_type {};
5846035553Spatrick
5946035553Spatricktemplate <class _One>
60*4bdff4beSrobertstruct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {};
6146035553Spatrick
6246035553Spatrick_LIBCPP_FUNC_VIS
6346035553Spatricksize_t __next_prime(size_t __n);
6446035553Spatrick
6546035553Spatricktemplate <class _NodePtr>
6646035553Spatrickstruct __hash_node_base
6746035553Spatrick{
6846035553Spatrick    typedef typename pointer_traits<_NodePtr>::element_type __node_type;
6946035553Spatrick    typedef __hash_node_base __first_node;
70*4bdff4beSrobert    typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer;
7146035553Spatrick    typedef _NodePtr __node_pointer;
7246035553Spatrick
7346035553Spatrick#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
7446035553Spatrick  typedef __node_base_pointer __next_pointer;
7546035553Spatrick#else
76*4bdff4beSrobert    typedef __conditional_t<is_pointer<__node_pointer>::value, __node_base_pointer, __node_pointer> __next_pointer;
7746035553Spatrick#endif
7846035553Spatrick
7946035553Spatrick    __next_pointer    __next_;
8046035553Spatrick
8146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
8246035553Spatrick    __next_pointer __ptr() _NOEXCEPT {
8346035553Spatrick        return static_cast<__next_pointer>(
8446035553Spatrick            pointer_traits<__node_base_pointer>::pointer_to(*this));
8546035553Spatrick    }
8646035553Spatrick
8746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
8846035553Spatrick    __node_pointer __upcast() _NOEXCEPT {
8946035553Spatrick        return static_cast<__node_pointer>(
9046035553Spatrick            pointer_traits<__node_base_pointer>::pointer_to(*this));
9146035553Spatrick    }
9246035553Spatrick
9346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
9446035553Spatrick    size_t __hash() const _NOEXCEPT {
9546035553Spatrick        return static_cast<__node_type const&>(*this).__hash_;
9646035553Spatrick    }
9746035553Spatrick
9846035553Spatrick    _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
9946035553Spatrick};
10046035553Spatrick
10146035553Spatricktemplate <class _Tp, class _VoidPtr>
10276d0caaeSpatrickstruct _LIBCPP_STANDALONE_DEBUG __hash_node
10346035553Spatrick    : public __hash_node_base
10446035553Spatrick             <
105*4bdff4beSrobert                 __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> >
10646035553Spatrick             >
10746035553Spatrick{
10846035553Spatrick    typedef _Tp __node_value_type;
10946035553Spatrick
11046035553Spatrick    size_t            __hash_;
11146035553Spatrick    __node_value_type __value_;
11246035553Spatrick};
11346035553Spatrick
11446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
11546035553Spatrickbool
11646035553Spatrick__is_hash_power2(size_t __bc)
11746035553Spatrick{
11846035553Spatrick    return __bc > 2 && !(__bc & (__bc - 1));
11946035553Spatrick}
12046035553Spatrick
12146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
12246035553Spatricksize_t
12346035553Spatrick__constrain_hash(size_t __h, size_t __bc)
12446035553Spatrick{
12546035553Spatrick    return !(__bc & (__bc - 1)) ? __h & (__bc - 1) :
12646035553Spatrick        (__h < __bc ? __h : __h % __bc);
12746035553Spatrick}
12846035553Spatrick
12946035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
13046035553Spatricksize_t
13146035553Spatrick__next_hash_pow2(size_t __n)
13246035553Spatrick{
13376d0caaeSpatrick    return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1)));
13446035553Spatrick}
13546035553Spatrick
13646035553Spatrick
13746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
13846035553Spatrick
13946035553Spatricktemplate <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_iterator;
14046035553Spatricktemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
14146035553Spatricktemplate <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_local_iterator;
14246035553Spatricktemplate <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
14346035553Spatricktemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
14446035553Spatricktemplate <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
14546035553Spatrick
14646035553Spatricktemplate <class _Tp>
14746035553Spatrickstruct __hash_key_value_types {
14846035553Spatrick  static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
14946035553Spatrick  typedef _Tp key_type;
15046035553Spatrick  typedef _Tp __node_value_type;
15146035553Spatrick  typedef _Tp __container_value_type;
15246035553Spatrick  static const bool __is_map = false;
15346035553Spatrick
15446035553Spatrick  _LIBCPP_INLINE_VISIBILITY
15546035553Spatrick  static key_type const& __get_key(_Tp const& __v) {
15646035553Spatrick    return __v;
15746035553Spatrick  }
15846035553Spatrick  _LIBCPP_INLINE_VISIBILITY
15946035553Spatrick  static __container_value_type const& __get_value(__node_value_type const& __v) {
16046035553Spatrick    return __v;
16146035553Spatrick  }
16246035553Spatrick  _LIBCPP_INLINE_VISIBILITY
16346035553Spatrick  static __container_value_type* __get_ptr(__node_value_type& __n) {
16446035553Spatrick    return _VSTD::addressof(__n);
16546035553Spatrick  }
16646035553Spatrick  _LIBCPP_INLINE_VISIBILITY
16746035553Spatrick  static __container_value_type&& __move(__node_value_type& __v) {
16846035553Spatrick    return _VSTD::move(__v);
16946035553Spatrick  }
17046035553Spatrick};
17146035553Spatrick
17246035553Spatricktemplate <class _Key, class _Tp>
17346035553Spatrickstruct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
17446035553Spatrick  typedef _Key                                         key_type;
17546035553Spatrick  typedef _Tp                                          mapped_type;
17646035553Spatrick  typedef __hash_value_type<_Key, _Tp>                 __node_value_type;
17746035553Spatrick  typedef pair<const _Key, _Tp>                        __container_value_type;
17846035553Spatrick  typedef __container_value_type                       __map_value_type;
17946035553Spatrick  static const bool __is_map = true;
18046035553Spatrick
18146035553Spatrick  _LIBCPP_INLINE_VISIBILITY
18246035553Spatrick  static key_type const& __get_key(__container_value_type const& __v) {
18346035553Spatrick    return __v.first;
18446035553Spatrick  }
18546035553Spatrick
18646035553Spatrick  template <class _Up>
18746035553Spatrick  _LIBCPP_INLINE_VISIBILITY
188*4bdff4beSrobert  static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&>
18946035553Spatrick  __get_value(_Up& __t) {
19046035553Spatrick    return __t.__get_value();
19146035553Spatrick  }
19246035553Spatrick
19346035553Spatrick  template <class _Up>
19446035553Spatrick  _LIBCPP_INLINE_VISIBILITY
195*4bdff4beSrobert  static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&>
19646035553Spatrick  __get_value(_Up& __t) {
19746035553Spatrick    return __t;
19846035553Spatrick  }
19946035553Spatrick
20046035553Spatrick  _LIBCPP_INLINE_VISIBILITY
20146035553Spatrick  static __container_value_type* __get_ptr(__node_value_type& __n) {
20246035553Spatrick    return _VSTD::addressof(__n.__get_value());
20346035553Spatrick  }
20446035553Spatrick  _LIBCPP_INLINE_VISIBILITY
20546035553Spatrick  static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
20646035553Spatrick    return __v.__move();
20746035553Spatrick  }
20846035553Spatrick};
20946035553Spatrick
21046035553Spatricktemplate <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>,
21146035553Spatrick          bool = _KVTypes::__is_map>
21246035553Spatrickstruct __hash_map_pointer_types {};
21346035553Spatrick
21446035553Spatricktemplate <class _Tp, class _AllocPtr, class _KVTypes>
21546035553Spatrickstruct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
21646035553Spatrick  typedef typename _KVTypes::__map_value_type   _Mv;
217*4bdff4beSrobert  typedef __rebind_pointer_t<_AllocPtr, _Mv>
21846035553Spatrick                                                       __map_value_type_pointer;
219*4bdff4beSrobert  typedef __rebind_pointer_t<_AllocPtr, const _Mv>
22046035553Spatrick                                                 __const_map_value_type_pointer;
22146035553Spatrick};
22246035553Spatrick
22346035553Spatricktemplate <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
22446035553Spatrickstruct __hash_node_types;
22546035553Spatrick
22646035553Spatricktemplate <class _NodePtr, class _Tp, class _VoidPtr>
22746035553Spatrickstruct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> >
22846035553Spatrick    : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr>
22946035553Spatrick
23046035553Spatrick{
23146035553Spatrick  typedef __hash_key_value_types<_Tp>           __base;
23246035553Spatrick
23346035553Spatrickpublic:
23446035553Spatrick  typedef ptrdiff_t difference_type;
23546035553Spatrick  typedef size_t size_type;
23646035553Spatrick
237*4bdff4beSrobert  typedef __rebind_pointer_t<_NodePtr, void>       __void_pointer;
23846035553Spatrick
23946035553Spatrick  typedef typename pointer_traits<_NodePtr>::element_type       __node_type;
24046035553Spatrick  typedef _NodePtr                                              __node_pointer;
24146035553Spatrick
24246035553Spatrick  typedef __hash_node_base<__node_pointer>                      __node_base_type;
243*4bdff4beSrobert  typedef __rebind_pointer_t<_NodePtr, __node_base_type>
24446035553Spatrick                                                             __node_base_pointer;
24546035553Spatrick
24646035553Spatrick  typedef typename __node_base_type::__next_pointer          __next_pointer;
24746035553Spatrick
24846035553Spatrick  typedef _Tp                                                 __node_value_type;
249*4bdff4beSrobert  typedef __rebind_pointer_t<_VoidPtr, __node_value_type>
25046035553Spatrick                                                      __node_value_type_pointer;
251*4bdff4beSrobert  typedef __rebind_pointer_t<_VoidPtr, const __node_value_type>
25246035553Spatrick                                                __const_node_value_type_pointer;
25346035553Spatrick
25446035553Spatrickprivate:
25546035553Spatrick    static_assert(!is_const<__node_type>::value,
25646035553Spatrick                "_NodePtr should never be a pointer to const");
25746035553Spatrick    static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
25846035553Spatrick                  "_VoidPtr does not point to unqualified void type");
259*4bdff4beSrobert    static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>,
26046035553Spatrick                          _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
26146035553Spatrick};
26246035553Spatrick
26346035553Spatricktemplate <class _HashIterator>
26446035553Spatrickstruct __hash_node_types_from_iterator;
26546035553Spatricktemplate <class _NodePtr>
26646035553Spatrickstruct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
26746035553Spatricktemplate <class _NodePtr>
26846035553Spatrickstruct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
26946035553Spatricktemplate <class _NodePtr>
27046035553Spatrickstruct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
27146035553Spatricktemplate <class _NodePtr>
27246035553Spatrickstruct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
27346035553Spatrick
27446035553Spatrick
27546035553Spatricktemplate <class _NodeValueTp, class _VoidPtr>
27646035553Spatrickstruct __make_hash_node_types {
27746035553Spatrick  typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp;
278*4bdff4beSrobert  typedef __rebind_pointer_t<_VoidPtr, _NodeTp> _NodePtr;
27946035553Spatrick  typedef __hash_node_types<_NodePtr> type;
28046035553Spatrick};
28146035553Spatrick
28246035553Spatricktemplate <class _NodePtr>
28346035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_iterator
28446035553Spatrick{
28546035553Spatrick    typedef __hash_node_types<_NodePtr> _NodeTypes;
28646035553Spatrick    typedef _NodePtr                            __node_pointer;
28746035553Spatrick    typedef typename _NodeTypes::__next_pointer __next_pointer;
28846035553Spatrick
28946035553Spatrick    __next_pointer            __node_;
29046035553Spatrick
29146035553Spatrickpublic:
29246035553Spatrick    typedef forward_iterator_tag                           iterator_category;
29346035553Spatrick    typedef typename _NodeTypes::__node_value_type         value_type;
29446035553Spatrick    typedef typename _NodeTypes::difference_type           difference_type;
29546035553Spatrick    typedef value_type&                                    reference;
29646035553Spatrick    typedef typename _NodeTypes::__node_value_type_pointer pointer;
29746035553Spatrick
29846035553Spatrick    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) {
299*4bdff4beSrobert        _VSTD::__debug_db_insert_i(this);
30046035553Spatrick    }
30146035553Spatrick
302*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
30346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
30446035553Spatrick    __hash_iterator(const __hash_iterator& __i)
30546035553Spatrick        : __node_(__i.__node_)
30646035553Spatrick    {
307*4bdff4beSrobert        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
30846035553Spatrick    }
30946035553Spatrick
31046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
31146035553Spatrick    ~__hash_iterator()
31246035553Spatrick    {
31346035553Spatrick        __get_db()->__erase_i(this);
31446035553Spatrick    }
31546035553Spatrick
31646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
31746035553Spatrick    __hash_iterator& operator=(const __hash_iterator& __i)
31846035553Spatrick    {
319*4bdff4beSrobert        if (this != _VSTD::addressof(__i))
32046035553Spatrick        {
321*4bdff4beSrobert            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
32246035553Spatrick            __node_ = __i.__node_;
32346035553Spatrick        }
32446035553Spatrick        return *this;
32546035553Spatrick    }
326*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
32746035553Spatrick
32846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
32946035553Spatrick    reference operator*() const {
33046035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
33146035553Spatrick                             "Attempted to dereference a non-dereferenceable unordered container iterator");
33246035553Spatrick        return __node_->__upcast()->__value_;
33346035553Spatrick    }
33446035553Spatrick
33546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
33646035553Spatrick    pointer operator->() const {
33746035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
33846035553Spatrick                           "Attempted to dereference a non-dereferenceable unordered container iterator");
33946035553Spatrick        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
34046035553Spatrick    }
34146035553Spatrick
34246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
34346035553Spatrick    __hash_iterator& operator++() {
34446035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
34576d0caaeSpatrick                       "Attempted to increment a non-incrementable unordered container iterator");
34646035553Spatrick        __node_ = __node_->__next_;
34746035553Spatrick        return *this;
34846035553Spatrick    }
34946035553Spatrick
35046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
35146035553Spatrick    __hash_iterator operator++(int)
35246035553Spatrick    {
35346035553Spatrick        __hash_iterator __t(*this);
35446035553Spatrick        ++(*this);
35546035553Spatrick        return __t;
35646035553Spatrick    }
35746035553Spatrick
35846035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
35946035553Spatrick    bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)
36046035553Spatrick    {
36146035553Spatrick        return __x.__node_ == __y.__node_;
36246035553Spatrick    }
36346035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
36446035553Spatrick    bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)
36546035553Spatrick        {return !(__x == __y);}
36646035553Spatrick
36746035553Spatrickprivate:
36846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
369*4bdff4beSrobert    explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
37046035553Spatrick        : __node_(__node)
37146035553Spatrick        {
372*4bdff4beSrobert            (void)__c;
373*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
37446035553Spatrick            __get_db()->__insert_ic(this, __c);
37546035553Spatrick#endif
376*4bdff4beSrobert        }
37746035553Spatrick    template <class, class, class, class> friend class __hash_table;
37846035553Spatrick    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
37946035553Spatrick    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
38046035553Spatrick    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
38146035553Spatrick    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
38246035553Spatrick};
38346035553Spatrick
38446035553Spatricktemplate <class _NodePtr>
38546035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_const_iterator
38646035553Spatrick{
38746035553Spatrick    static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, "");
38846035553Spatrick    typedef __hash_node_types<_NodePtr> _NodeTypes;
38946035553Spatrick    typedef _NodePtr                            __node_pointer;
39046035553Spatrick    typedef typename _NodeTypes::__next_pointer __next_pointer;
39146035553Spatrick
39246035553Spatrick    __next_pointer __node_;
39346035553Spatrick
39446035553Spatrickpublic:
39546035553Spatrick    typedef __hash_iterator<_NodePtr> __non_const_iterator;
39646035553Spatrick
39746035553Spatrick    typedef forward_iterator_tag                                 iterator_category;
39846035553Spatrick    typedef typename _NodeTypes::__node_value_type               value_type;
39946035553Spatrick    typedef typename _NodeTypes::difference_type                 difference_type;
40046035553Spatrick    typedef const value_type&                                    reference;
40146035553Spatrick    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
40246035553Spatrick
40346035553Spatrick
40446035553Spatrick    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {
405*4bdff4beSrobert        _VSTD::__debug_db_insert_i(this);
40646035553Spatrick    }
40746035553Spatrick
40846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
40946035553Spatrick    __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
41046035553Spatrick        : __node_(__x.__node_)
41146035553Spatrick    {
412*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
413*4bdff4beSrobert        __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
41476d0caaeSpatrick#endif
41546035553Spatrick    }
41646035553Spatrick
417*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
41846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
41946035553Spatrick    __hash_const_iterator(const __hash_const_iterator& __i)
42046035553Spatrick        : __node_(__i.__node_)
42146035553Spatrick    {
422*4bdff4beSrobert        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
42346035553Spatrick    }
42446035553Spatrick
42546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
42646035553Spatrick    ~__hash_const_iterator()
42746035553Spatrick    {
42846035553Spatrick        __get_db()->__erase_i(this);
42946035553Spatrick    }
43046035553Spatrick
43146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
43246035553Spatrick    __hash_const_iterator& operator=(const __hash_const_iterator& __i)
43346035553Spatrick    {
434*4bdff4beSrobert        if (this != _VSTD::addressof(__i))
43546035553Spatrick        {
436*4bdff4beSrobert            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
43746035553Spatrick            __node_ = __i.__node_;
43846035553Spatrick        }
43946035553Spatrick        return *this;
44046035553Spatrick    }
441*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
44246035553Spatrick
44346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
44446035553Spatrick    reference operator*() const {
44546035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
44646035553Spatrick                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
44746035553Spatrick        return __node_->__upcast()->__value_;
44846035553Spatrick    }
44946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
45046035553Spatrick    pointer operator->() const {
45146035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
45246035553Spatrick                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
45346035553Spatrick        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
45446035553Spatrick    }
45546035553Spatrick
45646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
45746035553Spatrick    __hash_const_iterator& operator++() {
45846035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
45976d0caaeSpatrick                             "Attempted to increment a non-incrementable unordered container const_iterator");
46046035553Spatrick        __node_ = __node_->__next_;
46146035553Spatrick        return *this;
46246035553Spatrick    }
46346035553Spatrick
46446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
46546035553Spatrick    __hash_const_iterator operator++(int)
46646035553Spatrick    {
46746035553Spatrick        __hash_const_iterator __t(*this);
46846035553Spatrick        ++(*this);
46946035553Spatrick        return __t;
47046035553Spatrick    }
47146035553Spatrick
47246035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
47346035553Spatrick    bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
47446035553Spatrick    {
47546035553Spatrick        return __x.__node_ == __y.__node_;
47646035553Spatrick    }
47746035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
47846035553Spatrick    bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
47946035553Spatrick        {return !(__x == __y);}
48046035553Spatrick
48146035553Spatrickprivate:
48246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
483*4bdff4beSrobert    explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT
48446035553Spatrick        : __node_(__node)
48546035553Spatrick        {
486*4bdff4beSrobert            (void)__c;
487*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
48846035553Spatrick            __get_db()->__insert_ic(this, __c);
48946035553Spatrick#endif
490*4bdff4beSrobert        }
49146035553Spatrick    template <class, class, class, class> friend class __hash_table;
49246035553Spatrick    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
49346035553Spatrick    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
49446035553Spatrick    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
49546035553Spatrick};
49646035553Spatrick
49746035553Spatricktemplate <class _NodePtr>
49846035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_local_iterator
49946035553Spatrick{
50046035553Spatrick    typedef __hash_node_types<_NodePtr> _NodeTypes;
50146035553Spatrick    typedef _NodePtr                            __node_pointer;
50246035553Spatrick    typedef typename _NodeTypes::__next_pointer __next_pointer;
50346035553Spatrick
50446035553Spatrick    __next_pointer         __node_;
50546035553Spatrick    size_t                 __bucket_;
50646035553Spatrick    size_t                 __bucket_count_;
50746035553Spatrick
50846035553Spatrickpublic:
50946035553Spatrick    typedef forward_iterator_tag                                iterator_category;
51046035553Spatrick    typedef typename _NodeTypes::__node_value_type              value_type;
51146035553Spatrick    typedef typename _NodeTypes::difference_type                difference_type;
51246035553Spatrick    typedef value_type&                                         reference;
51346035553Spatrick    typedef typename _NodeTypes::__node_value_type_pointer      pointer;
51446035553Spatrick
51546035553Spatrick    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {
516*4bdff4beSrobert        _VSTD::__debug_db_insert_i(this);
51746035553Spatrick    }
51846035553Spatrick
519*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
52046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
52146035553Spatrick    __hash_local_iterator(const __hash_local_iterator& __i)
52246035553Spatrick        : __node_(__i.__node_),
52346035553Spatrick          __bucket_(__i.__bucket_),
52446035553Spatrick          __bucket_count_(__i.__bucket_count_)
52546035553Spatrick    {
526*4bdff4beSrobert        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
52746035553Spatrick    }
52846035553Spatrick
52946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
53046035553Spatrick    ~__hash_local_iterator()
53146035553Spatrick    {
53246035553Spatrick        __get_db()->__erase_i(this);
53346035553Spatrick    }
53446035553Spatrick
53546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
53646035553Spatrick    __hash_local_iterator& operator=(const __hash_local_iterator& __i)
53746035553Spatrick    {
538*4bdff4beSrobert        if (this != _VSTD::addressof(__i))
53946035553Spatrick        {
540*4bdff4beSrobert            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
54146035553Spatrick            __node_ = __i.__node_;
54246035553Spatrick            __bucket_ = __i.__bucket_;
54346035553Spatrick            __bucket_count_ = __i.__bucket_count_;
54446035553Spatrick        }
54546035553Spatrick        return *this;
54646035553Spatrick    }
547*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
54846035553Spatrick
54946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
55046035553Spatrick    reference operator*() const {
55146035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
55246035553Spatrick                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
55346035553Spatrick        return __node_->__upcast()->__value_;
55446035553Spatrick    }
55546035553Spatrick
55646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
55746035553Spatrick    pointer operator->() const {
55846035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
55946035553Spatrick                             "Attempted to dereference a non-dereferenceable unordered container local_iterator");
56046035553Spatrick        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
56146035553Spatrick    }
56246035553Spatrick
56346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
56446035553Spatrick    __hash_local_iterator& operator++() {
56546035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
56676d0caaeSpatrick                       "Attempted to increment a non-incrementable unordered container local_iterator");
56746035553Spatrick        __node_ = __node_->__next_;
568*4bdff4beSrobert        if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
56946035553Spatrick            __node_ = nullptr;
57046035553Spatrick        return *this;
57146035553Spatrick    }
57246035553Spatrick
57346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
57446035553Spatrick    __hash_local_iterator operator++(int)
57546035553Spatrick    {
57646035553Spatrick        __hash_local_iterator __t(*this);
57746035553Spatrick        ++(*this);
57846035553Spatrick        return __t;
57946035553Spatrick    }
58046035553Spatrick
58146035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
58246035553Spatrick    bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
58346035553Spatrick    {
58446035553Spatrick        return __x.__node_ == __y.__node_;
58546035553Spatrick    }
58646035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
58746035553Spatrick    bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
58846035553Spatrick        {return !(__x == __y);}
58946035553Spatrick
59046035553Spatrickprivate:
59146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
592*4bdff4beSrobert    explicit __hash_local_iterator(__next_pointer __node, size_t __bucket,
59346035553Spatrick                                   size_t __bucket_count, const void* __c) _NOEXCEPT
59446035553Spatrick        : __node_(__node),
59546035553Spatrick          __bucket_(__bucket),
59646035553Spatrick          __bucket_count_(__bucket_count)
59746035553Spatrick        {
598*4bdff4beSrobert            (void)__c;
599*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
60046035553Spatrick            __get_db()->__insert_ic(this, __c);
60146035553Spatrick#endif
602*4bdff4beSrobert            if (__node_ != nullptr)
603*4bdff4beSrobert                __node_ = __node_->__next_;
604*4bdff4beSrobert        }
60546035553Spatrick    template <class, class, class, class> friend class __hash_table;
60646035553Spatrick    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
60746035553Spatrick    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
60846035553Spatrick};
60946035553Spatrick
61046035553Spatricktemplate <class _ConstNodePtr>
61146035553Spatrickclass _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator
61246035553Spatrick{
61346035553Spatrick    typedef __hash_node_types<_ConstNodePtr> _NodeTypes;
61446035553Spatrick    typedef _ConstNodePtr                       __node_pointer;
61546035553Spatrick    typedef typename _NodeTypes::__next_pointer __next_pointer;
61646035553Spatrick
61746035553Spatrick    __next_pointer         __node_;
61846035553Spatrick    size_t                 __bucket_;
61946035553Spatrick    size_t                 __bucket_count_;
62046035553Spatrick
62146035553Spatrick    typedef pointer_traits<__node_pointer>          __pointer_traits;
62246035553Spatrick    typedef typename __pointer_traits::element_type __node;
623*4bdff4beSrobert    typedef __remove_const_t<__node>                  __non_const_node;
624*4bdff4beSrobert    typedef __rebind_pointer_t<__node_pointer, __non_const_node>
62546035553Spatrick        __non_const_node_pointer;
62646035553Spatrickpublic:
62746035553Spatrick    typedef __hash_local_iterator<__non_const_node_pointer>
62846035553Spatrick                                                    __non_const_iterator;
62946035553Spatrick
63046035553Spatrick    typedef forward_iterator_tag                                 iterator_category;
63146035553Spatrick    typedef typename _NodeTypes::__node_value_type               value_type;
63246035553Spatrick    typedef typename _NodeTypes::difference_type                 difference_type;
63346035553Spatrick    typedef const value_type&                                    reference;
63446035553Spatrick    typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
63546035553Spatrick
63646035553Spatrick
63746035553Spatrick    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {
638*4bdff4beSrobert        _VSTD::__debug_db_insert_i(this);
63946035553Spatrick    }
64046035553Spatrick
64146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
64246035553Spatrick    __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
64346035553Spatrick        : __node_(__x.__node_),
64446035553Spatrick          __bucket_(__x.__bucket_),
64546035553Spatrick          __bucket_count_(__x.__bucket_count_)
64646035553Spatrick    {
647*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
648*4bdff4beSrobert        __get_db()->__iterator_copy(this, _VSTD::addressof(__x));
64976d0caaeSpatrick#endif
65046035553Spatrick    }
65146035553Spatrick
652*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
65346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
65446035553Spatrick    __hash_const_local_iterator(const __hash_const_local_iterator& __i)
65546035553Spatrick        : __node_(__i.__node_),
65646035553Spatrick          __bucket_(__i.__bucket_),
65746035553Spatrick          __bucket_count_(__i.__bucket_count_)
65846035553Spatrick    {
659*4bdff4beSrobert        __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
66046035553Spatrick    }
66146035553Spatrick
66246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
66346035553Spatrick    ~__hash_const_local_iterator()
66446035553Spatrick    {
66546035553Spatrick        __get_db()->__erase_i(this);
66646035553Spatrick    }
66746035553Spatrick
66846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
66946035553Spatrick    __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)
67046035553Spatrick    {
671*4bdff4beSrobert        if (this != _VSTD::addressof(__i))
67246035553Spatrick        {
673*4bdff4beSrobert            __get_db()->__iterator_copy(this, _VSTD::addressof(__i));
67446035553Spatrick            __node_ = __i.__node_;
67546035553Spatrick            __bucket_ = __i.__bucket_;
67646035553Spatrick            __bucket_count_ = __i.__bucket_count_;
67746035553Spatrick        }
67846035553Spatrick        return *this;
67946035553Spatrick    }
680*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
68146035553Spatrick
68246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
68346035553Spatrick    reference operator*() const {
68446035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
68546035553Spatrick                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
68646035553Spatrick        return __node_->__upcast()->__value_;
68746035553Spatrick    }
68846035553Spatrick
68946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
69046035553Spatrick    pointer operator->() const {
69146035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
69246035553Spatrick                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
69346035553Spatrick        return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
69446035553Spatrick    }
69546035553Spatrick
69646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
69746035553Spatrick    __hash_const_local_iterator& operator++() {
69846035553Spatrick        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this),
69976d0caaeSpatrick                       "Attempted to increment a non-incrementable unordered container const_local_iterator");
70046035553Spatrick        __node_ = __node_->__next_;
701*4bdff4beSrobert        if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
70246035553Spatrick            __node_ = nullptr;
70346035553Spatrick        return *this;
70446035553Spatrick    }
70546035553Spatrick
70646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
70746035553Spatrick    __hash_const_local_iterator operator++(int)
70846035553Spatrick    {
70946035553Spatrick        __hash_const_local_iterator __t(*this);
71046035553Spatrick        ++(*this);
71146035553Spatrick        return __t;
71246035553Spatrick    }
71346035553Spatrick
71446035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
71546035553Spatrick    bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
71646035553Spatrick    {
71746035553Spatrick        return __x.__node_ == __y.__node_;
71846035553Spatrick    }
71946035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
72046035553Spatrick    bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
72146035553Spatrick        {return !(__x == __y);}
72246035553Spatrick
72346035553Spatrickprivate:
72446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
725*4bdff4beSrobert    explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
72646035553Spatrick                                         size_t __bucket_count, const void* __c) _NOEXCEPT
72776d0caaeSpatrick        : __node_(__node_ptr),
72846035553Spatrick          __bucket_(__bucket),
72946035553Spatrick          __bucket_count_(__bucket_count)
73046035553Spatrick        {
731*4bdff4beSrobert            (void)__c;
732*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
73346035553Spatrick            __get_db()->__insert_ic(this, __c);
73446035553Spatrick#endif
735*4bdff4beSrobert            if (__node_ != nullptr)
736*4bdff4beSrobert                __node_ = __node_->__next_;
737*4bdff4beSrobert        }
73846035553Spatrick    template <class, class, class, class> friend class __hash_table;
73946035553Spatrick    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
74046035553Spatrick};
74146035553Spatrick
74246035553Spatricktemplate <class _Alloc>
74346035553Spatrickclass __bucket_list_deallocator
74446035553Spatrick{
74546035553Spatrick    typedef _Alloc                                          allocator_type;
74646035553Spatrick    typedef allocator_traits<allocator_type>                __alloc_traits;
74746035553Spatrick    typedef typename __alloc_traits::size_type              size_type;
74846035553Spatrick
74946035553Spatrick    __compressed_pair<size_type, allocator_type> __data_;
75046035553Spatrickpublic:
75146035553Spatrick    typedef typename __alloc_traits::pointer pointer;
75246035553Spatrick
75346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
75446035553Spatrick    __bucket_list_deallocator()
75546035553Spatrick        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
75646035553Spatrick        : __data_(0, __default_init_tag()) {}
75746035553Spatrick
75846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
75946035553Spatrick    __bucket_list_deallocator(const allocator_type& __a, size_type __size)
76046035553Spatrick        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
76146035553Spatrick        : __data_(__size, __a) {}
76246035553Spatrick
76346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
76446035553Spatrick    __bucket_list_deallocator(__bucket_list_deallocator&& __x)
76546035553Spatrick        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
76646035553Spatrick        : __data_(_VSTD::move(__x.__data_))
76746035553Spatrick    {
76846035553Spatrick        __x.size() = 0;
76946035553Spatrick    }
77046035553Spatrick
77146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
77246035553Spatrick    size_type& size() _NOEXCEPT {return __data_.first();}
77346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
77446035553Spatrick    size_type  size() const _NOEXCEPT {return __data_.first();}
77546035553Spatrick
77646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
77746035553Spatrick    allocator_type& __alloc() _NOEXCEPT {return __data_.second();}
77846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
77946035553Spatrick    const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();}
78046035553Spatrick
78146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
78246035553Spatrick    void operator()(pointer __p) _NOEXCEPT
78346035553Spatrick    {
78446035553Spatrick        __alloc_traits::deallocate(__alloc(), __p, size());
78546035553Spatrick    }
78646035553Spatrick};
78746035553Spatrick
78846035553Spatricktemplate <class _Alloc> class __hash_map_node_destructor;
78946035553Spatrick
79046035553Spatricktemplate <class _Alloc>
79146035553Spatrickclass __hash_node_destructor
79246035553Spatrick{
79346035553Spatrick    typedef _Alloc                                          allocator_type;
79446035553Spatrick    typedef allocator_traits<allocator_type>                __alloc_traits;
79546035553Spatrick
79646035553Spatrickpublic:
79746035553Spatrick    typedef typename __alloc_traits::pointer                pointer;
79846035553Spatrickprivate:
79946035553Spatrick    typedef __hash_node_types<pointer> _NodeTypes;
80046035553Spatrick
80146035553Spatrick    allocator_type& __na_;
80246035553Spatrick
80346035553Spatrickpublic:
80446035553Spatrick    bool __value_constructed;
80546035553Spatrick
80646035553Spatrick    __hash_node_destructor(__hash_node_destructor const&) = default;
80746035553Spatrick    __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
80846035553Spatrick
80946035553Spatrick
81046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
81146035553Spatrick    explicit __hash_node_destructor(allocator_type& __na,
81246035553Spatrick                                    bool __constructed = false) _NOEXCEPT
81346035553Spatrick        : __na_(__na),
81446035553Spatrick          __value_constructed(__constructed)
81546035553Spatrick        {}
81646035553Spatrick
81746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
81846035553Spatrick    void operator()(pointer __p) _NOEXCEPT
81946035553Spatrick    {
82046035553Spatrick        if (__value_constructed)
82146035553Spatrick            __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
82246035553Spatrick        if (__p)
82346035553Spatrick            __alloc_traits::deallocate(__na_, __p, 1);
82446035553Spatrick    }
82546035553Spatrick
82646035553Spatrick    template <class> friend class __hash_map_node_destructor;
82746035553Spatrick};
82846035553Spatrick
82946035553Spatrick#if _LIBCPP_STD_VER > 14
83046035553Spatricktemplate <class _NodeType, class _Alloc>
83146035553Spatrickstruct __generic_container_node_destructor;
83246035553Spatrick
83346035553Spatricktemplate <class _Tp, class _VoidPtr, class _Alloc>
83446035553Spatrickstruct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
83546035553Spatrick    : __hash_node_destructor<_Alloc>
83646035553Spatrick{
83746035553Spatrick    using __hash_node_destructor<_Alloc>::__hash_node_destructor;
83846035553Spatrick};
83946035553Spatrick#endif
84046035553Spatrick
84146035553Spatricktemplate <class _Key, class _Hash, class _Equal>
84246035553Spatrickstruct __enforce_unordered_container_requirements {
84346035553Spatrick#ifndef _LIBCPP_CXX03_LANG
84446035553Spatrick    static_assert(__check_hash_requirements<_Key, _Hash>::value,
84546035553Spatrick    "the specified hash does not meet the Hash requirements");
84646035553Spatrick    static_assert(is_copy_constructible<_Equal>::value,
84746035553Spatrick    "the specified comparator is required to be copy constructible");
84846035553Spatrick#endif
84946035553Spatrick    typedef int type;
85046035553Spatrick};
85146035553Spatrick
85246035553Spatricktemplate <class _Key, class _Hash, class _Equal>
85346035553Spatrick#ifndef _LIBCPP_CXX03_LANG
85446035553Spatrick    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
85546035553Spatrick    "the specified comparator type does not provide a viable const call operator")
85646035553Spatrick    _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
85746035553Spatrick    "the specified hash functor does not provide a viable const call operator")
85846035553Spatrick#endif
85946035553Spatricktypename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
86046035553Spatrick__diagnose_unordered_container_requirements(int);
86146035553Spatrick
86246035553Spatrick// This dummy overload is used so that the compiler won't emit a spurious
86346035553Spatrick// "no matching function for call to __diagnose_unordered_xxx" diagnostic
86446035553Spatrick// when the overload above causes a hard error.
86546035553Spatricktemplate <class _Key, class _Hash, class _Equal>
86646035553Spatrickint __diagnose_unordered_container_requirements(void*);
86746035553Spatrick
86846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
86946035553Spatrickclass __hash_table
87046035553Spatrick{
87146035553Spatrickpublic:
87246035553Spatrick    typedef _Tp    value_type;
87346035553Spatrick    typedef _Hash  hasher;
87446035553Spatrick    typedef _Equal key_equal;
87546035553Spatrick    typedef _Alloc allocator_type;
87646035553Spatrick
87746035553Spatrickprivate:
87846035553Spatrick    typedef allocator_traits<allocator_type> __alloc_traits;
87946035553Spatrick    typedef typename
88046035553Spatrick      __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type
88146035553Spatrick                                                                     _NodeTypes;
88246035553Spatrickpublic:
88346035553Spatrick
88446035553Spatrick    typedef typename _NodeTypes::__node_value_type           __node_value_type;
88546035553Spatrick    typedef typename _NodeTypes::__container_value_type      __container_value_type;
88646035553Spatrick    typedef typename _NodeTypes::key_type                    key_type;
88746035553Spatrick    typedef value_type&                              reference;
88846035553Spatrick    typedef const value_type&                        const_reference;
88946035553Spatrick    typedef typename __alloc_traits::pointer         pointer;
89046035553Spatrick    typedef typename __alloc_traits::const_pointer   const_pointer;
89146035553Spatrick#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
89246035553Spatrick    typedef typename __alloc_traits::size_type       size_type;
89346035553Spatrick#else
89446035553Spatrick    typedef typename _NodeTypes::size_type           size_type;
89546035553Spatrick#endif
89646035553Spatrick    typedef typename _NodeTypes::difference_type     difference_type;
89746035553Spatrickpublic:
89846035553Spatrick    // Create __node
89946035553Spatrick
90046035553Spatrick    typedef typename _NodeTypes::__node_type __node;
901*4bdff4beSrobert    typedef __rebind_alloc<__alloc_traits, __node>   __node_allocator;
90246035553Spatrick    typedef allocator_traits<__node_allocator>       __node_traits;
90346035553Spatrick    typedef typename _NodeTypes::__void_pointer      __void_pointer;
90446035553Spatrick    typedef typename _NodeTypes::__node_pointer      __node_pointer;
90546035553Spatrick    typedef typename _NodeTypes::__node_pointer      __node_const_pointer;
90646035553Spatrick    typedef typename _NodeTypes::__node_base_type    __first_node;
90746035553Spatrick    typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
90846035553Spatrick    typedef typename _NodeTypes::__next_pointer      __next_pointer;
90946035553Spatrick
91046035553Spatrickprivate:
91146035553Spatrick    // check for sane allocator pointer rebinding semantics. Rebinding the
91246035553Spatrick    // allocator for a new pointer type should be exactly the same as rebinding
91346035553Spatrick    // the pointer using 'pointer_traits'.
91446035553Spatrick    static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
91546035553Spatrick                  "Allocator does not rebind pointers in a sane manner.");
916*4bdff4beSrobert    typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator;
91746035553Spatrick    typedef allocator_traits<__node_base_allocator> __node_base_traits;
91846035553Spatrick    static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
91946035553Spatrick                 "Allocator does not rebind pointers in a sane manner.");
92046035553Spatrick
92146035553Spatrickprivate:
92246035553Spatrick
923*4bdff4beSrobert    typedef __rebind_alloc<__node_traits, __next_pointer>  __pointer_allocator;
92446035553Spatrick    typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
92546035553Spatrick    typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
92646035553Spatrick    typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
92746035553Spatrick    typedef typename __bucket_list_deleter::pointer       __node_pointer_pointer;
92846035553Spatrick
92946035553Spatrick    // --- Member data begin ---
93046035553Spatrick    __bucket_list                                         __bucket_list_;
93146035553Spatrick    __compressed_pair<__first_node, __node_allocator>     __p1_;
93246035553Spatrick    __compressed_pair<size_type, hasher>                  __p2_;
93346035553Spatrick    __compressed_pair<float, key_equal>                   __p3_;
93446035553Spatrick    // --- Member data end ---
93546035553Spatrick
93646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
93746035553Spatrick    size_type& size() _NOEXCEPT {return __p2_.first();}
93846035553Spatrickpublic:
93946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
94046035553Spatrick    size_type  size() const _NOEXCEPT {return __p2_.first();}
94146035553Spatrick
94246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
94346035553Spatrick    hasher& hash_function() _NOEXCEPT {return __p2_.second();}
94446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
94546035553Spatrick    const hasher& hash_function() const _NOEXCEPT {return __p2_.second();}
94646035553Spatrick
94746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
94846035553Spatrick    float& max_load_factor() _NOEXCEPT {return __p3_.first();}
94946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
95046035553Spatrick    float  max_load_factor() const _NOEXCEPT {return __p3_.first();}
95146035553Spatrick
95246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
95346035553Spatrick    key_equal& key_eq() _NOEXCEPT {return __p3_.second();}
95446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
95546035553Spatrick    const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();}
95646035553Spatrick
95746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
95846035553Spatrick    __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();}
95946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
96046035553Spatrick    const __node_allocator& __node_alloc() const _NOEXCEPT
96146035553Spatrick        {return __p1_.second();}
96246035553Spatrick
96346035553Spatrickpublic:
96446035553Spatrick    typedef __hash_iterator<__node_pointer>                   iterator;
96546035553Spatrick    typedef __hash_const_iterator<__node_pointer>             const_iterator;
96646035553Spatrick    typedef __hash_local_iterator<__node_pointer>             local_iterator;
96746035553Spatrick    typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;
96846035553Spatrick
96946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
97046035553Spatrick    __hash_table()
97146035553Spatrick        _NOEXCEPT_(
97246035553Spatrick            is_nothrow_default_constructible<__bucket_list>::value &&
97346035553Spatrick            is_nothrow_default_constructible<__first_node>::value &&
97446035553Spatrick            is_nothrow_default_constructible<__node_allocator>::value &&
97546035553Spatrick            is_nothrow_default_constructible<hasher>::value &&
97646035553Spatrick            is_nothrow_default_constructible<key_equal>::value);
97746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
97846035553Spatrick    __hash_table(const hasher& __hf, const key_equal& __eql);
97946035553Spatrick    __hash_table(const hasher& __hf, const key_equal& __eql,
98046035553Spatrick                 const allocator_type& __a);
98146035553Spatrick    explicit __hash_table(const allocator_type& __a);
98246035553Spatrick    __hash_table(const __hash_table& __u);
98346035553Spatrick    __hash_table(const __hash_table& __u, const allocator_type& __a);
98446035553Spatrick    __hash_table(__hash_table&& __u)
98546035553Spatrick        _NOEXCEPT_(
98646035553Spatrick            is_nothrow_move_constructible<__bucket_list>::value &&
98746035553Spatrick            is_nothrow_move_constructible<__first_node>::value &&
98846035553Spatrick            is_nothrow_move_constructible<__node_allocator>::value &&
98946035553Spatrick            is_nothrow_move_constructible<hasher>::value &&
99046035553Spatrick            is_nothrow_move_constructible<key_equal>::value);
99146035553Spatrick    __hash_table(__hash_table&& __u, const allocator_type& __a);
99246035553Spatrick    ~__hash_table();
99346035553Spatrick
99446035553Spatrick    __hash_table& operator=(const __hash_table& __u);
99546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
99646035553Spatrick    __hash_table& operator=(__hash_table&& __u)
99746035553Spatrick        _NOEXCEPT_(
99846035553Spatrick            __node_traits::propagate_on_container_move_assignment::value &&
99946035553Spatrick            is_nothrow_move_assignable<__node_allocator>::value &&
100046035553Spatrick            is_nothrow_move_assignable<hasher>::value &&
100146035553Spatrick            is_nothrow_move_assignable<key_equal>::value);
100246035553Spatrick    template <class _InputIterator>
100346035553Spatrick        void __assign_unique(_InputIterator __first, _InputIterator __last);
100446035553Spatrick    template <class _InputIterator>
100546035553Spatrick        void __assign_multi(_InputIterator __first, _InputIterator __last);
100646035553Spatrick
100746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
100846035553Spatrick    size_type max_size() const _NOEXCEPT
100946035553Spatrick    {
101076d0caaeSpatrick        return _VSTD::min<size_type>(
101146035553Spatrick            __node_traits::max_size(__node_alloc()),
101246035553Spatrick            numeric_limits<difference_type >::max()
101346035553Spatrick        );
101446035553Spatrick    }
101546035553Spatrick
101646035553Spatrickprivate:
101746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
101846035553Spatrick    __next_pointer __node_insert_multi_prepare(size_t __cp_hash,
101946035553Spatrick                                               value_type& __cp_val);
102046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
102146035553Spatrick    void __node_insert_multi_perform(__node_pointer __cp,
102246035553Spatrick                                     __next_pointer __pn) _NOEXCEPT;
102346035553Spatrick
102446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
102546035553Spatrick    __next_pointer __node_insert_unique_prepare(size_t __nd_hash,
102646035553Spatrick                                                value_type& __nd_val);
102746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
102846035553Spatrick    void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
102946035553Spatrick
103046035553Spatrickpublic:
103146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
103246035553Spatrick    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
103346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
103446035553Spatrick    iterator             __node_insert_multi(__node_pointer __nd);
103546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
103646035553Spatrick    iterator             __node_insert_multi(const_iterator __p,
103746035553Spatrick                                             __node_pointer __nd);
103846035553Spatrick
103946035553Spatrick    template <class _Key, class ..._Args>
104046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
104146035553Spatrick    pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
104246035553Spatrick
104346035553Spatrick    template <class... _Args>
104446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
104546035553Spatrick    pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
104646035553Spatrick
104746035553Spatrick    template <class _Pp>
104846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
104946035553Spatrick    pair<iterator, bool> __emplace_unique(_Pp&& __x) {
105046035553Spatrick      return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
105146035553Spatrick                                          __can_extract_key<_Pp, key_type>());
105246035553Spatrick    }
105346035553Spatrick
105446035553Spatrick    template <class _First, class _Second>
105546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
1056*4bdff4beSrobert    __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair<iterator, bool> >
1057*4bdff4beSrobert    __emplace_unique(_First&& __f, _Second&& __s) {
105846035553Spatrick        return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
105946035553Spatrick                                              _VSTD::forward<_Second>(__s));
106046035553Spatrick    }
106146035553Spatrick
106246035553Spatrick    template <class... _Args>
106346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
106446035553Spatrick    pair<iterator, bool> __emplace_unique(_Args&&... __args) {
106546035553Spatrick      return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
106646035553Spatrick    }
106746035553Spatrick
106846035553Spatrick    template <class _Pp>
106946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
107046035553Spatrick    pair<iterator, bool>
107146035553Spatrick    __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
107246035553Spatrick      return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
107346035553Spatrick    }
107446035553Spatrick    template <class _Pp>
107546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
107646035553Spatrick    pair<iterator, bool>
107746035553Spatrick    __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
107846035553Spatrick      return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
107946035553Spatrick    }
108046035553Spatrick    template <class _Pp>
108146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
108246035553Spatrick    pair<iterator, bool>
108346035553Spatrick    __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
108446035553Spatrick      return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
108546035553Spatrick    }
108646035553Spatrick
108746035553Spatrick    template <class... _Args>
108846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
108946035553Spatrick    iterator __emplace_multi(_Args&&... __args);
109046035553Spatrick    template <class... _Args>
109146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
109246035553Spatrick    iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
109346035553Spatrick
109446035553Spatrick
109546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
109646035553Spatrick    pair<iterator, bool>
109746035553Spatrick    __insert_unique(__container_value_type&& __x) {
109846035553Spatrick      return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x));
109946035553Spatrick    }
110046035553Spatrick
1101*4bdff4beSrobert    template <class _Pp, class = __enable_if_t<!__is_same_uncvref<_Pp, __container_value_type>::value> >
110246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
110346035553Spatrick    pair<iterator, bool> __insert_unique(_Pp&& __x) {
110446035553Spatrick      return __emplace_unique(_VSTD::forward<_Pp>(__x));
110546035553Spatrick    }
110646035553Spatrick
110746035553Spatrick    template <class _Pp>
110846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
110946035553Spatrick    iterator __insert_multi(_Pp&& __x) {
111046035553Spatrick      return __emplace_multi(_VSTD::forward<_Pp>(__x));
111146035553Spatrick    }
111246035553Spatrick
111346035553Spatrick    template <class _Pp>
111446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
111546035553Spatrick    iterator __insert_multi(const_iterator __p, _Pp&& __x) {
111646035553Spatrick        return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x));
111746035553Spatrick    }
111846035553Spatrick
111946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
112046035553Spatrick    pair<iterator, bool> __insert_unique(const __container_value_type& __x) {
112146035553Spatrick        return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
112246035553Spatrick    }
112346035553Spatrick
112446035553Spatrick#if _LIBCPP_STD_VER > 14
112546035553Spatrick    template <class _NodeHandle, class _InsertReturnType>
112646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
112746035553Spatrick    _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
112846035553Spatrick    template <class _NodeHandle>
112946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
113046035553Spatrick    iterator __node_handle_insert_unique(const_iterator __hint,
113146035553Spatrick                                         _NodeHandle&& __nh);
113246035553Spatrick    template <class _Table>
113346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
113446035553Spatrick    void __node_handle_merge_unique(_Table& __source);
113546035553Spatrick
113646035553Spatrick    template <class _NodeHandle>
113746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
113846035553Spatrick    iterator __node_handle_insert_multi(_NodeHandle&& __nh);
113946035553Spatrick    template <class _NodeHandle>
114046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
114146035553Spatrick    iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
114246035553Spatrick    template <class _Table>
114346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
114446035553Spatrick    void __node_handle_merge_multi(_Table& __source);
114546035553Spatrick
114646035553Spatrick    template <class _NodeHandle>
114746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
114846035553Spatrick    _NodeHandle __node_handle_extract(key_type const& __key);
114946035553Spatrick    template <class _NodeHandle>
115046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
115146035553Spatrick    _NodeHandle __node_handle_extract(const_iterator __it);
115246035553Spatrick#endif
115346035553Spatrick
115446035553Spatrick    void clear() _NOEXCEPT;
1155*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); }
1156*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); }
1157*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n)
1158*4bdff4beSrobert    {
1159*4bdff4beSrobert        __rehash_unique(static_cast<size_type>(std::ceil(__n / max_load_factor())));
1160*4bdff4beSrobert    }
1161*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n)
1162*4bdff4beSrobert    {
1163*4bdff4beSrobert        __rehash_multi(static_cast<size_type>(std::ceil(__n / max_load_factor())));
1164*4bdff4beSrobert    }
116546035553Spatrick
116646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
116746035553Spatrick    size_type bucket_count() const _NOEXCEPT
116846035553Spatrick    {
116946035553Spatrick        return __bucket_list_.get_deleter().size();
117046035553Spatrick    }
117146035553Spatrick
117246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
117346035553Spatrick    iterator       begin() _NOEXCEPT;
117446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
117546035553Spatrick    iterator       end() _NOEXCEPT;
117646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
117746035553Spatrick    const_iterator begin() const _NOEXCEPT;
117846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
117946035553Spatrick    const_iterator end() const _NOEXCEPT;
118046035553Spatrick
118146035553Spatrick    template <class _Key>
118246035553Spatrick        _LIBCPP_INLINE_VISIBILITY
118346035553Spatrick        size_type bucket(const _Key& __k) const
118446035553Spatrick        {
118546035553Spatrick            _LIBCPP_ASSERT(bucket_count() > 0,
118646035553Spatrick                "unordered container::bucket(key) called when bucket_count() == 0");
1187*4bdff4beSrobert            return std::__constrain_hash(hash_function()(__k), bucket_count());
118846035553Spatrick        }
118946035553Spatrick
119046035553Spatrick    template <class _Key>
119146035553Spatrick        iterator       find(const _Key& __x);
119246035553Spatrick    template <class _Key>
119346035553Spatrick        const_iterator find(const _Key& __x) const;
119446035553Spatrick
119546035553Spatrick    typedef __hash_node_destructor<__node_allocator> _Dp;
119646035553Spatrick    typedef unique_ptr<__node, _Dp> __node_holder;
119746035553Spatrick
119846035553Spatrick    iterator erase(const_iterator __p);
119946035553Spatrick    iterator erase(const_iterator __first, const_iterator __last);
120046035553Spatrick    template <class _Key>
120146035553Spatrick        size_type __erase_unique(const _Key& __k);
120246035553Spatrick    template <class _Key>
120346035553Spatrick        size_type __erase_multi(const _Key& __k);
120446035553Spatrick    __node_holder remove(const_iterator __p) _NOEXCEPT;
120546035553Spatrick
120646035553Spatrick    template <class _Key>
120746035553Spatrick        _LIBCPP_INLINE_VISIBILITY
120846035553Spatrick        size_type __count_unique(const _Key& __k) const;
120946035553Spatrick    template <class _Key>
121046035553Spatrick        size_type __count_multi(const _Key& __k) const;
121146035553Spatrick
121246035553Spatrick    template <class _Key>
121346035553Spatrick        pair<iterator, iterator>
121446035553Spatrick        __equal_range_unique(const _Key& __k);
121546035553Spatrick    template <class _Key>
121646035553Spatrick        pair<const_iterator, const_iterator>
121746035553Spatrick        __equal_range_unique(const _Key& __k) const;
121846035553Spatrick
121946035553Spatrick    template <class _Key>
122046035553Spatrick        pair<iterator, iterator>
122146035553Spatrick        __equal_range_multi(const _Key& __k);
122246035553Spatrick    template <class _Key>
122346035553Spatrick        pair<const_iterator, const_iterator>
122446035553Spatrick        __equal_range_multi(const _Key& __k) const;
122546035553Spatrick
122646035553Spatrick    void swap(__hash_table& __u)
122746035553Spatrick#if _LIBCPP_STD_VER <= 11
122846035553Spatrick        _NOEXCEPT_(
122946035553Spatrick            __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
123046035553Spatrick            && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
123146035553Spatrick                  || __is_nothrow_swappable<__pointer_allocator>::value)
123246035553Spatrick            && (!__node_traits::propagate_on_container_swap::value
123346035553Spatrick                  || __is_nothrow_swappable<__node_allocator>::value)
123446035553Spatrick            );
123546035553Spatrick#else
123646035553Spatrick     _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
123746035553Spatrick#endif
123846035553Spatrick
123946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
124046035553Spatrick    size_type max_bucket_count() const _NOEXCEPT
124146035553Spatrick        {return max_size(); }
124246035553Spatrick    size_type bucket_size(size_type __n) const;
124346035553Spatrick    _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
124446035553Spatrick    {
124546035553Spatrick        size_type __bc = bucket_count();
124646035553Spatrick        return __bc != 0 ? (float)size() / __bc : 0.f;
124746035553Spatrick    }
124846035553Spatrick    _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
124946035553Spatrick    {
125046035553Spatrick        _LIBCPP_ASSERT(__mlf > 0,
125146035553Spatrick            "unordered container::max_load_factor(lf) called with lf <= 0");
125246035553Spatrick        max_load_factor() = _VSTD::max(__mlf, load_factor());
125346035553Spatrick    }
125446035553Spatrick
125546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
125646035553Spatrick    local_iterator
125746035553Spatrick    begin(size_type __n)
125846035553Spatrick    {
125946035553Spatrick        _LIBCPP_ASSERT(__n < bucket_count(),
126046035553Spatrick            "unordered container::begin(n) called with n >= bucket_count()");
126146035553Spatrick        return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
126246035553Spatrick    }
126346035553Spatrick
126446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
126546035553Spatrick    local_iterator
126646035553Spatrick    end(size_type __n)
126746035553Spatrick    {
126846035553Spatrick        _LIBCPP_ASSERT(__n < bucket_count(),
126946035553Spatrick            "unordered container::end(n) called with n >= bucket_count()");
127046035553Spatrick        return local_iterator(nullptr, __n, bucket_count(), this);
127146035553Spatrick    }
127246035553Spatrick
127346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
127446035553Spatrick    const_local_iterator
127546035553Spatrick    cbegin(size_type __n) const
127646035553Spatrick    {
127746035553Spatrick        _LIBCPP_ASSERT(__n < bucket_count(),
127846035553Spatrick            "unordered container::cbegin(n) called with n >= bucket_count()");
127946035553Spatrick        return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
128046035553Spatrick    }
128146035553Spatrick
128246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
128346035553Spatrick    const_local_iterator
128446035553Spatrick    cend(size_type __n) const
128546035553Spatrick    {
128646035553Spatrick        _LIBCPP_ASSERT(__n < bucket_count(),
128746035553Spatrick            "unordered container::cend(n) called with n >= bucket_count()");
128846035553Spatrick        return const_local_iterator(nullptr, __n, bucket_count(), this);
128946035553Spatrick    }
129046035553Spatrick
1291*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
129246035553Spatrick
129346035553Spatrick    bool __dereferenceable(const const_iterator* __i) const;
129446035553Spatrick    bool __decrementable(const const_iterator* __i) const;
129546035553Spatrick    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
129646035553Spatrick    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
129746035553Spatrick
1298*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
129946035553Spatrick
130046035553Spatrickprivate:
1301*4bdff4beSrobert    template <bool _UniqueKeys> void __rehash(size_type __n);
1302*4bdff4beSrobert    template <bool _UniqueKeys> void __do_rehash(size_type __n);
130346035553Spatrick
130446035553Spatrick    template <class ..._Args>
130546035553Spatrick    __node_holder __construct_node(_Args&& ...__args);
130646035553Spatrick
130746035553Spatrick    template <class _First, class ..._Rest>
130846035553Spatrick    __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
130946035553Spatrick
131046035553Spatrick
131146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
131246035553Spatrick    void __copy_assign_alloc(const __hash_table& __u)
131346035553Spatrick        {__copy_assign_alloc(__u, integral_constant<bool,
131446035553Spatrick             __node_traits::propagate_on_container_copy_assignment::value>());}
131546035553Spatrick    void __copy_assign_alloc(const __hash_table& __u, true_type);
131646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
131746035553Spatrick        void __copy_assign_alloc(const __hash_table&, false_type) {}
131846035553Spatrick
131946035553Spatrick    void __move_assign(__hash_table& __u, false_type);
132046035553Spatrick    void __move_assign(__hash_table& __u, true_type)
132146035553Spatrick        _NOEXCEPT_(
132246035553Spatrick            is_nothrow_move_assignable<__node_allocator>::value &&
132346035553Spatrick            is_nothrow_move_assignable<hasher>::value &&
132446035553Spatrick            is_nothrow_move_assignable<key_equal>::value);
132546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
132646035553Spatrick    void __move_assign_alloc(__hash_table& __u)
132746035553Spatrick        _NOEXCEPT_(
132846035553Spatrick            !__node_traits::propagate_on_container_move_assignment::value ||
132946035553Spatrick            (is_nothrow_move_assignable<__pointer_allocator>::value &&
133046035553Spatrick             is_nothrow_move_assignable<__node_allocator>::value))
133146035553Spatrick        {__move_assign_alloc(__u, integral_constant<bool,
133246035553Spatrick             __node_traits::propagate_on_container_move_assignment::value>());}
133346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
133446035553Spatrick    void __move_assign_alloc(__hash_table& __u, true_type)
133546035553Spatrick        _NOEXCEPT_(
133646035553Spatrick            is_nothrow_move_assignable<__pointer_allocator>::value &&
133746035553Spatrick            is_nothrow_move_assignable<__node_allocator>::value)
133846035553Spatrick    {
133946035553Spatrick        __bucket_list_.get_deleter().__alloc() =
134046035553Spatrick                _VSTD::move(__u.__bucket_list_.get_deleter().__alloc());
134146035553Spatrick        __node_alloc() = _VSTD::move(__u.__node_alloc());
134246035553Spatrick    }
134346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
134446035553Spatrick        void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
134546035553Spatrick
134646035553Spatrick    void __deallocate_node(__next_pointer __np) _NOEXCEPT;
134746035553Spatrick    __next_pointer __detach() _NOEXCEPT;
134846035553Spatrick
134946035553Spatrick    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
135046035553Spatrick    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
135146035553Spatrick};
135246035553Spatrick
135346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
135446035553Spatrickinline
135546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()
135646035553Spatrick    _NOEXCEPT_(
135746035553Spatrick        is_nothrow_default_constructible<__bucket_list>::value &&
135846035553Spatrick        is_nothrow_default_constructible<__first_node>::value &&
135946035553Spatrick        is_nothrow_default_constructible<__node_allocator>::value &&
136046035553Spatrick        is_nothrow_default_constructible<hasher>::value &&
136146035553Spatrick        is_nothrow_default_constructible<key_equal>::value)
136246035553Spatrick    : __p2_(0, __default_init_tag()),
136346035553Spatrick      __p3_(1.0f, __default_init_tag())
136446035553Spatrick{
136546035553Spatrick}
136646035553Spatrick
136746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
136846035553Spatrickinline
136946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
137046035553Spatrick                                                       const key_equal& __eql)
137146035553Spatrick    : __bucket_list_(nullptr, __bucket_list_deleter()),
137246035553Spatrick      __p1_(),
137346035553Spatrick      __p2_(0, __hf),
137446035553Spatrick      __p3_(1.0f, __eql)
137546035553Spatrick{
137646035553Spatrick}
137746035553Spatrick
137846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
137946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
138046035553Spatrick                                                       const key_equal& __eql,
138146035553Spatrick                                                       const allocator_type& __a)
138246035553Spatrick    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
138346035553Spatrick      __p1_(__default_init_tag(), __node_allocator(__a)),
138446035553Spatrick      __p2_(0, __hf),
138546035553Spatrick      __p3_(1.0f, __eql)
138646035553Spatrick{
138746035553Spatrick}
138846035553Spatrick
138946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
139046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
139146035553Spatrick    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
139246035553Spatrick      __p1_(__default_init_tag(), __node_allocator(__a)),
139346035553Spatrick      __p2_(0, __default_init_tag()),
139446035553Spatrick      __p3_(1.0f, __default_init_tag())
139546035553Spatrick{
139646035553Spatrick}
139746035553Spatrick
139846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
139946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
140046035553Spatrick    : __bucket_list_(nullptr,
140146035553Spatrick          __bucket_list_deleter(allocator_traits<__pointer_allocator>::
140246035553Spatrick              select_on_container_copy_construction(
140346035553Spatrick                  __u.__bucket_list_.get_deleter().__alloc()), 0)),
140446035553Spatrick      __p1_(__default_init_tag(), allocator_traits<__node_allocator>::
140546035553Spatrick          select_on_container_copy_construction(__u.__node_alloc())),
140646035553Spatrick      __p2_(0, __u.hash_function()),
140746035553Spatrick      __p3_(__u.__p3_)
140846035553Spatrick{
140946035553Spatrick}
141046035553Spatrick
141146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
141246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
141346035553Spatrick                                                       const allocator_type& __a)
141446035553Spatrick    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
141546035553Spatrick      __p1_(__default_init_tag(), __node_allocator(__a)),
141646035553Spatrick      __p2_(0, __u.hash_function()),
141746035553Spatrick      __p3_(__u.__p3_)
141846035553Spatrick{
141946035553Spatrick}
142046035553Spatrick
142146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
142246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
142346035553Spatrick        _NOEXCEPT_(
142446035553Spatrick            is_nothrow_move_constructible<__bucket_list>::value &&
142546035553Spatrick            is_nothrow_move_constructible<__first_node>::value &&
142646035553Spatrick            is_nothrow_move_constructible<__node_allocator>::value &&
142746035553Spatrick            is_nothrow_move_constructible<hasher>::value &&
142846035553Spatrick            is_nothrow_move_constructible<key_equal>::value)
142946035553Spatrick    : __bucket_list_(_VSTD::move(__u.__bucket_list_)),
143046035553Spatrick      __p1_(_VSTD::move(__u.__p1_)),
143146035553Spatrick      __p2_(_VSTD::move(__u.__p2_)),
143246035553Spatrick      __p3_(_VSTD::move(__u.__p3_))
143346035553Spatrick{
143446035553Spatrick    if (size() > 0)
143546035553Spatrick    {
1436*4bdff4beSrobert        __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
143746035553Spatrick            __p1_.first().__ptr();
143846035553Spatrick        __u.__p1_.first().__next_ = nullptr;
143946035553Spatrick        __u.size() = 0;
144046035553Spatrick    }
144146035553Spatrick}
144246035553Spatrick
144346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
144446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
144546035553Spatrick                                                       const allocator_type& __a)
144646035553Spatrick    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
144746035553Spatrick      __p1_(__default_init_tag(), __node_allocator(__a)),
144846035553Spatrick      __p2_(0, _VSTD::move(__u.hash_function())),
144946035553Spatrick      __p3_(_VSTD::move(__u.__p3_))
145046035553Spatrick{
145146035553Spatrick    if (__a == allocator_type(__u.__node_alloc()))
145246035553Spatrick    {
145346035553Spatrick        __bucket_list_.reset(__u.__bucket_list_.release());
145446035553Spatrick        __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
145546035553Spatrick        __u.__bucket_list_.get_deleter().size() = 0;
145646035553Spatrick        if (__u.size() > 0)
145746035553Spatrick        {
145846035553Spatrick            __p1_.first().__next_ = __u.__p1_.first().__next_;
145946035553Spatrick            __u.__p1_.first().__next_ = nullptr;
1460*4bdff4beSrobert            __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
146146035553Spatrick                __p1_.first().__ptr();
146246035553Spatrick            size() = __u.size();
146346035553Spatrick            __u.size() = 0;
146446035553Spatrick        }
146546035553Spatrick    }
146646035553Spatrick}
146746035553Spatrick
146846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
146946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
147046035553Spatrick{
147146035553Spatrick#if defined(_LIBCPP_CXX03_LANG)
147246035553Spatrick    static_assert((is_copy_constructible<key_equal>::value),
147346035553Spatrick                 "Predicate must be copy-constructible.");
147446035553Spatrick    static_assert((is_copy_constructible<hasher>::value),
147546035553Spatrick                 "Hasher must be copy-constructible.");
147646035553Spatrick#endif
147746035553Spatrick
147846035553Spatrick    __deallocate_node(__p1_.first().__next_);
1479*4bdff4beSrobert    std::__debug_db_erase_c(this);
148046035553Spatrick}
148146035553Spatrick
148246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
148346035553Spatrickvoid
148446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(
148546035553Spatrick        const __hash_table& __u, true_type)
148646035553Spatrick{
148746035553Spatrick    if (__node_alloc() != __u.__node_alloc())
148846035553Spatrick    {
148946035553Spatrick        clear();
149046035553Spatrick        __bucket_list_.reset();
149146035553Spatrick        __bucket_list_.get_deleter().size() = 0;
149246035553Spatrick    }
149346035553Spatrick    __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();
149446035553Spatrick    __node_alloc() = __u.__node_alloc();
149546035553Spatrick}
149646035553Spatrick
149746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
149846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>&
149946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u)
150046035553Spatrick{
1501*4bdff4beSrobert    if (this != _VSTD::addressof(__u))
150246035553Spatrick    {
150346035553Spatrick        __copy_assign_alloc(__u);
150446035553Spatrick        hash_function() = __u.hash_function();
150546035553Spatrick        key_eq() = __u.key_eq();
150646035553Spatrick        max_load_factor() = __u.max_load_factor();
150746035553Spatrick        __assign_multi(__u.begin(), __u.end());
150846035553Spatrick    }
150946035553Spatrick    return *this;
151046035553Spatrick}
151146035553Spatrick
151246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
151346035553Spatrickvoid
151446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
151546035553Spatrick    _NOEXCEPT
151646035553Spatrick{
151746035553Spatrick    __node_allocator& __na = __node_alloc();
151846035553Spatrick    while (__np != nullptr)
151946035553Spatrick    {
152046035553Spatrick        __next_pointer __next = __np->__next_;
1521*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
152246035553Spatrick        __c_node* __c = __get_db()->__find_c_and_lock(this);
152346035553Spatrick        for (__i_node** __p = __c->end_; __p != __c->beg_; )
152446035553Spatrick        {
152546035553Spatrick            --__p;
152646035553Spatrick            iterator* __i = static_cast<iterator*>((*__p)->__i_);
152746035553Spatrick            if (__i->__node_ == __np)
152846035553Spatrick            {
152946035553Spatrick                (*__p)->__c_ = nullptr;
153046035553Spatrick                if (--__c->end_ != __p)
153176d0caaeSpatrick                    _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
153246035553Spatrick            }
153346035553Spatrick        }
153446035553Spatrick        __get_db()->unlock();
153546035553Spatrick#endif
153646035553Spatrick        __node_pointer __real_np = __np->__upcast();
153746035553Spatrick        __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_));
153846035553Spatrick        __node_traits::deallocate(__na, __real_np, 1);
153946035553Spatrick        __np = __next;
154046035553Spatrick    }
154146035553Spatrick}
154246035553Spatrick
154346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
154446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
154546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT
154646035553Spatrick{
154746035553Spatrick    size_type __bc = bucket_count();
154846035553Spatrick    for (size_type __i = 0; __i < __bc; ++__i)
154946035553Spatrick        __bucket_list_[__i] = nullptr;
155046035553Spatrick    size() = 0;
155146035553Spatrick    __next_pointer __cache = __p1_.first().__next_;
155246035553Spatrick    __p1_.first().__next_ = nullptr;
155346035553Spatrick    return __cache;
155446035553Spatrick}
155546035553Spatrick
155646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
155746035553Spatrickvoid
155846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
155946035553Spatrick        __hash_table& __u, true_type)
156046035553Spatrick    _NOEXCEPT_(
156146035553Spatrick        is_nothrow_move_assignable<__node_allocator>::value &&
156246035553Spatrick        is_nothrow_move_assignable<hasher>::value &&
156346035553Spatrick        is_nothrow_move_assignable<key_equal>::value)
156446035553Spatrick{
156546035553Spatrick    clear();
156646035553Spatrick    __bucket_list_.reset(__u.__bucket_list_.release());
156746035553Spatrick    __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
156846035553Spatrick    __u.__bucket_list_.get_deleter().size() = 0;
156946035553Spatrick    __move_assign_alloc(__u);
157046035553Spatrick    size() = __u.size();
157146035553Spatrick    hash_function() = _VSTD::move(__u.hash_function());
157246035553Spatrick    max_load_factor() = __u.max_load_factor();
157346035553Spatrick    key_eq() = _VSTD::move(__u.key_eq());
157446035553Spatrick    __p1_.first().__next_ = __u.__p1_.first().__next_;
157546035553Spatrick    if (size() > 0)
157646035553Spatrick    {
1577*4bdff4beSrobert        __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
157846035553Spatrick            __p1_.first().__ptr();
157946035553Spatrick        __u.__p1_.first().__next_ = nullptr;
158046035553Spatrick        __u.size() = 0;
158146035553Spatrick    }
1582*4bdff4beSrobert    std::__debug_db_swap(this, std::addressof(__u));
158346035553Spatrick}
158446035553Spatrick
158546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
158646035553Spatrickvoid
158746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
158846035553Spatrick        __hash_table& __u, false_type)
158946035553Spatrick{
159046035553Spatrick    if (__node_alloc() == __u.__node_alloc())
159146035553Spatrick        __move_assign(__u, true_type());
159246035553Spatrick    else
159346035553Spatrick    {
159446035553Spatrick        hash_function() = _VSTD::move(__u.hash_function());
159546035553Spatrick        key_eq() = _VSTD::move(__u.key_eq());
159646035553Spatrick        max_load_factor() = __u.max_load_factor();
159746035553Spatrick        if (bucket_count() != 0)
159846035553Spatrick        {
159946035553Spatrick            __next_pointer __cache = __detach();
160046035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
160146035553Spatrick            try
160246035553Spatrick            {
160346035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
160446035553Spatrick                const_iterator __i = __u.begin();
160546035553Spatrick                while (__cache != nullptr && __u.size() != 0)
160646035553Spatrick                {
160746035553Spatrick                    __cache->__upcast()->__value_ =
160846035553Spatrick                        _VSTD::move(__u.remove(__i++)->__value_);
160946035553Spatrick                    __next_pointer __next = __cache->__next_;
161046035553Spatrick                    __node_insert_multi(__cache->__upcast());
161146035553Spatrick                    __cache = __next;
161246035553Spatrick                }
161346035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
161446035553Spatrick            }
161546035553Spatrick            catch (...)
161646035553Spatrick            {
161746035553Spatrick                __deallocate_node(__cache);
161846035553Spatrick                throw;
161946035553Spatrick            }
162046035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
162146035553Spatrick            __deallocate_node(__cache);
162246035553Spatrick        }
162346035553Spatrick        const_iterator __i = __u.begin();
162446035553Spatrick        while (__u.size() != 0)
162546035553Spatrick        {
162646035553Spatrick            __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_));
162746035553Spatrick            __node_insert_multi(__h.get());
162846035553Spatrick            __h.release();
162946035553Spatrick        }
163046035553Spatrick    }
163146035553Spatrick}
163246035553Spatrick
163346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
163446035553Spatrickinline
163546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>&
163646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
163746035553Spatrick    _NOEXCEPT_(
163846035553Spatrick        __node_traits::propagate_on_container_move_assignment::value &&
163946035553Spatrick        is_nothrow_move_assignable<__node_allocator>::value &&
164046035553Spatrick        is_nothrow_move_assignable<hasher>::value &&
164146035553Spatrick        is_nothrow_move_assignable<key_equal>::value)
164246035553Spatrick{
164346035553Spatrick    __move_assign(__u, integral_constant<bool,
164446035553Spatrick                  __node_traits::propagate_on_container_move_assignment::value>());
164546035553Spatrick    return *this;
164646035553Spatrick}
164746035553Spatrick
164846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
164946035553Spatricktemplate <class _InputIterator>
165046035553Spatrickvoid
165146035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,
165246035553Spatrick                                                          _InputIterator __last)
165346035553Spatrick{
165446035553Spatrick    typedef iterator_traits<_InputIterator> _ITraits;
165546035553Spatrick    typedef typename _ITraits::value_type _ItValueType;
165646035553Spatrick    static_assert((is_same<_ItValueType, __container_value_type>::value),
165746035553Spatrick                  "__assign_unique may only be called with the containers value type");
165846035553Spatrick
165946035553Spatrick    if (bucket_count() != 0)
166046035553Spatrick    {
166146035553Spatrick        __next_pointer __cache = __detach();
166246035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
166346035553Spatrick        try
166446035553Spatrick        {
166546035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
166646035553Spatrick            for (; __cache != nullptr && __first != __last; ++__first)
166746035553Spatrick            {
166846035553Spatrick                __cache->__upcast()->__value_ = *__first;
166946035553Spatrick                __next_pointer __next = __cache->__next_;
167046035553Spatrick                __node_insert_unique(__cache->__upcast());
167146035553Spatrick                __cache = __next;
167246035553Spatrick            }
167346035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
167446035553Spatrick        }
167546035553Spatrick        catch (...)
167646035553Spatrick        {
167746035553Spatrick            __deallocate_node(__cache);
167846035553Spatrick            throw;
167946035553Spatrick        }
168046035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
168146035553Spatrick        __deallocate_node(__cache);
168246035553Spatrick    }
168346035553Spatrick    for (; __first != __last; ++__first)
168446035553Spatrick        __insert_unique(*__first);
168546035553Spatrick}
168646035553Spatrick
168746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
168846035553Spatricktemplate <class _InputIterator>
168946035553Spatrickvoid
169046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
169146035553Spatrick                                                         _InputIterator __last)
169246035553Spatrick{
169346035553Spatrick    typedef iterator_traits<_InputIterator> _ITraits;
169446035553Spatrick    typedef typename _ITraits::value_type _ItValueType;
169546035553Spatrick    static_assert((is_same<_ItValueType, __container_value_type>::value ||
169646035553Spatrick                  is_same<_ItValueType, __node_value_type>::value),
169746035553Spatrick                  "__assign_multi may only be called with the containers value type"
169846035553Spatrick                  " or the nodes value type");
169946035553Spatrick    if (bucket_count() != 0)
170046035553Spatrick    {
170146035553Spatrick        __next_pointer __cache = __detach();
170246035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
170346035553Spatrick        try
170446035553Spatrick        {
170546035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
170646035553Spatrick            for (; __cache != nullptr && __first != __last; ++__first)
170746035553Spatrick            {
170846035553Spatrick                __cache->__upcast()->__value_ = *__first;
170946035553Spatrick                __next_pointer __next = __cache->__next_;
171046035553Spatrick                __node_insert_multi(__cache->__upcast());
171146035553Spatrick                __cache = __next;
171246035553Spatrick            }
171346035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
171446035553Spatrick        }
171546035553Spatrick        catch (...)
171646035553Spatrick        {
171746035553Spatrick            __deallocate_node(__cache);
171846035553Spatrick            throw;
171946035553Spatrick        }
172046035553Spatrick#endif // _LIBCPP_NO_EXCEPTIONS
172146035553Spatrick        __deallocate_node(__cache);
172246035553Spatrick    }
172346035553Spatrick    for (; __first != __last; ++__first)
172446035553Spatrick        __insert_multi(_NodeTypes::__get_value(*__first));
172546035553Spatrick}
172646035553Spatrick
172746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
172846035553Spatrickinline
172946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
173046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
173146035553Spatrick{
173246035553Spatrick    return iterator(__p1_.first().__next_, this);
173346035553Spatrick}
173446035553Spatrick
173546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
173646035553Spatrickinline
173746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
173846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
173946035553Spatrick{
174046035553Spatrick    return iterator(nullptr, this);
174146035553Spatrick}
174246035553Spatrick
174346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
174446035553Spatrickinline
174546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
174646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
174746035553Spatrick{
174846035553Spatrick    return const_iterator(__p1_.first().__next_, this);
174946035553Spatrick}
175046035553Spatrick
175146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
175246035553Spatrickinline
175346035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
175446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
175546035553Spatrick{
175646035553Spatrick    return const_iterator(nullptr, this);
175746035553Spatrick}
175846035553Spatrick
175946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
176046035553Spatrickvoid
176146035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
176246035553Spatrick{
176346035553Spatrick    if (size() > 0)
176446035553Spatrick    {
176546035553Spatrick        __deallocate_node(__p1_.first().__next_);
176646035553Spatrick        __p1_.first().__next_ = nullptr;
176746035553Spatrick        size_type __bc = bucket_count();
176846035553Spatrick        for (size_type __i = 0; __i < __bc; ++__i)
176946035553Spatrick            __bucket_list_[__i] = nullptr;
177046035553Spatrick        size() = 0;
177146035553Spatrick    }
177246035553Spatrick}
177346035553Spatrick
177446035553Spatrick
177546035553Spatrick// Prepare the container for an insertion of the value __value with the hash
177646035553Spatrick// __hash. This does a lookup into the container to see if __value is already
177746035553Spatrick// present, and performs a rehash if necessary. Returns a pointer to the
177846035553Spatrick// existing element if it exists, otherwise nullptr.
177946035553Spatrick//
178046035553Spatrick// Note that this function does forward exceptions if key_eq() throws, and never
178146035553Spatrick// mutates __value or actually inserts into the map.
178246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
178346035553Spatrick_LIBCPP_INLINE_VISIBILITY
178446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
178546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
178646035553Spatrick    size_t __hash, value_type& __value)
178746035553Spatrick{
178846035553Spatrick    size_type __bc = bucket_count();
178946035553Spatrick
179046035553Spatrick    if (__bc != 0)
179146035553Spatrick    {
1792*4bdff4beSrobert        size_t __chash = std::__constrain_hash(__hash, __bc);
179346035553Spatrick        __next_pointer __ndptr = __bucket_list_[__chash];
179446035553Spatrick        if (__ndptr != nullptr)
179546035553Spatrick        {
179646035553Spatrick            for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
1797*4bdff4beSrobert                                             std::__constrain_hash(__ndptr->__hash(), __bc) == __chash;
179846035553Spatrick                                                     __ndptr = __ndptr->__next_)
179946035553Spatrick            {
180046035553Spatrick                if (key_eq()(__ndptr->__upcast()->__value_, __value))
180146035553Spatrick                    return __ndptr;
180246035553Spatrick            }
180346035553Spatrick        }
180446035553Spatrick    }
180546035553Spatrick    if (size()+1 > __bc * max_load_factor() || __bc == 0)
180646035553Spatrick    {
1807*4bdff4beSrobert        __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
1808*4bdff4beSrobert                                     size_type(std::ceil(float(size() + 1) / max_load_factor()))));
180946035553Spatrick    }
181046035553Spatrick    return nullptr;
181146035553Spatrick}
181246035553Spatrick
181346035553Spatrick// Insert the node __nd into the container by pushing it into the right bucket,
181446035553Spatrick// and updating size(). Assumes that __nd->__hash is up-to-date, and that
181546035553Spatrick// rehashing has already occurred and that no element with the same key exists
181646035553Spatrick// in the map.
181746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
181846035553Spatrick_LIBCPP_INLINE_VISIBILITY
181946035553Spatrickvoid
182046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
182146035553Spatrick    __node_pointer __nd) _NOEXCEPT
182246035553Spatrick{
182346035553Spatrick    size_type __bc = bucket_count();
1824*4bdff4beSrobert    size_t __chash = std::__constrain_hash(__nd->__hash(), __bc);
182546035553Spatrick    // insert_after __bucket_list_[__chash], or __first_node if bucket is null
182646035553Spatrick    __next_pointer __pn = __bucket_list_[__chash];
182746035553Spatrick    if (__pn == nullptr)
182846035553Spatrick    {
182946035553Spatrick        __pn =__p1_.first().__ptr();
183046035553Spatrick        __nd->__next_ = __pn->__next_;
183146035553Spatrick        __pn->__next_ = __nd->__ptr();
183246035553Spatrick        // fix up __bucket_list_
183346035553Spatrick        __bucket_list_[__chash] = __pn;
183446035553Spatrick        if (__nd->__next_ != nullptr)
1835*4bdff4beSrobert            __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
183646035553Spatrick    }
183746035553Spatrick    else
183846035553Spatrick    {
183946035553Spatrick        __nd->__next_ = __pn->__next_;
184046035553Spatrick        __pn->__next_ = __nd->__ptr();
184146035553Spatrick    }
184246035553Spatrick    ++size();
184346035553Spatrick}
184446035553Spatrick
184546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
184646035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
184746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
184846035553Spatrick{
184946035553Spatrick    __nd->__hash_ = hash_function()(__nd->__value_);
185046035553Spatrick    __next_pointer __existing_node =
185146035553Spatrick        __node_insert_unique_prepare(__nd->__hash(), __nd->__value_);
185246035553Spatrick
185346035553Spatrick    // Insert the node, unless it already exists in the container.
185446035553Spatrick    bool __inserted = false;
185546035553Spatrick    if (__existing_node == nullptr)
185646035553Spatrick    {
185746035553Spatrick        __node_insert_unique_perform(__nd);
185846035553Spatrick        __existing_node = __nd->__ptr();
185946035553Spatrick        __inserted = true;
186046035553Spatrick    }
186146035553Spatrick    return pair<iterator, bool>(iterator(__existing_node, this), __inserted);
186246035553Spatrick}
186346035553Spatrick
186446035553Spatrick// Prepare the container for an insertion of the value __cp_val with the hash
186546035553Spatrick// __cp_hash. This does a lookup into the container to see if __cp_value is
186646035553Spatrick// already present, and performs a rehash if necessary. Returns a pointer to the
186776d0caaeSpatrick// last occurrence of __cp_val in the map.
186846035553Spatrick//
186946035553Spatrick// Note that this function does forward exceptions if key_eq() throws, and never
187046035553Spatrick// mutates __value or actually inserts into the map.
187146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
187246035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
187346035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
187446035553Spatrick    size_t __cp_hash, value_type& __cp_val)
187546035553Spatrick{
187646035553Spatrick    size_type __bc = bucket_count();
187746035553Spatrick    if (size()+1 > __bc * max_load_factor() || __bc == 0)
187846035553Spatrick    {
1879*4bdff4beSrobert        __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
1880*4bdff4beSrobert                       size_type(std::ceil(float(size() + 1) / max_load_factor()))));
188146035553Spatrick        __bc = bucket_count();
188246035553Spatrick    }
1883*4bdff4beSrobert    size_t __chash = std::__constrain_hash(__cp_hash, __bc);
188446035553Spatrick    __next_pointer __pn = __bucket_list_[__chash];
188546035553Spatrick    if (__pn != nullptr)
188646035553Spatrick    {
188746035553Spatrick        for (bool __found = false; __pn->__next_ != nullptr &&
1888*4bdff4beSrobert                                   std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
188946035553Spatrick                                                           __pn = __pn->__next_)
189046035553Spatrick        {
189146035553Spatrick            //      __found    key_eq()     action
189246035553Spatrick            //      false       false       loop
189346035553Spatrick            //      true        true        loop
189446035553Spatrick            //      false       true        set __found to true
189546035553Spatrick            //      true        false       break
189646035553Spatrick            if (__found != (__pn->__next_->__hash() == __cp_hash &&
189746035553Spatrick                            key_eq()(__pn->__next_->__upcast()->__value_, __cp_val)))
189846035553Spatrick            {
189946035553Spatrick                if (!__found)
190046035553Spatrick                    __found = true;
190146035553Spatrick                else
190246035553Spatrick                    break;
190346035553Spatrick            }
190446035553Spatrick        }
190546035553Spatrick    }
190646035553Spatrick    return __pn;
190746035553Spatrick}
190846035553Spatrick
190946035553Spatrick// Insert the node __cp into the container after __pn (which is the last node in
191046035553Spatrick// the bucket that compares equal to __cp). Rehashing, and checking for
191146035553Spatrick// uniqueness has already been performed (in __node_insert_multi_prepare), so
191246035553Spatrick// all we need to do is update the bucket and size(). Assumes that __cp->__hash
191346035553Spatrick// is up-to-date.
191446035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
191546035553Spatrickvoid
191646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
191746035553Spatrick    __node_pointer __cp, __next_pointer __pn) _NOEXCEPT
191846035553Spatrick{
191946035553Spatrick    size_type __bc = bucket_count();
1920*4bdff4beSrobert    size_t __chash = std::__constrain_hash(__cp->__hash_, __bc);
192146035553Spatrick    if (__pn == nullptr)
192246035553Spatrick    {
192346035553Spatrick        __pn =__p1_.first().__ptr();
192446035553Spatrick        __cp->__next_ = __pn->__next_;
192546035553Spatrick        __pn->__next_ = __cp->__ptr();
192646035553Spatrick        // fix up __bucket_list_
192746035553Spatrick        __bucket_list_[__chash] = __pn;
192846035553Spatrick        if (__cp->__next_ != nullptr)
1929*4bdff4beSrobert            __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)]
193046035553Spatrick                = __cp->__ptr();
193146035553Spatrick    }
193246035553Spatrick    else
193346035553Spatrick    {
193446035553Spatrick        __cp->__next_ = __pn->__next_;
193546035553Spatrick        __pn->__next_ = __cp->__ptr();
193646035553Spatrick        if (__cp->__next_ != nullptr)
193746035553Spatrick        {
1938*4bdff4beSrobert            size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc);
193946035553Spatrick            if (__nhash != __chash)
194046035553Spatrick                __bucket_list_[__nhash] = __cp->__ptr();
194146035553Spatrick        }
194246035553Spatrick    }
194346035553Spatrick    ++size();
194446035553Spatrick}
194546035553Spatrick
194646035553Spatrick
194746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
194846035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
194946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
195046035553Spatrick{
195146035553Spatrick    __cp->__hash_ = hash_function()(__cp->__value_);
195246035553Spatrick    __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
195346035553Spatrick    __node_insert_multi_perform(__cp, __pn);
195446035553Spatrick
195546035553Spatrick    return iterator(__cp->__ptr(), this);
195646035553Spatrick}
195746035553Spatrick
195846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
195946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
196046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
196146035553Spatrick        const_iterator __p, __node_pointer __cp)
196246035553Spatrick{
1963*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
196446035553Spatrick                         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
196546035553Spatrick                         " referring to this unordered container");
196646035553Spatrick    if (__p != end() && key_eq()(*__p, __cp->__value_))
196746035553Spatrick    {
196846035553Spatrick        __next_pointer __np = __p.__node_;
196946035553Spatrick        __cp->__hash_ = __np->__hash();
197046035553Spatrick        size_type __bc = bucket_count();
197146035553Spatrick        if (size()+1 > __bc * max_load_factor() || __bc == 0)
197246035553Spatrick        {
1973*4bdff4beSrobert            __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
1974*4bdff4beSrobert                           size_type(std::ceil(float(size() + 1) / max_load_factor()))));
197546035553Spatrick            __bc = bucket_count();
197646035553Spatrick        }
1977*4bdff4beSrobert        size_t __chash = std::__constrain_hash(__cp->__hash_, __bc);
197846035553Spatrick        __next_pointer __pp = __bucket_list_[__chash];
197946035553Spatrick        while (__pp->__next_ != __np)
198046035553Spatrick            __pp = __pp->__next_;
198146035553Spatrick        __cp->__next_ = __np;
198246035553Spatrick        __pp->__next_ = static_cast<__next_pointer>(__cp);
198346035553Spatrick        ++size();
198446035553Spatrick        return iterator(static_cast<__next_pointer>(__cp), this);
198546035553Spatrick    }
198646035553Spatrick    return __node_insert_multi(__cp);
198746035553Spatrick}
198846035553Spatrick
198946035553Spatrick
199046035553Spatrick
199146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
199246035553Spatricktemplate <class _Key, class ..._Args>
199346035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
199446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
199546035553Spatrick{
199646035553Spatrick
199746035553Spatrick    size_t __hash = hash_function()(__k);
199846035553Spatrick    size_type __bc = bucket_count();
199946035553Spatrick    bool __inserted = false;
200046035553Spatrick    __next_pointer __nd;
200146035553Spatrick    size_t __chash;
200246035553Spatrick    if (__bc != 0)
200346035553Spatrick    {
2004*4bdff4beSrobert        __chash = std::__constrain_hash(__hash, __bc);
200546035553Spatrick        __nd = __bucket_list_[__chash];
200646035553Spatrick        if (__nd != nullptr)
200746035553Spatrick        {
200846035553Spatrick            for (__nd = __nd->__next_; __nd != nullptr &&
2009*4bdff4beSrobert                (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
201046035553Spatrick                                                           __nd = __nd->__next_)
201146035553Spatrick            {
201246035553Spatrick                if (key_eq()(__nd->__upcast()->__value_, __k))
201346035553Spatrick                    goto __done;
201446035553Spatrick            }
201546035553Spatrick        }
201646035553Spatrick    }
201746035553Spatrick    {
201846035553Spatrick        __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...);
201946035553Spatrick        if (size()+1 > __bc * max_load_factor() || __bc == 0)
202046035553Spatrick        {
2021*4bdff4beSrobert            __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
2022*4bdff4beSrobert                           size_type(std::ceil(float(size() + 1) / max_load_factor()))));
202346035553Spatrick            __bc = bucket_count();
2024*4bdff4beSrobert            __chash = std::__constrain_hash(__hash, __bc);
202546035553Spatrick        }
202646035553Spatrick        // insert_after __bucket_list_[__chash], or __first_node if bucket is null
202746035553Spatrick        __next_pointer __pn = __bucket_list_[__chash];
202846035553Spatrick        if (__pn == nullptr)
202946035553Spatrick        {
203046035553Spatrick            __pn = __p1_.first().__ptr();
203146035553Spatrick            __h->__next_ = __pn->__next_;
203246035553Spatrick            __pn->__next_ = __h.get()->__ptr();
203346035553Spatrick            // fix up __bucket_list_
203446035553Spatrick            __bucket_list_[__chash] = __pn;
203546035553Spatrick            if (__h->__next_ != nullptr)
2036*4bdff4beSrobert                __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)]
203746035553Spatrick                    = __h.get()->__ptr();
203846035553Spatrick        }
203946035553Spatrick        else
204046035553Spatrick        {
204146035553Spatrick            __h->__next_ = __pn->__next_;
204246035553Spatrick            __pn->__next_ = static_cast<__next_pointer>(__h.get());
204346035553Spatrick        }
204446035553Spatrick        __nd = static_cast<__next_pointer>(__h.release());
204546035553Spatrick        // increment size
204646035553Spatrick        ++size();
204746035553Spatrick        __inserted = true;
204846035553Spatrick    }
204946035553Spatrick__done:
205046035553Spatrick    return pair<iterator, bool>(iterator(__nd, this), __inserted);
205146035553Spatrick}
205246035553Spatrick
205346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
205446035553Spatricktemplate <class... _Args>
205546035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
205646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args)
205746035553Spatrick{
205846035553Spatrick    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
205946035553Spatrick    pair<iterator, bool> __r = __node_insert_unique(__h.get());
206046035553Spatrick    if (__r.second)
206146035553Spatrick        __h.release();
206246035553Spatrick    return __r;
206346035553Spatrick}
206446035553Spatrick
206546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
206646035553Spatricktemplate <class... _Args>
206746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
206846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args)
206946035553Spatrick{
207046035553Spatrick    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
207146035553Spatrick    iterator __r = __node_insert_multi(__h.get());
207246035553Spatrick    __h.release();
207346035553Spatrick    return __r;
207446035553Spatrick}
207546035553Spatrick
207646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
207746035553Spatricktemplate <class... _Args>
207846035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
207946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
208046035553Spatrick        const_iterator __p, _Args&&... __args)
208146035553Spatrick{
2082*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
208346035553Spatrick                         "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
208446035553Spatrick                         " referring to this unordered container");
208546035553Spatrick    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
208646035553Spatrick    iterator __r = __node_insert_multi(__p, __h.get());
208746035553Spatrick    __h.release();
208846035553Spatrick    return __r;
208946035553Spatrick}
209046035553Spatrick
209146035553Spatrick#if _LIBCPP_STD_VER > 14
209246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
209346035553Spatricktemplate <class _NodeHandle, class _InsertReturnType>
209446035553Spatrick_LIBCPP_INLINE_VISIBILITY
209546035553Spatrick_InsertReturnType
209646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
209746035553Spatrick    _NodeHandle&& __nh)
209846035553Spatrick{
209946035553Spatrick    if (__nh.empty())
210046035553Spatrick        return _InsertReturnType{end(), false, _NodeHandle()};
210146035553Spatrick    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
210246035553Spatrick    if (__result.second)
210346035553Spatrick        __nh.__release_ptr();
210446035553Spatrick    return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
210546035553Spatrick}
210646035553Spatrick
210746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
210846035553Spatricktemplate <class _NodeHandle>
210946035553Spatrick_LIBCPP_INLINE_VISIBILITY
211046035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
211146035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
211246035553Spatrick    const_iterator, _NodeHandle&& __nh)
211346035553Spatrick{
211446035553Spatrick    if (__nh.empty())
211546035553Spatrick        return end();
211646035553Spatrick    pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
211746035553Spatrick    if (__result.second)
211846035553Spatrick        __nh.__release_ptr();
211946035553Spatrick    return __result.first;
212046035553Spatrick}
212146035553Spatrick
212246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
212346035553Spatricktemplate <class _NodeHandle>
212446035553Spatrick_LIBCPP_INLINE_VISIBILITY
212546035553Spatrick_NodeHandle
212646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
212746035553Spatrick    key_type const& __key)
212846035553Spatrick{
212946035553Spatrick    iterator __i = find(__key);
213046035553Spatrick    if (__i == end())
213146035553Spatrick        return _NodeHandle();
213246035553Spatrick    return __node_handle_extract<_NodeHandle>(__i);
213346035553Spatrick}
213446035553Spatrick
213546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
213646035553Spatricktemplate <class _NodeHandle>
213746035553Spatrick_LIBCPP_INLINE_VISIBILITY
213846035553Spatrick_NodeHandle
213946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
214046035553Spatrick    const_iterator __p)
214146035553Spatrick{
214246035553Spatrick    allocator_type __alloc(__node_alloc());
214346035553Spatrick    return _NodeHandle(remove(__p).release(), __alloc);
214446035553Spatrick}
214546035553Spatrick
214646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
214746035553Spatricktemplate <class _Table>
214846035553Spatrick_LIBCPP_INLINE_VISIBILITY
214946035553Spatrickvoid
215046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
215146035553Spatrick    _Table& __source)
215246035553Spatrick{
215346035553Spatrick    static_assert(is_same<__node, typename _Table::__node>::value, "");
215446035553Spatrick
215546035553Spatrick    for (typename _Table::iterator __it = __source.begin();
215646035553Spatrick         __it != __source.end();)
215746035553Spatrick    {
215846035553Spatrick        __node_pointer __src_ptr = __it.__node_->__upcast();
215946035553Spatrick        size_t __hash = hash_function()(__src_ptr->__value_);
216046035553Spatrick        __next_pointer __existing_node =
216146035553Spatrick            __node_insert_unique_prepare(__hash, __src_ptr->__value_);
216246035553Spatrick        auto __prev_iter = __it++;
216346035553Spatrick        if (__existing_node == nullptr)
216446035553Spatrick        {
216546035553Spatrick            (void)__source.remove(__prev_iter).release();
216646035553Spatrick            __src_ptr->__hash_ = __hash;
216746035553Spatrick            __node_insert_unique_perform(__src_ptr);
216846035553Spatrick        }
216946035553Spatrick    }
217046035553Spatrick}
217146035553Spatrick
217246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
217346035553Spatricktemplate <class _NodeHandle>
217446035553Spatrick_LIBCPP_INLINE_VISIBILITY
217546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
217646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
217746035553Spatrick    _NodeHandle&& __nh)
217846035553Spatrick{
217946035553Spatrick    if (__nh.empty())
218046035553Spatrick        return end();
218146035553Spatrick    iterator __result = __node_insert_multi(__nh.__ptr_);
218246035553Spatrick    __nh.__release_ptr();
218346035553Spatrick    return __result;
218446035553Spatrick}
218546035553Spatrick
218646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
218746035553Spatricktemplate <class _NodeHandle>
218846035553Spatrick_LIBCPP_INLINE_VISIBILITY
218946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
219046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
219146035553Spatrick    const_iterator __hint, _NodeHandle&& __nh)
219246035553Spatrick{
219346035553Spatrick    if (__nh.empty())
219446035553Spatrick        return end();
219546035553Spatrick    iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
219646035553Spatrick    __nh.__release_ptr();
219746035553Spatrick    return __result;
219846035553Spatrick}
219946035553Spatrick
220046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
220146035553Spatricktemplate <class _Table>
220246035553Spatrick_LIBCPP_INLINE_VISIBILITY
220346035553Spatrickvoid
220446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
220546035553Spatrick    _Table& __source)
220646035553Spatrick{
220746035553Spatrick    static_assert(is_same<typename _Table::__node, __node>::value, "");
220846035553Spatrick
220946035553Spatrick    for (typename _Table::iterator __it = __source.begin();
221046035553Spatrick         __it != __source.end();)
221146035553Spatrick    {
221246035553Spatrick        __node_pointer __src_ptr = __it.__node_->__upcast();
221346035553Spatrick        size_t __src_hash = hash_function()(__src_ptr->__value_);
221446035553Spatrick        __next_pointer __pn =
221546035553Spatrick            __node_insert_multi_prepare(__src_hash, __src_ptr->__value_);
221646035553Spatrick        (void)__source.remove(__it++).release();
221746035553Spatrick        __src_ptr->__hash_ = __src_hash;
221846035553Spatrick        __node_insert_multi_perform(__src_ptr, __pn);
221946035553Spatrick    }
222046035553Spatrick}
222146035553Spatrick#endif // _LIBCPP_STD_VER > 14
222246035553Spatrick
222346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2224*4bdff4beSroberttemplate <bool _UniqueKeys>
222546035553Spatrickvoid
2226*4bdff4beSrobert__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n)
222746035553Spatrick_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
222846035553Spatrick{
222946035553Spatrick    if (__n == 1)
223046035553Spatrick        __n = 2;
223146035553Spatrick    else if (__n & (__n - 1))
2232*4bdff4beSrobert        __n = std::__next_prime(__n);
223346035553Spatrick    size_type __bc = bucket_count();
223446035553Spatrick    if (__n > __bc)
2235*4bdff4beSrobert        __do_rehash<_UniqueKeys>(__n);
223646035553Spatrick    else if (__n < __bc)
223746035553Spatrick    {
223846035553Spatrick        __n = _VSTD::max<size_type>
223946035553Spatrick              (
224046035553Spatrick                  __n,
2241*4bdff4beSrobert                  std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) :
2242*4bdff4beSrobert                                           std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor())))
224346035553Spatrick              );
224446035553Spatrick        if (__n < __bc)
2245*4bdff4beSrobert            __do_rehash<_UniqueKeys>(__n);
224646035553Spatrick    }
224746035553Spatrick}
224846035553Spatrick
224946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
2250*4bdff4beSroberttemplate <bool _UniqueKeys>
225146035553Spatrickvoid
2252*4bdff4beSrobert__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
225346035553Spatrick{
2254*4bdff4beSrobert    std::__debug_db_invalidate_all(this);
225546035553Spatrick    __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
225646035553Spatrick    __bucket_list_.reset(__nbc > 0 ?
225746035553Spatrick                      __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
225846035553Spatrick    __bucket_list_.get_deleter().size() = __nbc;
225946035553Spatrick    if (__nbc > 0)
226046035553Spatrick    {
226146035553Spatrick        for (size_type __i = 0; __i < __nbc; ++__i)
226246035553Spatrick            __bucket_list_[__i] = nullptr;
226346035553Spatrick        __next_pointer __pp = __p1_.first().__ptr();
226446035553Spatrick        __next_pointer __cp = __pp->__next_;
226546035553Spatrick        if (__cp != nullptr)
226646035553Spatrick        {
2267*4bdff4beSrobert            size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc);
226846035553Spatrick            __bucket_list_[__chash] = __pp;
226946035553Spatrick            size_type __phash = __chash;
2270*4bdff4beSrobert            for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr;
227146035553Spatrick                                                           __cp = __pp->__next_)
227246035553Spatrick            {
2273*4bdff4beSrobert                __chash = std::__constrain_hash(__cp->__hash(), __nbc);
227446035553Spatrick                if (__chash == __phash)
227546035553Spatrick                    __pp = __cp;
227646035553Spatrick                else
227746035553Spatrick                {
227846035553Spatrick                    if (__bucket_list_[__chash] == nullptr)
227946035553Spatrick                    {
228046035553Spatrick                        __bucket_list_[__chash] = __pp;
228146035553Spatrick                        __pp = __cp;
228246035553Spatrick                        __phash = __chash;
228346035553Spatrick                    }
228446035553Spatrick                    else
228546035553Spatrick                    {
228646035553Spatrick                        __next_pointer __np = __cp;
2287*4bdff4beSrobert                        if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys)
2288*4bdff4beSrobert                        {
228946035553Spatrick                            for (; __np->__next_ != nullptr &&
229046035553Spatrick                                   key_eq()(__cp->__upcast()->__value_,
229146035553Spatrick                                            __np->__next_->__upcast()->__value_);
229246035553Spatrick                                                               __np = __np->__next_)
229346035553Spatrick                                ;
2294*4bdff4beSrobert                        }
229546035553Spatrick                        __pp->__next_ = __np->__next_;
229646035553Spatrick                        __np->__next_ = __bucket_list_[__chash]->__next_;
229746035553Spatrick                        __bucket_list_[__chash]->__next_ = __cp;
229846035553Spatrick
229946035553Spatrick                    }
230046035553Spatrick                }
230146035553Spatrick            }
230246035553Spatrick        }
230346035553Spatrick    }
230446035553Spatrick}
230546035553Spatrick
230646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
230746035553Spatricktemplate <class _Key>
230846035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
230946035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
231046035553Spatrick{
231146035553Spatrick    size_t __hash = hash_function()(__k);
231246035553Spatrick    size_type __bc = bucket_count();
231346035553Spatrick    if (__bc != 0)
231446035553Spatrick    {
2315*4bdff4beSrobert        size_t __chash = std::__constrain_hash(__hash, __bc);
231646035553Spatrick        __next_pointer __nd = __bucket_list_[__chash];
231746035553Spatrick        if (__nd != nullptr)
231846035553Spatrick        {
231946035553Spatrick            for (__nd = __nd->__next_; __nd != nullptr &&
232046035553Spatrick                (__nd->__hash() == __hash
2321*4bdff4beSrobert                  || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
232246035553Spatrick                                                           __nd = __nd->__next_)
232346035553Spatrick            {
232446035553Spatrick                if ((__nd->__hash() == __hash)
232546035553Spatrick                    && key_eq()(__nd->__upcast()->__value_, __k))
232646035553Spatrick                    return iterator(__nd, this);
232746035553Spatrick            }
232846035553Spatrick        }
232946035553Spatrick    }
233046035553Spatrick    return end();
233146035553Spatrick}
233246035553Spatrick
233346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
233446035553Spatricktemplate <class _Key>
233546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
233646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
233746035553Spatrick{
233846035553Spatrick    size_t __hash = hash_function()(__k);
233946035553Spatrick    size_type __bc = bucket_count();
234046035553Spatrick    if (__bc != 0)
234146035553Spatrick    {
2342*4bdff4beSrobert        size_t __chash = std::__constrain_hash(__hash, __bc);
234346035553Spatrick        __next_pointer __nd = __bucket_list_[__chash];
234446035553Spatrick        if (__nd != nullptr)
234546035553Spatrick        {
234646035553Spatrick            for (__nd = __nd->__next_; __nd != nullptr &&
234746035553Spatrick                (__hash == __nd->__hash()
2348*4bdff4beSrobert                    || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
234946035553Spatrick                                                           __nd = __nd->__next_)
235046035553Spatrick            {
235146035553Spatrick                if ((__nd->__hash() == __hash)
235246035553Spatrick                    && key_eq()(__nd->__upcast()->__value_, __k))
235346035553Spatrick                    return const_iterator(__nd, this);
235446035553Spatrick            }
235546035553Spatrick        }
235646035553Spatrick
235746035553Spatrick    }
235846035553Spatrick    return end();
235946035553Spatrick}
236046035553Spatrick
236146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
236246035553Spatricktemplate <class ..._Args>
236346035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
236446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
236546035553Spatrick{
236646035553Spatrick    static_assert(!__is_hash_value_type<_Args...>::value,
236746035553Spatrick                  "Construct cannot be called with a hash value type");
236846035553Spatrick    __node_allocator& __na = __node_alloc();
236946035553Spatrick    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
237046035553Spatrick    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
237146035553Spatrick    __h.get_deleter().__value_constructed = true;
237246035553Spatrick    __h->__hash_ = hash_function()(__h->__value_);
237346035553Spatrick    __h->__next_ = nullptr;
237446035553Spatrick    return __h;
237546035553Spatrick}
237646035553Spatrick
237746035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
237846035553Spatricktemplate <class _First, class ..._Rest>
237946035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
238046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(
238146035553Spatrick    size_t __hash, _First&& __f, _Rest&& ...__rest)
238246035553Spatrick{
238346035553Spatrick    static_assert(!__is_hash_value_type<_First, _Rest...>::value,
238446035553Spatrick                  "Construct cannot be called with a hash value type");
238546035553Spatrick    __node_allocator& __na = __node_alloc();
238646035553Spatrick    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
238746035553Spatrick    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_),
238846035553Spatrick                             _VSTD::forward<_First>(__f),
238946035553Spatrick                             _VSTD::forward<_Rest>(__rest)...);
239046035553Spatrick    __h.get_deleter().__value_constructed = true;
239146035553Spatrick    __h->__hash_ = __hash;
239246035553Spatrick    __h->__next_ = nullptr;
239346035553Spatrick    return __h;
239446035553Spatrick}
239546035553Spatrick
239646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
239746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
239846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
239946035553Spatrick{
240046035553Spatrick    __next_pointer __np = __p.__node_;
2401*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
240246035553Spatrick                         "unordered container erase(iterator) called with an iterator not"
240346035553Spatrick                         " referring to this container");
240446035553Spatrick    _LIBCPP_ASSERT(__p != end(),
240546035553Spatrick                   "unordered container erase(iterator) called with a non-dereferenceable iterator");
240646035553Spatrick    iterator __r(__np, this);
240746035553Spatrick    ++__r;
240846035553Spatrick    remove(__p);
240946035553Spatrick    return __r;
241046035553Spatrick}
241146035553Spatrick
241246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
241346035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
241446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
241546035553Spatrick                                                const_iterator __last)
241646035553Spatrick{
2417*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this,
241876d0caaeSpatrick                         "unordered container::erase(iterator, iterator) called with an iterator not"
241976d0caaeSpatrick                         " referring to this container");
2420*4bdff4beSrobert    _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this,
242176d0caaeSpatrick                         "unordered container::erase(iterator, iterator) called with an iterator not"
242276d0caaeSpatrick                         " referring to this container");
242346035553Spatrick    for (const_iterator __p = __first; __first != __last; __p = __first)
242446035553Spatrick    {
242546035553Spatrick        ++__first;
242646035553Spatrick        erase(__p);
242746035553Spatrick    }
242846035553Spatrick    __next_pointer __np = __last.__node_;
242946035553Spatrick    return iterator (__np, this);
243046035553Spatrick}
243146035553Spatrick
243246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
243346035553Spatricktemplate <class _Key>
243446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
243546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k)
243646035553Spatrick{
243746035553Spatrick    iterator __i = find(__k);
243846035553Spatrick    if (__i == end())
243946035553Spatrick        return 0;
244046035553Spatrick    erase(__i);
244146035553Spatrick    return 1;
244246035553Spatrick}
244346035553Spatrick
244446035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
244546035553Spatricktemplate <class _Key>
244646035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
244746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k)
244846035553Spatrick{
244946035553Spatrick    size_type __r = 0;
245046035553Spatrick    iterator __i = find(__k);
245146035553Spatrick    if (__i != end())
245246035553Spatrick    {
245346035553Spatrick        iterator __e = end();
245446035553Spatrick        do
245546035553Spatrick        {
245646035553Spatrick            erase(__i++);
245746035553Spatrick            ++__r;
245846035553Spatrick        } while (__i != __e && key_eq()(*__i, __k));
245946035553Spatrick    }
246046035553Spatrick    return __r;
246146035553Spatrick}
246246035553Spatrick
246346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
246446035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
246546035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
246646035553Spatrick{
246746035553Spatrick    // current node
246846035553Spatrick    __next_pointer __cn = __p.__node_;
246946035553Spatrick    size_type __bc = bucket_count();
2470*4bdff4beSrobert    size_t __chash = std::__constrain_hash(__cn->__hash(), __bc);
247146035553Spatrick    // find previous node
247246035553Spatrick    __next_pointer __pn = __bucket_list_[__chash];
247346035553Spatrick    for (; __pn->__next_ != __cn; __pn = __pn->__next_)
247446035553Spatrick        ;
247546035553Spatrick    // Fix up __bucket_list_
247646035553Spatrick        // if __pn is not in same bucket (before begin is not in same bucket) &&
247746035553Spatrick        //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
247846035553Spatrick    if (__pn == __p1_.first().__ptr()
2479*4bdff4beSrobert            || std::__constrain_hash(__pn->__hash(), __bc) != __chash)
248046035553Spatrick    {
248146035553Spatrick        if (__cn->__next_ == nullptr
2482*4bdff4beSrobert            || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
248346035553Spatrick            __bucket_list_[__chash] = nullptr;
248446035553Spatrick    }
248546035553Spatrick        // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
248646035553Spatrick    if (__cn->__next_ != nullptr)
248746035553Spatrick    {
2488*4bdff4beSrobert        size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc);
248946035553Spatrick        if (__nhash != __chash)
249046035553Spatrick            __bucket_list_[__nhash] = __pn;
249146035553Spatrick    }
249246035553Spatrick    // remove __cn
249346035553Spatrick    __pn->__next_ = __cn->__next_;
249446035553Spatrick    __cn->__next_ = nullptr;
249546035553Spatrick    --size();
2496*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
249746035553Spatrick    __c_node* __c = __get_db()->__find_c_and_lock(this);
249846035553Spatrick    for (__i_node** __dp = __c->end_; __dp != __c->beg_; )
249946035553Spatrick    {
250046035553Spatrick        --__dp;
250146035553Spatrick        iterator* __i = static_cast<iterator*>((*__dp)->__i_);
250246035553Spatrick        if (__i->__node_ == __cn)
250346035553Spatrick        {
250446035553Spatrick            (*__dp)->__c_ = nullptr;
250546035553Spatrick            if (--__c->end_ != __dp)
250676d0caaeSpatrick                _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*));
250746035553Spatrick        }
250846035553Spatrick    }
250946035553Spatrick    __get_db()->unlock();
251046035553Spatrick#endif
251146035553Spatrick    return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
251246035553Spatrick}
251346035553Spatrick
251446035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
251546035553Spatricktemplate <class _Key>
251646035553Spatrickinline
251746035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
251846035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const
251946035553Spatrick{
252046035553Spatrick    return static_cast<size_type>(find(__k) != end());
252146035553Spatrick}
252246035553Spatrick
252346035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
252446035553Spatricktemplate <class _Key>
252546035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
252646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const
252746035553Spatrick{
252846035553Spatrick    size_type __r = 0;
252946035553Spatrick    const_iterator __i = find(__k);
253046035553Spatrick    if (__i != end())
253146035553Spatrick    {
253246035553Spatrick        const_iterator __e = end();
253346035553Spatrick        do
253446035553Spatrick        {
253546035553Spatrick            ++__i;
253646035553Spatrick            ++__r;
253746035553Spatrick        } while (__i != __e && key_eq()(*__i, __k));
253846035553Spatrick    }
253946035553Spatrick    return __r;
254046035553Spatrick}
254146035553Spatrick
254246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
254346035553Spatricktemplate <class _Key>
254446035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
254546035553Spatrick     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
254646035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
254746035553Spatrick        const _Key& __k)
254846035553Spatrick{
254946035553Spatrick    iterator __i = find(__k);
255046035553Spatrick    iterator __j = __i;
255146035553Spatrick    if (__i != end())
255246035553Spatrick        ++__j;
255346035553Spatrick    return pair<iterator, iterator>(__i, __j);
255446035553Spatrick}
255546035553Spatrick
255646035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
255746035553Spatricktemplate <class _Key>
255846035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
255946035553Spatrick     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
256046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
256146035553Spatrick        const _Key& __k) const
256246035553Spatrick{
256346035553Spatrick    const_iterator __i = find(__k);
256446035553Spatrick    const_iterator __j = __i;
256546035553Spatrick    if (__i != end())
256646035553Spatrick        ++__j;
256746035553Spatrick    return pair<const_iterator, const_iterator>(__i, __j);
256846035553Spatrick}
256946035553Spatrick
257046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
257146035553Spatricktemplate <class _Key>
257246035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
257346035553Spatrick     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
257446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
257546035553Spatrick        const _Key& __k)
257646035553Spatrick{
257746035553Spatrick    iterator __i = find(__k);
257846035553Spatrick    iterator __j = __i;
257946035553Spatrick    if (__i != end())
258046035553Spatrick    {
258146035553Spatrick        iterator __e = end();
258246035553Spatrick        do
258346035553Spatrick        {
258446035553Spatrick            ++__j;
258546035553Spatrick        } while (__j != __e && key_eq()(*__j, __k));
258646035553Spatrick    }
258746035553Spatrick    return pair<iterator, iterator>(__i, __j);
258846035553Spatrick}
258946035553Spatrick
259046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
259146035553Spatricktemplate <class _Key>
259246035553Spatrickpair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
259346035553Spatrick     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
259446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
259546035553Spatrick        const _Key& __k) const
259646035553Spatrick{
259746035553Spatrick    const_iterator __i = find(__k);
259846035553Spatrick    const_iterator __j = __i;
259946035553Spatrick    if (__i != end())
260046035553Spatrick    {
260146035553Spatrick        const_iterator __e = end();
260246035553Spatrick        do
260346035553Spatrick        {
260446035553Spatrick            ++__j;
260546035553Spatrick        } while (__j != __e && key_eq()(*__j, __k));
260646035553Spatrick    }
260746035553Spatrick    return pair<const_iterator, const_iterator>(__i, __j);
260846035553Spatrick}
260946035553Spatrick
261046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
261146035553Spatrickvoid
261246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
261346035553Spatrick#if _LIBCPP_STD_VER <= 11
261446035553Spatrick    _NOEXCEPT_(
261546035553Spatrick        __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
261646035553Spatrick        && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
261746035553Spatrick              || __is_nothrow_swappable<__pointer_allocator>::value)
261846035553Spatrick        && (!__node_traits::propagate_on_container_swap::value
261946035553Spatrick              || __is_nothrow_swappable<__node_allocator>::value)
262046035553Spatrick            )
262146035553Spatrick#else
262246035553Spatrick  _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
262346035553Spatrick#endif
262446035553Spatrick{
262546035553Spatrick    _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value ||
262646035553Spatrick                   this->__node_alloc() == __u.__node_alloc(),
262746035553Spatrick                   "list::swap: Either propagate_on_container_swap must be true"
262846035553Spatrick                   " or the allocators must compare equal");
262946035553Spatrick    {
263046035553Spatrick    __node_pointer_pointer __npp = __bucket_list_.release();
263146035553Spatrick    __bucket_list_.reset(__u.__bucket_list_.release());
263246035553Spatrick    __u.__bucket_list_.reset(__npp);
263346035553Spatrick    }
263446035553Spatrick    _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
263576d0caaeSpatrick    _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(),
263646035553Spatrick             __u.__bucket_list_.get_deleter().__alloc());
263776d0caaeSpatrick    _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc());
263846035553Spatrick    _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
263946035553Spatrick    __p2_.swap(__u.__p2_);
264046035553Spatrick    __p3_.swap(__u.__p3_);
264146035553Spatrick    if (size() > 0)
2642*4bdff4beSrobert        __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
264346035553Spatrick            __p1_.first().__ptr();
264446035553Spatrick    if (__u.size() > 0)
2645*4bdff4beSrobert        __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
264646035553Spatrick            __u.__p1_.first().__ptr();
2647*4bdff4beSrobert    std::__debug_db_swap(this, std::addressof(__u));
264846035553Spatrick}
264946035553Spatrick
265046035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
265146035553Spatricktypename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
265246035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
265346035553Spatrick{
265446035553Spatrick    _LIBCPP_ASSERT(__n < bucket_count(),
265546035553Spatrick        "unordered container::bucket_size(n) called with n >= bucket_count()");
265646035553Spatrick    __next_pointer __np = __bucket_list_[__n];
265746035553Spatrick    size_type __bc = bucket_count();
265846035553Spatrick    size_type __r = 0;
265946035553Spatrick    if (__np != nullptr)
266046035553Spatrick    {
266146035553Spatrick        for (__np = __np->__next_; __np != nullptr &&
2662*4bdff4beSrobert                                   std::__constrain_hash(__np->__hash(), __bc) == __n;
2663*4bdff4beSrobert                                                         __np = __np->__next_, (void) ++__r)
266446035553Spatrick            ;
266546035553Spatrick    }
266646035553Spatrick    return __r;
266746035553Spatrick}
266846035553Spatrick
266946035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
267046035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
267146035553Spatrickvoid
267246035553Spatrickswap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
267346035553Spatrick     __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)
267446035553Spatrick    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
267546035553Spatrick{
267646035553Spatrick    __x.swap(__y);
267746035553Spatrick}
267846035553Spatrick
2679*4bdff4beSrobert#ifdef _LIBCPP_ENABLE_DEBUG_MODE
268046035553Spatrick
268146035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
268246035553Spatrickbool
268346035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const
268446035553Spatrick{
268546035553Spatrick    return __i->__node_ != nullptr;
268646035553Spatrick}
268746035553Spatrick
268846035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
268946035553Spatrickbool
269046035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const
269146035553Spatrick{
269246035553Spatrick    return false;
269346035553Spatrick}
269446035553Spatrick
269546035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
269646035553Spatrickbool
269746035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
269846035553Spatrick{
269946035553Spatrick    return false;
270046035553Spatrick}
270146035553Spatrick
270246035553Spatricktemplate <class _Tp, class _Hash, class _Equal, class _Alloc>
270346035553Spatrickbool
270446035553Spatrick__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
270546035553Spatrick{
270646035553Spatrick    return false;
270746035553Spatrick}
270846035553Spatrick
2709*4bdff4beSrobert#endif // _LIBCPP_ENABLE_DEBUG_MODE
271046035553Spatrick
271146035553Spatrick_LIBCPP_END_NAMESPACE_STD
271246035553Spatrick
271346035553Spatrick_LIBCPP_POP_MACROS
271446035553Spatrick
2715*4bdff4beSrobert#endif // _LIBCPP___HASH_TABLE
2716