31#ifndef _HASHTABLE_POLICY_H
32#define _HASHTABLE_POLICY_H 1
40namespace std _GLIBCXX_VISIBILITY(default)
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
45 template<
typename _Key,
typename _Value,
typename _Alloc,
46 typename _ExtractKey,
typename _Equal,
47 typename _Hash,
typename _RangeHash,
typename _Unused,
48 typename _RehashPolicy,
typename _Traits>
58 template<
typename _Key,
typename _Value,
typename _ExtractKey,
59 typename _Equal,
typename _Hash,
typename _RangeHash,
60 typename _Unused,
typename _Traits>
61 struct _Hashtable_base;
65 template<
typename _Iterator>
67 __distance_fw(_Iterator __first, _Iterator __last,
69 {
return __first != __last ? 1 : 0; }
71 template<
typename _Iterator>
73 __distance_fw(_Iterator __first, _Iterator __last,
77 template<
typename _Iterator>
79 __distance_fw(_Iterator __first, _Iterator __last)
80 {
return __distance_fw(__first, __last,
85 template<
typename _Tp>
87 operator()(_Tp&& __x)
const noexcept
88 {
return std::forward<_Tp>(__x); }
93 template<
typename _Pair>
96 template<
typename _Tp,
typename _Up>
97 struct __1st_type<pair<_Tp, _Up>>
98 {
using type = _Tp; };
100 template<
typename _Tp,
typename _Up>
101 struct __1st_type<const pair<_Tp, _Up>>
102 {
using type =
const _Tp; };
104 template<
typename _Pair>
105 struct __1st_type<_Pair&>
106 {
using type =
typename __1st_type<_Pair>::type&; };
108 template<
typename _Tp>
109 typename __1st_type<_Tp>::type&&
110 operator()(_Tp&& __x)
const noexcept
111 {
return std::forward<_Tp>(__x).first; }
114 template<
typename _ExKey>
118 struct _NodeBuilder<_Select1st>
120 template<
typename _Kt,
typename _Arg,
typename _NodeGenerator>
122 _S_build(_Kt&& __k, _Arg&& __arg,
const _NodeGenerator& __node_gen)
123 ->
typename _NodeGenerator::__node_type*
125 return __node_gen(std::forward<_Kt>(__k),
126 std::forward<_Arg>(__arg).second);
131 struct _NodeBuilder<_Identity>
133 template<
typename _Kt,
typename _Arg,
typename _NodeGenerator>
135 _S_build(_Kt&& __k, _Arg&&,
const _NodeGenerator& __node_gen)
136 ->
typename _NodeGenerator::__node_type*
137 {
return __node_gen(std::forward<_Kt>(__k)); }
140 template<
typename _NodeAlloc>
141 struct _Hashtable_alloc;
145 template<
typename _NodeAlloc>
146 struct _ReuseOrAllocNode
149 using __node_alloc_type = _NodeAlloc;
150 using __hashtable_alloc = _Hashtable_alloc<__node_alloc_type>;
151 using __node_alloc_traits =
152 typename __hashtable_alloc::__node_alloc_traits;
155 using __node_type =
typename __hashtable_alloc::__node_type;
157 _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h)
158 : _M_nodes(__nodes), _M_h(__h) { }
159 _ReuseOrAllocNode(
const _ReuseOrAllocNode&) =
delete;
162 { _M_h._M_deallocate_nodes(_M_nodes); }
164 template<
typename... _Args>
166 operator()(_Args&&... __args)
const
170 __node_type* __node = _M_nodes;
171 _M_nodes = _M_nodes->_M_next();
172 __node->_M_nxt =
nullptr;
173 auto& __a = _M_h._M_node_allocator();
174 __node_alloc_traits::destroy(__a, __node->_M_valptr());
177 __node_alloc_traits::construct(__a, __node->_M_valptr(),
178 std::forward<_Args>(__args)...);
182 _M_h._M_deallocate_node_ptr(__node);
183 __throw_exception_again;
187 return _M_h._M_allocate_node(std::forward<_Args>(__args)...);
191 mutable __node_type* _M_nodes;
192 __hashtable_alloc& _M_h;
197 template<
typename _NodeAlloc>
201 using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>;
204 using __node_type =
typename __hashtable_alloc::__node_type;
206 _AllocNode(__hashtable_alloc& __h)
209 template<
typename... _Args>
211 operator()(_Args&&... __args)
const
212 {
return _M_h._M_allocate_node(std::forward<_Args>(__args)...); }
215 __hashtable_alloc& _M_h;
243 template<
bool _Cache_hash_code,
bool _Constant_iterators,
bool _Unique_keys>
244 struct _Hashtable_traits
246 using __hash_cached = __bool_constant<_Cache_hash_code>;
247 using __constant_iterators = __bool_constant<_Constant_iterators>;
248 using __unique_keys = __bool_constant<_Unique_keys>;
257 template<
typename _Hash>
258 struct _Hashtable_hash_traits
260 static constexpr std::size_t
261 __small_size_threshold() noexcept
262 {
return std::__is_fast_hash<_Hash>::value ? 0 : 20; }
273 struct _Hash_node_base
275 _Hash_node_base* _M_nxt;
277 _Hash_node_base() noexcept : _M_nxt() { }
279 _Hash_node_base(_Hash_node_base* __next) noexcept : _M_nxt(__next) { }
287 template<
typename _Value>
288 struct _Hash_node_value_base
290 typedef _Value value_type;
292 __gnu_cxx::__aligned_buffer<_Value> _M_storage;
296 {
return _M_storage._M_ptr(); }
299 _M_valptr() const noexcept
300 {
return _M_storage._M_ptr(); }
304 {
return *_M_valptr(); }
307 _M_v() const noexcept
308 {
return *_M_valptr(); }
314 template<
bool _Cache_hash_code>
315 struct _Hash_node_code_cache
322 struct _Hash_node_code_cache<true>
323 { std::size_t _M_hash_code; };
325 template<
typename _Value,
bool _Cache_hash_code>
326 struct _Hash_node_value
327 : _Hash_node_value_base<_Value>
328 , _Hash_node_code_cache<_Cache_hash_code>
334 template<
typename _Value,
bool _Cache_hash_code>
337 , _Hash_node_value<_Value, _Cache_hash_code>
340 _M_next() const noexcept
341 {
return static_cast<_Hash_node*
>(this->_M_nxt); }
345 template<
typename _Value,
bool _Cache_hash_code>
346 struct _Node_iterator_base
348 using __node_type = _Hash_node<_Value, _Cache_hash_code>;
352 _Node_iterator_base() : _M_cur(nullptr) { }
353 _Node_iterator_base(__node_type* __p) noexcept
358 { _M_cur = _M_cur->_M_next(); }
361 operator==(
const _Node_iterator_base& __x,
const _Node_iterator_base& __y)
363 {
return __x._M_cur == __y._M_cur; }
365#if __cpp_impl_three_way_comparison < 201907L
367 operator!=(
const _Node_iterator_base& __x,
const _Node_iterator_base& __y)
369 {
return __x._M_cur != __y._M_cur; }
374 template<
typename _Value,
bool __constant_iterators,
bool __cache>
375 struct _Node_iterator
376 :
public _Node_iterator_base<_Value, __cache>
379 using __base_type = _Node_iterator_base<_Value, __cache>;
380 using __node_type =
typename __base_type::__node_type;
383 using value_type = _Value;
384 using difference_type = std::ptrdiff_t;
387 using pointer = __conditional_t<__constant_iterators,
388 const value_type*, value_type*>;
390 using reference = __conditional_t<__constant_iterators,
391 const value_type&, value_type&>;
393 _Node_iterator() =
default;
396 _Node_iterator(__node_type* __p) noexcept
397 : __base_type(__p) { }
401 {
return this->_M_cur->_M_v(); }
404 operator->() const noexcept
405 {
return this->_M_cur->_M_valptr(); }
408 operator++() noexcept
415 operator++(
int)
noexcept
417 _Node_iterator __tmp(*
this);
424 template<
typename _Value,
bool __constant_iterators,
bool __cache>
425 struct _Node_const_iterator
426 :
public _Node_iterator_base<_Value, __cache>
429 using __base_type = _Node_iterator_base<_Value, __cache>;
430 using __node_type =
typename __base_type::__node_type;
433 typedef _Value value_type;
434 typedef std::ptrdiff_t difference_type;
437 typedef const value_type* pointer;
438 typedef const value_type& reference;
440 _Node_const_iterator() =
default;
443 _Node_const_iterator(__node_type* __p) noexcept
444 : __base_type(__p) { }
446 _Node_const_iterator(
const _Node_iterator<_Value, __constant_iterators,
447 __cache>& __x) noexcept
448 : __base_type(__x._M_cur) { }
452 {
return this->_M_cur->_M_v(); }
455 operator->() const noexcept
456 {
return this->_M_cur->_M_valptr(); }
458 _Node_const_iterator&
459 operator++() noexcept
466 operator++(
int)
noexcept
468 _Node_const_iterator __tmp(*
this);
479 struct _Mod_range_hashing
481 typedef std::size_t first_argument_type;
482 typedef std::size_t second_argument_type;
483 typedef std::size_t result_type;
486 operator()(first_argument_type __num,
487 second_argument_type __den)
const noexcept
488 {
return __num % __den; }
496 struct _Default_ranged_hash { };
500 struct _Prime_rehash_policy
504 _Prime_rehash_policy(
float __z = 1.0) noexcept
505 : _M_max_load_factor(__z), _M_next_resize(0) { }
508 max_load_factor() const noexcept
509 {
return _M_max_load_factor; }
513 _M_next_bkt(std::size_t __n)
const;
517 _M_bkt_for_elements(std::size_t __n)
const
518 {
return __builtin_ceil(__n / (
double)_M_max_load_factor); }
525 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
526 std::size_t __n_ins)
const;
528 typedef std::size_t _State;
532 {
return _M_next_resize; }
536 { _M_next_resize = 0; }
539 _M_reset(_State __state)
540 { _M_next_resize = __state; }
542 static const std::size_t _S_growth_factor = 2;
544 float _M_max_load_factor;
545 mutable std::size_t _M_next_resize;
549 struct _Mask_range_hashing
551 typedef std::size_t first_argument_type;
552 typedef std::size_t second_argument_type;
553 typedef std::size_t result_type;
556 operator()(first_argument_type __num,
557 second_argument_type __den)
const noexcept
558 {
return __num & (__den - 1); }
563 __clp2(std::size_t __n)
noexcept
569 const unsigned __lz =
sizeof(size_t) >
sizeof(
long)
570 ? __builtin_clzll(__n - 1ull)
571 : __builtin_clzl(__n - 1ul);
573 return (
size_t(1) << (__int_traits<size_t>::__digits - __lz - 1)) << 1;
578 struct _Power2_rehash_policy
582 _Power2_rehash_policy(
float __z = 1.0) noexcept
583 : _M_max_load_factor(__z), _M_next_resize(0) { }
586 max_load_factor() const noexcept
587 {
return _M_max_load_factor; }
592 _M_next_bkt(std::size_t __n)
noexcept
600 const auto __max_width = std::min<size_t>(
sizeof(
size_t), 8);
601 const auto __max_bkt = size_t(1) << (__max_width * __CHAR_BIT__ - 1);
602 std::size_t __res = __clp2(__n);
612 if (__res == __max_bkt)
616 _M_next_resize = size_t(-1);
619 = __builtin_floor(__res * (
double)_M_max_load_factor);
626 _M_bkt_for_elements(std::size_t __n)
const noexcept
627 {
return __builtin_ceil(__n / (
double)_M_max_load_factor); }
634 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
635 std::size_t __n_ins)
noexcept
637 if (__n_elt + __n_ins > _M_next_resize)
643 = std::max<std::size_t>(__n_elt + __n_ins, _M_next_resize ? 0 : 11)
644 / (double)_M_max_load_factor;
645 if (__min_bkts >= __n_bkt)
647 _M_next_bkt(std::max<std::size_t>(__builtin_floor(__min_bkts) + 1,
648 __n_bkt * _S_growth_factor)) };
651 = __builtin_floor(__n_bkt * (
double)_M_max_load_factor);
658 typedef std::size_t _State;
661 _M_state() const noexcept
662 {
return _M_next_resize; }
666 { _M_next_resize = 0; }
669 _M_reset(_State __state)
noexcept
670 { _M_next_resize = __state; }
672 static const std::size_t _S_growth_factor = 2;
674 float _M_max_load_factor;
675 std::size_t _M_next_resize;
696 template<
typename _Key,
typename _Value,
typename _Alloc,
697 typename _ExtractKey,
typename _Equal,
698 typename _Hash,
typename _RangeHash,
typename _Unused,
699 typename _RehashPolicy,
typename _Traits,
700 bool _Unique_keys = _Traits::__unique_keys::value>
701 struct _Map_base { };
704 template<
typename _Key,
typename _Val,
typename _Alloc,
typename _Equal,
705 typename _Hash,
typename _RangeHash,
typename _Unused,
706 typename _RehashPolicy,
typename _Traits>
707 struct _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
708 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>
710 using mapped_type = _Val;
714 template<
typename _Key,
typename _Val,
typename _Alloc,
typename _Equal,
715 typename _Hash,
typename _RangeHash,
typename _Unused,
716 typename _RehashPolicy,
typename _Traits>
717 struct _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
718 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>
721 using __hashtable_base = _Hashtable_base<_Key, pair<const _Key, _Val>,
722 _Select1st, _Equal, _Hash,
726 using __hashtable = _Hashtable<_Key, pair<const _Key, _Val>, _Alloc,
727 _Select1st, _Equal, _Hash, _RangeHash,
728 _Unused, _RehashPolicy, _Traits>;
730 using __hash_code =
typename __hashtable_base::__hash_code;
733 using key_type =
typename __hashtable_base::key_type;
734 using mapped_type = _Val;
737 operator[](
const key_type& __k);
740 operator[](key_type&& __k);
745 at(
const key_type& __k)
747 auto __ite =
static_cast<__hashtable*
>(
this)->find(__k);
749 __throw_out_of_range(__N(
"unordered_map::at"));
750 return __ite->second;
754 at(
const key_type& __k)
const
756 auto __ite =
static_cast<const __hashtable*
>(
this)->find(__k);
758 __throw_out_of_range(__N(
"unordered_map::at"));
759 return __ite->second;
763 template<
typename _Key,
typename _Val,
typename _Alloc,
typename _Equal,
764 typename _Hash,
typename _RangeHash,
typename _Unused,
765 typename _RehashPolicy,
typename _Traits>
767 _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
768 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
true>::
769 operator[](
const key_type& __k)
772 __hashtable* __h =
static_cast<__hashtable*
>(
this);
773 __hash_code __code = __h->_M_hash_code(__k);
774 std::size_t __bkt = __h->_M_bucket_index(__code);
775 if (
auto __node = __h->_M_find_node(__bkt, __k, __code))
776 return __node->_M_v().second;
778 typename __hashtable::_Scoped_node __node {
785 = __h->_M_insert_unique_node(__bkt, __code, __node._M_node);
786 __node._M_node =
nullptr;
787 return __pos->second;
790 template<
typename _Key,
typename _Val,
typename _Alloc,
typename _Equal,
791 typename _Hash,
typename _RangeHash,
typename _Unused,
792 typename _RehashPolicy,
typename _Traits>
794 _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal,
795 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
true>::
796 operator[](key_type&& __k)
799 __hashtable* __h =
static_cast<__hashtable*
>(
this);
800 __hash_code __code = __h->_M_hash_code(__k);
801 std::size_t __bkt = __h->_M_bucket_index(__code);
802 if (
auto __node = __h->_M_find_node(__bkt, __k, __code))
803 return __node->_M_v().second;
805 typename __hashtable::_Scoped_node __node {
812 = __h->_M_insert_unique_node(__bkt, __code, __node._M_node);
813 __node._M_node =
nullptr;
814 return __pos->second;
818 template<
typename _Key,
typename _Val,
typename _Alloc,
typename _Equal,
819 typename _Hash,
typename _RangeHash,
typename _Unused,
820 typename _RehashPolicy,
typename _Traits,
bool __uniq>
821 struct _Map_base<const _Key, pair<const _Key, _Val>,
822 _Alloc, _Select1st, _Equal, _Hash,
823 _RangeHash, _Unused, _RehashPolicy, _Traits, __uniq>
824 : _Map_base<_Key, pair<const _Key, _Val>, _Alloc, _Select1st, _Equal, _Hash,
825 _RangeHash, _Unused, _RehashPolicy, _Traits, __uniq>
833 template<
typename _Key,
typename _Value,
typename _Alloc,
834 typename _ExtractKey,
typename _Equal,
835 typename _Hash,
typename _RangeHash,
typename _Unused,
836 typename _RehashPolicy,
typename _Traits>
840 using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey,
841 _Equal, _Hash, _RangeHash,
844 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
846 _Unused, _RehashPolicy, _Traits>;
848 using __hash_cached =
typename _Traits::__hash_cached;
849 using __constant_iterators =
typename _Traits::__constant_iterators;
851 using __hashtable_alloc = _Hashtable_alloc<
852 __alloc_rebind<_Alloc, _Hash_node<_Value,
853 __hash_cached::value>>>;
855 using value_type =
typename __hashtable_base::value_type;
856 using size_type =
typename __hashtable_base::size_type;
858 using __unique_keys =
typename _Traits::__unique_keys;
859 using __node_alloc_type =
typename __hashtable_alloc::__node_alloc_type;
860 using __node_gen_type = _AllocNode<__node_alloc_type>;
863 _M_conjure_hashtable()
864 {
return *(
static_cast<__hashtable*
>(
this)); }
866 template<
typename _InputIterator,
typename _NodeGetter>
868 _M_insert_range(_InputIterator __first, _InputIterator __last,
869 const _NodeGetter&, true_type __uks);
871 template<
typename _InputIterator,
typename _NodeGetter>
873 _M_insert_range(_InputIterator __first, _InputIterator __last,
874 const _NodeGetter&, false_type __uks);
877 using iterator = _Node_iterator<_Value, __constant_iterators::value,
878 __hash_cached::value>;
880 using const_iterator = _Node_const_iterator<_Value,
881 __constant_iterators::value,
882 __hash_cached::value>;
884 using __ireturn_type = __conditional_t<__unique_keys::value,
889 insert(
const value_type& __v)
891 __hashtable& __h = _M_conjure_hashtable();
892 __node_gen_type __node_gen(__h);
893 return __h._M_insert(__v, __node_gen, __unique_keys{});
897 insert(const_iterator __hint,
const value_type& __v)
899 __hashtable& __h = _M_conjure_hashtable();
900 __node_gen_type __node_gen(__h);
901 return __h._M_insert(__hint, __v, __node_gen, __unique_keys{});
904 template<
typename _KType,
typename... _Args>
906 try_emplace(const_iterator, _KType&& __k, _Args&&... __args)
908 __hashtable& __h = _M_conjure_hashtable();
909 auto __code = __h._M_hash_code(__k);
910 std::size_t __bkt = __h._M_bucket_index(__code);
911 if (
auto __node = __h._M_find_node(__bkt, __k, __code))
912 return { iterator(__node),
false };
914 typename __hashtable::_Scoped_node __node {
921 = __h._M_insert_unique_node(__bkt, __code, __node._M_node);
922 __node._M_node =
nullptr;
923 return { __it,
true };
927 insert(initializer_list<value_type> __l)
928 { this->insert(__l.begin(), __l.end()); }
930 template<
typename _InputIterator>
932 insert(_InputIterator __first, _InputIterator __last)
934 __hashtable& __h = _M_conjure_hashtable();
935 __node_gen_type __node_gen(__h);
936 return _M_insert_range(__first, __last, __node_gen, __unique_keys{});
940 template<
typename _Key,
typename _Value,
typename _Alloc,
941 typename _ExtractKey,
typename _Equal,
942 typename _Hash,
typename _RangeHash,
typename _Unused,
943 typename _RehashPolicy,
typename _Traits>
944 template<
typename _InputIterator,
typename _NodeGetter>
946 _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
947 _Hash, _RangeHash, _Unused,
948 _RehashPolicy, _Traits>::
949 _M_insert_range(_InputIterator __first, _InputIterator __last,
950 const _NodeGetter& __node_gen,
true_type __uks)
952 __hashtable& __h = _M_conjure_hashtable();
953 for (; __first != __last; ++__first)
954 __h._M_insert(*__first, __node_gen, __uks);
957 template<
typename _Key,
typename _Value,
typename _Alloc,
958 typename _ExtractKey,
typename _Equal,
959 typename _Hash,
typename _RangeHash,
typename _Unused,
960 typename _RehashPolicy,
typename _Traits>
961 template<
typename _InputIterator,
typename _NodeGetter>
963 _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
964 _Hash, _RangeHash, _Unused,
965 _RehashPolicy, _Traits>::
966 _M_insert_range(_InputIterator __first, _InputIterator __last,
967 const _NodeGetter& __node_gen,
false_type __uks)
969 using __rehash_type =
typename __hashtable::__rehash_type;
970 using __rehash_state =
typename __hashtable::__rehash_state;
973 size_type __n_elt = __detail::__distance_fw(__first, __last);
977 __hashtable& __h = _M_conjure_hashtable();
978 __rehash_type& __rehash = __h._M_rehash_policy;
979 const __rehash_state& __saved_state = __rehash._M_state();
980 pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
981 __h._M_element_count,
984 if (__do_rehash.first)
985 __h._M_rehash(__do_rehash.second, __saved_state);
987 for (; __first != __last; ++__first)
988 __h._M_insert(*__first, __node_gen, __uks);
997 template<
typename _Key,
typename _Value,
typename _Alloc,
998 typename _ExtractKey,
typename _Equal,
999 typename _Hash,
typename _RangeHash,
typename _Unused,
1000 typename _RehashPolicy,
typename _Traits,
1001 bool _Constant_iterators = _Traits::__constant_iterators::value>
1005 template<
typename _Key,
typename _Value,
typename _Alloc,
1006 typename _ExtractKey,
typename _Equal,
1007 typename _Hash,
typename _RangeHash,
typename _Unused,
1008 typename _RehashPolicy,
typename _Traits>
1009 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1010 _Hash, _RangeHash, _Unused,
1011 _RehashPolicy, _Traits, true>
1012 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1013 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>
1015 using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
1016 _Equal, _Hash, _RangeHash, _Unused,
1017 _RehashPolicy, _Traits>;
1019 using value_type =
typename __base_type::value_type;
1020 using iterator =
typename __base_type::iterator;
1021 using const_iterator =
typename __base_type::const_iterator;
1022 using __ireturn_type =
typename __base_type::__ireturn_type;
1024 using __unique_keys =
typename __base_type::__unique_keys;
1025 using __hashtable =
typename __base_type::__hashtable;
1026 using __node_gen_type =
typename __base_type::__node_gen_type;
1028 using __base_type::insert;
1031 insert(value_type&& __v)
1033 __hashtable& __h = this->_M_conjure_hashtable();
1034 __node_gen_type __node_gen(__h);
1035 return __h._M_insert(
std::move(__v), __node_gen, __unique_keys{});
1039 insert(const_iterator __hint, value_type&& __v)
1041 __hashtable& __h = this->_M_conjure_hashtable();
1042 __node_gen_type __node_gen(__h);
1043 return __h._M_insert(__hint,
std::move(__v), __node_gen,
1049 template<
typename _Key,
typename _Value,
typename _Alloc,
1050 typename _ExtractKey,
typename _Equal,
1051 typename _Hash,
typename _RangeHash,
typename _Unused,
1052 typename _RehashPolicy,
typename _Traits>
1053 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1054 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>
1055 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1056 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>
1058 using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
1059 _Equal, _Hash, _RangeHash, _Unused,
1060 _RehashPolicy, _Traits>;
1061 using value_type =
typename __base_type::value_type;
1062 using iterator =
typename __base_type::iterator;
1063 using const_iterator =
typename __base_type::const_iterator;
1065 using __unique_keys =
typename __base_type::__unique_keys;
1066 using __hashtable =
typename __base_type::__hashtable;
1067 using __ireturn_type =
typename __base_type::__ireturn_type;
1069 using __base_type::insert;
1071 template<
typename _Pair>
1074 template<
typename _Pair>
1077 template<
typename _Pair>
1078 using _IFconsp =
typename _IFcons<_Pair>::type;
1080 template<
typename _Pair,
typename = _IFconsp<_Pair>>
1084 __hashtable& __h = this->_M_conjure_hashtable();
1085 return __h._M_emplace(__unique_keys{}, std::forward<_Pair>(__v));
1088 template<
typename _Pair,
typename = _IFconsp<_Pair>>
1090 insert(const_iterator __hint, _Pair&& __v)
1092 __hashtable& __h = this->_M_conjure_hashtable();
1093 return __h._M_emplace(__hint, __unique_keys{},
1094 std::forward<_Pair>(__v));
1098 template<
typename _Policy>
1099 using __has_load_factor =
typename _Policy::__has_load_factor;
1107 template<
typename _Key,
typename _Value,
typename _Alloc,
1108 typename _ExtractKey,
typename _Equal,
1109 typename _Hash,
typename _RangeHash,
typename _Unused,
1110 typename _RehashPolicy,
typename _Traits,
1112 __detected_or_t<false_type, __has_load_factor, _RehashPolicy>>
1113 struct _Rehash_base;
1116 template<
typename _Key,
typename _Value,
typename _Alloc,
1117 typename _ExtractKey,
typename _Equal,
1118 typename _Hash,
typename _RangeHash,
typename _Unused,
1119 typename _RehashPolicy,
typename _Traits>
1120 struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1121 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
1127 template<
typename _Key,
typename _Value,
typename _Alloc,
1128 typename _ExtractKey,
typename _Equal,
1129 typename _Hash,
typename _RangeHash,
typename _Unused,
1130 typename _RehashPolicy,
typename _Traits>
1131 struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1132 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
1136 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
1137 _Equal, _Hash, _RangeHash, _Unused,
1138 _RehashPolicy, _Traits>;
1142 max_load_factor() const noexcept
1144 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1145 return __this->__rehash_policy().max_load_factor();
1149 max_load_factor(
float __z)
1151 __hashtable* __this =
static_cast<__hashtable*
>(
this);
1152 __this->__rehash_policy(_RehashPolicy(__z));
1156 reserve(std::size_t __n)
1158 __hashtable* __this =
static_cast<__hashtable*
>(
this);
1159 __this->rehash(__this->__rehash_policy()._M_bkt_for_elements(__n));
1169 template<
int _Nm,
typename _Tp,
1170 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
1171 struct _Hashtable_ebo_helper;
1174 template<
int _Nm,
typename _Tp>
1175 struct _Hashtable_ebo_helper<_Nm, _Tp, true>
1178 _Hashtable_ebo_helper() noexcept(noexcept(_Tp())) : _Tp() { }
1180 template<
typename _OtherTp>
1181 _Hashtable_ebo_helper(_OtherTp&& __tp)
1185 const _Tp& _M_cget()
const {
return static_cast<const _Tp&
>(*this); }
1186 _Tp& _M_get() {
return static_cast<_Tp&
>(*this); }
1190 template<
int _Nm,
typename _Tp>
1191 struct _Hashtable_ebo_helper<_Nm, _Tp, false>
1193 _Hashtable_ebo_helper() =
default;
1195 template<
typename _OtherTp>
1196 _Hashtable_ebo_helper(_OtherTp&& __tp)
1200 const _Tp& _M_cget()
const {
return _M_tp; }
1201 _Tp& _M_get() {
return _M_tp; }
1213 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1214 typename _Hash,
typename _RangeHash,
typename _Unused,
1215 bool __cache_hash_code>
1216 struct _Local_iterator_base;
1236 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1237 typename _Hash,
typename _RangeHash,
typename _Unused,
1238 bool __cache_hash_code>
1239 struct _Hash_code_base
1240 :
private _Hashtable_ebo_helper<1, _Hash>
1243 using __ebo_hash = _Hashtable_ebo_helper<1, _Hash>;
1246 friend struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1247 _Hash, _RangeHash, _Unused, false>;
1250 typedef _Hash hasher;
1253 hash_function()
const
1254 {
return _M_hash(); }
1257 typedef std::size_t __hash_code;
1261 _Hash_code_base() =
default;
1263 _Hash_code_base(
const _Hash& __hash) : __ebo_hash(__hash) { }
1266 _M_hash_code(
const _Key& __k)
const
1268 static_assert(__is_invocable<const _Hash&, const _Key&>{},
1269 "hash function must be invocable with an argument of key type");
1270 return _M_hash()(__k);
1273 template<
typename _Kt>
1275 _M_hash_code_tr(
const _Kt& __k)
const
1277 static_assert(__is_invocable<const _Hash&, const _Kt&>{},
1278 "hash function must be invocable with an argument of key type");
1279 return _M_hash()(__k);
1283 _M_hash_code(
const _Hash&,
1284 const _Hash_node_value<_Value, true>& __n)
const
1285 {
return __n._M_hash_code; }
1289 template<
typename _H2>
1291 _M_hash_code(
const _H2&,
1292 const _Hash_node_value<_Value, __cache_hash_code>& __n)
const
1293 {
return _M_hash_code(_ExtractKey{}(__n._M_v())); }
1296 _M_hash_code(
const _Hash_node_value<_Value, false>& __n)
const
1297 {
return _M_hash_code(_ExtractKey{}(__n._M_v())); }
1300 _M_hash_code(
const _Hash_node_value<_Value, true>& __n)
const
1301 {
return __n._M_hash_code; }
1304 _M_bucket_index(__hash_code __c, std::size_t __bkt_count)
const
1305 {
return _RangeHash{}(__c, __bkt_count); }
1308 _M_bucket_index(
const _Hash_node_value<_Value, false>& __n,
1309 std::size_t __bkt_count)
const
1310 noexcept(
noexcept(declval<const _Hash&>()(declval<const _Key&>()))
1311 &&
noexcept(declval<const _RangeHash&>()((__hash_code)0,
1314 return _RangeHash{}(_M_hash_code(_ExtractKey{}(__n._M_v())),
1319 _M_bucket_index(
const _Hash_node_value<_Value, true>& __n,
1320 std::size_t __bkt_count)
const
1321 noexcept(
noexcept(declval<const _RangeHash&>()((__hash_code)0,
1323 {
return _RangeHash{}(__n._M_hash_code, __bkt_count); }
1326 _M_store_code(_Hash_node_code_cache<false>&, __hash_code)
const
1330 _M_copy_code(_Hash_node_code_cache<false>&,
1331 const _Hash_node_code_cache<false>&)
const
1335 _M_store_code(_Hash_node_code_cache<true>& __n, __hash_code __c)
const
1336 { __n._M_hash_code = __c; }
1339 _M_copy_code(_Hash_node_code_cache<true>& __to,
1340 const _Hash_node_code_cache<true>& __from)
const
1341 { __to._M_hash_code = __from._M_hash_code; }
1344 _M_swap(_Hash_code_base& __x)
1345 {
std::swap(__ebo_hash::_M_get(), __x.__ebo_hash::_M_get()); }
1348 _M_hash()
const {
return __ebo_hash::_M_cget(); }
1352 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1353 typename _Hash,
typename _RangeHash,
typename _Unused>
1354 struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1355 _Hash, _RangeHash, _Unused, true>
1356 :
public _Node_iterator_base<_Value, true>
1359 using __base_node_iter = _Node_iterator_base<_Value, true>;
1360 using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1361 _Hash, _RangeHash, _Unused,
true>;
1363 _Local_iterator_base() =
default;
1364 _Local_iterator_base(
const __hash_code_base&,
1365 _Hash_node<_Value, true>* __p,
1366 std::size_t __bkt, std::size_t __bkt_count)
1367 : __base_node_iter(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
1373 __base_node_iter::_M_incr();
1377 = _RangeHash{}(this->_M_cur->_M_hash_code, _M_bucket_count);
1378 if (__bkt != _M_bucket)
1379 this->_M_cur =
nullptr;
1383 std::size_t _M_bucket;
1384 std::size_t _M_bucket_count;
1388 _M_get_bucket()
const {
return _M_bucket; }
1395 template<typename _Tp, bool _IsEmpty = std::is_empty<_Tp>::value>
1396 struct _Hash_code_storage
1398 __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
1401 _M_h() {
return _M_storage._M_ptr(); }
1404 _M_h()
const {
return _M_storage._M_ptr(); }
1408 template<
typename _Tp>
1409 struct _Hash_code_storage<_Tp, true>
1416 _M_h() {
return reinterpret_cast<_Tp*
>(
this); }
1419 _M_h()
const {
return reinterpret_cast<const _Tp*
>(
this); }
1422 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1423 typename _Hash,
typename _RangeHash,
typename _Unused>
1424 using __hash_code_for_local_iter
1425 = _Hash_code_storage<_Hash_code_base<_Key, _Value, _ExtractKey,
1426 _Hash, _RangeHash, _Unused,
false>>;
1429 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1430 typename _Hash,
typename _RangeHash,
typename _Unused>
1431 struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1432 _Hash, _RangeHash, _Unused, false>
1433 : __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _Hash, _RangeHash,
1435 , _Node_iterator_base<_Value, false>
1438 using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1439 _Hash, _RangeHash, _Unused,
false>;
1440 using __node_iter_base = _Node_iterator_base<_Value, false>;
1442 _Local_iterator_base() : _M_bucket_count(-1) { }
1444 _Local_iterator_base(
const __hash_code_base& __base,
1445 _Hash_node<_Value, false>* __p,
1446 std::size_t __bkt, std::size_t __bkt_count)
1447 : __node_iter_base(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
1448 { _M_init(__base); }
1450 ~_Local_iterator_base()
1452 if (_M_bucket_count !=
size_t(-1))
1456 _Local_iterator_base(
const _Local_iterator_base& __iter)
1457 : __node_iter_base(__iter._M_cur), _M_bucket(__iter._M_bucket)
1458 , _M_bucket_count(__iter._M_bucket_count)
1460 if (_M_bucket_count !=
size_t(-1))
1461 _M_init(*__iter._M_h());
1464 _Local_iterator_base&
1465 operator=(
const _Local_iterator_base& __iter)
1467 if (_M_bucket_count != -1)
1469 this->_M_cur = __iter._M_cur;
1470 _M_bucket = __iter._M_bucket;
1471 _M_bucket_count = __iter._M_bucket_count;
1472 if (_M_bucket_count != -1)
1473 _M_init(*__iter._M_h());
1480 __node_iter_base::_M_incr();
1483 std::size_t __bkt = this->_M_h()->_M_bucket_index(*this->_M_cur,
1485 if (__bkt != _M_bucket)
1486 this->_M_cur =
nullptr;
1490 std::size_t _M_bucket;
1491 std::size_t _M_bucket_count;
1494 _M_init(
const __hash_code_base& __base)
1495 { ::new(this->_M_h()) __hash_code_base(__base); }
1498 _M_destroy() { this->_M_h()->~__hash_code_base(); }
1502 _M_get_bucket()
const {
return _M_bucket; }
1506 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1507 typename _Hash,
typename _RangeHash,
typename _Unused,
1508 bool __constant_iterators,
bool __cache>
1509 struct _Local_iterator
1510 :
public _Local_iterator_base<_Key, _Value, _ExtractKey,
1511 _Hash, _RangeHash, _Unused, __cache>
1514 using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1515 _Hash, _RangeHash, _Unused, __cache>;
1516 using __hash_code_base =
typename __base_type::__hash_code_base;
1519 using value_type = _Value;
1520 using pointer = __conditional_t<__constant_iterators,
1521 const value_type*, value_type*>;
1522 using reference = __conditional_t<__constant_iterators,
1523 const value_type&, value_type&>;
1524 using difference_type = ptrdiff_t;
1525 using iterator_category = forward_iterator_tag;
1527 _Local_iterator() =
default;
1529 _Local_iterator(
const __hash_code_base& __base,
1530 _Hash_node<_Value, __cache>* __n,
1531 std::size_t __bkt, std::size_t __bkt_count)
1532 : __base_type(
__base, __n, __bkt, __bkt_count)
1537 {
return this->_M_cur->_M_v(); }
1541 {
return this->_M_cur->_M_valptr(); }
1553 _Local_iterator __tmp(*
this);
1560 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1561 typename _Hash,
typename _RangeHash,
typename _Unused,
1562 bool __constant_iterators,
bool __cache>
1563 struct _Local_const_iterator
1564 :
public _Local_iterator_base<_Key, _Value, _ExtractKey,
1565 _Hash, _RangeHash, _Unused, __cache>
1568 using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1569 _Hash, _RangeHash, _Unused, __cache>;
1570 using __hash_code_base =
typename __base_type::__hash_code_base;
1573 typedef _Value value_type;
1574 typedef const value_type* pointer;
1575 typedef const value_type& reference;
1576 typedef std::ptrdiff_t difference_type;
1579 _Local_const_iterator() =
default;
1581 _Local_const_iterator(
const __hash_code_base& __base,
1582 _Hash_node<_Value, __cache>* __n,
1583 std::size_t __bkt, std::size_t __bkt_count)
1584 : __base_type(
__base, __n, __bkt, __bkt_count)
1587 _Local_const_iterator(
const _Local_iterator<_Key, _Value, _ExtractKey,
1588 _Hash, _RangeHash, _Unused,
1589 __constant_iterators,
1596 {
return this->_M_cur->_M_v(); }
1600 {
return this->_M_cur->_M_valptr(); }
1602 _Local_const_iterator&
1609 _Local_const_iterator
1612 _Local_const_iterator __tmp(*
this);
1628 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1629 typename _Equal,
typename _Hash,
typename _RangeHash,
1630 typename _Unused,
typename _Traits>
1631 struct _Hashtable_base
1632 :
public _Hash_code_base<_Key, _Value, _ExtractKey, _Hash, _RangeHash,
1633 _Unused, _Traits::__hash_cached::value>,
1634 private _Hashtable_ebo_helper<0, _Equal>
1637 typedef _Key key_type;
1638 typedef _Value value_type;
1639 typedef _Equal key_equal;
1640 typedef std::size_t size_type;
1641 typedef std::ptrdiff_t difference_type;
1643 using __traits_type = _Traits;
1644 using __hash_cached =
typename __traits_type::__hash_cached;
1646 using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1647 _Hash, _RangeHash, _Unused,
1648 __hash_cached::value>;
1650 using __hash_code =
typename __hash_code_base::__hash_code;
1653 using _EqualEBO = _Hashtable_ebo_helper<0, _Equal>;
1656 _S_equals(__hash_code,
const _Hash_node_code_cache<false>&)
1660 _S_node_equals(
const _Hash_node_code_cache<false>&,
1661 const _Hash_node_code_cache<false>&)
1665 _S_equals(__hash_code __c,
const _Hash_node_code_cache<true>& __n)
1666 {
return __c == __n._M_hash_code; }
1669 _S_node_equals(
const _Hash_node_code_cache<true>& __lhn,
1670 const _Hash_node_code_cache<true>& __rhn)
1671 {
return __lhn._M_hash_code == __rhn._M_hash_code; }
1674 _Hashtable_base() =
default;
1676 _Hashtable_base(
const _Hash& __hash,
const _Equal& __eq)
1677 : __hash_code_base(__hash), _EqualEBO(__eq)
1681 _M_key_equals(
const _Key& __k,
1682 const _Hash_node_value<_Value,
1683 __hash_cached::value>& __n)
const
1685 static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
1686 "key equality predicate must be invocable with two arguments of "
1688 return _M_eq()(__k, _ExtractKey{}(__n._M_v()));
1691 template<
typename _Kt>
1693 _M_key_equals_tr(
const _Kt& __k,
1694 const _Hash_node_value<_Value,
1695 __hash_cached::value>& __n)
const
1698 __is_invocable<const _Equal&, const _Kt&, const _Key&>{},
1699 "key equality predicate must be invocable with two arguments of "
1701 return _M_eq()(__k, _ExtractKey{}(__n._M_v()));
1705 _M_equals(
const _Key& __k, __hash_code __c,
1706 const _Hash_node_value<_Value, __hash_cached::value>& __n)
const
1707 {
return _S_equals(__c, __n) && _M_key_equals(__k, __n); }
1709 template<
typename _Kt>
1711 _M_equals_tr(
const _Kt& __k, __hash_code __c,
1712 const _Hash_node_value<_Value,
1713 __hash_cached::value>& __n)
const
1714 {
return _S_equals(__c, __n) && _M_key_equals_tr(__k, __n); }
1718 const _Hash_node_value<_Value, __hash_cached::value>& __lhn,
1719 const _Hash_node_value<_Value, __hash_cached::value>& __rhn)
const
1721 return _S_node_equals(__lhn, __rhn)
1722 && _M_key_equals(_ExtractKey{}(__lhn._M_v()), __rhn);
1726 _M_swap(_Hashtable_base& __x)
1728 __hash_code_base::_M_swap(__x);
1729 std::swap(_EqualEBO::_M_get(), __x._EqualEBO::_M_get());
1733 _M_eq()
const {
return _EqualEBO::_M_cget(); }
1744 template<
typename _Key,
typename _Value,
typename _Alloc,
1745 typename _ExtractKey,
typename _Equal,
1746 typename _Hash,
typename _RangeHash,
typename _Unused,
1747 typename _RehashPolicy,
typename _Traits,
1748 bool _Unique_keys = _Traits::__unique_keys::value>
1752 template<
typename _Key,
typename _Value,
typename _Alloc,
1753 typename _ExtractKey,
typename _Equal,
1754 typename _Hash,
typename _RangeHash,
typename _Unused,
1755 typename _RehashPolicy,
typename _Traits>
1756 struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1757 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>
1759 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1760 _Hash, _RangeHash, _Unused,
1761 _RehashPolicy, _Traits>;
1764 _M_equal(
const __hashtable&)
const;
1767 template<
typename _Key,
typename _Value,
typename _Alloc,
1768 typename _ExtractKey,
typename _Equal,
1769 typename _Hash,
typename _RangeHash,
typename _Unused,
1770 typename _RehashPolicy,
typename _Traits>
1772 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1773 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
true>::
1774 _M_equal(
const __hashtable& __other)
const
1776 using __node_type =
typename __hashtable::__node_type;
1777 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1778 if (__this->size() != __other.size())
1781 for (
auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1783 std::size_t __ybkt = __other._M_bucket_index(*__itx._M_cur);
1784 auto __prev_n = __other._M_buckets[__ybkt];
1788 for (__node_type* __n =
static_cast<__node_type*
>(__prev_n->_M_nxt);;
1789 __n = __n->_M_next())
1791 if (__n->_M_v() == *__itx)
1795 || __other._M_bucket_index(*__n->_M_next()) != __ybkt)
1804 template<
typename _Key,
typename _Value,
typename _Alloc,
1805 typename _ExtractKey,
typename _Equal,
1806 typename _Hash,
typename _RangeHash,
typename _Unused,
1807 typename _RehashPolicy,
typename _Traits>
1808 struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1809 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>
1811 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1812 _Hash, _RangeHash, _Unused,
1813 _RehashPolicy, _Traits>;
1816 _M_equal(
const __hashtable&)
const;
1819 template<
typename _Key,
typename _Value,
typename _Alloc,
1820 typename _ExtractKey,
typename _Equal,
1821 typename _Hash,
typename _RangeHash,
typename _Unused,
1822 typename _RehashPolicy,
typename _Traits>
1824 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1825 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits,
false>::
1826 _M_equal(
const __hashtable& __other)
const
1828 using __node_type =
typename __hashtable::__node_type;
1829 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1830 if (__this->size() != __other.size())
1833 for (
auto __itx = __this->begin(); __itx != __this->end();)
1835 std::size_t __x_count = 1;
1836 auto __itx_end = __itx;
1837 for (++__itx_end; __itx_end != __this->end()
1838 && __this->key_eq()(_ExtractKey{}(*__itx),
1839 _ExtractKey{}(*__itx_end));
1843 std::size_t __ybkt = __other._M_bucket_index(*__itx._M_cur);
1844 auto __y_prev_n = __other._M_buckets[__ybkt];
1848 __node_type* __y_n =
static_cast<__node_type*
>(__y_prev_n->_M_nxt);
1851 if (__this->key_eq()(_ExtractKey{}(__y_n->_M_v()),
1852 _ExtractKey{}(*__itx)))
1855 auto __y_ref_n = __y_n;
1856 for (__y_n = __y_n->_M_next(); __y_n; __y_n = __y_n->_M_next())
1857 if (!__other._M_node_equals(*__y_ref_n, *__y_n))
1860 if (!__y_n || __other._M_bucket_index(*__y_n) != __ybkt)
1864 typename __hashtable::const_iterator __ity(__y_n);
1865 for (
auto __ity_end = __ity; __ity_end != __other.end(); ++__ity_end)
1866 if (--__x_count == 0)
1872 if (!std::is_permutation(__itx, __itx_end, __ity))
1884 template<
typename _NodeAlloc>
1885 struct _Hashtable_alloc :
private _Hashtable_ebo_helper<0, _NodeAlloc>
1888 using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>;
1891 struct __get_value_type;
1892 template<
typename _Val,
bool _Cache_hash_code>
1893 struct __get_value_type<_Hash_node<_Val, _Cache_hash_code>>
1894 {
using type = _Val; };
1897 using __node_type =
typename _NodeAlloc::value_type;
1898 using __node_alloc_type = _NodeAlloc;
1902 using __value_alloc_traits =
typename __node_alloc_traits::template
1903 rebind_traits<typename __get_value_type<__node_type>::type>;
1905 using __node_ptr = __node_type*;
1906 using __node_base = _Hash_node_base;
1907 using __node_base_ptr = __node_base*;
1908 using __buckets_alloc_type =
1909 __alloc_rebind<__node_alloc_type, __node_base_ptr>;
1911 using __buckets_ptr = __node_base_ptr*;
1913 _Hashtable_alloc() =
default;
1914 _Hashtable_alloc(
const _Hashtable_alloc&) =
default;
1915 _Hashtable_alloc(_Hashtable_alloc&&) =
default;
1917 template<
typename _Alloc>
1918 _Hashtable_alloc(_Alloc&& __a)
1919 : __ebo_node_alloc(
std::
forward<_Alloc>(__a))
1924 {
return __ebo_node_alloc::_M_get(); }
1926 const __node_alloc_type&
1927 _M_node_allocator()
const
1928 {
return __ebo_node_alloc::_M_cget(); }
1931 template<
typename... _Args>
1933 _M_allocate_node(_Args&&... __args);
1937 _M_deallocate_node(__node_ptr __n);
1941 _M_deallocate_node_ptr(__node_ptr __n);
1946 _M_deallocate_nodes(__node_ptr __n);
1949 _M_allocate_buckets(std::size_t __bkt_count);
1952 _M_deallocate_buckets(__buckets_ptr, std::size_t __bkt_count);
1957 template<
typename _NodeAlloc>
1958 template<
typename... _Args>
1960 _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
1963 auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
1964 __node_ptr __n = std::__to_address(__nptr);
1967 ::new ((
void*)__n) __node_type;
1968 __node_alloc_traits::construct(_M_node_allocator(),
1970 std::forward<_Args>(__args)...);
1975 __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
1976 __throw_exception_again;
1980 template<
typename _NodeAlloc>
1982 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_ptr __n)
1984 __node_alloc_traits::destroy(_M_node_allocator(), __n->_M_valptr());
1985 _M_deallocate_node_ptr(__n);
1988 template<
typename _NodeAlloc>
1990 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node_ptr(__node_ptr __n)
1992 typedef typename __node_alloc_traits::pointer _Ptr;
1994 __n->~__node_type();
1995 __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
1998 template<
typename _NodeAlloc>
2000 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_ptr __n)
2004 __node_ptr __tmp = __n;
2005 __n = __n->_M_next();
2006 _M_deallocate_node(__tmp);
2010 template<
typename _NodeAlloc>
2012 _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __bkt_count)
2015 __buckets_alloc_type __alloc(_M_node_allocator());
2017 auto __ptr = __buckets_alloc_traits::allocate(__alloc, __bkt_count);
2018 __buckets_ptr __p = std::__to_address(__ptr);
2019 __builtin_memset(__p, 0, __bkt_count *
sizeof(__node_base_ptr));
2023 template<
typename _NodeAlloc>
2025 _Hashtable_alloc<_NodeAlloc>::
2026 _M_deallocate_buckets(__buckets_ptr __bkts,
2027 std::size_t __bkt_count)
2029 typedef typename __buckets_alloc_traits::pointer _Ptr;
2031 __buckets_alloc_type __alloc(_M_node_allocator());
2032 __buckets_alloc_traits::deallocate(__alloc, __ptr, __bkt_count);
2038_GLIBCXX_END_NAMESPACE_VERSION
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
constexpr tuple< _Elements &&... > forward_as_tuple(_Elements &&... __args) noexcept
std::forward_as_tuple
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr piecewise_construct_t piecewise_construct
Tag for piecewise construction of std::pair objects.
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
constexpr iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
ISO C++ entities toplevel namespace is std.
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
__numeric_traits_integer< _Tp > __int_traits
Convenience alias for __numeric_traits<integer-type>.
constexpr _Iterator __base(_Iterator __it)
Primary class template, tuple.
Define a member typedef type only if a boolean constant is true.
Uniform interface to all allocator types.
Traits class for iterators.
Uniform interface to all pointer-like types.
Struct holding two objects of arbitrary type.
Forward iterators support a superset of input iterator operations.
Uniform interface to C++98 and C++11 allocators.