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