[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / libcxx / include / __hash_table
blob98337abe5583304d2b4c1dd31f2a647743b63af8
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___HASH_TABLE
11 #define _LIBCPP___HASH_TABLE
13 #include <__algorithm/max.h>
14 #include <__algorithm/min.h>
15 #include <__assert>
16 #include <__bit/countl.h>
17 #include <__config>
18 #include <__functional/hash.h>
19 #include <__functional/invoke.h>
20 #include <__iterator/iterator_traits.h>
21 #include <__memory/addressof.h>
22 #include <__memory/allocator_traits.h>
23 #include <__memory/compressed_pair.h>
24 #include <__memory/pointer_traits.h>
25 #include <__memory/swap_allocator.h>
26 #include <__memory/unique_ptr.h>
27 #include <__type_traits/can_extract_key.h>
28 #include <__type_traits/conditional.h>
29 #include <__type_traits/is_const.h>
30 #include <__type_traits/is_copy_constructible.h>
31 #include <__type_traits/is_nothrow_constructible.h>
32 #include <__type_traits/is_nothrow_copy_constructible.h>
33 #include <__type_traits/is_nothrow_default_constructible.h>
34 #include <__type_traits/is_nothrow_move_assignable.h>
35 #include <__type_traits/is_nothrow_move_constructible.h>
36 #include <__type_traits/is_pointer.h>
37 #include <__type_traits/is_reference.h>
38 #include <__type_traits/is_swappable.h>
39 #include <__type_traits/remove_const.h>
40 #include <__type_traits/remove_cvref.h>
41 #include <__utility/forward.h>
42 #include <__utility/move.h>
43 #include <__utility/pair.h>
44 #include <__utility/swap.h>
45 #include <cmath>
46 #include <cstring>
47 #include <initializer_list>
49 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
50 #  pragma GCC system_header
51 #endif
53 _LIBCPP_PUSH_MACROS
54 #include <__undef_macros>
57 _LIBCPP_BEGIN_NAMESPACE_STD
59 template <class _Key, class _Tp>
60 struct __hash_value_type;
62 template <class _Tp>
63 struct __is_hash_value_type_imp : false_type {};
65 template <class _Key, class _Value>
66 struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {};
68 template <class ..._Args>
69 struct __is_hash_value_type : false_type {};
71 template <class _One>
72 struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {};
74 _LIBCPP_EXPORTED_FROM_ABI size_t __next_prime(size_t __n);
76 template <class _NodePtr>
77 struct __hash_node_base
79     typedef typename pointer_traits<_NodePtr>::element_type __node_type;
80     typedef __hash_node_base __first_node;
81     typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer;
82     typedef _NodePtr __node_pointer;
84 #if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
85   typedef __node_base_pointer __next_pointer;
86 #else
87     typedef __conditional_t<is_pointer<__node_pointer>::value, __node_base_pointer, __node_pointer> __next_pointer;
88 #endif
90     __next_pointer    __next_;
92     _LIBCPP_INLINE_VISIBILITY
93     __next_pointer __ptr() _NOEXCEPT {
94         return static_cast<__next_pointer>(
95             pointer_traits<__node_base_pointer>::pointer_to(*this));
96     }
98     _LIBCPP_INLINE_VISIBILITY
99     __node_pointer __upcast() _NOEXCEPT {
100         return static_cast<__node_pointer>(
101             pointer_traits<__node_base_pointer>::pointer_to(*this));
102     }
104     _LIBCPP_INLINE_VISIBILITY
105     size_t __hash() const _NOEXCEPT {
106         return static_cast<__node_type const&>(*this).__hash_;
107     }
109     _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
112 template <class _Tp, class _VoidPtr>
113 struct _LIBCPP_STANDALONE_DEBUG __hash_node
114     : public __hash_node_base
115              <
116                  __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> >
117              >
119     typedef _Tp __node_value_type;
121     size_t            __hash_;
122     __node_value_type __value_;
125 inline _LIBCPP_INLINE_VISIBILITY
126 bool
127 __is_hash_power2(size_t __bc)
129     return __bc > 2 && !(__bc & (__bc - 1));
132 inline _LIBCPP_INLINE_VISIBILITY
133 size_t
134 __constrain_hash(size_t __h, size_t __bc)
136     return !(__bc & (__bc - 1)) ? __h & (__bc - 1) :
137         (__h < __bc ? __h : __h % __bc);
140 inline _LIBCPP_INLINE_VISIBILITY
141 size_t
142 __next_hash_pow2(size_t __n)
144     return __n < 2 ? __n : (size_t(1) << (numeric_limits<size_t>::digits - __libcpp_clz(__n-1)));
148 template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
150 template <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_iterator;
151 template <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
152 template <class _NodePtr>      class _LIBCPP_TEMPLATE_VIS __hash_local_iterator;
153 template <class _ConstNodePtr> class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
154 template <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
155 template <class _HashIterator> class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
157 template <class _Tp>
158 struct __hash_key_value_types {
159   static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
160   typedef _Tp key_type;
161   typedef _Tp __node_value_type;
162   typedef _Tp __container_value_type;
163   static const bool __is_map = false;
165   _LIBCPP_INLINE_VISIBILITY
166   static key_type const& __get_key(_Tp const& __v) {
167     return __v;
168   }
169   _LIBCPP_INLINE_VISIBILITY
170   static __container_value_type const& __get_value(__node_value_type const& __v) {
171     return __v;
172   }
173   _LIBCPP_INLINE_VISIBILITY
174   static __container_value_type* __get_ptr(__node_value_type& __n) {
175     return _VSTD::addressof(__n);
176   }
177   _LIBCPP_INLINE_VISIBILITY
178   static __container_value_type&& __move(__node_value_type& __v) {
179     return _VSTD::move(__v);
180   }
183 template <class _Key, class _Tp>
184 struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
185   typedef _Key                                         key_type;
186   typedef _Tp                                          mapped_type;
187   typedef __hash_value_type<_Key, _Tp>                 __node_value_type;
188   typedef pair<const _Key, _Tp>                        __container_value_type;
189   typedef __container_value_type                       __map_value_type;
190   static const bool __is_map = true;
192   _LIBCPP_INLINE_VISIBILITY
193   static key_type const& __get_key(__container_value_type const& __v) {
194     return __v.first;
195   }
197   template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, int> = 0>
198   _LIBCPP_INLINE_VISIBILITY
199   static __container_value_type const&
200   __get_value(_Up& __t) {
201     return __t.__get_value();
202   }
204   template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0>
205   _LIBCPP_INLINE_VISIBILITY
206   static __container_value_type const&
207   __get_value(_Up& __t) {
208     return __t;
209   }
211   _LIBCPP_INLINE_VISIBILITY
212   static __container_value_type* __get_ptr(__node_value_type& __n) {
213     return _VSTD::addressof(__n.__get_value());
214   }
215   _LIBCPP_INLINE_VISIBILITY
216   static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) {
217     return __v.__move();
218   }
221 template <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>,
222           bool = _KVTypes::__is_map>
223 struct __hash_map_pointer_types {};
225 template <class _Tp, class _AllocPtr, class _KVTypes>
226 struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
227   typedef typename _KVTypes::__map_value_type   _Mv;
228   typedef __rebind_pointer_t<_AllocPtr, _Mv>
229                                                        __map_value_type_pointer;
230   typedef __rebind_pointer_t<_AllocPtr, const _Mv>
231                                                  __const_map_value_type_pointer;
234 template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
235 struct __hash_node_types;
237 template <class _NodePtr, class _Tp, class _VoidPtr>
238 struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> >
239     : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr>
242   typedef __hash_key_value_types<_Tp>           __base;
244 public:
245   typedef ptrdiff_t difference_type;
246   typedef size_t size_type;
248   typedef __rebind_pointer_t<_NodePtr, void>       __void_pointer;
250   typedef typename pointer_traits<_NodePtr>::element_type       __node_type;
251   typedef _NodePtr                                              __node_pointer;
253   typedef __hash_node_base<__node_pointer>                      __node_base_type;
254   typedef __rebind_pointer_t<_NodePtr, __node_base_type>
255                                                              __node_base_pointer;
257   typedef typename __node_base_type::__next_pointer          __next_pointer;
259   typedef _Tp                                                 __node_value_type;
260   typedef __rebind_pointer_t<_VoidPtr, __node_value_type>
261                                                       __node_value_type_pointer;
262   typedef __rebind_pointer_t<_VoidPtr, const __node_value_type>
263                                                 __const_node_value_type_pointer;
265 private:
266     static_assert(!is_const<__node_type>::value,
267                 "_NodePtr should never be a pointer to const");
268     static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value),
269                   "_VoidPtr does not point to unqualified void type");
270     static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>,
271                           _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
274 template <class _HashIterator>
275 struct __hash_node_types_from_iterator;
276 template <class _NodePtr>
277 struct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
278 template <class _NodePtr>
279 struct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
280 template <class _NodePtr>
281 struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
282 template <class _NodePtr>
283 struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {};
286 template <class _NodeValueTp, class _VoidPtr>
287 struct __make_hash_node_types {
288   typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp;
289   typedef __rebind_pointer_t<_VoidPtr, _NodeTp> _NodePtr;
290   typedef __hash_node_types<_NodePtr> type;
293 template <class _NodePtr>
294 class _LIBCPP_TEMPLATE_VIS __hash_iterator
296     typedef __hash_node_types<_NodePtr> _NodeTypes;
297     typedef _NodePtr                            __node_pointer;
298     typedef typename _NodeTypes::__next_pointer __next_pointer;
300     __next_pointer            __node_;
302 public:
303     typedef forward_iterator_tag                           iterator_category;
304     typedef typename _NodeTypes::__node_value_type         value_type;
305     typedef typename _NodeTypes::difference_type           difference_type;
306     typedef value_type&                                    reference;
307     typedef typename _NodeTypes::__node_value_type_pointer pointer;
309     _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) {
310     }
312     _LIBCPP_INLINE_VISIBILITY
313     reference operator*() const {
314         return __node_->__upcast()->__value_;
315     }
317     _LIBCPP_INLINE_VISIBILITY
318     pointer operator->() const {
319         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
320     }
322     _LIBCPP_INLINE_VISIBILITY
323     __hash_iterator& operator++() {
324         __node_ = __node_->__next_;
325         return *this;
326     }
328     _LIBCPP_INLINE_VISIBILITY
329     __hash_iterator operator++(int)
330     {
331         __hash_iterator __t(*this);
332         ++(*this);
333         return __t;
334     }
336     friend _LIBCPP_INLINE_VISIBILITY
337     bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)
338     {
339         return __x.__node_ == __y.__node_;
340     }
341     friend _LIBCPP_INLINE_VISIBILITY
342     bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)
343         {return !(__x == __y);}
345 private:
346     _LIBCPP_INLINE_VISIBILITY
347     explicit __hash_iterator(__next_pointer __node) _NOEXCEPT
348         : __node_(__node)
349         {
350         }
352     template <class, class, class, class> friend class __hash_table;
353     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
354     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
355     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
356     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
359 template <class _NodePtr>
360 class _LIBCPP_TEMPLATE_VIS __hash_const_iterator
362     static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, "");
363     typedef __hash_node_types<_NodePtr> _NodeTypes;
364     typedef _NodePtr                            __node_pointer;
365     typedef typename _NodeTypes::__next_pointer __next_pointer;
367     __next_pointer __node_;
369 public:
370     typedef __hash_iterator<_NodePtr> __non_const_iterator;
372     typedef forward_iterator_tag                                 iterator_category;
373     typedef typename _NodeTypes::__node_value_type               value_type;
374     typedef typename _NodeTypes::difference_type                 difference_type;
375     typedef const value_type&                                    reference;
376     typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
379     _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {
380     }
382     _LIBCPP_INLINE_VISIBILITY
383     __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
384         : __node_(__x.__node_)
385     {
386     }
388     _LIBCPP_INLINE_VISIBILITY
389     reference operator*() const {
390         return __node_->__upcast()->__value_;
391     }
392     _LIBCPP_INLINE_VISIBILITY
393     pointer operator->() const {
394         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
395     }
397     _LIBCPP_INLINE_VISIBILITY
398     __hash_const_iterator& operator++() {
399         __node_ = __node_->__next_;
400         return *this;
401     }
403     _LIBCPP_INLINE_VISIBILITY
404     __hash_const_iterator operator++(int)
405     {
406         __hash_const_iterator __t(*this);
407         ++(*this);
408         return __t;
409     }
411     friend _LIBCPP_INLINE_VISIBILITY
412     bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
413     {
414         return __x.__node_ == __y.__node_;
415     }
416     friend _LIBCPP_INLINE_VISIBILITY
417     bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
418         {return !(__x == __y);}
420 private:
421     _LIBCPP_INLINE_VISIBILITY
422     explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT
423         : __node_(__node)
424         {
425         }
427     template <class, class, class, class> friend class __hash_table;
428     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
429     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
430     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
433 template <class _NodePtr>
434 class _LIBCPP_TEMPLATE_VIS __hash_local_iterator
436     typedef __hash_node_types<_NodePtr> _NodeTypes;
437     typedef _NodePtr                            __node_pointer;
438     typedef typename _NodeTypes::__next_pointer __next_pointer;
440     __next_pointer         __node_;
441     size_t                 __bucket_;
442     size_t                 __bucket_count_;
444 public:
445     typedef forward_iterator_tag                                iterator_category;
446     typedef typename _NodeTypes::__node_value_type              value_type;
447     typedef typename _NodeTypes::difference_type                difference_type;
448     typedef value_type&                                         reference;
449     typedef typename _NodeTypes::__node_value_type_pointer      pointer;
451     _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {
452     }
454     _LIBCPP_INLINE_VISIBILITY
455     reference operator*() const {
456         return __node_->__upcast()->__value_;
457     }
459     _LIBCPP_INLINE_VISIBILITY
460     pointer operator->() const {
461         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
462     }
464     _LIBCPP_INLINE_VISIBILITY
465     __hash_local_iterator& operator++() {
466         __node_ = __node_->__next_;
467         if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
468             __node_ = nullptr;
469         return *this;
470     }
472     _LIBCPP_INLINE_VISIBILITY
473     __hash_local_iterator operator++(int)
474     {
475         __hash_local_iterator __t(*this);
476         ++(*this);
477         return __t;
478     }
480     friend _LIBCPP_INLINE_VISIBILITY
481     bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
482     {
483         return __x.__node_ == __y.__node_;
484     }
485     friend _LIBCPP_INLINE_VISIBILITY
486     bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
487         {return !(__x == __y);}
489 private:
490     _LIBCPP_INLINE_VISIBILITY
491     explicit __hash_local_iterator(__next_pointer __node, size_t __bucket,
492                                    size_t __bucket_count) _NOEXCEPT
493         : __node_(__node),
494           __bucket_(__bucket),
495           __bucket_count_(__bucket_count)
496         {
497             if (__node_ != nullptr)
498                 __node_ = __node_->__next_;
499         }
501     template <class, class, class, class> friend class __hash_table;
502     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
503     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator;
506 template <class _ConstNodePtr>
507 class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator
509     typedef __hash_node_types<_ConstNodePtr> _NodeTypes;
510     typedef _ConstNodePtr                       __node_pointer;
511     typedef typename _NodeTypes::__next_pointer __next_pointer;
513     __next_pointer         __node_;
514     size_t                 __bucket_;
515     size_t                 __bucket_count_;
517     typedef pointer_traits<__node_pointer>          __pointer_traits;
518     typedef typename __pointer_traits::element_type __node;
519     typedef __remove_const_t<__node>                  __non_const_node;
520     typedef __rebind_pointer_t<__node_pointer, __non_const_node>
521         __non_const_node_pointer;
522 public:
523     typedef __hash_local_iterator<__non_const_node_pointer>
524                                                     __non_const_iterator;
526     typedef forward_iterator_tag                                 iterator_category;
527     typedef typename _NodeTypes::__node_value_type               value_type;
528     typedef typename _NodeTypes::difference_type                 difference_type;
529     typedef const value_type&                                    reference;
530     typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
533     _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {
534     }
536     _LIBCPP_INLINE_VISIBILITY
537     __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
538         : __node_(__x.__node_),
539           __bucket_(__x.__bucket_),
540           __bucket_count_(__x.__bucket_count_)
541     {
542     }
544     _LIBCPP_INLINE_VISIBILITY
545     reference operator*() const {
546         return __node_->__upcast()->__value_;
547     }
549     _LIBCPP_INLINE_VISIBILITY
550     pointer operator->() const {
551         return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_);
552     }
554     _LIBCPP_INLINE_VISIBILITY
555     __hash_const_local_iterator& operator++() {
556         __node_ = __node_->__next_;
557         if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_)
558             __node_ = nullptr;
559         return *this;
560     }
562     _LIBCPP_INLINE_VISIBILITY
563     __hash_const_local_iterator operator++(int)
564     {
565         __hash_const_local_iterator __t(*this);
566         ++(*this);
567         return __t;
568     }
570     friend _LIBCPP_INLINE_VISIBILITY
571     bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
572     {
573         return __x.__node_ == __y.__node_;
574     }
575     friend _LIBCPP_INLINE_VISIBILITY
576     bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
577         {return !(__x == __y);}
579 private:
580     _LIBCPP_INLINE_VISIBILITY
581     explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket,
582                                          size_t __bucket_count) _NOEXCEPT
583         : __node_(__node_ptr),
584           __bucket_(__bucket),
585           __bucket_count_(__bucket_count)
586         {
587             if (__node_ != nullptr)
588                 __node_ = __node_->__next_;
589         }
591     template <class, class, class, class> friend class __hash_table;
592     template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
595 template <class _Alloc>
596 class __bucket_list_deallocator
598     typedef _Alloc                                          allocator_type;
599     typedef allocator_traits<allocator_type>                __alloc_traits;
600     typedef typename __alloc_traits::size_type              size_type;
602     __compressed_pair<size_type, allocator_type> __data_;
603 public:
604     typedef typename __alloc_traits::pointer pointer;
606     _LIBCPP_INLINE_VISIBILITY
607     __bucket_list_deallocator()
608         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
609         : __data_(0, __default_init_tag()) {}
611     _LIBCPP_INLINE_VISIBILITY
612     __bucket_list_deallocator(const allocator_type& __a, size_type __size)
613         _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
614         : __data_(__size, __a) {}
616     _LIBCPP_INLINE_VISIBILITY
617     __bucket_list_deallocator(__bucket_list_deallocator&& __x)
618         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
619         : __data_(_VSTD::move(__x.__data_))
620     {
621         __x.size() = 0;
622     }
624     _LIBCPP_INLINE_VISIBILITY
625     size_type& size() _NOEXCEPT {return __data_.first();}
626     _LIBCPP_INLINE_VISIBILITY
627     size_type  size() const _NOEXCEPT {return __data_.first();}
629     _LIBCPP_INLINE_VISIBILITY
630     allocator_type& __alloc() _NOEXCEPT {return __data_.second();}
631     _LIBCPP_INLINE_VISIBILITY
632     const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();}
634     _LIBCPP_INLINE_VISIBILITY
635     void operator()(pointer __p) _NOEXCEPT
636     {
637         __alloc_traits::deallocate(__alloc(), __p, size());
638     }
641 template <class _Alloc> class __hash_map_node_destructor;
643 template <class _Alloc>
644 class __hash_node_destructor
646     typedef _Alloc                                          allocator_type;
647     typedef allocator_traits<allocator_type>                __alloc_traits;
649 public:
650     typedef typename __alloc_traits::pointer                pointer;
651 private:
652     typedef __hash_node_types<pointer> _NodeTypes;
654     allocator_type& __na_;
656 public:
657     bool __value_constructed;
659     _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default;
660     _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete;
663     _LIBCPP_INLINE_VISIBILITY
664     explicit __hash_node_destructor(allocator_type& __na,
665                                     bool __constructed = false) _NOEXCEPT
666         : __na_(__na),
667           __value_constructed(__constructed)
668         {}
670     _LIBCPP_INLINE_VISIBILITY
671     void operator()(pointer __p) _NOEXCEPT
672     {
673         if (__value_constructed)
674             __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
675         if (__p)
676             __alloc_traits::deallocate(__na_, __p, 1);
677     }
679     template <class> friend class __hash_map_node_destructor;
682 #if _LIBCPP_STD_VER >= 17
683 template <class _NodeType, class _Alloc>
684 struct __generic_container_node_destructor;
686 template <class _Tp, class _VoidPtr, class _Alloc>
687 struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
688     : __hash_node_destructor<_Alloc>
690     using __hash_node_destructor<_Alloc>::__hash_node_destructor;
692 #endif
694 template <class _Key, class _Hash, class _Equal>
695 struct __enforce_unordered_container_requirements {
696 #ifndef _LIBCPP_CXX03_LANG
697     static_assert(__check_hash_requirements<_Key, _Hash>::value,
698     "the specified hash does not meet the Hash requirements");
699     static_assert(is_copy_constructible<_Equal>::value,
700     "the specified comparator is required to be copy constructible");
701 #endif
702     typedef int type;
705 template <class _Key, class _Hash, class _Equal>
706 #ifndef _LIBCPP_CXX03_LANG
707     _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
708     "the specified comparator type does not provide a viable const call operator")
709     _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
710     "the specified hash functor does not provide a viable const call operator")
711 #endif
712 typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type
713 __diagnose_unordered_container_requirements(int);
715 // This dummy overload is used so that the compiler won't emit a spurious
716 // "no matching function for call to __diagnose_unordered_xxx" diagnostic
717 // when the overload above causes a hard error.
718 template <class _Key, class _Hash, class _Equal>
719 int __diagnose_unordered_container_requirements(void*);
721 template <class _Tp, class _Hash, class _Equal, class _Alloc>
722 class __hash_table
724 public:
725     typedef _Tp    value_type;
726     typedef _Hash  hasher;
727     typedef _Equal key_equal;
728     typedef _Alloc allocator_type;
730 private:
731     typedef allocator_traits<allocator_type> __alloc_traits;
732     typedef typename
733       __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type
734                                                                      _NodeTypes;
735 public:
737     typedef typename _NodeTypes::__node_value_type           __node_value_type;
738     typedef typename _NodeTypes::__container_value_type      __container_value_type;
739     typedef typename _NodeTypes::key_type                    key_type;
740     typedef value_type&                              reference;
741     typedef const value_type&                        const_reference;
742     typedef typename __alloc_traits::pointer         pointer;
743     typedef typename __alloc_traits::const_pointer   const_pointer;
744 #ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
745     typedef typename __alloc_traits::size_type       size_type;
746 #else
747     typedef typename _NodeTypes::size_type           size_type;
748 #endif
749     typedef typename _NodeTypes::difference_type     difference_type;
750 public:
751     // Create __node
753     typedef typename _NodeTypes::__node_type __node;
754     typedef __rebind_alloc<__alloc_traits, __node>   __node_allocator;
755     typedef allocator_traits<__node_allocator>       __node_traits;
756     typedef typename _NodeTypes::__void_pointer      __void_pointer;
757     typedef typename _NodeTypes::__node_pointer      __node_pointer;
758     typedef typename _NodeTypes::__node_pointer      __node_const_pointer;
759     typedef typename _NodeTypes::__node_base_type    __first_node;
760     typedef typename _NodeTypes::__node_base_pointer __node_base_pointer;
761     typedef typename _NodeTypes::__next_pointer      __next_pointer;
763 private:
764     // check for sane allocator pointer rebinding semantics. Rebinding the
765     // allocator for a new pointer type should be exactly the same as rebinding
766     // the pointer using 'pointer_traits'.
767     static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
768                   "Allocator does not rebind pointers in a sane manner.");
769     typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator;
770     typedef allocator_traits<__node_base_allocator> __node_base_traits;
771     static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
772                  "Allocator does not rebind pointers in a sane manner.");
774 private:
776     typedef __rebind_alloc<__node_traits, __next_pointer>  __pointer_allocator;
777     typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
778     typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
779     typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
780     typedef typename __bucket_list_deleter::pointer       __node_pointer_pointer;
782     // --- Member data begin ---
783     __bucket_list                                         __bucket_list_;
784     __compressed_pair<__first_node, __node_allocator>     __p1_;
785     __compressed_pair<size_type, hasher>                  __p2_;
786     __compressed_pair<float, key_equal>                   __p3_;
787     // --- Member data end ---
789     _LIBCPP_INLINE_VISIBILITY
790     size_type& size() _NOEXCEPT {return __p2_.first();}
791 public:
792     _LIBCPP_INLINE_VISIBILITY
793     size_type  size() const _NOEXCEPT {return __p2_.first();}
795     _LIBCPP_INLINE_VISIBILITY
796     hasher& hash_function() _NOEXCEPT {return __p2_.second();}
797     _LIBCPP_INLINE_VISIBILITY
798     const hasher& hash_function() const _NOEXCEPT {return __p2_.second();}
800     _LIBCPP_INLINE_VISIBILITY
801     float& max_load_factor() _NOEXCEPT {return __p3_.first();}
802     _LIBCPP_INLINE_VISIBILITY
803     float  max_load_factor() const _NOEXCEPT {return __p3_.first();}
805     _LIBCPP_INLINE_VISIBILITY
806     key_equal& key_eq() _NOEXCEPT {return __p3_.second();}
807     _LIBCPP_INLINE_VISIBILITY
808     const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();}
810     _LIBCPP_INLINE_VISIBILITY
811     __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();}
812     _LIBCPP_INLINE_VISIBILITY
813     const __node_allocator& __node_alloc() const _NOEXCEPT
814         {return __p1_.second();}
816 public:
817     typedef __hash_iterator<__node_pointer>                   iterator;
818     typedef __hash_const_iterator<__node_pointer>             const_iterator;
819     typedef __hash_local_iterator<__node_pointer>             local_iterator;
820     typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;
822     _LIBCPP_INLINE_VISIBILITY
823     __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<__node_allocator>::value &&
828             is_nothrow_default_constructible<hasher>::value &&
829             is_nothrow_default_constructible<key_equal>::value);
830     _LIBCPP_INLINE_VISIBILITY
831     __hash_table(const hasher& __hf, const key_equal& __eql);
832     _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql,
833                  const allocator_type& __a);
834     _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a);
835     _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u);
836     _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a);
837     _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u)
838         _NOEXCEPT_(
839             is_nothrow_move_constructible<__bucket_list>::value &&
840             is_nothrow_move_constructible<__first_node>::value &&
841             is_nothrow_move_constructible<__node_allocator>::value &&
842             is_nothrow_move_constructible<hasher>::value &&
843             is_nothrow_move_constructible<key_equal>::value);
844     _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a);
845     _LIBCPP_HIDE_FROM_ABI ~__hash_table();
847     _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u);
848     _LIBCPP_INLINE_VISIBILITY
849     __hash_table& operator=(__hash_table&& __u)
850         _NOEXCEPT_(
851             __node_traits::propagate_on_container_move_assignment::value &&
852             is_nothrow_move_assignable<__node_allocator>::value &&
853             is_nothrow_move_assignable<hasher>::value &&
854             is_nothrow_move_assignable<key_equal>::value);
855     template <class _InputIterator>
856     _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
857     template <class _InputIterator>
858     _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
860     _LIBCPP_INLINE_VISIBILITY
861     size_type max_size() const _NOEXCEPT
862     {
863         return _VSTD::min<size_type>(
864             __node_traits::max_size(__node_alloc()),
865             numeric_limits<difference_type >::max()
866         );
867     }
869 private:
870     _LIBCPP_INLINE_VISIBILITY
871     __next_pointer __node_insert_multi_prepare(size_t __cp_hash,
872                                                value_type& __cp_val);
873     _LIBCPP_INLINE_VISIBILITY
874     void __node_insert_multi_perform(__node_pointer __cp,
875                                      __next_pointer __pn) _NOEXCEPT;
877     _LIBCPP_INLINE_VISIBILITY
878     __next_pointer __node_insert_unique_prepare(size_t __nd_hash,
879                                                 value_type& __nd_val);
880     _LIBCPP_INLINE_VISIBILITY
881     void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT;
883 public:
884     _LIBCPP_INLINE_VISIBILITY
885     pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
886     _LIBCPP_INLINE_VISIBILITY
887     iterator             __node_insert_multi(__node_pointer __nd);
888     _LIBCPP_INLINE_VISIBILITY
889     iterator             __node_insert_multi(const_iterator __p,
890                                              __node_pointer __nd);
892     template <class _Key, class ..._Args>
893     _LIBCPP_INLINE_VISIBILITY
894     pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
896     template <class... _Args>
897     _LIBCPP_INLINE_VISIBILITY
898     pair<iterator, bool> __emplace_unique_impl(_Args&&... __args);
900     template <class _Pp>
901     _LIBCPP_INLINE_VISIBILITY
902     pair<iterator, bool> __emplace_unique(_Pp&& __x) {
903       return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x),
904                                           __can_extract_key<_Pp, key_type>());
905     }
907     template <class _First, class _Second,
908               __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, int> = 0>
909     _LIBCPP_INLINE_VISIBILITY
910     pair<iterator, bool>
911     __emplace_unique(_First&& __f, _Second&& __s) {
912         return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f),
913                                               _VSTD::forward<_Second>(__s));
914     }
916     template <class... _Args>
917     _LIBCPP_INLINE_VISIBILITY
918     pair<iterator, bool> __emplace_unique(_Args&&... __args) {
919       return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...);
920     }
922     template <class _Pp>
923     _LIBCPP_INLINE_VISIBILITY
924     pair<iterator, bool>
925     __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) {
926       return __emplace_unique_impl(_VSTD::forward<_Pp>(__x));
927     }
928     template <class _Pp>
929     _LIBCPP_INLINE_VISIBILITY
930     pair<iterator, bool>
931     __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) {
932       return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x));
933     }
934     template <class _Pp>
935     _LIBCPP_INLINE_VISIBILITY
936     pair<iterator, bool>
937     __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) {
938       return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x));
939     }
941     template <class... _Args>
942     _LIBCPP_INLINE_VISIBILITY
943     iterator __emplace_multi(_Args&&... __args);
944     template <class... _Args>
945     _LIBCPP_INLINE_VISIBILITY
946     iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
949     _LIBCPP_INLINE_VISIBILITY
950     pair<iterator, bool>
951     __insert_unique(__container_value_type&& __x) {
952       return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x));
953     }
955     template <class _Pp, class = __enable_if_t<!__is_same_uncvref<_Pp, __container_value_type>::value> >
956     _LIBCPP_INLINE_VISIBILITY
957     pair<iterator, bool> __insert_unique(_Pp&& __x) {
958       return __emplace_unique(_VSTD::forward<_Pp>(__x));
959     }
961     template <class _Pp>
962     _LIBCPP_INLINE_VISIBILITY
963     iterator __insert_multi(_Pp&& __x) {
964       return __emplace_multi(_VSTD::forward<_Pp>(__x));
965     }
967     template <class _Pp>
968     _LIBCPP_INLINE_VISIBILITY
969     iterator __insert_multi(const_iterator __p, _Pp&& __x) {
970         return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x));
971     }
973     _LIBCPP_INLINE_VISIBILITY
974     pair<iterator, bool> __insert_unique(const __container_value_type& __x) {
975         return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
976     }
978 #if _LIBCPP_STD_VER >= 17
979     template <class _NodeHandle, class _InsertReturnType>
980     _LIBCPP_INLINE_VISIBILITY
981     _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
982     template <class _NodeHandle>
983     _LIBCPP_INLINE_VISIBILITY
984     iterator __node_handle_insert_unique(const_iterator __hint,
985                                          _NodeHandle&& __nh);
986     template <class _Table>
987     _LIBCPP_INLINE_VISIBILITY
988     void __node_handle_merge_unique(_Table& __source);
990     template <class _NodeHandle>
991     _LIBCPP_INLINE_VISIBILITY
992     iterator __node_handle_insert_multi(_NodeHandle&& __nh);
993     template <class _NodeHandle>
994     _LIBCPP_INLINE_VISIBILITY
995     iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
996     template <class _Table>
997     _LIBCPP_INLINE_VISIBILITY
998     void __node_handle_merge_multi(_Table& __source);
1000     template <class _NodeHandle>
1001     _LIBCPP_INLINE_VISIBILITY
1002     _NodeHandle __node_handle_extract(key_type const& __key);
1003     template <class _NodeHandle>
1004     _LIBCPP_INLINE_VISIBILITY
1005     _NodeHandle __node_handle_extract(const_iterator __it);
1006 #endif
1008     _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
1009     _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); }
1010     _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); }
1011     _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n)
1012     {
1013         __rehash_unique(static_cast<size_type>(std::ceil(__n / max_load_factor())));
1014     }
1015     _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n)
1016     {
1017         __rehash_multi(static_cast<size_type>(std::ceil(__n / max_load_factor())));
1018     }
1020     _LIBCPP_INLINE_VISIBILITY
1021     size_type bucket_count() const _NOEXCEPT
1022     {
1023         return __bucket_list_.get_deleter().size();
1024     }
1026     _LIBCPP_INLINE_VISIBILITY
1027     iterator       begin() _NOEXCEPT;
1028     _LIBCPP_INLINE_VISIBILITY
1029     iterator       end() _NOEXCEPT;
1030     _LIBCPP_INLINE_VISIBILITY
1031     const_iterator begin() const _NOEXCEPT;
1032     _LIBCPP_INLINE_VISIBILITY
1033     const_iterator end() const _NOEXCEPT;
1035     template <class _Key>
1036         _LIBCPP_INLINE_VISIBILITY
1037         size_type bucket(const _Key& __k) const
1038         {
1039             _LIBCPP_ASSERT_UNCATEGORIZED(bucket_count() > 0,
1040                 "unordered container::bucket(key) called when bucket_count() == 0");
1041             return std::__constrain_hash(hash_function()(__k), bucket_count());
1042         }
1044     template <class _Key>
1045     _LIBCPP_HIDE_FROM_ABI iterator       find(const _Key& __x);
1046     template <class _Key>
1047     _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const;
1049     typedef __hash_node_destructor<__node_allocator> _Dp;
1050     typedef unique_ptr<__node, _Dp> __node_holder;
1052     _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
1053     _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
1054     template <class _Key>
1055     _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
1056     template <class _Key>
1057     _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);
1058     _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
1060     template <class _Key>
1061         _LIBCPP_INLINE_VISIBILITY
1062         size_type __count_unique(const _Key& __k) const;
1063     template <class _Key>
1064     _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
1066     template <class _Key>
1067     _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
1068         __equal_range_unique(const _Key& __k);
1069     template <class _Key>
1070     _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
1071         __equal_range_unique(const _Key& __k) const;
1073     template <class _Key>
1074     _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator>
1075         __equal_range_multi(const _Key& __k);
1076     template <class _Key>
1077     _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator>
1078         __equal_range_multi(const _Key& __k) const;
1080     _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u)
1081 #if _LIBCPP_STD_VER <= 11
1082         _NOEXCEPT_(
1083             __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
1084             && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
1085                   || __is_nothrow_swappable<__pointer_allocator>::value)
1086             && (!__node_traits::propagate_on_container_swap::value
1087                   || __is_nothrow_swappable<__node_allocator>::value)
1088             );
1089 #else
1090      _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
1091 #endif
1093     _LIBCPP_INLINE_VISIBILITY
1094     size_type max_bucket_count() const _NOEXCEPT
1095         {return max_size(); }
1096     _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const;
1097     _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
1098     {
1099         size_type __bc = bucket_count();
1100         return __bc != 0 ? (float)size() / __bc : 0.f;
1101     }
1102     _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
1103     {
1104         _LIBCPP_ASSERT_UNCATEGORIZED(__mlf > 0,
1105             "unordered container::max_load_factor(lf) called with lf <= 0");
1106         max_load_factor() = _VSTD::max(__mlf, load_factor());
1107     }
1109     _LIBCPP_INLINE_VISIBILITY
1110     local_iterator
1111     begin(size_type __n)
1112     {
1113         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
1114             "unordered container::begin(n) called with n >= bucket_count()");
1115         return local_iterator(__bucket_list_[__n], __n, bucket_count());
1116     }
1118     _LIBCPP_INLINE_VISIBILITY
1119     local_iterator
1120     end(size_type __n)
1121     {
1122         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
1123             "unordered container::end(n) called with n >= bucket_count()");
1124         return local_iterator(nullptr, __n, bucket_count());
1125     }
1127     _LIBCPP_INLINE_VISIBILITY
1128     const_local_iterator
1129     cbegin(size_type __n) const
1130     {
1131         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
1132             "unordered container::cbegin(n) called with n >= bucket_count()");
1133         return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
1134     }
1136     _LIBCPP_INLINE_VISIBILITY
1137     const_local_iterator
1138     cend(size_type __n) const
1139     {
1140         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
1141             "unordered container::cend(n) called with n >= bucket_count()");
1142         return const_local_iterator(nullptr, __n, bucket_count());
1143     }
1145 private:
1146     template <bool _UniqueKeys>
1147     _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n);
1148     template <bool _UniqueKeys>
1149     _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n);
1151     template <class ..._Args>
1152     _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args);
1154     template <class _First, class ..._Rest>
1155     _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest);
1158     _LIBCPP_INLINE_VISIBILITY
1159     void __copy_assign_alloc(const __hash_table& __u)
1160         {__copy_assign_alloc(__u, integral_constant<bool,
1161              __node_traits::propagate_on_container_copy_assignment::value>());}
1162     _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type);
1163     _LIBCPP_INLINE_VISIBILITY
1164         void __copy_assign_alloc(const __hash_table&, false_type) {}
1166     _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type);
1167     _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type)
1168         _NOEXCEPT_(
1169             is_nothrow_move_assignable<__node_allocator>::value &&
1170             is_nothrow_move_assignable<hasher>::value &&
1171             is_nothrow_move_assignable<key_equal>::value);
1172     _LIBCPP_INLINE_VISIBILITY
1173     void __move_assign_alloc(__hash_table& __u)
1174         _NOEXCEPT_(
1175             !__node_traits::propagate_on_container_move_assignment::value ||
1176             (is_nothrow_move_assignable<__pointer_allocator>::value &&
1177              is_nothrow_move_assignable<__node_allocator>::value))
1178         {__move_assign_alloc(__u, integral_constant<bool,
1179              __node_traits::propagate_on_container_move_assignment::value>());}
1180     _LIBCPP_INLINE_VISIBILITY
1181     void __move_assign_alloc(__hash_table& __u, true_type)
1182         _NOEXCEPT_(
1183             is_nothrow_move_assignable<__pointer_allocator>::value &&
1184             is_nothrow_move_assignable<__node_allocator>::value)
1185     {
1186         __bucket_list_.get_deleter().__alloc() =
1187                 _VSTD::move(__u.__bucket_list_.get_deleter().__alloc());
1188         __node_alloc() = _VSTD::move(__u.__node_alloc());
1189     }
1190     _LIBCPP_INLINE_VISIBILITY
1191         void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
1193     _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT;
1194     _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT;
1196     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map;
1197     template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap;
1200 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1201 inline
1202 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()
1203     _NOEXCEPT_(
1204         is_nothrow_default_constructible<__bucket_list>::value &&
1205         is_nothrow_default_constructible<__first_node>::value &&
1206         is_nothrow_default_constructible<__node_allocator>::value &&
1207         is_nothrow_default_constructible<hasher>::value &&
1208         is_nothrow_default_constructible<key_equal>::value)
1209     : __p2_(0, __default_init_tag()),
1210       __p3_(1.0f, __default_init_tag())
1214 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1215 inline
1216 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
1217                                                        const key_equal& __eql)
1218     : __bucket_list_(nullptr, __bucket_list_deleter()),
1219       __p1_(),
1220       __p2_(0, __hf),
1221       __p3_(1.0f, __eql)
1225 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1226 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
1227                                                        const key_equal& __eql,
1228                                                        const allocator_type& __a)
1229     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1230       __p1_(__default_init_tag(), __node_allocator(__a)),
1231       __p2_(0, __hf),
1232       __p3_(1.0f, __eql)
1236 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1237 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
1238     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1239       __p1_(__default_init_tag(), __node_allocator(__a)),
1240       __p2_(0, __default_init_tag()),
1241       __p3_(1.0f, __default_init_tag())
1245 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1246 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
1247     : __bucket_list_(nullptr,
1248           __bucket_list_deleter(allocator_traits<__pointer_allocator>::
1249               select_on_container_copy_construction(
1250                   __u.__bucket_list_.get_deleter().__alloc()), 0)),
1251       __p1_(__default_init_tag(), allocator_traits<__node_allocator>::
1252           select_on_container_copy_construction(__u.__node_alloc())),
1253       __p2_(0, __u.hash_function()),
1254       __p3_(__u.__p3_)
1258 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1259 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
1260                                                        const allocator_type& __a)
1261     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1262       __p1_(__default_init_tag(), __node_allocator(__a)),
1263       __p2_(0, __u.hash_function()),
1264       __p3_(__u.__p3_)
1268 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1269 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
1270         _NOEXCEPT_(
1271             is_nothrow_move_constructible<__bucket_list>::value &&
1272             is_nothrow_move_constructible<__first_node>::value &&
1273             is_nothrow_move_constructible<__node_allocator>::value &&
1274             is_nothrow_move_constructible<hasher>::value &&
1275             is_nothrow_move_constructible<key_equal>::value)
1276     : __bucket_list_(_VSTD::move(__u.__bucket_list_)),
1277       __p1_(_VSTD::move(__u.__p1_)),
1278       __p2_(_VSTD::move(__u.__p2_)),
1279       __p3_(_VSTD::move(__u.__p3_))
1281     if (size() > 0)
1282     {
1283         __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
1284             __p1_.first().__ptr();
1285         __u.__p1_.first().__next_ = nullptr;
1286         __u.size() = 0;
1287     }
1290 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1291 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
1292                                                        const allocator_type& __a)
1293     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
1294       __p1_(__default_init_tag(), __node_allocator(__a)),
1295       __p2_(0, _VSTD::move(__u.hash_function())),
1296       __p3_(_VSTD::move(__u.__p3_))
1298     if (__a == allocator_type(__u.__node_alloc()))
1299     {
1300         __bucket_list_.reset(__u.__bucket_list_.release());
1301         __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
1302         __u.__bucket_list_.get_deleter().size() = 0;
1303         if (__u.size() > 0)
1304         {
1305             __p1_.first().__next_ = __u.__p1_.first().__next_;
1306             __u.__p1_.first().__next_ = nullptr;
1307             __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
1308                 __p1_.first().__ptr();
1309             size() = __u.size();
1310             __u.size() = 0;
1311         }
1312     }
1315 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1316 __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
1318 #if defined(_LIBCPP_CXX03_LANG)
1319     static_assert((is_copy_constructible<key_equal>::value),
1320                  "Predicate must be copy-constructible.");
1321     static_assert((is_copy_constructible<hasher>::value),
1322                  "Hasher must be copy-constructible.");
1323 #endif
1325     __deallocate_node(__p1_.first().__next_);
1328 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1329 void
1330 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(
1331         const __hash_table& __u, true_type)
1333     if (__node_alloc() != __u.__node_alloc())
1334     {
1335         clear();
1336         __bucket_list_.reset();
1337         __bucket_list_.get_deleter().size() = 0;
1338     }
1339     __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();
1340     __node_alloc() = __u.__node_alloc();
1343 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1344 __hash_table<_Tp, _Hash, _Equal, _Alloc>&
1345 __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u)
1347     if (this != _VSTD::addressof(__u))
1348     {
1349         __copy_assign_alloc(__u);
1350         hash_function() = __u.hash_function();
1351         key_eq() = __u.key_eq();
1352         max_load_factor() = __u.max_load_factor();
1353         __assign_multi(__u.begin(), __u.end());
1354     }
1355     return *this;
1358 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1359 void
1360 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np)
1361     _NOEXCEPT
1363     __node_allocator& __na = __node_alloc();
1364     while (__np != nullptr)
1365     {
1366         __next_pointer __next = __np->__next_;
1367         __node_pointer __real_np = __np->__upcast();
1368         __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_));
1369         __node_traits::deallocate(__na, __real_np, 1);
1370         __np = __next;
1371     }
1374 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1375 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1376 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT
1378     size_type __bc = bucket_count();
1379     for (size_type __i = 0; __i < __bc; ++__i)
1380         __bucket_list_[__i] = nullptr;
1381     size() = 0;
1382     __next_pointer __cache = __p1_.first().__next_;
1383     __p1_.first().__next_ = nullptr;
1384     return __cache;
1387 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1388 void
1389 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
1390         __hash_table& __u, true_type)
1391     _NOEXCEPT_(
1392         is_nothrow_move_assignable<__node_allocator>::value &&
1393         is_nothrow_move_assignable<hasher>::value &&
1394         is_nothrow_move_assignable<key_equal>::value)
1396     clear();
1397     __bucket_list_.reset(__u.__bucket_list_.release());
1398     __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
1399     __u.__bucket_list_.get_deleter().size() = 0;
1400     __move_assign_alloc(__u);
1401     size() = __u.size();
1402     hash_function() = _VSTD::move(__u.hash_function());
1403     max_load_factor() = __u.max_load_factor();
1404     key_eq() = _VSTD::move(__u.key_eq());
1405     __p1_.first().__next_ = __u.__p1_.first().__next_;
1406     if (size() > 0)
1407     {
1408         __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
1409             __p1_.first().__ptr();
1410         __u.__p1_.first().__next_ = nullptr;
1411         __u.size() = 0;
1412     }
1415 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1416 void
1417 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
1418         __hash_table& __u, false_type)
1420     if (__node_alloc() == __u.__node_alloc())
1421         __move_assign(__u, true_type());
1422     else
1423     {
1424         hash_function() = _VSTD::move(__u.hash_function());
1425         key_eq() = _VSTD::move(__u.key_eq());
1426         max_load_factor() = __u.max_load_factor();
1427         if (bucket_count() != 0)
1428         {
1429             __next_pointer __cache = __detach();
1430 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1431             try
1432             {
1433 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1434                 const_iterator __i = __u.begin();
1435                 while (__cache != nullptr && __u.size() != 0)
1436                 {
1437                     __cache->__upcast()->__value_ =
1438                         _VSTD::move(__u.remove(__i++)->__value_);
1439                     __next_pointer __next = __cache->__next_;
1440                     __node_insert_multi(__cache->__upcast());
1441                     __cache = __next;
1442                 }
1443 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1444             }
1445             catch (...)
1446             {
1447                 __deallocate_node(__cache);
1448                 throw;
1449             }
1450 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1451             __deallocate_node(__cache);
1452         }
1453         const_iterator __i = __u.begin();
1454         while (__u.size() != 0)
1455         {
1456             __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_));
1457             __node_insert_multi(__h.get());
1458             __h.release();
1459         }
1460     }
1463 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1464 inline
1465 __hash_table<_Tp, _Hash, _Equal, _Alloc>&
1466 __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
1467     _NOEXCEPT_(
1468         __node_traits::propagate_on_container_move_assignment::value &&
1469         is_nothrow_move_assignable<__node_allocator>::value &&
1470         is_nothrow_move_assignable<hasher>::value &&
1471         is_nothrow_move_assignable<key_equal>::value)
1473     __move_assign(__u, integral_constant<bool,
1474                   __node_traits::propagate_on_container_move_assignment::value>());
1475     return *this;
1478 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1479 template <class _InputIterator>
1480 void
1481 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,
1482                                                           _InputIterator __last)
1484     typedef iterator_traits<_InputIterator> _ITraits;
1485     typedef typename _ITraits::value_type _ItValueType;
1486     static_assert((is_same<_ItValueType, __container_value_type>::value),
1487                   "__assign_unique may only be called with the containers value type");
1489     if (bucket_count() != 0)
1490     {
1491         __next_pointer __cache = __detach();
1492 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1493         try
1494         {
1495 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1496             for (; __cache != nullptr && __first != __last; ++__first)
1497             {
1498                 __cache->__upcast()->__value_ = *__first;
1499                 __next_pointer __next = __cache->__next_;
1500                 __node_insert_unique(__cache->__upcast());
1501                 __cache = __next;
1502             }
1503 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1504         }
1505         catch (...)
1506         {
1507             __deallocate_node(__cache);
1508             throw;
1509         }
1510 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1511         __deallocate_node(__cache);
1512     }
1513     for (; __first != __last; ++__first)
1514         __insert_unique(*__first);
1517 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1518 template <class _InputIterator>
1519 void
1520 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
1521                                                          _InputIterator __last)
1523     typedef iterator_traits<_InputIterator> _ITraits;
1524     typedef typename _ITraits::value_type _ItValueType;
1525     static_assert((is_same<_ItValueType, __container_value_type>::value ||
1526                   is_same<_ItValueType, __node_value_type>::value),
1527                   "__assign_multi may only be called with the containers value type"
1528                   " or the nodes value type");
1529     if (bucket_count() != 0)
1530     {
1531         __next_pointer __cache = __detach();
1532 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1533         try
1534         {
1535 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1536             for (; __cache != nullptr && __first != __last; ++__first)
1537             {
1538                 __cache->__upcast()->__value_ = *__first;
1539                 __next_pointer __next = __cache->__next_;
1540                 __node_insert_multi(__cache->__upcast());
1541                 __cache = __next;
1542             }
1543 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1544         }
1545         catch (...)
1546         {
1547             __deallocate_node(__cache);
1548             throw;
1549         }
1550 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
1551         __deallocate_node(__cache);
1552     }
1553     for (; __first != __last; ++__first)
1554         __insert_multi(_NodeTypes::__get_value(*__first));
1557 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1558 inline
1559 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1560 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
1562     return iterator(__p1_.first().__next_);
1565 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1566 inline
1567 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1568 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
1570     return iterator(nullptr);
1573 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1574 inline
1575 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
1576 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
1578     return const_iterator(__p1_.first().__next_);
1581 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1582 inline
1583 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
1584 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
1586     return const_iterator(nullptr);
1589 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1590 void
1591 __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
1593     if (size() > 0)
1594     {
1595         __deallocate_node(__p1_.first().__next_);
1596         __p1_.first().__next_ = nullptr;
1597         size_type __bc = bucket_count();
1598         for (size_type __i = 0; __i < __bc; ++__i)
1599             __bucket_list_[__i] = nullptr;
1600         size() = 0;
1601     }
1605 // Prepare the container for an insertion of the value __value with the hash
1606 // __hash. This does a lookup into the container to see if __value is already
1607 // present, and performs a rehash if necessary. Returns a pointer to the
1608 // existing element if it exists, otherwise nullptr.
1610 // Note that this function does forward exceptions if key_eq() throws, and never
1611 // mutates __value or actually inserts into the map.
1612 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1613 _LIBCPP_INLINE_VISIBILITY
1614 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1615 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(
1616     size_t __hash, value_type& __value)
1618     size_type __bc = bucket_count();
1620     if (__bc != 0)
1621     {
1622         size_t __chash = std::__constrain_hash(__hash, __bc);
1623         __next_pointer __ndptr = __bucket_list_[__chash];
1624         if (__ndptr != nullptr)
1625         {
1626             for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
1627                     (__ndptr->__hash() == __hash ||
1628                      std::__constrain_hash(__ndptr->__hash(), __bc) == __chash);
1629                                                      __ndptr = __ndptr->__next_)
1630             {
1631                 if ((__ndptr->__hash() == __hash) &&
1632                     key_eq()(__ndptr->__upcast()->__value_, __value))
1633                     return __ndptr;
1634             }
1635         }
1636     }
1637     if (size()+1 > __bc * max_load_factor() || __bc == 0)
1638     {
1639         __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
1640                                      size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1641     }
1642     return nullptr;
1645 // Insert the node __nd into the container by pushing it into the right bucket,
1646 // and updating size(). Assumes that __nd->__hash is up-to-date, and that
1647 // rehashing has already occurred and that no element with the same key exists
1648 // in the map.
1649 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1650 _LIBCPP_INLINE_VISIBILITY
1651 void
1652 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(
1653     __node_pointer __nd) _NOEXCEPT
1655     size_type __bc = bucket_count();
1656     size_t __chash = std::__constrain_hash(__nd->__hash(), __bc);
1657     // insert_after __bucket_list_[__chash], or __first_node if bucket is null
1658     __next_pointer __pn = __bucket_list_[__chash];
1659     if (__pn == nullptr)
1660     {
1661         __pn =__p1_.first().__ptr();
1662         __nd->__next_ = __pn->__next_;
1663         __pn->__next_ = __nd->__ptr();
1664         // fix up __bucket_list_
1665         __bucket_list_[__chash] = __pn;
1666         if (__nd->__next_ != nullptr)
1667             __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr();
1668     }
1669     else
1670     {
1671         __nd->__next_ = __pn->__next_;
1672         __pn->__next_ = __nd->__ptr();
1673     }
1674     ++size();
1677 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1678 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1679 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
1681     __nd->__hash_ = hash_function()(__nd->__value_);
1682     __next_pointer __existing_node =
1683         __node_insert_unique_prepare(__nd->__hash(), __nd->__value_);
1685     // Insert the node, unless it already exists in the container.
1686     bool __inserted = false;
1687     if (__existing_node == nullptr)
1688     {
1689         __node_insert_unique_perform(__nd);
1690         __existing_node = __nd->__ptr();
1691         __inserted = true;
1692     }
1693     return pair<iterator, bool>(iterator(__existing_node), __inserted);
1696 // Prepare the container for an insertion of the value __cp_val with the hash
1697 // __cp_hash. This does a lookup into the container to see if __cp_value is
1698 // already present, and performs a rehash if necessary. Returns a pointer to the
1699 // last occurrence of __cp_val in the map.
1701 // Note that this function does forward exceptions if key_eq() throws, and never
1702 // mutates __value or actually inserts into the map.
1703 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1704 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer
1705 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(
1706     size_t __cp_hash, value_type& __cp_val)
1708     size_type __bc = bucket_count();
1709     if (size()+1 > __bc * max_load_factor() || __bc == 0)
1710     {
1711         __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
1712                        size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1713         __bc = bucket_count();
1714     }
1715     size_t __chash = std::__constrain_hash(__cp_hash, __bc);
1716     __next_pointer __pn = __bucket_list_[__chash];
1717     if (__pn != nullptr)
1718     {
1719         for (bool __found = false; __pn->__next_ != nullptr &&
1720                                    std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash;
1721                                                            __pn = __pn->__next_)
1722         {
1723             //      __found    key_eq()     action
1724             //      false       false       loop
1725             //      true        true        loop
1726             //      false       true        set __found to true
1727             //      true        false       break
1728             if (__found != (__pn->__next_->__hash() == __cp_hash &&
1729                             key_eq()(__pn->__next_->__upcast()->__value_, __cp_val)))
1730             {
1731                 if (!__found)
1732                     __found = true;
1733                 else
1734                     break;
1735             }
1736         }
1737     }
1738     return __pn;
1741 // Insert the node __cp into the container after __pn (which is the last node in
1742 // the bucket that compares equal to __cp). Rehashing, and checking for
1743 // uniqueness has already been performed (in __node_insert_multi_prepare), so
1744 // all we need to do is update the bucket and size(). Assumes that __cp->__hash
1745 // is up-to-date.
1746 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1747 void
1748 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform(
1749     __node_pointer __cp, __next_pointer __pn) _NOEXCEPT
1751     size_type __bc = bucket_count();
1752     size_t __chash = std::__constrain_hash(__cp->__hash_, __bc);
1753     if (__pn == nullptr)
1754     {
1755         __pn =__p1_.first().__ptr();
1756         __cp->__next_ = __pn->__next_;
1757         __pn->__next_ = __cp->__ptr();
1758         // fix up __bucket_list_
1759         __bucket_list_[__chash] = __pn;
1760         if (__cp->__next_ != nullptr)
1761             __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)]
1762                 = __cp->__ptr();
1763     }
1764     else
1765     {
1766         __cp->__next_ = __pn->__next_;
1767         __pn->__next_ = __cp->__ptr();
1768         if (__cp->__next_ != nullptr)
1769         {
1770             size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc);
1771             if (__nhash != __chash)
1772                 __bucket_list_[__nhash] = __cp->__ptr();
1773         }
1774     }
1775     ++size();
1779 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1780 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1781 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
1783     __cp->__hash_ = hash_function()(__cp->__value_);
1784     __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_);
1785     __node_insert_multi_perform(__cp, __pn);
1787     return iterator(__cp->__ptr());
1790 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1791 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1792 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
1793         const_iterator __p, __node_pointer __cp)
1795     if (__p != end() && key_eq()(*__p, __cp->__value_))
1796     {
1797         __next_pointer __np = __p.__node_;
1798         __cp->__hash_ = __np->__hash();
1799         size_type __bc = bucket_count();
1800         if (size()+1 > __bc * max_load_factor() || __bc == 0)
1801         {
1802             __rehash_multi(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
1803                            size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1804             __bc = bucket_count();
1805         }
1806         size_t __chash = std::__constrain_hash(__cp->__hash_, __bc);
1807         __next_pointer __pp = __bucket_list_[__chash];
1808         while (__pp->__next_ != __np)
1809             __pp = __pp->__next_;
1810         __cp->__next_ = __np;
1811         __pp->__next_ = static_cast<__next_pointer>(__cp);
1812         ++size();
1813         return iterator(static_cast<__next_pointer>(__cp));
1814     }
1815     return __node_insert_multi(__cp);
1820 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1821 template <class _Key, class ..._Args>
1822 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1823 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args)
1826     size_t __hash = hash_function()(__k);
1827     size_type __bc = bucket_count();
1828     bool __inserted = false;
1829     __next_pointer __nd;
1830     size_t __chash;
1831     if (__bc != 0)
1832     {
1833         __chash = std::__constrain_hash(__hash, __bc);
1834         __nd = __bucket_list_[__chash];
1835         if (__nd != nullptr)
1836         {
1837             for (__nd = __nd->__next_; __nd != nullptr &&
1838                 (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
1839                                                            __nd = __nd->__next_)
1840             {
1841                 if ((__nd->__hash() == __hash) &&
1842                     key_eq()(__nd->__upcast()->__value_, __k))
1843                     goto __done;
1844             }
1845         }
1846     }
1847     {
1848         __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...);
1849         if (size()+1 > __bc * max_load_factor() || __bc == 0)
1850         {
1851             __rehash_unique(_VSTD::max<size_type>(2 * __bc + !std::__is_hash_power2(__bc),
1852                            size_type(std::ceil(float(size() + 1) / max_load_factor()))));
1853             __bc = bucket_count();
1854             __chash = std::__constrain_hash(__hash, __bc);
1855         }
1856         // insert_after __bucket_list_[__chash], or __first_node if bucket is null
1857         __next_pointer __pn = __bucket_list_[__chash];
1858         if (__pn == nullptr)
1859         {
1860             __pn = __p1_.first().__ptr();
1861             __h->__next_ = __pn->__next_;
1862             __pn->__next_ = __h.get()->__ptr();
1863             // fix up __bucket_list_
1864             __bucket_list_[__chash] = __pn;
1865             if (__h->__next_ != nullptr)
1866                 __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)]
1867                     = __h.get()->__ptr();
1868         }
1869         else
1870         {
1871             __h->__next_ = __pn->__next_;
1872             __pn->__next_ = static_cast<__next_pointer>(__h.get());
1873         }
1874         __nd = static_cast<__next_pointer>(__h.release());
1875         // increment size
1876         ++size();
1877         __inserted = true;
1878     }
1879 __done:
1880     return pair<iterator, bool>(iterator(__nd), __inserted);
1883 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1884 template <class... _Args>
1885 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
1886 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args)
1888     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
1889     pair<iterator, bool> __r = __node_insert_unique(__h.get());
1890     if (__r.second)
1891         __h.release();
1892     return __r;
1895 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1896 template <class... _Args>
1897 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1898 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args)
1900     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
1901     iterator __r = __node_insert_multi(__h.get());
1902     __h.release();
1903     return __r;
1906 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1907 template <class... _Args>
1908 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1909 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
1910         const_iterator __p, _Args&&... __args)
1912     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
1913     iterator __r = __node_insert_multi(__p, __h.get());
1914     __h.release();
1915     return __r;
1918 #if _LIBCPP_STD_VER >= 17
1919 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1920 template <class _NodeHandle, class _InsertReturnType>
1921 _LIBCPP_INLINE_VISIBILITY
1922 _InsertReturnType
1923 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
1924     _NodeHandle&& __nh)
1926     if (__nh.empty())
1927         return _InsertReturnType{end(), false, _NodeHandle()};
1928     pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
1929     if (__result.second)
1930         __nh.__release_ptr();
1931     return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
1934 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1935 template <class _NodeHandle>
1936 _LIBCPP_INLINE_VISIBILITY
1937 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
1938 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
1939     const_iterator, _NodeHandle&& __nh)
1941     if (__nh.empty())
1942         return end();
1943     pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
1944     if (__result.second)
1945         __nh.__release_ptr();
1946     return __result.first;
1949 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1950 template <class _NodeHandle>
1951 _LIBCPP_INLINE_VISIBILITY
1952 _NodeHandle
1953 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
1954     key_type const& __key)
1956     iterator __i = find(__key);
1957     if (__i == end())
1958         return _NodeHandle();
1959     return __node_handle_extract<_NodeHandle>(__i);
1962 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1963 template <class _NodeHandle>
1964 _LIBCPP_INLINE_VISIBILITY
1965 _NodeHandle
1966 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
1967     const_iterator __p)
1969     allocator_type __alloc(__node_alloc());
1970     return _NodeHandle(remove(__p).release(), __alloc);
1973 template <class _Tp, class _Hash, class _Equal, class _Alloc>
1974 template <class _Table>
1975 _LIBCPP_INLINE_VISIBILITY
1976 void
1977 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(
1978     _Table& __source)
1980     static_assert(is_same<__node, typename _Table::__node>::value, "");
1982     for (typename _Table::iterator __it = __source.begin();
1983          __it != __source.end();)
1984     {
1985         __node_pointer __src_ptr = __it.__node_->__upcast();
1986         size_t __hash = hash_function()(__src_ptr->__value_);
1987         __next_pointer __existing_node =
1988             __node_insert_unique_prepare(__hash, __src_ptr->__value_);
1989         auto __prev_iter = __it++;
1990         if (__existing_node == nullptr)
1991         {
1992             (void)__source.remove(__prev_iter).release();
1993             __src_ptr->__hash_ = __hash;
1994             __node_insert_unique_perform(__src_ptr);
1995         }
1996     }
1999 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2000 template <class _NodeHandle>
2001 _LIBCPP_INLINE_VISIBILITY
2002 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2003 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
2004     _NodeHandle&& __nh)
2006     if (__nh.empty())
2007         return end();
2008     iterator __result = __node_insert_multi(__nh.__ptr_);
2009     __nh.__release_ptr();
2010     return __result;
2013 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2014 template <class _NodeHandle>
2015 _LIBCPP_INLINE_VISIBILITY
2016 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2017 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
2018     const_iterator __hint, _NodeHandle&& __nh)
2020     if (__nh.empty())
2021         return end();
2022     iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
2023     __nh.__release_ptr();
2024     return __result;
2027 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2028 template <class _Table>
2029 _LIBCPP_INLINE_VISIBILITY
2030 void
2031 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(
2032     _Table& __source)
2034     static_assert(is_same<typename _Table::__node, __node>::value, "");
2036     for (typename _Table::iterator __it = __source.begin();
2037          __it != __source.end();)
2038     {
2039         __node_pointer __src_ptr = __it.__node_->__upcast();
2040         size_t __src_hash = hash_function()(__src_ptr->__value_);
2041         __next_pointer __pn =
2042             __node_insert_multi_prepare(__src_hash, __src_ptr->__value_);
2043         (void)__source.remove(__it++).release();
2044         __src_ptr->__hash_ = __src_hash;
2045         __node_insert_multi_perform(__src_ptr, __pn);
2046     }
2048 #endif // _LIBCPP_STD_VER >= 17
2050 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2051 template <bool _UniqueKeys>
2052 void
2053 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n)
2054 _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
2056     if (__n == 1)
2057         __n = 2;
2058     else if (__n & (__n - 1))
2059         __n = std::__next_prime(__n);
2060     size_type __bc = bucket_count();
2061     if (__n > __bc)
2062         __do_rehash<_UniqueKeys>(__n);
2063     else if (__n < __bc)
2064     {
2065         __n = _VSTD::max<size_type>
2066               (
2067                   __n,
2068                   std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) :
2069                                            std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor())))
2070               );
2071         if (__n < __bc)
2072             __do_rehash<_UniqueKeys>(__n);
2073     }
2076 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2077 template <bool _UniqueKeys>
2078 void
2079 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc)
2081     __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
2082     __bucket_list_.reset(__nbc > 0 ?
2083                       __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
2084     __bucket_list_.get_deleter().size() = __nbc;
2085     if (__nbc > 0)
2086     {
2087         for (size_type __i = 0; __i < __nbc; ++__i)
2088             __bucket_list_[__i] = nullptr;
2089         __next_pointer __pp = __p1_.first().__ptr();
2090         __next_pointer __cp = __pp->__next_;
2091         if (__cp != nullptr)
2092         {
2093             size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc);
2094             __bucket_list_[__chash] = __pp;
2095             size_type __phash = __chash;
2096             for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr;
2097                                                            __cp = __pp->__next_)
2098             {
2099                 __chash = std::__constrain_hash(__cp->__hash(), __nbc);
2100                 if (__chash == __phash)
2101                     __pp = __cp;
2102                 else
2103                 {
2104                     if (__bucket_list_[__chash] == nullptr)
2105                     {
2106                         __bucket_list_[__chash] = __pp;
2107                         __pp = __cp;
2108                         __phash = __chash;
2109                     }
2110                     else
2111                     {
2112                         __next_pointer __np = __cp;
2113                         if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys)
2114                         {
2115                             for (; __np->__next_ != nullptr &&
2116                                    key_eq()(__cp->__upcast()->__value_,
2117                                             __np->__next_->__upcast()->__value_);
2118                                                                __np = __np->__next_)
2119                                 ;
2120                         }
2121                         __pp->__next_ = __np->__next_;
2122                         __np->__next_ = __bucket_list_[__chash]->__next_;
2123                         __bucket_list_[__chash]->__next_ = __cp;
2125                     }
2126                 }
2127             }
2128         }
2129     }
2132 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2133 template <class _Key>
2134 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2135 __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
2137     size_t __hash = hash_function()(__k);
2138     size_type __bc = bucket_count();
2139     if (__bc != 0)
2140     {
2141         size_t __chash = std::__constrain_hash(__hash, __bc);
2142         __next_pointer __nd = __bucket_list_[__chash];
2143         if (__nd != nullptr)
2144         {
2145             for (__nd = __nd->__next_; __nd != nullptr &&
2146                 (__nd->__hash() == __hash
2147                   || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
2148                                                            __nd = __nd->__next_)
2149             {
2150                 if ((__nd->__hash() == __hash)
2151                     && key_eq()(__nd->__upcast()->__value_, __k))
2152                     return iterator(__nd);
2153             }
2154         }
2155     }
2156     return end();
2159 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2160 template <class _Key>
2161 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
2162 __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
2164     size_t __hash = hash_function()(__k);
2165     size_type __bc = bucket_count();
2166     if (__bc != 0)
2167     {
2168         size_t __chash = std::__constrain_hash(__hash, __bc);
2169         __next_pointer __nd = __bucket_list_[__chash];
2170         if (__nd != nullptr)
2171         {
2172             for (__nd = __nd->__next_; __nd != nullptr &&
2173                 (__hash == __nd->__hash()
2174                     || std::__constrain_hash(__nd->__hash(), __bc) == __chash);
2175                                                            __nd = __nd->__next_)
2176             {
2177                 if ((__nd->__hash() == __hash)
2178                     && key_eq()(__nd->__upcast()->__value_, __k))
2179                     return const_iterator(__nd);
2180             }
2181         }
2183     }
2184     return end();
2187 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2188 template <class ..._Args>
2189 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
2190 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
2192     static_assert(!__is_hash_value_type<_Args...>::value,
2193                   "Construct cannot be called with a hash value type");
2194     __node_allocator& __na = __node_alloc();
2195     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
2196     __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
2197     __h.get_deleter().__value_constructed = true;
2198     __h->__hash_ = hash_function()(__h->__value_);
2199     __h->__next_ = nullptr;
2200     return __h;
2203 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2204 template <class _First, class ..._Rest>
2205 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
2206 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(
2207     size_t __hash, _First&& __f, _Rest&& ...__rest)
2209     static_assert(!__is_hash_value_type<_First, _Rest...>::value,
2210                   "Construct cannot be called with a hash value type");
2211     __node_allocator& __na = __node_alloc();
2212     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
2213     __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_),
2214                              _VSTD::forward<_First>(__f),
2215                              _VSTD::forward<_Rest>(__rest)...);
2216     __h.get_deleter().__value_constructed = true;
2217     __h->__hash_ = __hash;
2218     __h->__next_ = nullptr;
2219     return __h;
2222 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2223 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2224 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
2226     __next_pointer __np = __p.__node_;
2227     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(),
2228         "unordered container::erase(iterator) called with a non-dereferenceable iterator");
2229     iterator __r(__np);
2230     ++__r;
2231     remove(__p);
2232     return __r;
2235 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2236 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
2237 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
2238                                                 const_iterator __last)
2240     for (const_iterator __p = __first; __first != __last; __p = __first)
2241     {
2242         ++__first;
2243         erase(__p);
2244     }
2245     __next_pointer __np = __last.__node_;
2246     return iterator (__np);
2249 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2250 template <class _Key>
2251 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2252 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k)
2254     iterator __i = find(__k);
2255     if (__i == end())
2256         return 0;
2257     erase(__i);
2258     return 1;
2261 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2262 template <class _Key>
2263 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2264 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k)
2266     size_type __r = 0;
2267     iterator __i = find(__k);
2268     if (__i != end())
2269     {
2270         iterator __e = end();
2271         do
2272         {
2273             erase(__i++);
2274             ++__r;
2275         } while (__i != __e && key_eq()(*__i, __k));
2276     }
2277     return __r;
2280 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2281 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
2282 __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
2284     // current node
2285     __next_pointer __cn = __p.__node_;
2286     size_type __bc = bucket_count();
2287     size_t __chash = std::__constrain_hash(__cn->__hash(), __bc);
2288     // find previous node
2289     __next_pointer __pn = __bucket_list_[__chash];
2290     for (; __pn->__next_ != __cn; __pn = __pn->__next_)
2291         ;
2292     // Fix up __bucket_list_
2293         // if __pn is not in same bucket (before begin is not in same bucket) &&
2294         //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
2295     if (__pn == __p1_.first().__ptr()
2296             || std::__constrain_hash(__pn->__hash(), __bc) != __chash)
2297     {
2298         if (__cn->__next_ == nullptr
2299             || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
2300             __bucket_list_[__chash] = nullptr;
2301     }
2302         // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
2303     if (__cn->__next_ != nullptr)
2304     {
2305         size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc);
2306         if (__nhash != __chash)
2307             __bucket_list_[__nhash] = __pn;
2308     }
2309     // remove __cn
2310     __pn->__next_ = __cn->__next_;
2311     __cn->__next_ = nullptr;
2312     --size();
2313     return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true));
2316 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2317 template <class _Key>
2318 inline
2319 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2320 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const
2322     return static_cast<size_type>(find(__k) != end());
2325 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2326 template <class _Key>
2327 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2328 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const
2330     size_type __r = 0;
2331     const_iterator __i = find(__k);
2332     if (__i != end())
2333     {
2334         const_iterator __e = end();
2335         do
2336         {
2337             ++__i;
2338             ++__r;
2339         } while (__i != __e && key_eq()(*__i, __k));
2340     }
2341     return __r;
2344 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2345 template <class _Key>
2346 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
2347      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
2348 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
2349         const _Key& __k)
2351     iterator __i = find(__k);
2352     iterator __j = __i;
2353     if (__i != end())
2354         ++__j;
2355     return pair<iterator, iterator>(__i, __j);
2358 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2359 template <class _Key>
2360 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
2361      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
2362 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
2363         const _Key& __k) const
2365     const_iterator __i = find(__k);
2366     const_iterator __j = __i;
2367     if (__i != end())
2368         ++__j;
2369     return pair<const_iterator, const_iterator>(__i, __j);
2372 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2373 template <class _Key>
2374 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
2375      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
2376 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
2377         const _Key& __k)
2379     iterator __i = find(__k);
2380     iterator __j = __i;
2381     if (__i != end())
2382     {
2383         iterator __e = end();
2384         do
2385         {
2386             ++__j;
2387         } while (__j != __e && key_eq()(*__j, __k));
2388     }
2389     return pair<iterator, iterator>(__i, __j);
2392 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2393 template <class _Key>
2394 pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
2395      typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
2396 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
2397         const _Key& __k) const
2399     const_iterator __i = find(__k);
2400     const_iterator __j = __i;
2401     if (__i != end())
2402     {
2403         const_iterator __e = end();
2404         do
2405         {
2406             ++__j;
2407         } while (__j != __e && key_eq()(*__j, __k));
2408     }
2409     return pair<const_iterator, const_iterator>(__i, __j);
2412 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2413 void
2414 __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
2415 #if _LIBCPP_STD_VER <= 11
2416     _NOEXCEPT_(
2417         __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
2418         && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
2419               || __is_nothrow_swappable<__pointer_allocator>::value)
2420         && (!__node_traits::propagate_on_container_swap::value
2421               || __is_nothrow_swappable<__node_allocator>::value)
2422             )
2423 #else
2424   _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
2425 #endif
2427     _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__node_traits::propagate_on_container_swap::value ||
2428                                         this->__node_alloc() == __u.__node_alloc(),
2429                                         "unordered container::swap: Either propagate_on_container_swap "
2430                                         "must be true or the allocators must compare equal");
2431     {
2432     __node_pointer_pointer __npp = __bucket_list_.release();
2433     __bucket_list_.reset(__u.__bucket_list_.release());
2434     __u.__bucket_list_.reset(__npp);
2435     }
2436     _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
2437     _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(),
2438              __u.__bucket_list_.get_deleter().__alloc());
2439     _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc());
2440     _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
2441     __p2_.swap(__u.__p2_);
2442     __p3_.swap(__u.__p3_);
2443     if (size() > 0)
2444         __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] =
2445             __p1_.first().__ptr();
2446     if (__u.size() > 0)
2447         __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] =
2448             __u.__p1_.first().__ptr();
2451 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2452 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
2453 __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
2455     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
2456         "unordered container::bucket_size(n) called with n >= bucket_count()");
2457     __next_pointer __np = __bucket_list_[__n];
2458     size_type __bc = bucket_count();
2459     size_type __r = 0;
2460     if (__np != nullptr)
2461     {
2462         for (__np = __np->__next_; __np != nullptr &&
2463                                    std::__constrain_hash(__np->__hash(), __bc) == __n;
2464                                                          __np = __np->__next_, (void) ++__r)
2465             ;
2466     }
2467     return __r;
2470 template <class _Tp, class _Hash, class _Equal, class _Alloc>
2471 inline _LIBCPP_INLINE_VISIBILITY
2472 void
2473 swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
2474      __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)
2475     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
2477     __x.swap(__y);
2480 _LIBCPP_END_NAMESPACE_STD
2482 _LIBCPP_POP_MACROS
2484 #endif // _LIBCPP___HASH_TABLE