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 typename __alloctr_rebind<_Alloc,
183 __detail::_Hash_node<_Value,
184 _Traits::__hash_cached::value> >::__type>
186 using __traits_type = _Traits;
187 using __hash_cached =
typename __traits_type::__hash_cached;
189 using __node_alloc_type =
190 typename __alloctr_rebind<_Alloc, __node_type>::__type;
194 using __value_alloc_traits =
196 using __node_alloc_traits =
202 typedef _Key key_type;
203 typedef _Value value_type;
204 typedef _Alloc allocator_type;
205 typedef _Equal key_equal;
209 typedef typename __value_alloc_traits::pointer pointer;
210 typedef typename __value_alloc_traits::const_pointer const_pointer;
211 typedef value_type& reference;
212 typedef const value_type& const_reference;
215 using __rehash_type = _RehashPolicy;
216 using __rehash_state =
typename __rehash_type::_State;
218 using __constant_iterators =
typename __traits_type::__constant_iterators;
219 using __unique_keys =
typename __traits_type::__unique_keys;
221 using __key_extract =
typename std::conditional<
222 __constant_iterators::value,
224 __detail::_Select1st>::type;
227 _Hashtable_base<_Key, _Value, _ExtractKey,
228 _Equal, _H1, _H2, _Hash, _Traits>;
231 using __hash_code =
typename __hashtable_base::__hash_code;
232 using __ireturn_type =
typename __hashtable_base::__ireturn_type;
235 _Equal, _H1, _H2, _Hash,
236 _RehashPolicy, _Traits>;
241 _RehashPolicy, _Traits>;
244 _Equal, _H1, _H2, _Hash,
245 _RehashPolicy, _Traits>;
247 using __reuse_or_alloc_node_type =
248 __detail::_ReuseOrAllocNode<__node_alloc_type>;
251 template<
typename _Cond>
252 using __if_hash_cached = __or_<__not_<__hash_cached>, _Cond>;
254 template<
typename _Cond>
255 using __if_hash_not_cached = __or_<__hash_cached, _Cond>;
261 struct __hash_code_base_access : __hash_code_base
262 {
using __hash_code_base::_M_bucket_index; };
266 static_assert(noexcept(declval<const __hash_code_base_access&>()
269 "Cache the hash code or qualify your functors involved" 270 " in hash code and bucket index computation with noexcept");
277 static_assert(__if_hash_cached<is_default_constructible<_H2>>::value,
278 "Functor used to map hash code to bucket index" 279 " must be default constructible");
281 template<
typename _Keya,
typename _Valuea,
typename _Alloca,
282 typename _ExtractKeya,
typename _Equala,
283 typename _H1a,
typename _H2a,
typename _Hasha,
284 typename _RehashPolicya,
typename _Traitsa,
288 template<
typename _Keya,
typename _Valuea,
typename _Alloca,
289 typename _ExtractKeya,
typename _Equala,
290 typename _H1a,
typename _H2a,
typename _Hasha,
291 typename _RehashPolicya,
typename _Traitsa>
294 template<
typename _Keya,
typename _Valuea,
typename _Alloca,
295 typename _ExtractKeya,
typename _Equala,
296 typename _H1a,
typename _H2a,
typename _Hasha,
297 typename _RehashPolicya,
typename _Traitsa,
298 bool _Constant_iteratorsa,
bool _Unique_keysa>
302 using size_type =
typename __hashtable_base::size_type;
303 using difference_type =
typename __hashtable_base::difference_type;
309 using const_local_iterator =
typename __hashtable_base::
310 const_local_iterator;
313 __bucket_type* _M_buckets = &_M_single_bucket;
314 size_type _M_bucket_count = 1;
315 __node_base _M_before_begin;
316 size_type _M_element_count = 0;
317 _RehashPolicy _M_rehash_policy;
325 __bucket_type _M_single_bucket =
nullptr;
328 _M_uses_single_bucket(__bucket_type* __bkts)
const 329 {
return __builtin_expect(__bkts == &_M_single_bucket,
false); }
332 _M_uses_single_bucket()
const 333 {
return _M_uses_single_bucket(_M_buckets); }
336 _M_base_alloc() {
return *
this; }
339 _M_allocate_buckets(size_type __n)
341 if (__builtin_expect(__n == 1,
false))
343 _M_single_bucket =
nullptr;
344 return &_M_single_bucket;
347 return __hashtable_alloc::_M_allocate_buckets(__n);
351 _M_deallocate_buckets(__bucket_type* __bkts, size_type __n)
353 if (_M_uses_single_bucket(__bkts))
356 __hashtable_alloc::_M_deallocate_buckets(__bkts, __n);
360 _M_deallocate_buckets()
361 { _M_deallocate_buckets(_M_buckets, _M_bucket_count); }
366 _M_bucket_begin(size_type __bkt)
const;
370 {
return static_cast<__node_type*
>(_M_before_begin._M_nxt); }
372 template<
typename _NodeGenerator>
374 _M_assign(
const _Hashtable&,
const _NodeGenerator&);
385 _Hashtable(
const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
386 const _Equal& __eq,
const _ExtractKey& __exk,
387 const allocator_type& __a)
396 const _H1&,
const _H2&,
const _Hash&,
397 const _Equal&,
const _ExtractKey&,
398 const allocator_type&);
400 template<
typename _InputIterator>
401 _Hashtable(_InputIterator __first, _InputIterator __last,
402 size_type __bucket_hint,
403 const _H1&,
const _H2&,
const _Hash&,
404 const _Equal&,
const _ExtractKey&,
405 const allocator_type&);
423 const _H1& __hf = _H1(),
424 const key_equal& __eql = key_equal(),
425 const allocator_type& __a = allocator_type())
426 :
_Hashtable(__n, __hf, _H2(), _Hash(), __eql,
427 __key_extract(), __a)
430 template<
typename _InputIterator>
431 _Hashtable(_InputIterator __f, _InputIterator __l,
433 const _H1& __hf = _H1(),
434 const key_equal& __eql = key_equal(),
435 const allocator_type& __a = allocator_type())
436 :
_Hashtable(__f, __l, __n, __hf, _H2(), _Hash(), __eql,
437 __key_extract(), __a)
442 const _H1& __hf = _H1(),
443 const key_equal& __eql = key_equal(),
444 const allocator_type& __a = allocator_type())
445 :
_Hashtable(__l.begin(), __l.end(), __n, __hf, _H2(), _Hash(), __eql,
446 __key_extract(), __a)
454 noexcept(__node_alloc_traits::_S_nothrow_move())
456 constexpr
bool __move_storage =
457 __node_alloc_traits::_S_propagate_on_move_assign()
458 || __node_alloc_traits::_S_always_equal();
459 _M_move_assign(std::move(__ht),
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(__node_alloc_traits::_S_nothrow_swap());
483 {
return iterator(_M_begin()); }
486 begin()
const noexcept
487 {
return const_iterator(_M_begin()); }
491 {
return iterator(
nullptr); }
495 {
return const_iterator(
nullptr); }
499 {
return const_iterator(_M_begin()); }
502 cend()
const noexcept
503 {
return const_iterator(
nullptr); }
506 size()
const noexcept
507 {
return _M_element_count; }
510 empty()
const noexcept
511 {
return size() == 0; }
514 get_allocator()
const noexcept
515 {
return allocator_type(this->_M_node_allocator()); }
518 max_size()
const noexcept
519 {
return __node_alloc_traits::max_size(this->_M_node_allocator()); }
524 {
return this->_M_eq(); }
530 bucket_count()
const noexcept
531 {
return _M_bucket_count; }
534 max_bucket_count()
const noexcept
535 {
return max_size(); }
538 bucket_size(size_type __n)
const 542 bucket(
const key_type& __k)
const 543 {
return _M_bucket_index(__k, this->_M_hash_code(__k)); }
548 return local_iterator(*
this, _M_bucket_begin(__n),
549 __n, _M_bucket_count);
554 {
return local_iterator(*
this,
nullptr, __n, _M_bucket_count); }
557 begin(size_type __n)
const 559 return const_local_iterator(*
this, _M_bucket_begin(__n),
560 __n, _M_bucket_count);
564 end(size_type __n)
const 565 {
return const_local_iterator(*
this,
nullptr, __n, _M_bucket_count); }
569 cbegin(size_type __n)
const 571 return const_local_iterator(*
this, _M_bucket_begin(__n),
572 __n, _M_bucket_count);
576 cend(size_type __n)
const 577 {
return const_local_iterator(*
this,
nullptr, __n, _M_bucket_count); }
580 load_factor()
const noexcept
582 return static_cast<float>(size()) / static_cast<float>(bucket_count());
591 __rehash_policy()
const 592 {
return _M_rehash_policy; }
595 __rehash_policy(
const _RehashPolicy&);
599 find(
const key_type& __k);
602 find(
const key_type& __k)
const;
605 count(
const key_type& __k)
const;
608 equal_range(
const key_type& __k);
611 equal_range(
const key_type& __k)
const;
617 {
return __hash_code_base::_M_bucket_index(__n, _M_bucket_count); }
620 _M_bucket_index(
const key_type& __k, __hash_code __c)
const 621 {
return __hash_code_base::_M_bucket_index(__k, __c, _M_bucket_count); }
626 _M_find_before_node(size_type,
const key_type&, __hash_code)
const;
629 _M_find_node(size_type __bkt,
const key_type& __key,
630 __hash_code __c)
const 632 __node_base* __before_n = _M_find_before_node(__bkt, __key, __c);
634 return static_cast<__node_type*
>(__before_n->_M_nxt);
644 _M_remove_bucket_begin(size_type __bkt,
__node_type* __next_n,
645 size_type __next_bkt);
649 _M_get_previous_node(size_type __bkt, __node_base* __n);
655 _M_insert_unique_node(size_type __bkt, __hash_code __code,
664 template<
typename... _Args>
668 template<
typename... _Args>
671 {
return _M_emplace(
cend(), __uk, std::forward<_Args>(__args)...); }
674 template<
typename... _Args>
676 _M_emplace(const_iterator,
std::true_type __uk, _Args&&... __args)
677 {
return _M_emplace(__uk, std::forward<_Args>(__args)...).first; }
679 template<
typename... _Args>
683 template<
typename _Arg,
typename _NodeGenerator>
687 template<
typename _Arg,
typename _NodeGenerator>
689 _M_insert(_Arg&& __arg,
const _NodeGenerator& __node_gen,
692 return _M_insert(
cend(), std::forward<_Arg>(__arg), __node_gen,
697 template<
typename _Arg,
typename _NodeGenerator>
699 _M_insert(const_iterator, _Arg&& __arg,
703 _M_insert(std::forward<_Arg>(__arg), __node_gen, __uk).
first;
707 template<
typename _Arg,
typename _NodeGenerator>
709 _M_insert(const_iterator, _Arg&&,
719 _M_erase(size_type __bkt, __node_base* __prev_n,
__node_type* __n);
723 template<
typename... _Args>
725 emplace(_Args&&... __args)
726 {
return _M_emplace(__unique_keys(), std::forward<_Args>(__args)...); }
728 template<
typename... _Args>
730 emplace_hint(const_iterator __hint, _Args&&... __args)
732 return _M_emplace(__hint, __unique_keys(),
733 std::forward<_Args>(__args)...);
740 erase(const_iterator);
745 {
return erase(const_iterator(__it)); }
748 erase(
const key_type& __k)
749 {
return _M_erase(__unique_keys(), __k); }
752 erase(const_iterator, const_iterator);
758 void rehash(size_type __n);
772 void _M_rehash(size_type __n,
const __rehash_state& __state);
777 template<
typename _Key,
typename _Value,
778 typename _Alloc,
typename _ExtractKey,
typename _Equal,
779 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
782 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
783 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
784 _M_bucket_begin(size_type __bkt)
const 787 __node_base* __n = _M_buckets[__bkt];
788 return __n ?
static_cast<__node_type*
>(__n->_M_nxt) :
nullptr;
791 template<
typename _Key,
typename _Value,
792 typename _Alloc,
typename _ExtractKey,
typename _Equal,
793 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
795 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
796 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
797 _Hashtable(size_type __bucket_hint,
798 const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
799 const _Equal& __eq,
const _ExtractKey& __exk,
800 const allocator_type& __a)
801 :
_Hashtable(__h1, __h2, __h, __eq, __exk, __a)
803 auto __bkt = _M_rehash_policy._M_next_bkt(__bucket_hint);
804 if (__bkt > _M_bucket_count)
806 _M_buckets = _M_allocate_buckets(__bkt);
807 _M_bucket_count = __bkt;
811 template<
typename _Key,
typename _Value,
812 typename _Alloc,
typename _ExtractKey,
typename _Equal,
813 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
815 template<
typename _InputIterator>
816 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
817 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
818 _Hashtable(_InputIterator __f, _InputIterator __l,
819 size_type __bucket_hint,
820 const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
821 const _Equal& __eq,
const _ExtractKey& __exk,
822 const allocator_type& __a)
823 :
_Hashtable(__h1, __h2, __h, __eq, __exk, __a)
825 auto __nb_elems = __detail::__distance_fw(__f, __l);
827 _M_rehash_policy._M_next_bkt(
828 std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems),
831 if (__bkt_count > _M_bucket_count)
833 _M_buckets = _M_allocate_buckets(__bkt_count);
834 _M_bucket_count = __bkt_count;
839 for (; __f != __l; ++__f)
845 _M_deallocate_buckets();
846 __throw_exception_again;
850 template<
typename _Key,
typename _Value,
851 typename _Alloc,
typename _ExtractKey,
typename _Equal,
852 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
855 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
856 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
863 if (__node_alloc_traits::_S_propagate_on_copy_assign())
865 auto& __this_alloc = this->_M_node_allocator();
866 auto& __that_alloc = __ht._M_node_allocator();
867 if (!__node_alloc_traits::_S_always_equal()
868 && __this_alloc != __that_alloc)
871 this->_M_deallocate_nodes(_M_begin());
872 _M_before_begin._M_nxt =
nullptr;
873 _M_deallocate_buckets();
874 _M_buckets =
nullptr;
875 std::__alloc_on_copy(__this_alloc, __that_alloc);
876 __hashtable_base::operator=(__ht);
877 _M_bucket_count = __ht._M_bucket_count;
878 _M_element_count = __ht._M_element_count;
879 _M_rehash_policy = __ht._M_rehash_policy;
884 {
return this->_M_allocate_node(__n->_M_v()); });
891 __throw_exception_again;
895 std::__alloc_on_copy(__this_alloc, __that_alloc);
899 __bucket_type* __former_buckets =
nullptr;
900 std::size_t __former_bucket_count = _M_bucket_count;
901 const __rehash_state& __former_state = _M_rehash_policy._M_state();
903 if (_M_bucket_count != __ht._M_bucket_count)
905 __former_buckets = _M_buckets;
906 _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
907 _M_bucket_count = __ht._M_bucket_count;
910 __builtin_memset(_M_buckets, 0,
911 _M_bucket_count *
sizeof(__bucket_type));
915 __hashtable_base::operator=(__ht);
916 _M_element_count = __ht._M_element_count;
917 _M_rehash_policy = __ht._M_rehash_policy;
918 __reuse_or_alloc_node_type __roan(_M_begin(), *
this);
919 _M_before_begin._M_nxt =
nullptr;
922 {
return __roan(__n->_M_v()); });
923 if (__former_buckets)
924 _M_deallocate_buckets(__former_buckets, __former_bucket_count);
928 if (__former_buckets)
931 _M_deallocate_buckets();
932 _M_rehash_policy._M_reset(__former_state);
933 _M_buckets = __former_buckets;
934 _M_bucket_count = __former_bucket_count;
936 __builtin_memset(_M_buckets, 0,
937 _M_bucket_count *
sizeof(__bucket_type));
938 __throw_exception_again;
943 template<
typename _Key,
typename _Value,
944 typename _Alloc,
typename _ExtractKey,
typename _Equal,
945 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
947 template<
typename _NodeGenerator>
949 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
950 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
951 _M_assign(
const _Hashtable& __ht,
const _NodeGenerator& __node_gen)
953 __bucket_type* __buckets =
nullptr;
955 _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count);
959 if (!__ht._M_before_begin._M_nxt)
966 this->_M_copy_code(__this_n, __ht_n);
967 _M_before_begin._M_nxt = __this_n;
968 _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin;
971 __node_base* __prev_n = __this_n;
972 for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next())
974 __this_n = __node_gen(__ht_n);
975 __prev_n->_M_nxt = __this_n;
976 this->_M_copy_code(__this_n, __ht_n);
977 size_type __bkt = _M_bucket_index(__this_n);
978 if (!_M_buckets[__bkt])
979 _M_buckets[__bkt] = __prev_n;
987 _M_deallocate_buckets();
988 __throw_exception_again;
992 template<
typename _Key,
typename _Value,
993 typename _Alloc,
typename _ExtractKey,
typename _Equal,
994 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
997 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
998 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1001 _M_rehash_policy._M_reset();
1002 _M_bucket_count = 1;
1003 _M_single_bucket =
nullptr;
1004 _M_buckets = &_M_single_bucket;
1005 _M_before_begin._M_nxt =
nullptr;
1006 _M_element_count = 0;
1009 template<
typename _Key,
typename _Value,
1010 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1011 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1014 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1015 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1018 this->_M_deallocate_nodes(_M_begin());
1019 _M_deallocate_buckets();
1020 __hashtable_base::operator=(std::move(__ht));
1021 _M_rehash_policy = __ht._M_rehash_policy;
1022 if (!__ht._M_uses_single_bucket())
1023 _M_buckets = __ht._M_buckets;
1026 _M_buckets = &_M_single_bucket;
1027 _M_single_bucket = __ht._M_single_bucket;
1029 _M_bucket_count = __ht._M_bucket_count;
1030 _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
1031 _M_element_count = __ht._M_element_count;
1032 std::__alloc_on_move(this->_M_node_allocator(), __ht._M_node_allocator());
1037 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1041 template<
typename _Key,
typename _Value,
1042 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1043 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1046 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1047 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1050 if (__ht._M_node_allocator() == this->_M_node_allocator())
1055 __bucket_type* __former_buckets =
nullptr;
1056 size_type __former_bucket_count = _M_bucket_count;
1057 const __rehash_state& __former_state = _M_rehash_policy._M_state();
1059 if (_M_bucket_count != __ht._M_bucket_count)
1061 __former_buckets = _M_buckets;
1062 _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
1063 _M_bucket_count = __ht._M_bucket_count;
1066 __builtin_memset(_M_buckets, 0,
1067 _M_bucket_count *
sizeof(__bucket_type));
1071 __hashtable_base::operator=(std::move(__ht));
1072 _M_element_count = __ht._M_element_count;
1073 _M_rehash_policy = __ht._M_rehash_policy;
1074 __reuse_or_alloc_node_type __roan(_M_begin(), *
this);
1075 _M_before_begin._M_nxt =
nullptr;
1083 if (__former_buckets)
1085 _M_deallocate_buckets();
1086 _M_rehash_policy._M_reset(__former_state);
1087 _M_buckets = __former_buckets;
1088 _M_bucket_count = __former_bucket_count;
1090 __builtin_memset(_M_buckets, 0,
1091 _M_bucket_count *
sizeof(__bucket_type));
1092 __throw_exception_again;
1097 template<
typename _Key,
typename _Value,
1098 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1099 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1101 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1102 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1108 __node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())),
1109 _M_buckets(
nullptr),
1110 _M_bucket_count(__ht._M_bucket_count),
1111 _M_element_count(__ht._M_element_count),
1112 _M_rehash_policy(__ht._M_rehash_policy)
1116 {
return this->_M_allocate_node(__n->_M_v()); });
1119 template<
typename _Key,
typename _Value,
1120 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1121 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1123 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1124 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1130 _M_buckets(__ht._M_buckets),
1131 _M_bucket_count(__ht._M_bucket_count),
1132 _M_before_begin(__ht._M_before_begin._M_nxt),
1133 _M_element_count(__ht._M_element_count),
1134 _M_rehash_policy(__ht._M_rehash_policy)
1137 if (__ht._M_uses_single_bucket())
1139 _M_buckets = &_M_single_bucket;
1140 _M_single_bucket = __ht._M_single_bucket;
1146 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1151 template<
typename _Key,
typename _Value,
1152 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1153 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1155 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1156 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1157 _Hashtable(
const _Hashtable& __ht,
const allocator_type& __a)
1163 _M_bucket_count(__ht._M_bucket_count),
1164 _M_element_count(__ht._M_element_count),
1165 _M_rehash_policy(__ht._M_rehash_policy)
1169 {
return this->_M_allocate_node(__n->_M_v()); });
1172 template<
typename _Key,
typename _Value,
1173 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1174 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1176 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1177 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1178 _Hashtable(
_Hashtable&& __ht,
const allocator_type& __a)
1183 _M_buckets(
nullptr),
1184 _M_bucket_count(__ht._M_bucket_count),
1185 _M_element_count(__ht._M_element_count),
1186 _M_rehash_policy(__ht._M_rehash_policy)
1188 if (__ht._M_node_allocator() == this->_M_node_allocator())
1190 if (__ht._M_uses_single_bucket())
1192 _M_buckets = &_M_single_bucket;
1193 _M_single_bucket = __ht._M_single_bucket;
1196 _M_buckets = __ht._M_buckets;
1198 _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
1202 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1210 return this->_M_allocate_node(
1217 template<
typename _Key,
typename _Value,
1218 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1219 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1221 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1222 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1223 ~_Hashtable() noexcept
1226 _M_deallocate_buckets();
1229 template<
typename _Key,
typename _Value,
1230 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1231 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1234 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1235 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1237 noexcept(__node_alloc_traits::_S_nothrow_swap())
1244 std::__alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator());
1245 std::swap(_M_rehash_policy, __x._M_rehash_policy);
1248 if (this->_M_uses_single_bucket())
1250 if (!__x._M_uses_single_bucket())
1252 _M_buckets = __x._M_buckets;
1253 __x._M_buckets = &__x._M_single_bucket;
1256 else if (__x._M_uses_single_bucket())
1258 __x._M_buckets = _M_buckets;
1259 _M_buckets = &_M_single_bucket;
1262 std::swap(_M_buckets, __x._M_buckets);
1264 std::swap(_M_bucket_count, __x._M_bucket_count);
1265 std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt);
1266 std::swap(_M_element_count, __x._M_element_count);
1267 std::swap(_M_single_bucket, __x._M_single_bucket);
1272 _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
1275 __x._M_buckets[__x._M_bucket_index(__x._M_begin())]
1276 = &__x._M_before_begin;
1279 template<
typename _Key,
typename _Value,
1280 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1281 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1284 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1285 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1286 __rehash_policy(
const _RehashPolicy& __pol)
1289 __pol._M_need_rehash(_M_bucket_count, _M_element_count, 0);
1290 if (__do_rehash.first)
1291 _M_rehash(__do_rehash.second, _M_rehash_policy._M_state());
1292 _M_rehash_policy = __pol;
1295 template<
typename _Key,
typename _Value,
1296 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1297 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1300 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1301 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1302 find(
const key_type& __k)
1305 __hash_code __code = this->_M_hash_code(__k);
1306 std::size_t __n = _M_bucket_index(__k, __code);
1307 __node_type* __p = _M_find_node(__n, __k, __code);
1308 return __p ? iterator(__p) :
end();
1311 template<
typename _Key,
typename _Value,
1312 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1313 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1316 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1317 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1318 find(
const key_type& __k)
const 1321 __hash_code __code = this->_M_hash_code(__k);
1322 std::size_t __n = _M_bucket_index(__k, __code);
1323 __node_type* __p = _M_find_node(__n, __k, __code);
1324 return __p ? const_iterator(__p) :
end();
1327 template<
typename _Key,
typename _Value,
1328 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1329 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1332 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1333 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1334 count(
const key_type& __k)
const 1337 __hash_code __code = this->_M_hash_code(__k);
1338 std::size_t __n = _M_bucket_index(__k, __code);
1343 std::size_t __result = 0;
1344 for (;; __p = __p->_M_next())
1346 if (this->_M_equals(__k, __code, __p))
1353 if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n)
1359 template<
typename _Key,
typename _Value,
1360 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1361 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1364 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1365 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1366 equal_range(
const key_type& __k)
1369 __hash_code __code = this->_M_hash_code(__k);
1370 std::size_t __n = _M_bucket_index(__k, __code);
1371 __node_type* __p = _M_find_node(__n, __k, __code);
1376 while (__p1 && _M_bucket_index(__p1) == __n
1377 && this->_M_equals(__k, __code, __p1))
1378 __p1 = __p1->_M_next();
1386 template<
typename _Key,
typename _Value,
1387 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1388 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1391 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1392 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1393 equal_range(
const key_type& __k)
const 1396 __hash_code __code = this->_M_hash_code(__k);
1397 std::size_t __n = _M_bucket_index(__k, __code);
1398 __node_type* __p = _M_find_node(__n, __k, __code);
1403 while (__p1 && _M_bucket_index(__p1) == __n
1404 && this->_M_equals(__k, __code, __p1))
1405 __p1 = __p1->_M_next();
1407 return std::make_pair(const_iterator(__p), const_iterator(__p1));
1415 template<
typename _Key,
typename _Value,
1416 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1417 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1420 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1421 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1422 _M_find_before_node(size_type __n,
const key_type& __k,
1423 __hash_code __code)
const 1426 __node_base* __prev_p = _M_buckets[__n];
1430 for (
__node_type* __p = static_cast<__node_type*>(__prev_p->_M_nxt);;
1431 __p = __p->_M_next())
1433 if (this->_M_equals(__k, __code, __p))
1436 if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n)
1443 template<
typename _Key,
typename _Value,
1444 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1445 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1448 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1449 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1450 _M_insert_bucket_begin(size_type __bkt,
__node_type* __node)
1452 if (_M_buckets[__bkt])
1456 __node->_M_nxt = _M_buckets[__bkt]->_M_nxt;
1457 _M_buckets[__bkt]->_M_nxt = __node;
1464 __node->_M_nxt = _M_before_begin._M_nxt;
1465 _M_before_begin._M_nxt = __node;
1469 _M_buckets[_M_bucket_index(__node->_M_next())] = __node;
1470 _M_buckets[__bkt] = &_M_before_begin;
1474 template<
typename _Key,
typename _Value,
1475 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1476 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1479 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1480 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1481 _M_remove_bucket_begin(size_type __bkt,
__node_type* __next,
1482 size_type __next_bkt)
1484 if (!__next || __next_bkt != __bkt)
1489 _M_buckets[__next_bkt] = _M_buckets[__bkt];
1492 if (&_M_before_begin == _M_buckets[__bkt])
1493 _M_before_begin._M_nxt = __next;
1494 _M_buckets[__bkt] =
nullptr;
1498 template<
typename _Key,
typename _Value,
1499 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1500 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1503 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1504 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1505 _M_get_previous_node(size_type __bkt, __node_base* __n)
1508 __node_base* __prev_n = _M_buckets[__bkt];
1509 while (__prev_n->_M_nxt != __n)
1510 __prev_n = __prev_n->_M_nxt;
1514 template<
typename _Key,
typename _Value,
1515 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1516 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1518 template<
typename... _Args>
1520 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1521 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1526 __node_type* __node = this->_M_allocate_node(std::forward<_Args>(__args)...);
1527 const key_type& __k = this->_M_extract()(__node->_M_v());
1531 __code = this->_M_hash_code(__k);
1535 this->_M_deallocate_node(__node);
1536 __throw_exception_again;
1539 size_type __bkt = _M_bucket_index(__k, __code);
1540 if (
__node_type* __p = _M_find_node(__bkt, __k, __code))
1543 this->_M_deallocate_node(__node);
1548 return std::make_pair(_M_insert_unique_node(__bkt, __code, __node),
1552 template<
typename _Key,
typename _Value,
1553 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1554 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1556 template<
typename... _Args>
1558 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1559 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1565 this->_M_allocate_node(std::forward<_Args>(__args)...);
1570 __code = this->_M_hash_code(this->_M_extract()(__node->_M_v()));
1574 this->_M_deallocate_node(__node);
1575 __throw_exception_again;
1578 return _M_insert_multi_node(__hint._M_cur, __code, __node);
1581 template<
typename _Key,
typename _Value,
1582 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1583 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1586 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1587 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1588 _M_insert_unique_node(size_type __bkt, __hash_code __code,
1592 const __rehash_state& __saved_state = _M_rehash_policy._M_state();
1594 = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1);
1598 if (__do_rehash.
first)
1600 _M_rehash(__do_rehash.
second, __saved_state);
1601 __bkt = _M_bucket_index(this->_M_extract()(__node->_M_v()), __code);
1604 this->_M_store_code(__node, __code);
1607 _M_insert_bucket_begin(__bkt, __node);
1609 return iterator(__node);
1613 this->_M_deallocate_node(__node);
1614 __throw_exception_again;
1620 template<
typename _Key,
typename _Value,
1621 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1622 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1625 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1626 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1627 _M_insert_multi_node(
__node_type* __hint, __hash_code __code,
1631 const __rehash_state& __saved_state = _M_rehash_policy._M_state();
1633 = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1);
1637 if (__do_rehash.
first)
1638 _M_rehash(__do_rehash.
second, __saved_state);
1640 this->_M_store_code(__node, __code);
1641 const key_type& __k = this->_M_extract()(__node->_M_v());
1642 size_type __bkt = _M_bucket_index(__k, __code);
1647 = __builtin_expect(__hint !=
nullptr,
false)
1648 && this->_M_equals(__k, __code, __hint)
1650 : _M_find_before_node(__bkt, __k, __code);
1654 __node->_M_nxt = __prev->_M_nxt;
1655 __prev->_M_nxt = __node;
1656 if (__builtin_expect(__prev == __hint,
false))
1660 && !this->_M_equals(__k, __code, __node->_M_next()))
1662 size_type __next_bkt = _M_bucket_index(__node->_M_next());
1663 if (__next_bkt != __bkt)
1664 _M_buckets[__next_bkt] = __node;
1672 _M_insert_bucket_begin(__bkt, __node);
1674 return iterator(__node);
1678 this->_M_deallocate_node(__node);
1679 __throw_exception_again;
1684 template<
typename _Key,
typename _Value,
1685 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1686 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1688 template<
typename _Arg,
typename _NodeGenerator>
1690 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1691 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1692 _M_insert(_Arg&& __v,
const _NodeGenerator& __node_gen,
std::true_type)
1695 const key_type& __k = this->_M_extract()(__v);
1696 __hash_code __code = this->_M_hash_code(__k);
1697 size_type __bkt = _M_bucket_index(__k, __code);
1699 __node_type* __n = _M_find_node(__bkt, __k, __code);
1703 __n = __node_gen(std::forward<_Arg>(__v));
1704 return std::make_pair(_M_insert_unique_node(__bkt, __code, __n),
true);
1708 template<
typename _Key,
typename _Value,
1709 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1710 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1712 template<
typename _Arg,
typename _NodeGenerator>
1714 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1715 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1716 _M_insert(const_iterator __hint, _Arg&& __v,
1722 __hash_code __code = this->_M_hash_code(this->_M_extract()(__v));
1725 __node_type* __node = __node_gen(std::forward<_Arg>(__v));
1727 return _M_insert_multi_node(__hint._M_cur, __code, __node);
1730 template<
typename _Key,
typename _Value,
1731 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1732 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1735 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1736 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1737 erase(const_iterator __it)
1741 std::size_t __bkt = _M_bucket_index(__n);
1746 __node_base* __prev_n = _M_get_previous_node(__bkt, __n);
1747 return _M_erase(__bkt, __prev_n, __n);
1750 template<
typename _Key,
typename _Value,
1751 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1752 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1755 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1756 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1757 _M_erase(size_type __bkt, __node_base* __prev_n,
__node_type* __n)
1760 if (__prev_n == _M_buckets[__bkt])
1761 _M_remove_bucket_begin(__bkt, __n->_M_next(),
1762 __n->_M_nxt ? _M_bucket_index(__n->_M_next()) : 0);
1763 else if (__n->_M_nxt)
1765 size_type __next_bkt = _M_bucket_index(__n->_M_next());
1766 if (__next_bkt != __bkt)
1767 _M_buckets[__next_bkt] = __prev_n;
1770 __prev_n->_M_nxt = __n->_M_nxt;
1771 iterator __result(__n->_M_next());
1772 this->_M_deallocate_node(__n);
1778 template<
typename _Key,
typename _Value,
1779 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1780 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1783 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1784 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1788 __hash_code __code = this->_M_hash_code(__k);
1789 std::size_t __bkt = _M_bucket_index(__k, __code);
1792 __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code);
1798 _M_erase(__bkt, __prev_n, __n);
1802 template<
typename _Key,
typename _Value,
1803 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1804 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1807 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1808 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1812 __hash_code __code = this->_M_hash_code(__k);
1813 std::size_t __bkt = _M_bucket_index(__k, __code);
1816 __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code);
1828 std::size_t __n_last_bkt = __bkt;
1831 __n_last = __n_last->_M_next();
1834 __n_last_bkt = _M_bucket_index(__n_last);
1836 while (__n_last_bkt == __bkt && this->_M_equals(__k, __code, __n_last));
1839 size_type __result = 0;
1843 this->_M_deallocate_node(__n);
1848 while (__n != __n_last);
1850 if (__prev_n == _M_buckets[__bkt])
1851 _M_remove_bucket_begin(__bkt, __n_last, __n_last_bkt);
1852 else if (__n_last && __n_last_bkt != __bkt)
1853 _M_buckets[__n_last_bkt] = __prev_n;
1854 __prev_n->_M_nxt = __n_last;
1858 template<
typename _Key,
typename _Value,
1859 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1860 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1863 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1864 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1865 erase(const_iterator __first, const_iterator __last)
1870 if (__n == __last_n)
1871 return iterator(__n);
1873 std::size_t __bkt = _M_bucket_index(__n);
1875 __node_base* __prev_n = _M_get_previous_node(__bkt, __n);
1876 bool __is_bucket_begin = __n == _M_bucket_begin(__bkt);
1877 std::size_t __n_bkt = __bkt;
1883 __n = __n->_M_next();
1884 this->_M_deallocate_node(__tmp);
1888 __n_bkt = _M_bucket_index(__n);
1890 while (__n != __last_n && __n_bkt == __bkt);
1891 if (__is_bucket_begin)
1892 _M_remove_bucket_begin(__bkt, __n, __n_bkt);
1893 if (__n == __last_n)
1895 __is_bucket_begin =
true;
1899 if (__n && (__n_bkt != __bkt || __is_bucket_begin))
1900 _M_buckets[__n_bkt] = __prev_n;
1901 __prev_n->_M_nxt = __n;
1902 return iterator(__n);
1905 template<
typename _Key,
typename _Value,
1906 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1907 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1910 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1911 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1914 this->_M_deallocate_nodes(_M_begin());
1915 __builtin_memset(_M_buckets, 0, _M_bucket_count *
sizeof(__bucket_type));
1916 _M_element_count = 0;
1917 _M_before_begin._M_nxt =
nullptr;
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 rehash(size_type __n)
1929 const __rehash_state& __saved_state = _M_rehash_policy._M_state();
1930 std::size_t __buckets
1931 =
std::max(_M_rehash_policy._M_bkt_for_elements(_M_element_count + 1),
1933 __buckets = _M_rehash_policy._M_next_bkt(__buckets);
1935 if (__buckets != _M_bucket_count)
1936 _M_rehash(__buckets, __saved_state);
1939 _M_rehash_policy._M_reset(__saved_state);
1942 template<
typename _Key,
typename _Value,
1943 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1944 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1947 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1948 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1949 _M_rehash(size_type __n,
const __rehash_state& __state)
1953 _M_rehash_aux(__n, __unique_keys());
1959 _M_rehash_policy._M_reset(__state);
1960 __throw_exception_again;
1965 template<
typename _Key,
typename _Value,
1966 typename _Alloc,
typename _ExtractKey,
typename _Equal,
1967 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1970 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1971 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
1974 __bucket_type* __new_buckets = _M_allocate_buckets(__n);
1976 _M_before_begin._M_nxt =
nullptr;
1977 std::size_t __bbegin_bkt = 0;
1981 std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n);
1982 if (!__new_buckets[__bkt])
1984 __p->_M_nxt = _M_before_begin._M_nxt;
1985 _M_before_begin._M_nxt = __p;
1986 __new_buckets[__bkt] = &_M_before_begin;
1988 __new_buckets[__bbegin_bkt] = __p;
1989 __bbegin_bkt = __bkt;
1993 __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
1994 __new_buckets[__bkt]->_M_nxt = __p;
1999 _M_deallocate_buckets();
2000 _M_bucket_count = __n;
2001 _M_buckets = __new_buckets;
2006 template<
typename _Key,
typename _Value,
2007 typename _Alloc,
typename _ExtractKey,
typename _Equal,
2008 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
2011 _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
2012 _H1, _H2, _Hash, _RehashPolicy, _Traits>::
2015 __bucket_type* __new_buckets = _M_allocate_buckets(__n);
2018 _M_before_begin._M_nxt =
nullptr;
2019 std::size_t __bbegin_bkt = 0;
2020 std::size_t __prev_bkt = 0;
2022 bool __check_bucket =
false;
2027 std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n);
2029 if (__prev_p && __prev_bkt == __bkt)
2034 __p->_M_nxt = __prev_p->_M_nxt;
2035 __prev_p->_M_nxt = __p;
2042 __check_bucket =
true;
2050 if (__prev_p->_M_nxt)
2052 std::size_t __next_bkt
2053 = __hash_code_base::_M_bucket_index(__prev_p->_M_next(),
2055 if (__next_bkt != __prev_bkt)
2056 __new_buckets[__next_bkt] = __prev_p;
2058 __check_bucket =
false;
2061 if (!__new_buckets[__bkt])
2063 __p->_M_nxt = _M_before_begin._M_nxt;
2064 _M_before_begin._M_nxt = __p;
2065 __new_buckets[__bkt] = &_M_before_begin;
2067 __new_buckets[__bbegin_bkt] = __p;
2068 __bbegin_bkt = __bkt;
2072 __p->_M_nxt = __new_buckets[__bkt]->_M_nxt;
2073 __new_buckets[__bkt]->_M_nxt = __p;
2081 if (__check_bucket && __prev_p->_M_nxt)
2083 std::size_t __next_bkt
2084 = __hash_code_base::_M_bucket_index(__prev_p->_M_next(), __n);
2085 if (__next_bkt != __prev_bkt)
2086 __new_buckets[__next_bkt] = __prev_p;
2089 _M_deallocate_buckets();
2090 _M_bucket_count = __n;
2091 _M_buckets = __new_buckets;
2094 _GLIBCXX_END_NAMESPACE_VERSION
2097 #endif // _HASHTABLE_H
Uniform interface to all allocator types.
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.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
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.
constexpr const _Tp * begin(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to the first element of the initializer_list.
_GLIBCXX14_CONSTEXPR const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
Node const_iterators, used to iterate through all the hashtable.
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.
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.
_T2 second
first is a copy of the first object
Node iterators, used to iterate through all the hashtable.
Struct holding two objects of arbitrary type.
_T1 first
second_type is the second bound type
ISO C++ entities toplevel namespace is std.
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to one past the last element of the initializer_list. ...
Uniform interface to C++98 and C++0x allocators.