Home | History | Annotate | Download | only in include
      1 // -*- C++ -*-
      2 //===----------------------------------------------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef _LIBCPP__HASH_TABLE
     12 #define _LIBCPP__HASH_TABLE
     13 
     14 #include <__config>
     15 #include <initializer_list>
     16 #include <memory>
     17 #include <iterator>
     18 #include <algorithm>
     19 #include <cmath>
     20 
     21 #include <__undef_min_max>
     22 
     23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     24 #pragma GCC system_header
     25 #endif
     26 
     27 _LIBCPP_BEGIN_NAMESPACE_STD
     28 
     29 _LIBCPP_VISIBLE
     30 size_t __next_prime(size_t __n);
     31 
     32 template <class _NodePtr>
     33 struct __hash_node_base
     34 {
     35     typedef __hash_node_base __first_node;
     36  //   typedef _NodePtr pointer;
     37 
     38     _NodePtr    __next_;
     39 
     40     _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
     41 };
     42 
     43 template <class _Tp, class _VoidPtr>
     44 struct __hash_node
     45     : public __hash_node_base
     46              <
     47                  typename pointer_traits<_VoidPtr>::template
     48 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
     49                      rebind<__hash_node<_Tp, _VoidPtr> >
     50 #else
     51                      rebind<__hash_node<_Tp, _VoidPtr> >::other
     52 #endif
     53              >
     54 {
     55     typedef _Tp value_type;
     56 
     57     size_t     __hash_;
     58     value_type __value_;
     59 };
     60 
     61 inline _LIBCPP_INLINE_VISIBILITY
     62 bool
     63 __is_power2(size_t __bc)
     64 {
     65     return __bc > 2 && !(__bc & (__bc - 1));
     66 }
     67 
     68 inline _LIBCPP_INLINE_VISIBILITY
     69 size_t
     70 __constrain_hash(size_t __h, size_t __bc)
     71 {
     72     return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc;
     73 }
     74 
     75 inline _LIBCPP_INLINE_VISIBILITY
     76 size_t
     77 __next_pow2(size_t __n)
     78 {
     79     return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
     80 }
     81 
     82 template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
     83 template <class _ConstNodePtr> class _LIBCPP_VISIBLE __hash_const_iterator;
     84 template <class _HashIterator> class _LIBCPP_VISIBLE __hash_map_iterator;
     85 template <class _HashIterator> class _LIBCPP_VISIBLE __hash_map_const_iterator;
     86 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
     87     class _LIBCPP_VISIBLE unordered_map;
     88 
     89 template <class _NodePtr>
     90 class _LIBCPP_VISIBLE __hash_iterator
     91 {
     92     typedef _NodePtr __node_pointer;
     93 
     94     __node_pointer            __node_;
     95 
     96 public:
     97     typedef forward_iterator_tag                         iterator_category;
     98     typedef typename pointer_traits<__node_pointer>::element_type::value_type value_type;
     99     typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
    100     typedef value_type&                                  reference;
    101     typedef typename pointer_traits<__node_pointer>::template
    102 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    103                      rebind<value_type>
    104 #else
    105                      rebind<value_type>::other
    106 #endif
    107                                                          pointer;
    108 
    109     _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT {}
    110 
    111     _LIBCPP_INLINE_VISIBILITY
    112         reference operator*() const {return __node_->__value_;}
    113     _LIBCPP_INLINE_VISIBILITY
    114         pointer operator->() const {return _VSTD::addressof(__node_->__value_);}
    115 
    116     _LIBCPP_INLINE_VISIBILITY
    117     __hash_iterator& operator++()
    118     {
    119         __node_ = __node_->__next_;
    120         return *this;
    121     }
    122 
    123     _LIBCPP_INLINE_VISIBILITY
    124     __hash_iterator operator++(int)
    125     {
    126         __hash_iterator __t(*this);
    127         ++(*this);
    128         return __t;
    129     }
    130 
    131     friend _LIBCPP_INLINE_VISIBILITY
    132     bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)
    133         {return __x.__node_ == __y.__node_;}
    134     friend _LIBCPP_INLINE_VISIBILITY
    135     bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)
    136         {return __x.__node_ != __y.__node_;}
    137 
    138 private:
    139     _LIBCPP_INLINE_VISIBILITY
    140     __hash_iterator(__node_pointer __node) _NOEXCEPT
    141         : __node_(__node)
    142         {}
    143 
    144     template <class, class, class, class> friend class __hash_table;
    145     template <class> friend class _LIBCPP_VISIBLE __hash_const_iterator;
    146     template <class> friend class _LIBCPP_VISIBLE __hash_map_iterator;
    147     template <class, class, class, class, class> friend class _LIBCPP_VISIBLE unordered_map;
    148     template <class, class, class, class, class> friend class _LIBCPP_VISIBLE unordered_multimap;
    149 };
    150 
    151 template <class _ConstNodePtr>
    152 class _LIBCPP_VISIBLE __hash_const_iterator
    153 {
    154     typedef _ConstNodePtr __node_pointer;
    155 
    156     __node_pointer         __node_;
    157 
    158     typedef typename remove_const<
    159         typename pointer_traits<__node_pointer>::element_type
    160                                  >::type __node;
    161 
    162 public:
    163     typedef forward_iterator_tag                       iterator_category;
    164     typedef typename __node::value_type                value_type;
    165     typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
    166     typedef const value_type&                          reference;
    167     typedef typename pointer_traits<__node_pointer>::template
    168 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    169             rebind<const value_type>
    170 #else
    171             rebind<const value_type>::other
    172 #endif
    173                                                        pointer;
    174     typedef typename pointer_traits<__node_pointer>::template
    175 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    176             rebind<__node>
    177 #else
    178             rebind<__node>::other
    179 #endif
    180                                                       __non_const_node_pointer;
    181     typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator;
    182 
    183     _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT {}
    184     _LIBCPP_INLINE_VISIBILITY 
    185     __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
    186         : __node_(__x.__node_)
    187         {}
    188 
    189     _LIBCPP_INLINE_VISIBILITY
    190         reference operator*() const {return __node_->__value_;}
    191     _LIBCPP_INLINE_VISIBILITY
    192         pointer operator->() const {return _VSTD::addressof(__node_->__value_);}
    193 
    194     _LIBCPP_INLINE_VISIBILITY
    195     __hash_const_iterator& operator++()
    196     {
    197         __node_ = __node_->__next_;
    198         return *this;
    199     }
    200 
    201     _LIBCPP_INLINE_VISIBILITY
    202     __hash_const_iterator operator++(int)
    203     {
    204         __hash_const_iterator __t(*this);
    205         ++(*this);
    206         return __t;
    207     }
    208 
    209     friend _LIBCPP_INLINE_VISIBILITY
    210     bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
    211         {return __x.__node_ == __y.__node_;}
    212     friend _LIBCPP_INLINE_VISIBILITY
    213     bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
    214         {return __x.__node_ != __y.__node_;}
    215 
    216 private:
    217     _LIBCPP_INLINE_VISIBILITY
    218     __hash_const_iterator(__node_pointer __node) _NOEXCEPT
    219         : __node_(__node)
    220         {}
    221 
    222     template <class, class, class, class> friend class __hash_table;
    223     template <class> friend class _LIBCPP_VISIBLE __hash_map_const_iterator;
    224     template <class, class, class, class, class> friend class _LIBCPP_VISIBLE unordered_map;
    225     template <class, class, class, class, class> friend class _LIBCPP_VISIBLE unordered_multimap;
    226 };
    227 
    228 template <class _ConstNodePtr> class _LIBCPP_VISIBLE __hash_const_local_iterator;
    229 
    230 template <class _NodePtr>
    231 class _LIBCPP_VISIBLE __hash_local_iterator
    232 {
    233     typedef _NodePtr __node_pointer;
    234 
    235     __node_pointer         __node_;
    236     size_t                 __bucket_;
    237     size_t                 __bucket_count_;
    238 
    239     typedef pointer_traits<__node_pointer>          __pointer_traits;
    240 public:
    241     typedef forward_iterator_tag                                iterator_category;
    242     typedef typename __pointer_traits::element_type::value_type value_type;
    243     typedef typename __pointer_traits::difference_type          difference_type;
    244     typedef value_type&                                         reference;
    245     typedef typename __pointer_traits::template
    246 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    247             rebind<value_type>
    248 #else
    249             rebind<value_type>::other
    250 #endif
    251                                                                 pointer;
    252 
    253     _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT {}
    254 
    255     _LIBCPP_INLINE_VISIBILITY
    256         reference operator*() const {return __node_->__value_;}
    257     _LIBCPP_INLINE_VISIBILITY
    258         pointer operator->() const {return &__node_->__value_;}
    259 
    260     _LIBCPP_INLINE_VISIBILITY
    261     __hash_local_iterator& operator++()
    262     {
    263         __node_ = __node_->__next_;
    264         if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
    265             __node_ = nullptr;
    266         return *this;
    267     }
    268 
    269     _LIBCPP_INLINE_VISIBILITY
    270     __hash_local_iterator operator++(int)
    271     {
    272         __hash_local_iterator __t(*this);
    273         ++(*this);
    274         return __t;
    275     }
    276 
    277     friend _LIBCPP_INLINE_VISIBILITY
    278     bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
    279         {return __x.__node_ == __y.__node_;}
    280     friend _LIBCPP_INLINE_VISIBILITY
    281     bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
    282         {return __x.__node_ != __y.__node_;}
    283 
    284 private:
    285     _LIBCPP_INLINE_VISIBILITY
    286     __hash_local_iterator(__node_pointer __node, size_t __bucket,
    287                           size_t __bucket_count) _NOEXCEPT
    288         : __node_(__node),
    289           __bucket_(__bucket),
    290           __bucket_count_(__bucket_count)
    291         {
    292             if (__node_ != nullptr)
    293                 __node_ = __node_->__next_;
    294         }
    295 
    296     template <class, class, class, class> friend class __hash_table;
    297     template <class> friend class _LIBCPP_VISIBLE __hash_const_local_iterator;
    298     template <class> friend class _LIBCPP_VISIBLE __hash_map_iterator;
    299 };
    300 
    301 template <class _ConstNodePtr>
    302 class _LIBCPP_VISIBLE __hash_const_local_iterator
    303 {
    304     typedef _ConstNodePtr __node_pointer;
    305 
    306     __node_pointer         __node_;
    307     size_t                 __bucket_;
    308     size_t                 __bucket_count_;
    309 
    310     typedef pointer_traits<__node_pointer>          __pointer_traits;
    311     typedef typename __pointer_traits::element_type __node;
    312     typedef typename remove_const<__node>::type     __non_const_node;
    313     typedef typename pointer_traits<__node_pointer>::template
    314 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    315             rebind<__non_const_node>
    316 #else
    317             rebind<__non_const_node>::other
    318 #endif
    319                                                     __non_const_node_pointer;
    320     typedef __hash_local_iterator<__non_const_node_pointer>
    321                                                     __non_const_iterator;
    322 public:
    323     typedef forward_iterator_tag                       iterator_category;
    324     typedef typename remove_const<
    325                         typename __pointer_traits::element_type::value_type
    326                      >::type                           value_type;
    327     typedef typename __pointer_traits::difference_type difference_type;
    328     typedef const value_type&                          reference;
    329     typedef typename __pointer_traits::template
    330 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    331             rebind<const value_type>
    332 #else
    333             rebind<const value_type>::other
    334 #endif
    335                                                        pointer;
    336 
    337     _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT {}
    338     _LIBCPP_INLINE_VISIBILITY
    339     __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
    340         : __node_(__x.__node_),
    341           __bucket_(__x.__bucket_),
    342           __bucket_count_(__x.__bucket_count_)
    343         {}
    344 
    345     _LIBCPP_INLINE_VISIBILITY
    346         reference operator*() const {return __node_->__value_;}
    347     _LIBCPP_INLINE_VISIBILITY
    348         pointer operator->() const {return &__node_->__value_;}
    349 
    350     _LIBCPP_INLINE_VISIBILITY
    351     __hash_const_local_iterator& operator++()
    352     {
    353         __node_ = __node_->__next_;
    354         if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
    355             __node_ = nullptr;
    356         return *this;
    357     }
    358 
    359     _LIBCPP_INLINE_VISIBILITY
    360     __hash_const_local_iterator operator++(int)
    361     {
    362         __hash_const_local_iterator __t(*this);
    363         ++(*this);
    364         return __t;
    365     }
    366 
    367     friend _LIBCPP_INLINE_VISIBILITY
    368     bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
    369         {return __x.__node_ == __y.__node_;}
    370     friend _LIBCPP_INLINE_VISIBILITY
    371     bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
    372         {return __x.__node_ != __y.__node_;}
    373 
    374 private:
    375     _LIBCPP_INLINE_VISIBILITY
    376     __hash_const_local_iterator(__node_pointer __node, size_t __bucket,
    377                                 size_t __bucket_count) _NOEXCEPT
    378         : __node_(__node),
    379           __bucket_(__bucket),
    380           __bucket_count_(__bucket_count)
    381         {
    382             if (__node_ != nullptr)
    383                 __node_ = __node_->__next_;
    384         }
    385 
    386     template <class, class, class, class> friend class __hash_table;
    387     template <class> friend class _LIBCPP_VISIBLE __hash_map_const_iterator;
    388 };
    389 
    390 template <class _Alloc>
    391 class __bucket_list_deallocator
    392 {
    393     typedef _Alloc                                          allocator_type;
    394     typedef allocator_traits<allocator_type>                __alloc_traits;
    395     typedef typename __alloc_traits::size_type              size_type;
    396 
    397     __compressed_pair<size_type, allocator_type> __data_;
    398 public:
    399     typedef typename __alloc_traits::pointer pointer;
    400 
    401     _LIBCPP_INLINE_VISIBILITY
    402     __bucket_list_deallocator()
    403         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
    404         : __data_(0) {}
    405 
    406     _LIBCPP_INLINE_VISIBILITY
    407     __bucket_list_deallocator(const allocator_type& __a, size_type __size)
    408         _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
    409         : __data_(__size, __a) {}
    410 
    411 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    412 
    413     _LIBCPP_INLINE_VISIBILITY
    414     __bucket_list_deallocator(__bucket_list_deallocator&& __x)
    415         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
    416         : __data_(_VSTD::move(__x.__data_))
    417     {
    418         __x.size() = 0;
    419     }
    420 
    421 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    422 
    423     _LIBCPP_INLINE_VISIBILITY
    424     size_type& size() _NOEXCEPT {return __data_.first();}
    425     _LIBCPP_INLINE_VISIBILITY
    426     size_type  size() const _NOEXCEPT {return __data_.first();}
    427 
    428     _LIBCPP_INLINE_VISIBILITY
    429     allocator_type& __alloc() _NOEXCEPT {return __data_.second();}
    430     _LIBCPP_INLINE_VISIBILITY
    431     const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();}
    432 
    433     _LIBCPP_INLINE_VISIBILITY
    434     void operator()(pointer __p) _NOEXCEPT
    435     {
    436         __alloc_traits::deallocate(__alloc(), __p, size());
    437     }
    438 };
    439 
    440 template <class _Alloc> class __hash_map_node_destructor;
    441 
    442 template <class _Alloc>
    443 class __hash_node_destructor
    444 {
    445     typedef _Alloc                                          allocator_type;
    446     typedef allocator_traits<allocator_type>                __alloc_traits;
    447     typedef typename __alloc_traits::value_type::value_type value_type;
    448 public:
    449     typedef typename __alloc_traits::pointer                pointer;
    450 private:
    451 
    452     allocator_type& __na_;
    453 
    454     __hash_node_destructor& operator=(const __hash_node_destructor&);
    455 
    456 public:
    457     bool __value_constructed;
    458 
    459     _LIBCPP_INLINE_VISIBILITY
    460     explicit __hash_node_destructor(allocator_type& __na,
    461                                     bool __constructed = false) _NOEXCEPT
    462         : __na_(__na),
    463           __value_constructed(__constructed)
    464         {}
    465 
    466     _LIBCPP_INLINE_VISIBILITY
    467     void operator()(pointer __p) _NOEXCEPT
    468     {
    469         if (__value_constructed)
    470             __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_));
    471         if (__p)
    472             __alloc_traits::deallocate(__na_, __p, 1);
    473     }
    474 
    475     template <class> friend class __hash_map_node_destructor;
    476 };
    477 
    478 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    479 class __hash_table
    480 {
    481 public:
    482     typedef _Tp    value_type;
    483     typedef _Hash  hasher;
    484     typedef _Equal key_equal;
    485     typedef _Alloc allocator_type;
    486 
    487 private:
    488     typedef allocator_traits<allocator_type> __alloc_traits;
    489 public:
    490     typedef value_type&                              reference;
    491     typedef const value_type&                        const_reference;
    492     typedef typename __alloc_traits::pointer         pointer;
    493     typedef typename __alloc_traits::const_pointer   const_pointer;
    494     typedef typename __alloc_traits::size_type       size_type;
    495     typedef typename __alloc_traits::difference_type difference_type;
    496 public:
    497     // Create __node
    498     typedef __hash_node<value_type, typename __alloc_traits::void_pointer> __node;
    499     typedef typename __alloc_traits::template
    500 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    501             rebind_alloc<__node>
    502 #else
    503             rebind_alloc<__node>::other
    504 #endif
    505                                                      __node_allocator;
    506     typedef allocator_traits<__node_allocator>       __node_traits;
    507     typedef typename __node_traits::pointer          __node_pointer;
    508     typedef typename __node_traits::const_pointer    __node_const_pointer;
    509     typedef __hash_node_base<__node_pointer>         __first_node;
    510 
    511 private:
    512 
    513     typedef typename __node_traits::template
    514 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
    515             rebind_alloc<__node_pointer>
    516 #else
    517             rebind_alloc<__node_pointer>::other
    518 #endif
    519                                                             __pointer_allocator;
    520     typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
    521     typedef unique_ptr<__node_pointer[], __bucket_list_deleter> __bucket_list;
    522     typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
    523     typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;
    524 
    525     // --- Member data begin ---
    526     __bucket_list                                     __bucket_list_;
    527     __compressed_pair<__first_node, __node_allocator> __p1_;
    528     __compressed_pair<size_type, hasher>              __p2_;
    529     __compressed_pair<float, key_equal>               __p3_;
    530     // --- Member data end ---
    531 
    532     _LIBCPP_INLINE_VISIBILITY
    533     size_type& size() _NOEXCEPT {return __p2_.first();}
    534 public:
    535     _LIBCPP_INLINE_VISIBILITY
    536     size_type  size() const _NOEXCEPT {return __p2_.first();}
    537 
    538     _LIBCPP_INLINE_VISIBILITY
    539     hasher& hash_function() _NOEXCEPT {return __p2_.second();}
    540     _LIBCPP_INLINE_VISIBILITY
    541     const hasher& hash_function() const _NOEXCEPT {return __p2_.second();}
    542 
    543     _LIBCPP_INLINE_VISIBILITY
    544     float& max_load_factor() _NOEXCEPT {return __p3_.first();}
    545     _LIBCPP_INLINE_VISIBILITY
    546     float  max_load_factor() const _NOEXCEPT {return __p3_.first();}
    547 
    548     _LIBCPP_INLINE_VISIBILITY
    549     key_equal& key_eq() _NOEXCEPT {return __p3_.second();}
    550     _LIBCPP_INLINE_VISIBILITY
    551     const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();}
    552 
    553     _LIBCPP_INLINE_VISIBILITY
    554     __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();}
    555     _LIBCPP_INLINE_VISIBILITY
    556     const __node_allocator& __node_alloc() const _NOEXCEPT
    557         {return __p1_.second();}
    558 
    559 public:
    560     typedef __hash_iterator<__node_pointer>                   iterator;
    561     typedef __hash_const_iterator<__node_const_pointer>       const_iterator;
    562     typedef __hash_local_iterator<__node_pointer>             local_iterator;
    563     typedef __hash_const_local_iterator<__node_const_pointer> const_local_iterator;
    564 
    565     __hash_table()
    566         _NOEXCEPT_(
    567             is_nothrow_default_constructible<__bucket_list>::value &&
    568             is_nothrow_default_constructible<__first_node>::value &&
    569             is_nothrow_default_constructible<__node_allocator>::value &&
    570             is_nothrow_default_constructible<hasher>::value &&
    571             is_nothrow_default_constructible<key_equal>::value);
    572     __hash_table(const hasher& __hf, const key_equal& __eql);
    573     __hash_table(const hasher& __hf, const key_equal& __eql,
    574                  const allocator_type& __a);
    575     explicit __hash_table(const allocator_type& __a);
    576     __hash_table(const __hash_table& __u);
    577     __hash_table(const __hash_table& __u, const allocator_type& __a);
    578 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    579     __hash_table(__hash_table&& __u)
    580         _NOEXCEPT_(
    581             is_nothrow_move_constructible<__bucket_list>::value &&
    582             is_nothrow_move_constructible<__first_node>::value &&
    583             is_nothrow_move_constructible<__node_allocator>::value &&
    584             is_nothrow_move_constructible<hasher>::value &&
    585             is_nothrow_move_constructible<key_equal>::value);
    586     __hash_table(__hash_table&& __u, const allocator_type& __a);
    587 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    588     ~__hash_table();
    589 
    590     __hash_table& operator=(const __hash_table& __u);
    591 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    592     __hash_table& operator=(__hash_table&& __u)
    593         _NOEXCEPT_(
    594             __node_traits::propagate_on_container_move_assignment::value &&
    595             is_nothrow_move_assignable<__node_allocator>::value &&
    596             is_nothrow_move_assignable<hasher>::value &&
    597             is_nothrow_move_assignable<key_equal>::value);
    598 #endif
    599     template <class _InputIterator>
    600         void __assign_unique(_InputIterator __first, _InputIterator __last);
    601     template <class _InputIterator>
    602         void __assign_multi(_InputIterator __first, _InputIterator __last);
    603 
    604     _LIBCPP_INLINE_VISIBILITY
    605     size_type max_size() const _NOEXCEPT
    606     {
    607         return allocator_traits<__pointer_allocator>::max_size(
    608             __bucket_list_.get_deleter().__alloc());
    609     }
    610 
    611     pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
    612     iterator             __node_insert_multi(__node_pointer __nd);
    613     iterator             __node_insert_multi(const_iterator __p,
    614                                              __node_pointer __nd);
    615 
    616 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
    617     template <class... _Args>
    618         pair<iterator, bool> __emplace_unique(_Args&&... __args);
    619     template <class... _Args>
    620         iterator __emplace_multi(_Args&&... __args);
    621     template <class... _Args>
    622         iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
    623 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
    624 
    625     pair<iterator, bool> __insert_unique(const value_type& __x);
    626 
    627 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    628     template <class _Pp>
    629         pair<iterator, bool> __insert_unique(_Pp&& __x);
    630 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    631 
    632 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    633     template <class _Pp>
    634         iterator __insert_multi(_Pp&& __x);
    635     template <class _Pp>
    636         iterator __insert_multi(const_iterator __p, _Pp&& __x);
    637 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    638     iterator __insert_multi(const value_type& __x);
    639     iterator __insert_multi(const_iterator __p, const value_type& __x);
    640 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    641 
    642     void clear() _NOEXCEPT;
    643     void rehash(size_type __n);
    644     _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)
    645         {rehash(static_cast<size_type>(ceil(__n / max_load_factor())));}
    646 
    647     _LIBCPP_INLINE_VISIBILITY
    648     size_type bucket_count() const _NOEXCEPT
    649     {
    650         return __bucket_list_.get_deleter().size();
    651     }
    652 
    653     iterator       begin() _NOEXCEPT;
    654     iterator       end() _NOEXCEPT;
    655     const_iterator begin() const _NOEXCEPT;
    656     const_iterator end() const _NOEXCEPT;
    657 
    658     template <class _Key>
    659         _LIBCPP_INLINE_VISIBILITY
    660         size_type bucket(const _Key& __k) const
    661             {return __constrain_hash(hash_function()(__k), bucket_count());}
    662 
    663     template <class _Key>
    664         iterator       find(const _Key& __x);
    665     template <class _Key>
    666         const_iterator find(const _Key& __x) const;
    667 
    668     typedef __hash_node_destructor<__node_allocator> _Dp;
    669     typedef unique_ptr<__node, _Dp> __node_holder;
    670 
    671     iterator erase(const_iterator __p);
    672     iterator erase(const_iterator __first, const_iterator __last);
    673     template <class _Key>
    674         size_type __erase_unique(const _Key& __k);
    675     template <class _Key>
    676         size_type __erase_multi(const _Key& __k);
    677     __node_holder remove(const_iterator __p) _NOEXCEPT;
    678 
    679     template <class _Key>
    680         size_type __count_unique(const _Key& __k) const;
    681     template <class _Key>
    682         size_type __count_multi(const _Key& __k) const;
    683 
    684     template <class _Key>
    685         pair<iterator, iterator>
    686         __equal_range_unique(const _Key& __k);
    687     template <class _Key>
    688         pair<const_iterator, const_iterator>
    689         __equal_range_unique(const _Key& __k) const;
    690 
    691     template <class _Key>
    692         pair<iterator, iterator>
    693         __equal_range_multi(const _Key& __k);
    694     template <class _Key>
    695         pair<const_iterator, const_iterator>
    696         __equal_range_multi(const _Key& __k) const;
    697 
    698     void swap(__hash_table& __u)
    699         _NOEXCEPT_(
    700             (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
    701              __is_nothrow_swappable<__pointer_allocator>::value) &&
    702             (!__node_traits::propagate_on_container_swap::value ||
    703              __is_nothrow_swappable<__node_allocator>::value) &&
    704             __is_nothrow_swappable<hasher>::value &&
    705             __is_nothrow_swappable<key_equal>::value);
    706 
    707     _LIBCPP_INLINE_VISIBILITY
    708     size_type max_bucket_count() const _NOEXCEPT
    709         {return __bucket_list_.get_deleter().__alloc().max_size();}
    710     size_type bucket_size(size_type __n) const;
    711     _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
    712     {
    713         size_type __bc = bucket_count();
    714         return __bc != 0 ? (float)size() / __bc : 0.f;
    715     }
    716     _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
    717         {max_load_factor() = _VSTD::max(__mlf, load_factor());}
    718 
    719     _LIBCPP_INLINE_VISIBILITY local_iterator       begin(size_type __n)
    720         {return local_iterator(__bucket_list_[__n], __n, bucket_count());}
    721     _LIBCPP_INLINE_VISIBILITY local_iterator       end(size_type __n)
    722         {return local_iterator(nullptr, __n, bucket_count());}
    723     _LIBCPP_INLINE_VISIBILITY const_local_iterator cbegin(size_type __n) const
    724         {return const_local_iterator(__bucket_list_[__n], __n, bucket_count());}
    725     _LIBCPP_INLINE_VISIBILITY const_local_iterator cend(size_type __n) const
    726         {return const_local_iterator(nullptr, __n, bucket_count());}
    727 private:
    728     void __rehash(size_type __n);
    729 
    730 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    731 #ifndef _LIBCPP_HAS_NO_VARIADICS
    732     template <class ..._Args>
    733         __node_holder __construct_node(_Args&& ...__args);
    734 #endif  // _LIBCPP_HAS_NO_VARIADICS
    735     __node_holder __construct_node(value_type&& __v, size_t __hash);
    736 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    737     __node_holder __construct_node(const value_type& __v);
    738 #endif
    739     __node_holder __construct_node(const value_type& __v, size_t __hash);
    740 
    741     _LIBCPP_INLINE_VISIBILITY
    742     void __copy_assign_alloc(const __hash_table& __u)
    743         {__copy_assign_alloc(__u, integral_constant<bool,
    744              __node_traits::propagate_on_container_copy_assignment::value>());}
    745     void __copy_assign_alloc(const __hash_table& __u, true_type);
    746     _LIBCPP_INLINE_VISIBILITY
    747         void __copy_assign_alloc(const __hash_table&, false_type) {}
    748 
    749     void __move_assign(__hash_table& __u, false_type);
    750     void __move_assign(__hash_table& __u, true_type)
    751         _NOEXCEPT_(
    752             is_nothrow_move_assignable<__node_allocator>::value &&
    753             is_nothrow_move_assignable<hasher>::value &&
    754             is_nothrow_move_assignable<key_equal>::value);
    755     _LIBCPP_INLINE_VISIBILITY
    756     void __move_assign_alloc(__hash_table& __u)
    757         _NOEXCEPT_(
    758             !__node_traits::propagate_on_container_move_assignment::value ||
    759             (is_nothrow_move_assignable<__pointer_allocator>::value &&
    760              is_nothrow_move_assignable<__node_allocator>::value))
    761         {__move_assign_alloc(__u, integral_constant<bool,
    762              __node_traits::propagate_on_container_move_assignment::value>());}
    763     _LIBCPP_INLINE_VISIBILITY
    764     void __move_assign_alloc(__hash_table& __u, true_type)
    765         _NOEXCEPT_(
    766             is_nothrow_move_assignable<__pointer_allocator>::value &&
    767             is_nothrow_move_assignable<__node_allocator>::value)
    768     {
    769         __bucket_list_.get_deleter().__alloc() =
    770                 _VSTD::move(__u.__bucket_list_.get_deleter().__alloc());
    771         __node_alloc() = _VSTD::move(__u.__node_alloc());
    772     }
    773     _LIBCPP_INLINE_VISIBILITY
    774         void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
    775 
    776     template <class _Ap>
    777     _LIBCPP_INLINE_VISIBILITY
    778     static
    779     void
    780     __swap_alloc(_Ap& __x, _Ap& __y)
    781         _NOEXCEPT_(
    782             !allocator_traits<_Ap>::propagate_on_container_swap::value ||
    783             __is_nothrow_swappable<_Ap>::value)
    784     {
    785         __swap_alloc(__x, __y,
    786                      integral_constant<bool,
    787                         allocator_traits<_Ap>::propagate_on_container_swap::value
    788                                       >());
    789     }
    790 
    791     template <class _Ap>
    792     _LIBCPP_INLINE_VISIBILITY
    793     static
    794     void
    795     __swap_alloc(_Ap& __x, _Ap& __y, true_type)
    796         _NOEXCEPT_(__is_nothrow_swappable<_Ap>::value)
    797     {
    798         using _VSTD::swap;
    799         swap(__x, __y);
    800     }
    801 
    802     template <class _Ap>
    803     _LIBCPP_INLINE_VISIBILITY
    804     static
    805     void
    806     __swap_alloc(_Ap&, _Ap&, false_type) _NOEXCEPT {}
    807 
    808     void __deallocate(__node_pointer __np) _NOEXCEPT;
    809     __node_pointer __detach() _NOEXCEPT;
    810 };
    811 
    812 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    813 inline _LIBCPP_INLINE_VISIBILITY
    814 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()
    815     _NOEXCEPT_(
    816         is_nothrow_default_constructible<__bucket_list>::value &&
    817         is_nothrow_default_constructible<__first_node>::value &&
    818         is_nothrow_default_constructible<hasher>::value &&
    819         is_nothrow_default_constructible<key_equal>::value)
    820     : __p2_(0),
    821       __p3_(1.0f)
    822 {
    823 }
    824 
    825 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    826 inline _LIBCPP_INLINE_VISIBILITY
    827 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
    828                                                        const key_equal& __eql)
    829     : __bucket_list_(nullptr, __bucket_list_deleter()),
    830       __p1_(),
    831       __p2_(0, __hf),
    832       __p3_(1.0f, __eql)
    833 {
    834 }
    835 
    836 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    837 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
    838                                                        const key_equal& __eql,
    839                                                        const allocator_type& __a)
    840     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
    841       __p1_(__node_allocator(__a)),
    842       __p2_(0, __hf),
    843       __p3_(1.0f, __eql)
    844 {
    845 }
    846 
    847 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    848 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
    849     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
    850       __p1_(__node_allocator(__a)),
    851       __p2_(0),
    852       __p3_(1.0f)
    853 {
    854 }
    855 
    856 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    857 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
    858     : __bucket_list_(nullptr,
    859           __bucket_list_deleter(allocator_traits<__pointer_allocator>::
    860               select_on_container_copy_construction(
    861                   __u.__bucket_list_.get_deleter().__alloc()), 0)),
    862       __p1_(allocator_traits<__node_allocator>::
    863           select_on_container_copy_construction(__u.__node_alloc())),
    864       __p2_(0, __u.hash_function()),
    865       __p3_(__u.__p3_)
    866 {
    867 }
    868 
    869 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    870 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
    871                                                        const allocator_type& __a)
    872     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
    873       __p1_(__node_allocator(__a)),
    874       __p2_(0, __u.hash_function()),
    875       __p3_(__u.__p3_)
    876 {
    877 }
    878 
    879 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    880 
    881 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    882 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
    883         _NOEXCEPT_(
    884             is_nothrow_move_constructible<__bucket_list>::value &&
    885             is_nothrow_move_constructible<__first_node>::value &&
    886             is_nothrow_move_constructible<hasher>::value &&
    887             is_nothrow_move_constructible<key_equal>::value)
    888     : __bucket_list_(_VSTD::move(__u.__bucket_list_)),
    889       __p1_(_VSTD::move(__u.__p1_)),
    890       __p2_(_VSTD::move(__u.__p2_)),
    891       __p3_(_VSTD::move(__u.__p3_))
    892 {
    893     if (size() > 0)
    894     {
    895         __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
    896             static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
    897         __u.__p1_.first().__next_ = nullptr;
    898         __u.size() = 0;
    899     }
    900 }
    901 
    902 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    903 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
    904                                                        const allocator_type& __a)
    905     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
    906       __p1_(__node_allocator(__a)),
    907       __p2_(0, _VSTD::move(__u.hash_function())),
    908       __p3_(_VSTD::move(__u.__p3_))
    909 {
    910     if (__a == allocator_type(__u.__node_alloc()))
    911     {
    912         __bucket_list_.reset(__u.__bucket_list_.release());
    913         __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
    914         __u.__bucket_list_.get_deleter().size() = 0;
    915         if (__u.size() > 0)
    916         {
    917             __p1_.first().__next_ = __u.__p1_.first().__next_;
    918             __u.__p1_.first().__next_ = nullptr;
    919             __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
    920                 static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
    921             size() = __u.size();
    922             __u.size() = 0;
    923         }
    924     }
    925 }
    926 
    927 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    928 
    929 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    930 __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
    931 {
    932     __deallocate(__p1_.first().__next_);
    933 }
    934 
    935 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    936 void
    937 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(
    938         const __hash_table& __u, true_type)
    939 {
    940     if (__node_alloc() != __u.__node_alloc())
    941     {
    942         clear();
    943         __bucket_list_.reset();
    944         __bucket_list_.get_deleter().size() = 0;
    945     }
    946     __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();
    947     __node_alloc() = __u.__node_alloc();
    948 }
    949 
    950 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    951 __hash_table<_Tp, _Hash, _Equal, _Alloc>&
    952 __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u)
    953 {
    954     if (this != &__u)
    955     {
    956         __copy_assign_alloc(__u);
    957         hash_function() = __u.hash_function();
    958         key_eq() = __u.key_eq();
    959         max_load_factor() = __u.max_load_factor();
    960         __assign_multi(__u.begin(), __u.end());
    961     }
    962     return *this;
    963 }
    964 
    965 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    966 void
    967 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np)
    968     _NOEXCEPT
    969 {
    970     __node_allocator& __na = __node_alloc();
    971     while (__np != nullptr)
    972     {
    973         __node_pointer __next = __np->__next_;
    974         __node_traits::destroy(__na, _VSTD::addressof(__np->__value_));
    975         __node_traits::deallocate(__na, __np, 1);
    976         __np = __next;
    977     }
    978 }
    979 
    980 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    981 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_pointer
    982 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT
    983 {
    984     size_type __bc = bucket_count();
    985     for (size_type __i = 0; __i < __bc; ++__i)
    986         __bucket_list_[__i] = nullptr;
    987     size() = 0;
    988     __node_pointer __cache = __p1_.first().__next_;
    989     __p1_.first().__next_ = nullptr;
    990     return __cache;
    991 }
    992 
    993 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    994 
    995 template <class _Tp, class _Hash, class _Equal, class _Alloc>
    996 void
    997 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
    998         __hash_table& __u, true_type)
    999     _NOEXCEPT_(
   1000         is_nothrow_move_assignable<__node_allocator>::value &&
   1001         is_nothrow_move_assignable<hasher>::value &&
   1002         is_nothrow_move_assignable<key_equal>::value)
   1003 {
   1004     clear();
   1005     __bucket_list_.reset(__u.__bucket_list_.release());
   1006     __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
   1007     __u.__bucket_list_.get_deleter().size() = 0;
   1008     __move_assign_alloc(__u);
   1009     size() = __u.size();
   1010     hash_function() = _VSTD::move(__u.hash_function());
   1011     max_load_factor() = __u.max_load_factor();
   1012     key_eq() = _VSTD::move(__u.key_eq());
   1013     __p1_.first().__next_ = __u.__p1_.first().__next_;
   1014     if (size() > 0)
   1015     {
   1016         __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
   1017             static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
   1018         __u.__p1_.first().__next_ = nullptr;
   1019         __u.size() = 0;
   1020     }
   1021 }
   1022 
   1023 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1024 void
   1025 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
   1026         __hash_table& __u, false_type)
   1027 {
   1028     if (__node_alloc() == __u.__node_alloc())
   1029         __move_assign(__u, true_type());
   1030     else
   1031     {
   1032         hash_function() = _VSTD::move(__u.hash_function());
   1033         key_eq() = _VSTD::move(__u.key_eq());
   1034         max_load_factor() = __u.max_load_factor();
   1035         if (bucket_count() != 0)
   1036         {
   1037             __node_pointer __cache = __detach();
   1038 #ifndef _LIBCPP_NO_EXCEPTIONS
   1039             try
   1040             {
   1041 #endif  // _LIBCPP_NO_EXCEPTIONS
   1042                 const_iterator __i = __u.begin();
   1043                 while (__cache != nullptr && __u.size() != 0)
   1044                 {
   1045                     __cache->__value_ = _VSTD::move(__u.remove(__i++)->__value_);
   1046                     __node_pointer __next = __cache->__next_;
   1047                     __node_insert_multi(__cache);
   1048                     __cache = __next;
   1049                 }
   1050 #ifndef _LIBCPP_NO_EXCEPTIONS
   1051             }
   1052             catch (...)
   1053             {
   1054                 __deallocate(__cache);
   1055                 throw;
   1056             }
   1057 #endif  // _LIBCPP_NO_EXCEPTIONS
   1058             __deallocate(__cache);
   1059         }
   1060         const_iterator __i = __u.begin();
   1061         while (__u.size() != 0)
   1062         {
   1063             __node_holder __h =
   1064                     __construct_node(_VSTD::move(__u.remove(__i++)->__value_));
   1065             __node_insert_multi(__h.get());
   1066             __h.release();
   1067         }
   1068     }
   1069 }
   1070 
   1071 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1072 inline _LIBCPP_INLINE_VISIBILITY
   1073 __hash_table<_Tp, _Hash, _Equal, _Alloc>&
   1074 __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
   1075     _NOEXCEPT_(
   1076         __node_traits::propagate_on_container_move_assignment::value &&
   1077         is_nothrow_move_assignable<__node_allocator>::value &&
   1078         is_nothrow_move_assignable<hasher>::value &&
   1079         is_nothrow_move_assignable<key_equal>::value)
   1080 {
   1081     __move_assign(__u, integral_constant<bool,
   1082                   __node_traits::propagate_on_container_move_assignment::value>());
   1083     return *this;
   1084 }
   1085 
   1086 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1087 
   1088 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1089 template <class _InputIterator>
   1090 void
   1091 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,
   1092                                                           _InputIterator __last)
   1093 {
   1094     if (bucket_count() != 0)
   1095     {
   1096         __node_pointer __cache = __detach();
   1097 #ifndef _LIBCPP_NO_EXCEPTIONS
   1098         try
   1099         {
   1100 #endif  // _LIBCPP_NO_EXCEPTIONS
   1101             for (; __cache != nullptr && __first != __last; ++__first)
   1102             {
   1103                 __cache->__value_ = *__first;
   1104                 __node_pointer __next = __cache->__next_;
   1105                 __node_insert_unique(__cache);
   1106                 __cache = __next;
   1107             }
   1108 #ifndef _LIBCPP_NO_EXCEPTIONS
   1109         }
   1110         catch (...)
   1111         {
   1112             __deallocate(__cache);
   1113             throw;
   1114         }
   1115 #endif  // _LIBCPP_NO_EXCEPTIONS
   1116         __deallocate(__cache);
   1117     }
   1118     for (; __first != __last; ++__first)
   1119         __insert_unique(*__first);
   1120 }
   1121 
   1122 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1123 template <class _InputIterator>
   1124 void
   1125 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
   1126                                                          _InputIterator __last)
   1127 {
   1128     if (bucket_count() != 0)
   1129     {
   1130         __node_pointer __cache = __detach();
   1131 #ifndef _LIBCPP_NO_EXCEPTIONS
   1132         try
   1133         {
   1134 #endif  // _LIBCPP_NO_EXCEPTIONS
   1135             for (; __cache != nullptr && __first != __last; ++__first)
   1136             {
   1137                 __cache->__value_ = *__first;
   1138                 __node_pointer __next = __cache->__next_;
   1139                 __node_insert_multi(__cache);
   1140                 __cache = __next;
   1141             }
   1142 #ifndef _LIBCPP_NO_EXCEPTIONS
   1143         }
   1144         catch (...)
   1145         {
   1146             __deallocate(__cache);
   1147             throw;
   1148         }
   1149 #endif  // _LIBCPP_NO_EXCEPTIONS
   1150         __deallocate(__cache);
   1151     }
   1152     for (; __first != __last; ++__first)
   1153         __insert_multi(*__first);
   1154 }
   1155 
   1156 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1157 inline _LIBCPP_INLINE_VISIBILITY
   1158 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1159 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
   1160 {
   1161     return iterator(__p1_.first().__next_);
   1162 }
   1163 
   1164 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1165 inline _LIBCPP_INLINE_VISIBILITY
   1166 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1167 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
   1168 {
   1169     return iterator(nullptr);
   1170 }
   1171 
   1172 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1173 inline _LIBCPP_INLINE_VISIBILITY
   1174 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
   1175 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
   1176 {
   1177     return const_iterator(__p1_.first().__next_);
   1178 }
   1179 
   1180 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1181 inline _LIBCPP_INLINE_VISIBILITY
   1182 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
   1183 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
   1184 {
   1185     return const_iterator(nullptr);
   1186 }
   1187 
   1188 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1189 void
   1190 __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
   1191 {
   1192     if (size() > 0)
   1193     {
   1194         __deallocate(__p1_.first().__next_);
   1195         __p1_.first().__next_ = nullptr;
   1196         size_type __bc = bucket_count();
   1197         for (size_type __i = 0; __i < __bc; ++__i)
   1198             __bucket_list_[__i] = nullptr;
   1199         size() = 0;
   1200     }
   1201 }
   1202 
   1203 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1204 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
   1205 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
   1206 {
   1207     __nd->__hash_ = hash_function()(__nd->__value_);
   1208     size_type __bc = bucket_count();
   1209     bool __inserted = false;
   1210     __node_pointer __ndptr;
   1211     size_t __chash;
   1212     if (__bc != 0)
   1213     {
   1214         __chash = __constrain_hash(__nd->__hash_, __bc);
   1215         __ndptr = __bucket_list_[__chash];
   1216         if (__ndptr != nullptr)
   1217         {
   1218             for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
   1219                                              __constrain_hash(__ndptr->__hash_, __bc) == __chash;
   1220                                                      __ndptr = __ndptr->__next_)
   1221             {
   1222                 if (key_eq()(__ndptr->__value_, __nd->__value_))
   1223                     goto __done;
   1224             }
   1225         }
   1226     }
   1227     {
   1228         if (size()+1 > __bc * max_load_factor() || __bc == 0)
   1229         {
   1230             rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
   1231                            size_type(ceil(float(size() + 1) / max_load_factor()))));
   1232             __bc = bucket_count();
   1233             __chash = __constrain_hash(__nd->__hash_, __bc);
   1234         }
   1235         // insert_after __bucket_list_[__chash], or __first_node if bucket is null
   1236         __node_pointer __pn = __bucket_list_[__chash];
   1237         if (__pn == nullptr)
   1238         {
   1239             __pn = static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
   1240             __nd->__next_ = __pn->__next_;
   1241             __pn->__next_ = __nd;
   1242             // fix up __bucket_list_
   1243             __bucket_list_[__chash] = __pn;
   1244             if (__nd->__next_ != nullptr)
   1245                 __bucket_list_[__constrain_hash(__nd->__next_->__hash_, __bc)] = __nd;
   1246         }
   1247         else
   1248         {
   1249             __nd->__next_ = __pn->__next_;
   1250             __pn->__next_ = __nd;
   1251         }
   1252         __ndptr = __nd;
   1253         // increment size
   1254         ++size();
   1255         __inserted = true;
   1256     }
   1257 __done:
   1258     return pair<iterator, bool>(iterator(__ndptr), __inserted);
   1259 }
   1260 
   1261 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1262 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1263 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
   1264 {
   1265     __cp->__hash_ = hash_function()(__cp->__value_);
   1266     size_type __bc = bucket_count();
   1267     if (size()+1 > __bc * max_load_factor() || __bc == 0)
   1268     {
   1269         rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
   1270                        size_type(ceil(float(size() + 1) / max_load_factor()))));
   1271         __bc = bucket_count();
   1272     }
   1273     size_t __chash = __constrain_hash(__cp->__hash_, __bc);
   1274     __node_pointer __pn = __bucket_list_[__chash];
   1275     if (__pn == nullptr)
   1276     {
   1277         __pn = static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
   1278         __cp->__next_ = __pn->__next_;
   1279         __pn->__next_ = __cp;
   1280         // fix up __bucket_list_
   1281         __bucket_list_[__chash] = __pn;
   1282         if (__cp->__next_ != nullptr)
   1283             __bucket_list_[__constrain_hash(__cp->__next_->__hash_, __bc)] = __cp;
   1284     }
   1285     else
   1286     {
   1287         for (bool __found = false; __pn->__next_ != nullptr &&
   1288                                    __constrain_hash(__pn->__next_->__hash_, __bc) == __chash;
   1289                                                            __pn = __pn->__next_)
   1290         {
   1291             //      __found    key_eq()     action
   1292             //      false       false       loop
   1293             //      true        true        loop
   1294             //      false       true        set __found to true
   1295             //      true        false       break
   1296             if (__found != (__pn->__next_->__hash_ == __cp->__hash_ &&
   1297                             key_eq()(__pn->__next_->__value_, __cp->__value_)))
   1298             {
   1299                 if (!__found)
   1300                     __found = true;
   1301                 else
   1302                     break;
   1303             }
   1304         }
   1305         __cp->__next_ = __pn->__next_;
   1306         __pn->__next_ = __cp;
   1307         if (__cp->__next_ != nullptr)
   1308         {
   1309             size_t __nhash = __constrain_hash(__cp->__next_->__hash_, __bc);
   1310             if (__nhash != __chash)
   1311                 __bucket_list_[__nhash] = __cp;
   1312         }
   1313     }
   1314     ++size();
   1315     return iterator(__cp);
   1316 }
   1317 
   1318 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1319 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1320 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
   1321         const_iterator __p, __node_pointer __cp)
   1322 {
   1323     if (__p != end() && key_eq()(*__p, __cp->__value_))
   1324     {
   1325         __node_pointer __np = const_cast<__node_pointer>(__p.__node_);
   1326         __cp->__hash_ = __np->__hash_;
   1327         size_type __bc = bucket_count();
   1328         if (size()+1 > __bc * max_load_factor() || __bc == 0)
   1329         {
   1330             rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
   1331                            size_type(ceil(float(size() + 1) / max_load_factor()))));
   1332             __bc = bucket_count();
   1333         }
   1334         size_t __chash = __constrain_hash(__cp->__hash_, __bc);
   1335         __node_pointer __pp = __bucket_list_[__chash];
   1336         while (__pp->__next_ != __np)
   1337             __pp = __pp->__next_;
   1338         __cp->__next_ = __np;
   1339         __pp->__next_ = __cp;
   1340         ++size();
   1341         return iterator(__cp);
   1342     }
   1343     return __node_insert_multi(__cp);
   1344 }
   1345 
   1346 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1347 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
   1348 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)
   1349 {
   1350     size_t __hash = hash_function()(__x);
   1351     size_type __bc = bucket_count();
   1352     bool __inserted = false;
   1353     __node_pointer __nd;
   1354     size_t __chash;
   1355     if (__bc != 0)
   1356     {
   1357         __chash = __constrain_hash(__hash, __bc);
   1358         __nd = __bucket_list_[__chash];
   1359         if (__nd != nullptr)
   1360         {
   1361             for (__nd = __nd->__next_; __nd != nullptr &&
   1362                                        __constrain_hash(__nd->__hash_, __bc) == __chash;
   1363                                                            __nd = __nd->__next_)
   1364             {
   1365                 if (key_eq()(__nd->__value_, __x))
   1366                     goto __done;
   1367             }
   1368         }
   1369     }
   1370     {
   1371         __node_holder __h = __construct_node(__x, __hash);
   1372         if (size()+1 > __bc * max_load_factor() || __bc == 0)
   1373         {
   1374             rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
   1375                            size_type(ceil(float(size() + 1) / max_load_factor()))));
   1376             __bc = bucket_count();
   1377             __chash = __constrain_hash(__hash, __bc);
   1378         }
   1379         // insert_after __bucket_list_[__chash], or __first_node if bucket is null
   1380         __node_pointer __pn = __bucket_list_[__chash];
   1381         if (__pn == nullptr)
   1382         {
   1383             __pn = static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
   1384             __h->__next_ = __pn->__next_;
   1385             __pn->__next_ = __h.get();
   1386             // fix up __bucket_list_
   1387             __bucket_list_[__chash] = __pn;
   1388             if (__h->__next_ != nullptr)
   1389                 __bucket_list_[__constrain_hash(__h->__next_->__hash_, __bc)] = __h.get();
   1390         }
   1391         else
   1392         {
   1393             __h->__next_ = __pn->__next_;
   1394             __pn->__next_ = __h.get();
   1395         }
   1396         __nd = __h.release();
   1397         // increment size
   1398         ++size();
   1399         __inserted = true;
   1400     }
   1401 __done:
   1402     return pair<iterator, bool>(iterator(__nd), __inserted);
   1403 }
   1404 
   1405 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1406 #ifndef _LIBCPP_HAS_NO_VARIADICS
   1407 
   1408 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1409 template <class... _Args>
   1410 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
   1411 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args)
   1412 {
   1413     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
   1414     pair<iterator, bool> __r = __node_insert_unique(__h.get());
   1415     if (__r.second)
   1416         __h.release();
   1417     return __r;
   1418 }
   1419 
   1420 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1421 template <class... _Args>
   1422 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1423 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args)
   1424 {
   1425     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
   1426     iterator __r = __node_insert_multi(__h.get());
   1427     __h.release();
   1428     return __r;
   1429 }
   1430 
   1431 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1432 template <class... _Args>
   1433 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1434 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
   1435         const_iterator __p, _Args&&... __args)
   1436 {
   1437     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
   1438     iterator __r = __node_insert_multi(__p, __h.get());
   1439     __h.release();
   1440     return __r;
   1441 }
   1442 
   1443 #endif  // _LIBCPP_HAS_NO_VARIADICS
   1444 
   1445 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1446 template <class _Pp>
   1447 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
   1448 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x)
   1449 {
   1450     __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
   1451     pair<iterator, bool> __r = __node_insert_unique(__h.get());
   1452     if (__r.second)
   1453         __h.release();
   1454     return __r;
   1455 }
   1456 
   1457 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1458 
   1459 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1460 
   1461 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1462 template <class _Pp>
   1463 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1464 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x)
   1465 {
   1466     __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
   1467     iterator __r = __node_insert_multi(__h.get());
   1468     __h.release();
   1469     return __r;
   1470 }
   1471 
   1472 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1473 template <class _Pp>
   1474 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1475 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
   1476                                                          _Pp&& __x)
   1477 {
   1478     __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
   1479     iterator __r = __node_insert_multi(__p, __h.get());
   1480     __h.release();
   1481     return __r;
   1482 }
   1483 
   1484 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1485 
   1486 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1487 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1488 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x)
   1489 {
   1490     __node_holder __h = __construct_node(__x);
   1491     iterator __r = __node_insert_multi(__h.get());
   1492     __h.release();
   1493     return __r;
   1494 }
   1495 
   1496 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1497 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1498 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
   1499                                                          const value_type& __x)
   1500 {
   1501     __node_holder __h = __construct_node(__x);
   1502     iterator __r = __node_insert_multi(__p, __h.get());
   1503     __h.release();
   1504     return __r;
   1505 }
   1506 
   1507 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1508 
   1509 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1510 void
   1511 __hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)
   1512 {
   1513     if (__n == 1)
   1514         __n = 2;
   1515     else if (__n & (__n - 1))
   1516         __n = __next_prime(__n);
   1517     size_type __bc = bucket_count();
   1518     if (__n > __bc)
   1519         __rehash(__n);
   1520     else if (__n < __bc)
   1521     {
   1522         __n = _VSTD::max<size_type>
   1523               (
   1524                   __n,
   1525                   __is_power2(__bc) ? __next_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
   1526                                       __next_prime(size_t(ceil(float(size()) / max_load_factor())))
   1527               );
   1528         if (__n < __bc)
   1529             __rehash(__n);
   1530     }
   1531 }
   1532 
   1533 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1534 void
   1535 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
   1536 {
   1537     __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
   1538     __bucket_list_.reset(__nbc > 0 ?
   1539                       __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
   1540     __bucket_list_.get_deleter().size() = __nbc;
   1541     if (__nbc > 0)
   1542     {
   1543         for (size_type __i = 0; __i < __nbc; ++__i)
   1544             __bucket_list_[__i] = nullptr;
   1545         __node_pointer __pp(static_cast<__node_pointer>(_VSTD::addressof(__p1_.first())));
   1546         __node_pointer __cp = __pp->__next_;
   1547         if (__cp != nullptr)
   1548         {
   1549             size_type __chash = __constrain_hash(__cp->__hash_, __nbc);
   1550             __bucket_list_[__chash] = __pp;
   1551             size_type __phash = __chash;
   1552             for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr;
   1553                                                            __cp = __pp->__next_)
   1554             {
   1555                 __chash = __constrain_hash(__cp->__hash_, __nbc);
   1556                 if (__chash == __phash)
   1557                     __pp = __cp;
   1558                 else
   1559                 {
   1560                     if (__bucket_list_[__chash] == nullptr)
   1561                     {
   1562                         __bucket_list_[__chash] = __pp;
   1563                         __pp = __cp;
   1564                         __phash = __chash;
   1565                     }
   1566                     else
   1567                     {
   1568                         __node_pointer __np = __cp;
   1569                         for (; __np->__next_ != nullptr &&
   1570                                key_eq()(__cp->__value_, __np->__next_->__value_);
   1571                                                            __np = __np->__next_)
   1572                             ;
   1573                         __pp->__next_ = __np->__next_;
   1574                         __np->__next_ = __bucket_list_[__chash]->__next_;
   1575                         __bucket_list_[__chash]->__next_ = __cp;
   1576 
   1577                     }
   1578                 }
   1579             }
   1580         }
   1581     }
   1582 }
   1583 
   1584 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1585 template <class _Key>
   1586 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1587 __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
   1588 {
   1589     size_t __hash = hash_function()(__k);
   1590     size_type __bc = bucket_count();
   1591     if (__bc != 0)
   1592     {
   1593         size_t __chash = __constrain_hash(__hash, __bc);
   1594         __node_pointer __nd = __bucket_list_[__chash];
   1595         if (__nd != nullptr)
   1596         {
   1597             for (__nd = __nd->__next_; __nd != nullptr &&
   1598                                        __constrain_hash(__nd->__hash_, __bc) == __chash;
   1599                                                            __nd = __nd->__next_)
   1600             {
   1601                 if (key_eq()(__nd->__value_, __k))
   1602                     return iterator(__nd);
   1603             }
   1604         }
   1605     }
   1606     return end();
   1607 }
   1608 
   1609 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1610 template <class _Key>
   1611 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
   1612 __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
   1613 {
   1614     size_t __hash = hash_function()(__k);
   1615     size_type __bc = bucket_count();
   1616     if (__bc != 0)
   1617     {
   1618         size_t __chash = __constrain_hash(__hash, __bc);
   1619         __node_const_pointer __nd = __bucket_list_[__chash];
   1620         if (__nd != nullptr)
   1621         {
   1622             for (__nd = __nd->__next_; __nd != nullptr &&
   1623                                            __constrain_hash(__nd->__hash_, __bc) == __chash;
   1624                                                            __nd = __nd->__next_)
   1625             {
   1626                 if (key_eq()(__nd->__value_, __k))
   1627                     return const_iterator(__nd);
   1628             }
   1629         }
   1630 
   1631     }
   1632     return end();
   1633 }
   1634 
   1635 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1636 #ifndef _LIBCPP_HAS_NO_VARIADICS
   1637 
   1638 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1639 template <class ..._Args>
   1640 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
   1641 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
   1642 {
   1643     __node_allocator& __na = __node_alloc();
   1644     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
   1645     __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);
   1646     __h.get_deleter().__value_constructed = true;
   1647     __h->__hash_ = hash_function()(__h->__value_);
   1648     __h->__next_ = nullptr;
   1649     return __h;
   1650 }
   1651 
   1652 #endif  // _LIBCPP_HAS_NO_VARIADICS
   1653 
   1654 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1655 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
   1656 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(value_type&& __v,
   1657                                                            size_t __hash)
   1658 {
   1659     __node_allocator& __na = __node_alloc();
   1660     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
   1661     __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
   1662     __h.get_deleter().__value_constructed = true;
   1663     __h->__hash_ = __hash;
   1664     __h->__next_ = nullptr;
   1665     return _VSTD::move(__h);
   1666 }
   1667 
   1668 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1669 
   1670 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1671 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
   1672 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v)
   1673 {
   1674     __node_allocator& __na = __node_alloc();
   1675     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
   1676     __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
   1677     __h.get_deleter().__value_constructed = true;
   1678     __h->__hash_ = hash_function()(__h->__value_);
   1679     __h->__next_ = nullptr;
   1680     return _VSTD::move(__h);
   1681 }
   1682 
   1683 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
   1684 
   1685 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1686 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
   1687 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v,
   1688                                                            size_t __hash)
   1689 {
   1690     __node_allocator& __na = __node_alloc();
   1691     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
   1692     __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
   1693     __h.get_deleter().__value_constructed = true;
   1694     __h->__hash_ = __hash;
   1695     __h->__next_ = nullptr;
   1696     return _VSTD::move(__h);
   1697 }
   1698 
   1699 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1700 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1701 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
   1702 {
   1703     __node_pointer __np = const_cast<__node_pointer>(__p.__node_);
   1704     iterator __r(__np);
   1705     ++__r;
   1706     remove(__p);
   1707     return __r;
   1708 }
   1709 
   1710 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1711 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
   1712 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
   1713                                                 const_iterator __last)
   1714 {
   1715     for (const_iterator __p = __first; __first != __last; __p = __first)
   1716     {
   1717         ++__first;
   1718         erase(__p);
   1719     }
   1720     __node_pointer __np = const_cast<__node_pointer>(__last.__node_);
   1721     return iterator (__np);
   1722 }
   1723 
   1724 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1725 template <class _Key>
   1726 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
   1727 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k)
   1728 {
   1729     iterator __i = find(__k);
   1730     if (__i == end())
   1731         return 0;
   1732     erase(__i);
   1733     return 1;
   1734 }
   1735 
   1736 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1737 template <class _Key>
   1738 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
   1739 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k)
   1740 {
   1741     size_type __r = 0;
   1742     iterator __i = find(__k);
   1743     if (__i != end())
   1744     {
   1745         iterator __e = end();
   1746         do
   1747         {
   1748             erase(__i++);
   1749             ++__r;
   1750         } while (__i != __e && key_eq()(*__i, __k));
   1751     }
   1752     return __r;
   1753 }
   1754 
   1755 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1756 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
   1757 __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
   1758 {
   1759     // current node
   1760     __node_pointer __cn = const_cast<__node_pointer>(__p.__node_);
   1761     size_type __bc = bucket_count();
   1762     size_t __chash = __constrain_hash(__cn->__hash_, __bc);
   1763     // find previous node
   1764     __node_pointer __pn = __bucket_list_[__chash];
   1765     for (; __pn->__next_ != __cn; __pn = __pn->__next_)
   1766         ;
   1767     // Fix up __bucket_list_
   1768         // if __pn is not in same bucket (before begin is not in same bucket) &&
   1769         //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
   1770     if (__pn == _VSTD::addressof(__p1_.first()) || __constrain_hash(__pn->__hash_, __bc) != __chash)
   1771     {
   1772         if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash)
   1773             __bucket_list_[__chash] = nullptr;
   1774     }
   1775         // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
   1776     if (__cn->__next_ != nullptr)
   1777     {
   1778         size_t __nhash = __constrain_hash(__cn->__next_->__hash_, __bc);
   1779         if (__nhash != __chash)
   1780             __bucket_list_[__nhash] = __pn;
   1781     }
   1782     // remove __cn
   1783     __pn->__next_ = __cn->__next_;
   1784     __cn->__next_ = nullptr;
   1785     --size();
   1786     return __node_holder(__cn, _Dp(__node_alloc(), true));
   1787 }
   1788 
   1789 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1790 template <class _Key>
   1791 inline _LIBCPP_INLINE_VISIBILITY
   1792 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
   1793 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const
   1794 {
   1795     return static_cast<size_type>(find(__k) != end());
   1796 }
   1797 
   1798 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1799 template <class _Key>
   1800 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
   1801 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const
   1802 {
   1803     size_type __r = 0;
   1804     const_iterator __i = find(__k);
   1805     if (__i != end())
   1806     {
   1807         const_iterator __e = end();
   1808         do
   1809         {
   1810             ++__i;
   1811             ++__r;
   1812         } while (__i != __e && key_eq()(*__i, __k));
   1813     }
   1814     return __r;
   1815 }
   1816 
   1817 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1818 template <class _Key>
   1819 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
   1820      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
   1821 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
   1822         const _Key& __k)
   1823 {
   1824     iterator __i = find(__k);
   1825     iterator __j = __i;
   1826     if (__i != end())
   1827         ++__j;
   1828     return pair<iterator, iterator>(__i, __j);
   1829 }
   1830 
   1831 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1832 template <class _Key>
   1833 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
   1834      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
   1835 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
   1836         const _Key& __k) const
   1837 {
   1838     const_iterator __i = find(__k);
   1839     const_iterator __j = __i;
   1840     if (__i != end())
   1841         ++__j;
   1842     return pair<const_iterator, const_iterator>(__i, __j);
   1843 }
   1844 
   1845 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1846 template <class _Key>
   1847 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
   1848      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
   1849 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
   1850         const _Key& __k)
   1851 {
   1852     iterator __i = find(__k);
   1853     iterator __j = __i;
   1854     if (__i != end())
   1855     {
   1856         iterator __e = end();
   1857         do
   1858         {
   1859             ++__j;
   1860         } while (__j != __e && key_eq()(*__j, __k));
   1861     }
   1862     return pair<iterator, iterator>(__i, __j);
   1863 }
   1864 
   1865 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1866 template <class _Key>
   1867 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
   1868      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
   1869 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
   1870         const _Key& __k) const
   1871 {
   1872     const_iterator __i = find(__k);
   1873     const_iterator __j = __i;
   1874     if (__i != end())
   1875     {
   1876         const_iterator __e = end();
   1877         do
   1878         {
   1879             ++__j;
   1880         } while (__j != __e && key_eq()(*__j, __k));
   1881     }
   1882     return pair<const_iterator, const_iterator>(__i, __j);
   1883 }
   1884 
   1885 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1886 void
   1887 __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
   1888     _NOEXCEPT_(
   1889         (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
   1890          __is_nothrow_swappable<__pointer_allocator>::value) &&
   1891         (!__node_traits::propagate_on_container_swap::value ||
   1892          __is_nothrow_swappable<__node_allocator>::value) &&
   1893         __is_nothrow_swappable<hasher>::value &&
   1894         __is_nothrow_swappable<key_equal>::value)
   1895 {
   1896     {
   1897     __node_pointer_pointer __npp = __bucket_list_.release();
   1898     __bucket_list_.reset(__u.__bucket_list_.release());
   1899     __u.__bucket_list_.reset(__npp);
   1900     }
   1901     _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
   1902     __swap_alloc(__bucket_list_.get_deleter().__alloc(),
   1903              __u.__bucket_list_.get_deleter().__alloc());
   1904     __swap_alloc(__node_alloc(), __u.__node_alloc());
   1905     _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
   1906     __p2_.swap(__u.__p2_);
   1907     __p3_.swap(__u.__p3_);
   1908     if (size() > 0)
   1909         __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
   1910             static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
   1911     if (__u.size() > 0)
   1912         __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] =
   1913             static_cast<__node_pointer>(_VSTD::addressof(__u.__p1_.first()));
   1914 }
   1915 
   1916 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1917 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
   1918 __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
   1919 {
   1920     __node_const_pointer __np = __bucket_list_[__n];
   1921     size_type __bc = bucket_count();
   1922     size_type __r = 0;
   1923     if (__np != nullptr)
   1924     {
   1925         for (__np = __np->__next_; __np != nullptr &&
   1926                                    __constrain_hash(__np->__hash_, __bc) == __n;
   1927                                                     __np = __np->__next_, ++__r)
   1928             ;
   1929     }
   1930     return __r;
   1931 }
   1932 
   1933 template <class _Tp, class _Hash, class _Equal, class _Alloc>
   1934 inline _LIBCPP_INLINE_VISIBILITY
   1935 void
   1936 swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
   1937      __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)
   1938     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
   1939 {
   1940     __x.swap(__y);
   1941 }
   1942 
   1943 _LIBCPP_END_NAMESPACE_STD
   1944 
   1945 #endif  // _LIBCPP__HASH_TABLE
   1946