31 #define _HASHTABLE_H 1 33 #pragma GCC system_header 37 namespace std _GLIBCXX_VISIBILITY(default)
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
41 template<
typename _Tp,
typename _Hash>
44 __is_fast_hash<_Hash>,
46 __detail::__is_noexcept_hash<_Tp, _Hash>>>;
166 template<
typename _Key,
typename _Value,
typename _Alloc,
167 typename _ExtractKey,
typename _Equal,
168 typename _H1,
typename _H2,
typename _Hash,
169 typename _RehashPolicy,
typename _Traits>
172 _H1, _H2, _Hash, _Traits>,
174 _H1, _H2, _Hash, _RehashPolicy, _Traits>,
176 _H1, _H2, _Hash, _RehashPolicy, _Traits>,
178 _H1, _H2, _Hash, _RehashPolicy, _Traits>,
180 _H1, _H2, _Hash, _RehashPolicy, _Traits>,
182 __alloc_rebind<_Alloc,
183 __detail::_Hash_node<_Value,
184 _Traits::__hash_cached::value>>>
186 using __traits_type = _Traits;
187 using __hash_cached =
typename __traits_type::__hash_cached;
189 using __node_alloc_type = __alloc_rebind<_Alloc, __node_type>;
193 using __value_alloc_traits =
195 using __node_alloc_traits =
201 typedef _Key key_type;
202 typedef _Value value_type;
203 typedef _Alloc allocator_type;
204 typedef _Equal key_equal;
208 typedef typename __value_alloc_traits::pointer pointer;
209 typedef typename __value_alloc_traits::const_pointer const_pointer;
210 typedef value_type& reference;
211 typedef const value_type& const_reference;
214 using __rehash_type = _RehashPolicy;
215 using __rehash_state =
typename __rehash_type::_State;
217 using __constant_iterators =
typename __traits_type::__constant_iterators;
218 using __unique_keys =
typename __traits_type::__unique_keys;
220 using __key_extract =
typename std::conditional<
221 __constant_iterators::value,
223 __detail::_Select1st>::type;
226 _Hashtable_base<_Key, _Value, _ExtractKey,
227 _Equal, _H1, _H2, _Hash, _Traits>;
230 using __hash_code =
typename __hashtable_base::__hash_code;
231 using __ireturn_type =
typename __hashtable_base::__ireturn_type;
234 _Equal, _H1, _H2, _Hash,
235 _RehashPolicy, _Traits>;
240 _RehashPolicy, _Traits>;
243 _Equal, _H1, _H2, _Hash,
244 _RehashPolicy, _Traits>;
246 using __reuse_or_alloc_node_type =
247 __detail::_ReuseOrAllocNode<__node_alloc_type>;
250 template<
typename _Cond>
251 using __if_hash_cached = __or_<__not_<__hash_cached>, _Cond>;
253 template<
typename _Cond>
254 using __if_hash_not_cached = __or_<__hash_cached, _Cond>;
260 struct __hash_code_base_access : __hash_code_base
261 {
using __hash_code_base::_M_bucket_index; };
265 static_assert(noexcept(declval<const __hash_code_base_access&>()
268 "Cache the hash code or qualify your functors involved" 269 " in hash code and bucket index computation with noexcept");
276 static_assert(__if_hash_cached<is_default_constructible<_H2>>::value,
277 "Functor used to map hash code to bucket index" 278 " must be default constructible");
280 template<
typename _Keya,
typename _Valuea,
typename _Alloca,
281 typename _ExtractKeya,
typename _Equala,
282 typename _H1a,
typename _H2a,
typename _Hasha,
283 typename _RehashPolicya,
typename _Traitsa,
287 template<
typename _Keya,
typename _Valuea,
typename _Alloca,
288 typename _ExtractKeya,
typename _Equala,
289 typename _H1a,
typename _H2a,
typename _Hasha,
290 typename _RehashPolicya,
typename _Traitsa>
293 template<
typename _Keya,
typename _Valuea,
typename _Alloca,
294 typename _ExtractKeya,
typename _Equala,
295 typename _H1a,
typename _H2a,
typename _Hasha,
296 typename _RehashPolicya,
typename _Traitsa,
297 bool _Constant_iteratorsa,
bool _Unique_keysa>
301 using size_type =
typename __hashtable_base::size_type;
302 using difference_type =
typename __hashtable_base::difference_type;
308 using const_local_iterator =
typename __hashtable_base::
309 const_local_iterator;
312 __bucket_type* _M_buckets = &_M_single_bucket;
313 size_type _M_bucket_count = 1;
314 __node_base _M_before_begin;
315 size_type _M_element_count = 0;
316 _RehashPolicy _M_rehash_policy;
324 __bucket_type _M_single_bucket =
nullptr;
327 _M_uses_single_bucket(__bucket_type* __bkts)
const 328 {
return __builtin_expect(__bkts == &_M_single_bucket,
false); }
331 _M_uses_single_bucket()
const 332 {
return _M_uses_single_bucket(_M_buckets); }
335 _M_base_alloc() {
return *
this; }
338 _M_allocate_buckets(size_type __n)
340 if (__builtin_expect(__n == 1,
false))
342 _M_single_bucket =
nullptr;
343 return &_M_single_bucket;
346 return __hashtable_alloc::_M_allocate_buckets(__n);
350 _M_deallocate_buckets(__bucket_type* __bkts, size_type __n)
352 if (_M_uses_single_bucket(__bkts))
355 __hashtable_alloc::_M_deallocate_buckets(__bkts, __n);
359 _M_deallocate_buckets()
360 { _M_deallocate_buckets(_M_buckets, _M_bucket_count); }
365 _M_bucket_begin(size_type __bkt)
const;
369 {
return static_cast<__node_type*
>(_M_before_begin._M_nxt); }
371 template<
typename _NodeGenerator>
373 _M_assign(
const _Hashtable&,
const _NodeGenerator&);
384 _Hashtable(
const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
385 const _Equal& __eq,
const _ExtractKey& __exk,
386 const allocator_type& __a)
395 const _H1&,
const _H2&,
const _Hash&,
396 const _Equal&,
const _ExtractKey&,
397 const allocator_type&);
399 template<
typename _InputIterator>
400 _Hashtable(_InputIterator __first, _InputIterator __last,
401 size_type __bucket_hint,
402 const _H1&,
const _H2&,
const _Hash&,
403 const _Equal&,
const _ExtractKey&,
404 const allocator_type&);
422 const _H1& __hf = _H1(),
423 const key_equal& __eql = key_equal(),
424 const allocator_type& __a = allocator_type())
425 :
_Hashtable(__n, __hf, _H2(), _Hash(), __eql,
426 __key_extract(), __a)
429 template<
typename _InputIterator>
430 _Hashtable(_InputIterator __f, _InputIterator __l,
432 const _H1& __hf = _H1(),
433 const key_equal& __eql = key_equal(),
434 const allocator_type& __a = allocator_type())
435 :
_Hashtable(__f, __l, __n, __hf, _H2(), _Hash(), __eql,
436 __key_extract(), __a)
441 const _H1& __hf = _H1(),
442 const key_equal& __eql = key_equal(),
443 const allocator_type& __a = allocator_type())
444 :
_Hashtable(__l.begin(), __l.end(), __n, __hf, _H2(), _Hash(), __eql,
445 __key_extract(), __a)
453 noexcept(__node_alloc_traits::_S_nothrow_move()
454 && is_nothrow_move_assignable<_H1>::value
455 && is_nothrow_move_assignable<_Equal>::value)
457 constexpr
bool __move_storage =
458 __node_alloc_traits::_S_propagate_on_move_assign()
459 || __node_alloc_traits::_S_always_equal();
467 __reuse_or_alloc_node_type __roan(_M_begin(), *
this);
468 _M_before_begin._M_nxt =
nullptr;
470 this->_M_insert_range(__l.begin(), __l.end(), __roan);
478 noexcept(__is_nothrow_swappable<_H1>::value
479 && __is_nothrow_swappable<_Equal>::value);
484 {
return iterator(_M_begin()); }
487 begin()
const noexcept
488 {
return const_iterator(_M_begin()); }
492 {
return iterator(
nullptr); }
496 {
return const_iterator(
nullptr); }
500 {
return const_iterator(_M_begin()); }
503 cend()
const noexcept
504 {
return const_iterator(
nullptr); }
507 size()
const noexcept
508 {
return _M_element_count; }
511 empty()
const noexcept
512 {
return size() == 0; }
515 get_allocator()
const noexcept
516 {
return allocator_type(this->_M_node_allocator()); }
519 max_size()
const noexcept
520 {
return __node_alloc_traits::max_size(this->_M_node_allocator()); }
525 {
return this->_M_eq(); }
531 bucket_count()
const noexcept
532 {
return _M_bucket_count; }
535 max_bucket_count()
const noexcept
536 {
return max_size(); }
539 bucket_size(size_type __n)
const 543 bucket(
const key_type& __k)
const 544 {
return _M_bucket_index(__k, this->_M_hash_code(__k)); }
549 return local_iterator(*
this, _M_bucket_begin(__n),
550 __n, _M_bucket_count);
555 {
return local_iterator(*
this,
nullptr, __n, _M_bucket_count); }
558 begin(size_type __n)
const 560 return const_local_iterator(*
this, _M_bucket_begin(__n),
561 __n, _M_bucket_count);
565 end(size_type __n)
const 566 {
return const_local_iterator(*
this,
nullptr, __n, _M_bucket_count); }
570 cbegin(size_type __n)
const 572 return const_local_iterator(*
this, _M_bucket_begin(__n),
573 __n, _M_bucket_count);
577 cend(size_type __n)
const 578 {
return const_local_iterator(*
this,
nullptr, __n, _M_bucket_count); }
581 load_factor()
const noexcept
583 return static_cast<float>(size()) / static_cast<float>(bucket_count());
592 __rehash_policy()
const 593 {
return _M_rehash_policy; }
596 __rehash_policy(
const _RehashPolicy& __pol)
597 { _M_rehash_policy = __pol; }
601 find(
const key_type& __k);
604 find(
const key_type& __k)
const;
607 count(
const key_type& __k)
const;
610 equal_range(
const key_type& __k);
613 equal_range(
const key_type& __k)
const;
619 {
return __hash_code_base::_M_bucket_index(__n, _M_bucket_count); }
622 _M_bucket_index(
const key_type& __k, __hash_code __c)
const 623 {
return __hash_code_base::_M_bucket_index(__k, __c, _M_bucket_count); }
628 _M_find_before_node(size_type,
const key_type&, __hash_code)
const;
631 _M_find_node(size_type __bkt,
const key_type& __key,
632 __hash_code __c)
const 634 __node_base* __before_n = _M_find_before_node(__bkt, __key, __c);
636 return static_cast<__node_type*
>(__before_n->_M_nxt);
646 _M_remove_bucket_begin(size_type __bkt,
__node_type* __next_n,
647 size_type __next_bkt);
651 _M_get_previous_node(size_type __bkt, __node_base* __n);
657 _M_insert_unique_node(size_type __bkt, __hash_code __code,
666 template<
typename... _Args>
670 template<
typename... _Args>
673 {
return _M_emplace(
cend(), __uk, std::forward<_Args>(__args)...); }
676 template<
typename... _Args>
678 _M_emplace(const_iterator,
std::true_type __uk, _Args&&... __args)
679 {
return _M_emplace(__uk, std::forward<_Args>(__args)...).first; }
681 template<
typename... _Args>
685 template<
typename _Arg,
typename _NodeGenerator>
689 template<
typename _Arg,
typename _NodeGenerator>
691 _M_insert(_Arg&& __arg,
const _NodeGenerator& __node_gen,
694 return _M_insert(
cend(), std::forward<_Arg>(__arg), __node_gen,
699 template<
typename _Arg,
typename _NodeGenerator>
701 _M_insert(const_iterator, _Arg&& __arg,
705 _M_insert(std::forward<_Arg>(__arg), __node_gen, __uk).
first;
709 template<
typename _Arg,
typename _NodeGenerator>
711 _M_insert(const_iterator, _Arg&&,
721 _M_erase(size_type __bkt, __node_base* __prev_n,
__node_type* __n);
725 template<
typename... _Args>
727 emplace(_Args&&... __args)
728 {
return _M_emplace(__unique_keys(), std::forward<_Args>(__args)...); }
730 template<
typename... _Args>
732 emplace_hint(const_iterator __hint, _Args&&... __args)
734 return _M_emplace(__hint, __unique_keys(),
735 std::forward<_Args>(__args)...);
742 erase(const_iterator);
747 {
return erase(const_iterator(__it)); }
750 erase(
const key_type& __k)
751 {
return _M_erase(__unique_keys(), __k); }
754 erase(const_iterator, const_iterator);
760 void rehash(size_type __n);
774 void _M_rehash(size_type __n,
const __rehash_state& __state);
779 template<
typename _Key,
typename _Value,
780 typename _Alloc,
typename _ExtractKey,
typename _Equal,
781 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
784 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
785 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
786 _M_bucket_begin(size_type __bkt)
const 789 __node_base* __n = _M_buckets[__bkt];
790 return __n ?
static_cast<__node_type*
>(__n->_M_nxt) :
nullptr;
793 template<
typename _Key,
typename _Value,
794 typename _Alloc,
typename _ExtractKey,
typename _Equal,
795 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
797 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
798 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
799 _Hashtable(size_type __bucket_hint,
800 const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
801 const _Equal& __eq,
const _ExtractKey& __exk,
802 const allocator_type& __a)
803 :
_Hashtable(__h1, __h2, __h, __eq, __exk, __a)
805 auto __bkt = _M_rehash_policy._M_next_bkt(__bucket_hint);
806 if (__bkt > _M_bucket_count)
808 _M_buckets = _M_allocate_buckets(__bkt);
809 _M_bucket_count = __bkt;
813 template<
typename _Key,
typename _Value,
814 typename _Alloc,
typename _ExtractKey,
typename _Equal,
815 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
817 template<
typename _InputIterator>
818 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
819 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
820 _Hashtable(_InputIterator __f, _InputIterator __l,
821 size_type __bucket_hint,
822 const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
823 const _Equal& __eq,
const _ExtractKey& __exk,
824 const allocator_type& __a)
825 :
_Hashtable(__h1, __h2, __h, __eq, __exk, __a)
827 auto __nb_elems = __detail::__distance_fw(__f, __l);
829 _M_rehash_policy._M_next_bkt(
830 std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems),
833 if (__bkt_count > _M_bucket_count)
835 _M_buckets = _M_allocate_buckets(__bkt_count);
836 _M_bucket_count = __bkt_count;
839 for (; __f != __l; ++__f)
843 template<
typename _Key,
typename _Value,
844 typename _Alloc,
typename _ExtractKey,
typename _Equal,
845 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
848 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
849 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
856 if (__node_alloc_traits::_S_propagate_on_copy_assign())
858 auto& __this_alloc = this->_M_node_allocator();
859 auto& __that_alloc = __ht._M_node_allocator();
860 if (!__node_alloc_traits::_S_always_equal()
861 && __this_alloc != __that_alloc)
864 this->_M_deallocate_nodes(_M_begin());
865 _M_before_begin._M_nxt =
nullptr;
866 _M_deallocate_buckets();
867 _M_buckets =
nullptr;
868 std::__alloc_on_copy(__this_alloc, __that_alloc);
869 __hashtable_base::operator=(__ht);
870 _M_bucket_count = __ht._M_bucket_count;
871 _M_element_count = __ht._M_element_count;
872 _M_rehash_policy = __ht._M_rehash_policy;
877 {
return this->_M_allocate_node(__n->_M_v()); });
884 __throw_exception_again;
888 std::__alloc_on_copy(__this_alloc, __that_alloc);
892 __bucket_type* __former_buckets =
nullptr;
893 std::size_t __former_bucket_count = _M_bucket_count;
894 const __rehash_state& __former_state = _M_rehash_policy._M_state();
896 if (_M_bucket_count != __ht._M_bucket_count)
898 __former_buckets = _M_buckets;
899 _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
900 _M_bucket_count = __ht._M_bucket_count;
903 __builtin_memset(_M_buckets, 0,
904 _M_bucket_count *
sizeof(__bucket_type));
908 __hashtable_base::operator=(__ht);
909 _M_element_count = __ht._M_element_count;
910 _M_rehash_policy = __ht._M_rehash_policy;
911 __reuse_or_alloc_node_type __roan(_M_begin(), *
this);
912 _M_before_begin._M_nxt =
nullptr;
915 {
return __roan(__n->_M_v()); });
916 if (__former_buckets)
917 _M_deallocate_buckets(__former_buckets, __former_bucket_count);
921 if (__former_buckets)
924 _M_deallocate_buckets();
925 _M_rehash_policy._M_reset(__former_state);
926 _M_buckets = __former_buckets;
927 _M_bucket_count = __former_bucket_count;
929 __builtin_memset(_M_buckets, 0,
930 _M_bucket_count *
sizeof(__bucket_type));
931 __throw_exception_again;
936 template<
typename _Key,
typename _Value,
937 typename _Alloc,
typename _ExtractKey,
typename _Equal,
938 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
940 template<
typename _NodeGenerator>
942 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
943 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
944 _M_assign(
const _Hashtable& __ht,
const _NodeGenerator& __node_gen)
946 __bucket_type* __buckets =
nullptr;
948 _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count);
952 if (!__ht._M_before_begin._M_nxt)
959 this->_M_copy_code(__this_n, __ht_n);
960 _M_before_begin._M_nxt = __this_n;
961 _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin;
964 __node_base* __prev_n = __this_n;
965 for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next())
967 __this_n = __node_gen(__ht_n);
968 __prev_n->_M_nxt = __this_n;
969 this->_M_copy_code(__this_n, __ht_n);
970 size_type __bkt = _M_bucket_index(__this_n);
971 if (!_M_buckets[__bkt])
972 _M_buckets[__bkt] = __prev_n;
980 _M_deallocate_buckets();
981 __throw_exception_again;
985 template<
typename _Key,
typename _Value,
986 typename _Alloc,
typename _ExtractKey,
typename _Equal,
987 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
990 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
991 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
994 _M_rehash_policy._M_reset();
996 _M_single_bucket =
nullptr;
997 _M_buckets = &_M_single_bucket;
998 _M_before_begin._M_nxt =
nullptr;
999 _M_element_count = 0;
1002 template<
typename _Key,
typename _Value,
1003 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1004 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1007 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1008 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1011 this->_M_deallocate_nodes(_M_begin());
1012 _M_deallocate_buckets();
1013 __hashtable_base::operator=(std::move(__ht));
1014 _M_rehash_policy = __ht._M_rehash_policy;
1015 if (!__ht._M_uses_single_bucket())
1016 _M_buckets = __ht._M_buckets;
1019 _M_buckets = &_M_single_bucket;
1020 _M_single_bucket = __ht._M_single_bucket;
1022 _M_bucket_count = __ht._M_bucket_count;
1023 _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
1024 _M_element_count = __ht._M_element_count;
1025 std::__alloc_on_move(this->_M_node_allocator(), __ht._M_node_allocator());
1030 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1034 template<
typename _Key,
typename _Value,
1035 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1036 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1039 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1040 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1043 if (__ht._M_node_allocator() == this->_M_node_allocator())
1048 __bucket_type* __former_buckets =
nullptr;
1049 size_type __former_bucket_count = _M_bucket_count;
1050 const __rehash_state& __former_state = _M_rehash_policy._M_state();
1052 if (_M_bucket_count != __ht._M_bucket_count)
1054 __former_buckets = _M_buckets;
1055 _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
1056 _M_bucket_count = __ht._M_bucket_count;
1059 __builtin_memset(_M_buckets, 0,
1060 _M_bucket_count *
sizeof(__bucket_type));
1064 __hashtable_base::operator=(std::move(__ht));
1065 _M_element_count = __ht._M_element_count;
1066 _M_rehash_policy = __ht._M_rehash_policy;
1067 __reuse_or_alloc_node_type __roan(_M_begin(), *
this);
1068 _M_before_begin._M_nxt =
nullptr;
1076 if (__former_buckets)
1078 _M_deallocate_buckets();
1079 _M_rehash_policy._M_reset(__former_state);
1080 _M_buckets = __former_buckets;
1081 _M_bucket_count = __former_bucket_count;
1083 __builtin_memset(_M_buckets, 0,
1084 _M_bucket_count *
sizeof(__bucket_type));
1085 __throw_exception_again;
1090 template<
typename _Key,
typename _Value,
1091 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1092 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1094 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1095 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1101 __node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())),
1102 _M_buckets(
nullptr),
1103 _M_bucket_count(__ht._M_bucket_count),
1104 _M_element_count(__ht._M_element_count),
1105 _M_rehash_policy(__ht._M_rehash_policy)
1109 {
return this->_M_allocate_node(__n->_M_v()); });
1112 template<
typename _Key,
typename _Value,
1113 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1114 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1116 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1117 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1123 _M_buckets(__ht._M_buckets),
1124 _M_bucket_count(__ht._M_bucket_count),
1125 _M_before_begin(__ht._M_before_begin._M_nxt),
1126 _M_element_count(__ht._M_element_count),
1127 _M_rehash_policy(__ht._M_rehash_policy)
1130 if (__ht._M_uses_single_bucket())
1132 _M_buckets = &_M_single_bucket;
1133 _M_single_bucket = __ht._M_single_bucket;
1139 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1144 template<
typename _Key,
typename _Value,
1145 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1146 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1148 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1149 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1150 _Hashtable(
const _Hashtable& __ht,
const allocator_type& __a)
1156 _M_bucket_count(__ht._M_bucket_count),
1157 _M_element_count(__ht._M_element_count),
1158 _M_rehash_policy(__ht._M_rehash_policy)
1162 {
return this->_M_allocate_node(__n->_M_v()); });
1165 template<
typename _Key,
typename _Value,
1166 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1167 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1169 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1170 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1171 _Hashtable(
_Hashtable&& __ht,
const allocator_type& __a)
1176 _M_buckets(
nullptr),
1177 _M_bucket_count(__ht._M_bucket_count),
1178 _M_element_count(__ht._M_element_count),
1179 _M_rehash_policy(__ht._M_rehash_policy)
1181 if (__ht._M_node_allocator() == this->_M_node_allocator())
1183 if (__ht._M_uses_single_bucket())
1185 _M_buckets = &_M_single_bucket;
1186 _M_single_bucket = __ht._M_single_bucket;
1189 _M_buckets = __ht._M_buckets;
1191 _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
1195 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1203 return this->_M_allocate_node(
1210 template<
typename _Key,
typename _Value,
1211 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1212 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1214 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1215 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1216 ~_Hashtable() noexcept
1219 _M_deallocate_buckets();
1222 template<
typename _Key,
typename _Value,
1223 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1224 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1227 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1228 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1230 noexcept(__is_nothrow_swappable<_H1>::value
1231 && __is_nothrow_swappable<_Equal>::value)
1238 std::__alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator());
1239 std::swap(_M_rehash_policy, __x._M_rehash_policy);
1242 if (this->_M_uses_single_bucket())
1244 if (!__x._M_uses_single_bucket())
1246 _M_buckets = __x._M_buckets;
1247 __x._M_buckets = &__x._M_single_bucket;
1250 else if (__x._M_uses_single_bucket())
1252 __x._M_buckets = _M_buckets;
1253 _M_buckets = &_M_single_bucket;
1256 std::swap(_M_buckets, __x._M_buckets);
1258 std::swap(_M_bucket_count, __x._M_bucket_count);
1259 std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt);
1260 std::swap(_M_element_count, __x._M_element_count);
1261 std::swap(_M_single_bucket, __x._M_single_bucket);
1266 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1269 __x._M_buckets[__x._M_bucket_index(__x._M_begin())]
1270 = &__x._M_before_begin;
1273 template<
typename _Key,
typename _Value,
1274 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1275 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1278 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1279 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1280 find(
const key_type& __k)
1283 __hash_code __code = this->_M_hash_code(__k);
1284 std::size_t __n = _M_bucket_index(__k, __code);
1285 __node_type* __p = _M_find_node(__n, __k, __code);
1286 return __p ? iterator(__p) :
end();
1289 template<
typename _Key,
typename _Value,
1290 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1291 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1294 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1295 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1296 find(
const key_type& __k)
const 1299 __hash_code __code = this->_M_hash_code(__k);
1300 std::size_t __n = _M_bucket_index(__k, __code);
1301 __node_type* __p = _M_find_node(__n, __k, __code);
1302 return __p ? const_iterator(__p) :
end();
1305 template<
typename _Key,
typename _Value,
1306 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1307 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1310 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1311 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1312 count(
const key_type& __k)
const 1315 __hash_code __code = this->_M_hash_code(__k);
1316 std::size_t __n = _M_bucket_index(__k, __code);
1321 std::size_t __result = 0;
1322 for (;; __p = __p->_M_next())
1324 if (this->_M_equals(__k, __code, __p))
1331 if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n)
1337 template<
typename _Key,
typename _Value,
1338 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1339 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1342 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1343 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1344 equal_range(
const key_type& __k)
1347 __hash_code __code = this->_M_hash_code(__k);
1348 std::size_t __n = _M_bucket_index(__k, __code);
1349 __node_type* __p = _M_find_node(__n, __k, __code);
1354 while (__p1 && _M_bucket_index(__p1) == __n
1355 && this->_M_equals(__k, __code, __p1))
1356 __p1 = __p1->_M_next();
1364 template<
typename _Key,
typename _Value,
1365 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1366 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1369 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1370 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1371 equal_range(
const key_type& __k)
const 1374 __hash_code __code = this->_M_hash_code(__k);
1375 std::size_t __n = _M_bucket_index(__k, __code);
1376 __node_type* __p = _M_find_node(__n, __k, __code);
1381 while (__p1 && _M_bucket_index(__p1) == __n
1382 && this->_M_equals(__k, __code, __p1))
1383 __p1 = __p1->_M_next();
1385 return std::make_pair(const_iterator(__p), const_iterator(__p1));
1393 template<
typename _Key,
typename _Value,
1394 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1395 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1398 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1399 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1400 _M_find_before_node(size_type __n,
const key_type& __k,
1401 __hash_code __code)
const 1404 __node_base* __prev_p = _M_buckets[__n];
1408 for (
__node_type* __p = static_cast<__node_type*>(__prev_p->_M_nxt);;
1409 __p = __p->_M_next())
1411 if (this->_M_equals(__k, __code, __p))
1414 if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n)
1421 template<
typename _Key,
typename _Value,
1422 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1423 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1426 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1427 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1428 _M_insert_bucket_begin(size_type __bkt,
__node_type* __node)
1430 if (_M_buckets[__bkt])
1434 __node->_M_nxt = _M_buckets[__bkt]->_M_nxt;
1435 _M_buckets[__bkt]->_M_nxt = __node;
1442 __node->_M_nxt = _M_before_begin._M_nxt;
1443 _M_before_begin._M_nxt = __node;
1447 _M_buckets[_M_bucket_index(__node->_M_next())] = __node;
1448 _M_buckets[__bkt] = &_M_before_begin;
1452 template<
typename _Key,
typename _Value,
1453 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1454 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1457 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1458 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1459 _M_remove_bucket_begin(size_type __bkt,
__node_type* __next,
1460 size_type __next_bkt)
1462 if (!__next || __next_bkt != __bkt)
1467 _M_buckets[__next_bkt] = _M_buckets[__bkt];
1470 if (&_M_before_begin == _M_buckets[__bkt])
1471 _M_before_begin._M_nxt = __next;
1472 _M_buckets[__bkt] =
nullptr;
1476 template<
typename _Key,
typename _Value,
1477 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1478 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1481 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1482 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1483 _M_get_previous_node(size_type __bkt, __node_base* __n)
1486 __node_base* __prev_n = _M_buckets[__bkt];
1487 while (__prev_n->_M_nxt != __n)
1488 __prev_n = __prev_n->_M_nxt;
1492 template<
typename _Key,
typename _Value,
1493 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1494 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1496 template<
typename... _Args>
1498 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1499 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1504 __node_type* __node = this->_M_allocate_node(std::forward<_Args>(__args)...);
1505 const key_type& __k = this->_M_extract()(__node->_M_v());
1509 __code = this->_M_hash_code(__k);
1513 this->_M_deallocate_node(__node);
1514 __throw_exception_again;
1517 size_type __bkt = _M_bucket_index(__k, __code);
1518 if (
__node_type* __p = _M_find_node(__bkt, __k, __code))
1521 this->_M_deallocate_node(__node);
1526 return std::make_pair(_M_insert_unique_node(__bkt, __code, __node),
1530 template<
typename _Key,
typename _Value,
1531 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1532 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1534 template<
typename... _Args>
1536 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1537 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1543 this->_M_allocate_node(std::forward<_Args>(__args)...);
1548 __code = this->_M_hash_code(this->_M_extract()(__node->_M_v()));
1552 this->_M_deallocate_node(__node);
1553 __throw_exception_again;
1556 return _M_insert_multi_node(__hint._M_cur, __code, __node);
1559 template<
typename _Key,
typename _Value,
1560 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1561 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1564 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1565 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1566 _M_insert_unique_node(size_type __bkt, __hash_code __code,
1570 const __rehash_state& __saved_state = _M_rehash_policy._M_state();
1572 = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1);
1576 if (__do_rehash.
first)
1578 _M_rehash(__do_rehash.
second, __saved_state);
1579 __bkt = _M_bucket_index(this->_M_extract()(__node->_M_v()), __code);
1582 this->_M_store_code(__node, __code);
1585 _M_insert_bucket_begin(__bkt, __node);
1587 return iterator(__node);
1591 this->_M_deallocate_node(__node);
1592 __throw_exception_again;
1598 template<
typename _Key,
typename _Value,
1599 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1600 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1603 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1604 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1605 _M_insert_multi_node(
__node_type* __hint, __hash_code __code,
1609 const __rehash_state& __saved_state = _M_rehash_policy._M_state();
1611 = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1);
1615 if (__do_rehash.
first)
1616 _M_rehash(__do_rehash.
second, __saved_state);
1618 this->_M_store_code(__node, __code);
1619 const key_type& __k = this->_M_extract()(__node->_M_v());
1620 size_type __bkt = _M_bucket_index(__k, __code);
1625 = __builtin_expect(__hint !=
nullptr,
false)
1626 && this->_M_equals(__k, __code, __hint)
1628 : _M_find_before_node(__bkt, __k, __code);
1632 __node->_M_nxt = __prev->_M_nxt;
1633 __prev->_M_nxt = __node;
1634 if (__builtin_expect(__prev == __hint,
false))
1638 && !this->_M_equals(__k, __code, __node->_M_next()))
1640 size_type __next_bkt = _M_bucket_index(__node->_M_next());
1641 if (__next_bkt != __bkt)
1642 _M_buckets[__next_bkt] = __node;
1650 _M_insert_bucket_begin(__bkt, __node);
1652 return iterator(__node);
1656 this->_M_deallocate_node(__node);
1657 __throw_exception_again;
1662 template<
typename _Key,
typename _Value,
1663 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1664 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1666 template<
typename _Arg,
typename _NodeGenerator>
1668 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1669 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1670 _M_insert(_Arg&& __v,
const _NodeGenerator& __node_gen,
std::true_type)
1673 const key_type& __k = this->_M_extract()(__v);
1674 __hash_code __code = this->_M_hash_code(__k);
1675 size_type __bkt = _M_bucket_index(__k, __code);
1677 __node_type* __n = _M_find_node(__bkt, __k, __code);
1681 __n = __node_gen(std::forward<_Arg>(__v));
1682 return std::make_pair(_M_insert_unique_node(__bkt, __code, __n),
true);
1686 template<
typename _Key,
typename _Value,
1687 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1688 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1690 template<
typename _Arg,
typename _NodeGenerator>
1692 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1693 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1694 _M_insert(const_iterator __hint, _Arg&& __v,
1700 __hash_code __code = this->_M_hash_code(this->_M_extract()(__v));
1703 __node_type* __node = __node_gen(std::forward<_Arg>(__v));
1705 return _M_insert_multi_node(__hint._M_cur, __code, __node);
1708 template<
typename _Key,
typename _Value,
1709 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1710 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1713 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1714 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1715 erase(const_iterator __it)
1719 std::size_t __bkt = _M_bucket_index(__n);
1724 __node_base* __prev_n = _M_get_previous_node(__bkt, __n);
1725 return _M_erase(__bkt, __prev_n, __n);
1728 template<
typename _Key,
typename _Value,
1729 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1730 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1733 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1734 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1735 _M_erase(size_type __bkt, __node_base* __prev_n,
__node_type* __n)
1738 if (__prev_n == _M_buckets[__bkt])
1739 _M_remove_bucket_begin(__bkt, __n->_M_next(),
1740 __n->_M_nxt ? _M_bucket_index(__n->_M_next()) : 0);
1741 else if (__n->_M_nxt)
1743 size_type __next_bkt = _M_bucket_index(__n->_M_next());
1744 if (__next_bkt != __bkt)
1745 _M_buckets[__next_bkt] = __prev_n;
1748 __prev_n->_M_nxt = __n->_M_nxt;
1749 iterator __result(__n->_M_next());
1750 this->_M_deallocate_node(__n);
1756 template<
typename _Key,
typename _Value,
1757 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1758 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1761 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1762 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1766 __hash_code __code = this->_M_hash_code(__k);
1767 std::size_t __bkt = _M_bucket_index(__k, __code);
1770 __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code);
1776 _M_erase(__bkt, __prev_n, __n);
1780 template<
typename _Key,
typename _Value,
1781 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1782 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1785 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1786 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1790 __hash_code __code = this->_M_hash_code(__k);
1791 std::size_t __bkt = _M_bucket_index(__k, __code);
1794 __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code);
1806 std::size_t __n_last_bkt = __bkt;
1809 __n_last = __n_last->_M_next();
1812 __n_last_bkt = _M_bucket_index(__n_last);
1814 while (__n_last_bkt == __bkt && this->_M_equals(__k, __code, __n_last));
1817 size_type __result = 0;
1821 this->_M_deallocate_node(__n);
1826 while (__n != __n_last);
1828 if (__prev_n == _M_buckets[__bkt])
1829 _M_remove_bucket_begin(__bkt, __n_last, __n_last_bkt);
1830 else if (__n_last && __n_last_bkt != __bkt)
1831 _M_buckets[__n_last_bkt] = __prev_n;
1832 __prev_n->_M_nxt = __n_last;
1836 template<
typename _Key,
typename _Value,
1837 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1838 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1841 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1842 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1843 erase(const_iterator __first, const_iterator __last)
1848 if (__n == __last_n)
1849 return iterator(__n);
1851 std::size_t __bkt = _M_bucket_index(__n);
1853 __node_base* __prev_n = _M_get_previous_node(__bkt, __n);
1854 bool __is_bucket_begin = __n == _M_bucket_begin(__bkt);
1855 std::size_t __n_bkt = __bkt;
1861 __n = __n->_M_next();
1862 this->_M_deallocate_node(__tmp);
1866 __n_bkt = _M_bucket_index(__n);
1868 while (__n != __last_n && __n_bkt == __bkt);
1869 if (__is_bucket_begin)
1870 _M_remove_bucket_begin(__bkt, __n, __n_bkt);
1871 if (__n == __last_n)
1873 __is_bucket_begin =
true;
1877 if (__n && (__n_bkt != __bkt || __is_bucket_begin))
1878 _M_buckets[__n_bkt] = __prev_n;
1879 __prev_n->_M_nxt = __n;
1880 return iterator(__n);
1883 template<
typename _Key,
typename _Value,
1884 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1885 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1888 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1889 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1892 this->_M_deallocate_nodes(_M_begin());
1893 __builtin_memset(_M_buckets, 0, _M_bucket_count *
sizeof(__bucket_type));
1894 _M_element_count = 0;
1895 _M_before_begin._M_nxt =
nullptr;
1898 template<
typename _Key,
typename _Value,
1899 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1900 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1903 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1904 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1905 rehash(size_type __n)
1907 const __rehash_state& __saved_state = _M_rehash_policy._M_state();
1908 std::size_t __buckets
1909 =
std::max(_M_rehash_policy._M_bkt_for_elements(_M_element_count + 1),
1911 __buckets = _M_rehash_policy._M_next_bkt(__buckets);
1913 if (__buckets != _M_bucket_count)
1914 _M_rehash(__buckets, __saved_state);
1917 _M_rehash_policy._M_reset(__saved_state);
1920 template<
typename _Key,
typename _Value,
1921 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1922 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1925 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1926 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1927 _M_rehash(size_type __n,
const __rehash_state& __state)
1931 _M_rehash_aux(__n, __unique_keys());
1937 _M_rehash_policy._M_reset(__state);
1938 __throw_exception_again;
1943 template<
typename _Key,
typename _Value,
1944 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1945 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1948 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1949 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1952 __bucket_type* __new_buckets = _M_allocate_buckets(__n);
1954 _M_before_begin._M_nxt =
nullptr;
1955 std::size_t __bbegin_bkt = 0;
1959 std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n);
1960 if (!__new_buckets[__bkt])
1962 __p->_M_nxt = _M_before_begin._M_nxt;
1963 _M_before_begin._M_nxt = __p;
1964 __new_buckets[__bkt] = &_M_before_begin;
1966 __new_buckets[__bbegin_bkt] = __p;
1967 __bbegin_bkt = __bkt;
1971 __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
1972 __new_buckets[__bkt]->_M_nxt = __p;
1977 _M_deallocate_buckets();
1978 _M_bucket_count = __n;
1979 _M_buckets = __new_buckets;
1984 template<
typename _Key,
typename _Value,
1985 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1986 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1989 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1990 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1993 __bucket_type* __new_buckets = _M_allocate_buckets(__n);
1996 _M_before_begin._M_nxt =
nullptr;
1997 std::size_t __bbegin_bkt = 0;
1998 std::size_t __prev_bkt = 0;
2000 bool __check_bucket =
false;
2005 std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n);
2007 if (__prev_p && __prev_bkt == __bkt)
2012 __p->_M_nxt = __prev_p->_M_nxt;
2013 __prev_p->_M_nxt = __p;
2020 __check_bucket =
true;
2028 if (__prev_p->_M_nxt)
2030 std::size_t __next_bkt
2031 = __hash_code_base::_M_bucket_index(__prev_p->_M_next(),
2033 if (__next_bkt != __prev_bkt)
2034 __new_buckets[__next_bkt] = __prev_p;
2036 __check_bucket =
false;
2039 if (!__new_buckets[__bkt])
2041 __p->_M_nxt = _M_before_begin._M_nxt;
2042 _M_before_begin._M_nxt = __p;
2043 __new_buckets[__bkt] = &_M_before_begin;
2045 __new_buckets[__bbegin_bkt] = __p;
2046 __bbegin_bkt = __bkt;
2050 __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
2051 __new_buckets[__bkt]->_M_nxt = __p;
2059 if (__check_bucket && __prev_p->_M_nxt)
2061 std::size_t __next_bkt
2062 = __hash_code_base::_M_bucket_index(__prev_p->_M_next(), __n);
2063 if (__next_bkt != __prev_bkt)
2064 __new_buckets[__next_bkt] = __prev_p;
2067 _M_deallocate_buckets();
2068 _M_bucket_count = __n;
2069 _M_buckets = __new_buckets;
2072 _GLIBCXX_END_NAMESPACE_VERSION
2075 #endif // _HASHTABLE_H _T2 second
first is a copy of the first object
Uniform interface to C++98 and C++11 allocators.
constexpr auto cend(const _Container &__cont) noexcept(noexcept(std::end(__cont))) -> decltype(std::end(__cont))
Return an iterator pointing to one past the last element of the const container.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
constexpr const _Tp * begin(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to the first element of the initializer_list.
constexpr conditional< __move_if_noexcept_cond< _Tp >::value, const _Tp &, _Tp && >::type move_if_noexcept(_Tp &__x) noexcept
Conditionally convert a value to an rvalue.
_T1 first
second_type is the second bound type
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to one past the last element of the initializer_list. ...
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
constexpr auto cbegin(const _Container &__cont) noexcept(noexcept(std::begin(__cont))) -> decltype(std::begin(__cont))
Return an iterator pointing to the first element of the const container.
_GLIBCXX14_CONSTEXPR const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
Node iterators, used to iterate through all the hashtable.
Struct holding two objects of arbitrary type.
Uniform interface to all allocator types.
Node const_iterators, used to iterate through all the hashtable.
ISO C++ entities toplevel namespace is std.
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.