31 #ifndef _HASHTABLE_POLICY_H
32 #define _HASHTABLE_POLICY_H 1
34 namespace std _GLIBCXX_VISIBILITY(default)
36 _GLIBCXX_BEGIN_NAMESPACE_VERSION
38 template<
typename _Key,
typename _Value,
typename _Alloc,
39 typename _ExtractKey,
typename _Equal,
40 typename _H1,
typename _H2,
typename _Hash,
41 typename _RehashPolicy,
typename _Traits>
44 _GLIBCXX_END_NAMESPACE_VERSION
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 template<
typename _Key,
typename _Value,
56 typename _ExtractKey,
typename _Equal,
57 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
62 template<
class _Iterator>
63 inline typename std::iterator_traits<_Iterator>::difference_type
64 __distance_fw(_Iterator __first, _Iterator __last,
68 template<
class _Iterator>
69 inline typename std::iterator_traits<_Iterator>::difference_type
70 __distance_fw(_Iterator __first, _Iterator __last,
74 template<
class _Iterator>
75 inline typename std::iterator_traits<_Iterator>::difference_type
76 __distance_fw(_Iterator __first, _Iterator __last)
78 typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
79 return __distance_fw(__first, __last, _Tag());
83 template <
typename _Key,
typename _Hash>
85 noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
90 template<
typename _Tp>
92 operator()(_Tp&& __x)
const
93 {
return std::forward<_Tp>(__x); }
98 template<
typename _Tp>
100 operator()(_Tp&& __x) const
101 -> decltype(std::get<0>(std::
forward<_Tp>(__x)))
102 {
return std::get<0>(std::forward<_Tp>(__x)); }
130 template<
bool _Cache_hash_code,
bool _Constant_iterators,
bool _Unique_keys>
163 template<
typename _Value>
166 __gnu_cxx::__aligned_buffer<_Value> _M_storage;
170 {
return _M_storage._M_ptr(); }
173 _M_valptr()
const noexcept
174 {
return _M_storage._M_ptr(); }
178 {
return *_M_valptr(); }
181 _M_v()
const noexcept
182 {
return *_M_valptr(); }
188 template<
typename _Value,
bool _Cache_hash_code>
196 template<
typename _Value>
199 std::size_t _M_hash_code;
202 _M_next()
const {
return static_cast<_Hash_node*
>(this->_M_nxt); }
210 template<
typename _Value>
214 _M_next()
const {
return static_cast<_Hash_node*
>(this->_M_nxt); }
218 template<
typename _Value,
bool _Cache_hash_code>
230 { _M_cur = _M_cur->_M_next(); }
233 template<
typename _Value,
bool _Cache_hash_code>
237 {
return __x._M_cur == __y._M_cur; }
239 template<
typename _Value,
bool _Cache_hash_code>
241 operator!=(
const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
242 const _Node_iterator_base<_Value, _Cache_hash_code>& __y)
243 {
return __x._M_cur != __y._M_cur; }
246 template<
typename _Value,
bool __constant_iterators,
bool __cache>
255 typedef _Value value_type;
256 typedef std::ptrdiff_t difference_type;
259 using pointer =
typename std::conditional<__constant_iterators,
260 const _Value*, _Value*>::type;
262 using reference =
typename std::conditional<__constant_iterators,
263 const _Value&, _Value&>::type;
274 {
return this->_M_cur->_M_v(); }
278 {
return this->_M_cur->_M_valptr(); }
297 template<
typename _Value,
bool __constant_iterators,
bool __cache>
306 typedef _Value value_type;
307 typedef std::ptrdiff_t difference_type;
310 typedef const _Value* pointer;
311 typedef const _Value& reference;
326 {
return this->_M_cur->_M_v(); }
330 {
return this->_M_cur->_M_valptr(); }
355 typedef std::size_t first_argument_type;
356 typedef std::size_t second_argument_type;
357 typedef std::size_t result_type;
360 operator()(first_argument_type __num,
361 second_argument_type __den)
const noexcept
362 {
return __num % __den; }
377 : _M_max_load_factor(__z), _M_next_resize(0) { }
380 max_load_factor()
const noexcept
381 {
return _M_max_load_factor; }
385 _M_next_bkt(std::size_t __n)
const;
389 _M_bkt_for_elements(std::size_t __n)
const
390 {
return __builtin_ceil(__n / (
long double)_M_max_load_factor); }
397 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
398 std::size_t __n_ins)
const;
400 typedef std::size_t _State;
404 {
return _M_next_resize; }
408 { _M_next_resize = 0; }
411 _M_reset(_State __state)
412 { _M_next_resize = __state; }
414 enum { _S_n_primes =
sizeof(
unsigned long) != 8 ? 256 : 256 + 48 };
416 static const std::size_t _S_growth_factor = 2;
418 float _M_max_load_factor;
419 mutable std::size_t _M_next_resize;
440 template<
typename _Key,
typename _Value,
typename _Alloc,
441 typename _ExtractKey,
typename _Equal,
442 typename _H1,
typename _H2,
typename _Hash,
443 typename _RehashPolicy,
typename _Traits,
444 bool _Unique_keys = _Traits::__unique_keys::value>
448 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
449 typename _H1,
typename _H2,
typename _Hash,
450 typename _RehashPolicy,
typename _Traits>
451 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
452 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
458 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
459 typename _H1,
typename _H2,
typename _Hash,
460 typename _RehashPolicy,
typename _Traits>
461 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
462 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
467 _Equal, _H1, _H2, _Hash,
472 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
474 using __hash_code =
typename __hashtable_base::__hash_code;
475 using __node_type =
typename __hashtable_base::__node_type;
478 using key_type =
typename __hashtable_base::key_type;
491 at(
const key_type& __k);
494 at(
const key_type& __k)
const;
497 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
498 typename _H1,
typename _H2,
typename _Hash,
499 typename _RehashPolicy,
typename _Traits>
500 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
501 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
503 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
504 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
505 operator[](
const key_type& __k)
507 __hashtable* __h =
static_cast<__hashtable*
>(
this);
508 __hash_code __code = __h->_M_hash_code(__k);
509 std::size_t __n = __h->_M_bucket_index(__k, __code);
510 __node_type* __p = __h->_M_find_node(__n, __k, __code);
517 return __h->_M_insert_unique_node(__n, __code, __p)->second;
520 return __p->_M_v().second;
523 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
524 typename _H1,
typename _H2,
typename _Hash,
525 typename _RehashPolicy,
typename _Traits>
526 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
527 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
529 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
530 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
531 operator[](key_type&& __k)
533 __hashtable* __h =
static_cast<__hashtable*
>(
this);
534 __hash_code __code = __h->_M_hash_code(__k);
535 std::size_t __n = __h->_M_bucket_index(__k, __code);
536 __node_type* __p = __h->_M_find_node(__n, __k, __code);
541 std::forward_as_tuple(std::move(__k)),
543 return __h->_M_insert_unique_node(__n, __code, __p)->second;
546 return __p->_M_v().second;
549 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
550 typename _H1,
typename _H2,
typename _Hash,
551 typename _RehashPolicy,
typename _Traits>
552 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
553 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
555 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
556 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
557 at(
const key_type& __k)
559 __hashtable* __h =
static_cast<__hashtable*
>(
this);
560 __hash_code __code = __h->_M_hash_code(__k);
561 std::size_t __n = __h->_M_bucket_index(__k, __code);
562 __node_type* __p = __h->_M_find_node(__n, __k, __code);
565 __throw_out_of_range(__N(
"_Map_base::at"));
566 return __p->_M_v().second;
569 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
570 typename _H1,
typename _H2,
typename _Hash,
571 typename _RehashPolicy,
typename _Traits>
572 const typename _Map_base<_Key, _Pair, _Alloc, _Select1st,
573 _Equal, _H1, _H2, _Hash, _RehashPolicy,
574 _Traits,
true>::mapped_type&
575 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
576 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
577 at(
const key_type& __k)
const
579 const __hashtable* __h =
static_cast<const __hashtable*
>(
this);
580 __hash_code __code = __h->_M_hash_code(__k);
581 std::size_t __n = __h->_M_bucket_index(__k, __code);
582 __node_type* __p = __h->_M_find_node(__n, __k, __code);
585 __throw_out_of_range(__N(
"_Map_base::at"));
586 return __p->_M_v().second;
594 template<
typename _Key,
typename _Value,
typename _Alloc,
595 typename _ExtractKey,
typename _Equal,
596 typename _H1,
typename _H2,
typename _Hash,
597 typename _RehashPolicy,
typename _Traits>
601 _Equal, _H1, _H2, _Hash,
602 _RehashPolicy, _Traits>;
605 _Equal, _H1, _H2, _Hash,
608 using value_type =
typename __hashtable_base::value_type;
611 using size_type =
typename __hashtable_base::size_type;
613 using __unique_keys =
typename __hashtable_base::__unique_keys;
614 using __ireturn_type =
typename __hashtable_base::__ireturn_type;
617 _M_conjure_hashtable()
621 insert(
const value_type& __v)
624 return __h._M_insert(__v, __unique_keys());
628 insert(const_iterator __hint,
const value_type& __v)
631 return __h._M_insert(__hint, __v, __unique_keys());
636 { this->insert(__l.begin(), __l.end()); }
638 template<
typename _InputIterator>
640 insert(_InputIterator __first, _InputIterator __last);
643 template<
typename _Key,
typename _Value,
typename _Alloc,
644 typename _ExtractKey,
typename _Equal,
645 typename _H1,
typename _H2,
typename _Hash,
646 typename _RehashPolicy,
typename _Traits>
647 template<
typename _InputIterator>
649 _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
650 _RehashPolicy, _Traits>::
651 insert(_InputIterator __first, _InputIterator __last)
653 using __rehash_type =
typename __hashtable::__rehash_type;
654 using __rehash_state =
typename __hashtable::__rehash_state;
657 size_type __n_elt = __detail::__distance_fw(__first, __last);
659 __hashtable& __h = _M_conjure_hashtable();
660 __rehash_type& __rehash = __h._M_rehash_policy;
661 const __rehash_state& __saved_state = __rehash._M_state();
662 pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
663 __h._M_element_count,
666 if (__do_rehash.first)
667 __h._M_rehash(__do_rehash.second, __saved_state);
669 for (; __first != __last; ++__first)
670 __h._M_insert(*__first, __unique_keys());
678 template<
typename _Key,
typename _Value,
typename _Alloc,
679 typename _ExtractKey,
typename _Equal,
680 typename _H1,
typename _H2,
typename _Hash,
681 typename _RehashPolicy,
typename _Traits,
682 bool _Constant_iterators = _Traits::__constant_iterators::value,
683 bool _Unique_keys = _Traits::__unique_keys::value>
687 template<
typename _Key,
typename _Value,
typename _Alloc,
688 typename _ExtractKey,
typename _Equal,
689 typename _H1,
typename _H2,
typename _Hash,
690 typename _RehashPolicy,
typename _Traits>
691 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
692 _RehashPolicy, _Traits, true, true>
693 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
694 _H1, _H2, _Hash, _RehashPolicy, _Traits>
697 _Equal, _H1, _H2, _Hash,
698 _RehashPolicy, _Traits>;
699 using value_type =
typename __base_type::value_type;
700 using iterator =
typename __base_type::iterator;
701 using const_iterator =
typename __base_type::const_iterator;
703 using __unique_keys =
typename __base_type::__unique_keys;
706 using __base_type::insert;
709 insert(value_type&& __v)
712 return __h._M_insert(std::move(__v), __unique_keys());
716 insert(const_iterator __hint, value_type&& __v)
719 return __h._M_insert(__hint, std::move(__v), __unique_keys());
724 template<
typename _Key,
typename _Value,
typename _Alloc,
725 typename _ExtractKey,
typename _Equal,
726 typename _H1,
typename _H2,
typename _Hash,
727 typename _RehashPolicy,
typename _Traits>
728 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
729 _RehashPolicy, _Traits, true, false>
730 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
731 _H1, _H2, _Hash, _RehashPolicy, _Traits>
734 _Equal, _H1, _H2, _Hash,
735 _RehashPolicy, _Traits>;
736 using value_type =
typename __base_type::value_type;
737 using iterator =
typename __base_type::iterator;
738 using const_iterator =
typename __base_type::const_iterator;
740 using __unique_keys =
typename __base_type::__unique_keys;
743 using __base_type::insert;
746 insert(value_type&& __v)
749 return __h._M_insert(std::move(__v), __unique_keys());
753 insert(const_iterator __hint, value_type&& __v)
756 return __h._M_insert(__hint, std::move(__v), __unique_keys());
761 template<
typename _Key,
typename _Value,
typename _Alloc,
762 typename _ExtractKey,
typename _Equal,
763 typename _H1,
typename _H2,
typename _Hash,
764 typename _RehashPolicy,
typename _Traits,
bool _Unique_keys>
765 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
766 _RehashPolicy, _Traits, false, _Unique_keys>
767 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
768 _H1, _H2, _Hash, _RehashPolicy, _Traits>
771 _Equal, _H1, _H2, _Hash,
772 _RehashPolicy, _Traits>;
773 using value_type =
typename __base_type::value_type;
774 using iterator =
typename __base_type::iterator;
775 using const_iterator =
typename __base_type::const_iterator;
777 using __unique_keys =
typename __base_type::__unique_keys;
779 using __ireturn_type =
typename __base_type::__ireturn_type;
781 using __base_type::insert;
783 template<
typename _Pair>
784 using __is_cons = std::is_constructible<value_type, _Pair&&>;
786 template<
typename _Pair>
787 using _IFcons = std::enable_if<__is_cons<_Pair>::value>;
789 template<
typename _Pair>
790 using _IFconsp =
typename _IFcons<_Pair>::type;
792 template<
typename _Pair,
typename = _IFconsp<_Pair>>
797 return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v));
800 template<
typename _Pair,
typename = _IFconsp<_Pair>>
802 insert(const_iterator __hint, _Pair&& __v)
805 return __h._M_emplace(__hint, __unique_keys(),
806 std::forward<_Pair>(__v));
816 template<
typename _Key,
typename _Value,
typename _Alloc,
817 typename _ExtractKey,
typename _Equal,
818 typename _H1,
typename _H2,
typename _Hash,
819 typename _RehashPolicy,
typename _Traits>
823 template<
typename _Key,
typename _Value,
typename _Alloc,
824 typename _ExtractKey,
typename _Equal,
825 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
830 _Equal, _H1, _H2, _Hash,
834 max_load_factor()
const noexcept
837 return __this->__rehash_policy().max_load_factor();
841 max_load_factor(
float __z)
848 reserve(std::size_t __n)
851 __this->rehash(__builtin_ceil(__n / max_load_factor()));
861 template<
int _Nm,
typename _Tp,
862 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
866 template<
int _Nm,
typename _Tp>
877 {
return static_cast<const _Tp&
>(__eboh); }
881 {
return static_cast<_Tp&
>(__eboh); }
885 template<
int _Nm,
typename _Tp>
895 {
return __eboh._M_tp; }
899 {
return __eboh._M_tp; }
911 template<
typename _Key,
typename _Value,
typename _ExtractKey,
912 typename _H1,
typename _H2,
typename _Hash,
913 bool __cache_hash_code>
936 template<
typename _Key,
typename _Value,
typename _ExtractKey,
937 typename _H1,
typename _H2,
typename _Hash,
938 bool __cache_hash_code>
943 template<
typename _Key,
typename _Value,
typename _ExtractKey,
944 typename _H1,
typename _H2,
typename _Hash>
954 typedef void* __hash_code;
965 _M_hash_code(
const _Key& __key)
const
969 _M_bucket_index(
const _Key& __k, __hash_code, std::size_t __n)
const
970 {
return _M_ranged_hash()(__k, __n); }
973 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
974 noexcept( noexcept(declval<const _Hash&>()(declval<const _Key&>(), (std::size_t)0)) )
975 {
return _M_ranged_hash()(_M_extract()(__p->_M_v()), __n); }
988 std::swap(_M_extract(), __x._M_extract());
989 std::swap(_M_ranged_hash(), __x._M_ranged_hash());
993 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
996 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
999 _M_ranged_hash()
const {
return __ebo_hash::_S_cget(*
this); }
1002 _M_ranged_hash() {
return __ebo_hash::_S_get(*
this); }
1011 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1012 typename _H1,
typename _H2,
typename _Hash>
1013 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>;
1018 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1019 typename _H1,
typename _H2>
1035 hash_function()
const
1039 typedef std::size_t __hash_code;
1046 const _H1& __h1,
const _H2& __h2,
1051 _M_hash_code(
const _Key& __k)
const
1052 {
return _M_h1()(__k); }
1055 _M_bucket_index(
const _Key&, __hash_code __c, std::size_t __n)
const
1056 {
return _M_h2()(__c, __n); }
1059 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1060 noexcept( noexcept(declval<const _H1&>()(declval<const _Key&>()))
1061 && noexcept(declval<const _H2&>()((__hash_code)0, (std::size_t)0)) )
1062 {
return _M_h2()(_M_h1()(_M_extract()(__p->_M_v())), __n); }
1075 std::swap(_M_extract(), __x._M_extract());
1076 std::swap(_M_h1(), __x._M_h1());
1077 std::swap(_M_h2(), __x._M_h2());
1081 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1084 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1087 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1090 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1093 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1096 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1102 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1103 typename _H1,
typename _H2>
1113 _Default_ranged_hash, true>;
1123 hash_function()
const
1127 typedef std::size_t __hash_code;
1131 const _H1& __h1,
const _H2& __h2,
1132 const _Default_ranged_hash&)
1136 _M_hash_code(
const _Key& __k)
const
1137 {
return _M_h1()(__k); }
1140 _M_bucket_index(
const _Key&, __hash_code __c,
1141 std::size_t __n)
const
1142 {
return _M_h2()(__c, __n); }
1145 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1146 noexcept( noexcept(declval<const _H2&>()((__hash_code)0,
1148 {
return _M_h2()(__p->_M_hash_code, __n); }
1151 _M_store_code(
__node_type* __n, __hash_code __c)
const
1152 { __n->_M_hash_code = __c; }
1156 { __to->_M_hash_code = __from->_M_hash_code; }
1161 std::swap(_M_extract(), __x._M_extract());
1162 std::swap(_M_h1(), __x._M_h1());
1163 std::swap(_M_h2(), __x._M_h2());
1167 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1170 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1173 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1176 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1179 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1182 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1189 template <
typename _Key,
typename _Value,
typename _ExtractKey,
1190 typename _Equal,
typename _HashCodeType,
1191 bool __cache_hash_code>
1195 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1196 typename _Equal,
typename _HashCodeType>
1200 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1202 {
return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); }
1206 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1207 typename _Equal,
typename _HashCodeType>
1211 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1213 {
return __eq(__k, __extract(__n->_M_v())); }
1218 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1219 typename _H1,
typename _H2,
typename _Hash>
1221 _H1, _H2, _Hash, true>
1227 _H1, _H2, _Hash,
true>;
1233 std::size_t __bkt, std::size_t __bkt_count)
1235 _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1240 _M_cur = _M_cur->_M_next();
1244 = __base_type::_S_get(*
this)(_M_cur->_M_hash_code,
1246 if (__bkt != _M_bucket)
1252 std::size_t _M_bucket;
1253 std::size_t _M_bucket_count;
1257 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1258 typename _H1,
typename _H2,
typename _Hash>
1260 _H1, _H2, _Hash, false>
1262 _H1, _H2, _Hash, false>
1266 _H1, _H2, _Hash,
false>;
1272 std::size_t __bkt, std::size_t __bkt_count)
1274 _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1279 _M_cur = _M_cur->_M_next();
1282 std::size_t __bkt = this->_M_bucket_index(_M_cur, _M_bucket_count);
1283 if (__bkt != _M_bucket)
1289 std::size_t _M_bucket;
1290 std::size_t _M_bucket_count;
1293 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1294 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1297 _H1, _H2, _Hash, __cache>& __x,
1299 _H1, _H2, _Hash, __cache>& __y)
1300 {
return __x._M_cur == __y._M_cur; }
1302 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1303 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1305 operator!=(
const _Local_iterator_base<_Key, _Value, _ExtractKey,
1306 _H1, _H2, _Hash, __cache>& __x,
1307 const _Local_iterator_base<_Key, _Value, _ExtractKey,
1308 _H1, _H2, _Hash, __cache>& __y)
1309 {
return __x._M_cur != __y._M_cur; }
1312 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1313 typename _H1,
typename _H2,
typename _Hash,
1314 bool __constant_iterators,
bool __cache>
1317 _H1, _H2, _Hash, __cache>
1321 _H1, _H2, _Hash, __cache>;
1322 using __hash_code_base =
typename __base_type::__hash_code_base;
1324 typedef _Value value_type;
1325 typedef typename std::conditional<__constant_iterators,
1326 const _Value*, _Value*>::type
1328 typedef typename std::conditional<__constant_iterators,
1329 const _Value&, _Value&>::type
1331 typedef std::ptrdiff_t difference_type;
1338 std::size_t __bkt, std::size_t __bkt_count)
1344 {
return this->_M_cur->_M_v(); }
1348 {
return this->_M_cur->_M_valptr(); }
1367 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1368 typename _H1,
typename _H2,
typename _Hash,
1369 bool __constant_iterators,
bool __cache>
1372 _H1, _H2, _Hash, __cache>
1376 _H1, _H2, _Hash, __cache>;
1377 using __hash_code_base =
typename __base_type::__hash_code_base;
1380 typedef _Value value_type;
1381 typedef const _Value* pointer;
1382 typedef const _Value& reference;
1383 typedef std::ptrdiff_t difference_type;
1390 std::size_t __bkt, std::size_t __bkt_count)
1396 __constant_iterators,
1403 {
return this->_M_cur->_M_v(); }
1407 {
return this->_M_cur->_M_valptr(); }
1435 template<
typename _Key,
typename _Value,
1436 typename _ExtractKey,
typename _Equal,
1437 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
1440 _Traits::__hash_cached::value>,
1444 typedef _Key key_type;
1445 typedef _Value value_type;
1446 typedef _Equal key_equal;
1447 typedef std::size_t size_type;
1448 typedef std::ptrdiff_t difference_type;
1450 using __traits_type = _Traits;
1451 using __hash_cached =
typename __traits_type::__hash_cached;
1452 using __constant_iterators =
typename __traits_type::__constant_iterators;
1453 using __unique_keys =
typename __traits_type::__unique_keys;
1457 __hash_cached::value>;
1459 using __hash_code =
typename __hash_code_base::__hash_code;
1460 using __node_type =
typename __hash_code_base::__node_type;
1463 __constant_iterators::value,
1464 __hash_cached::value>;
1467 __constant_iterators::value,
1468 __hash_cached::value>;
1471 _ExtractKey, _H1, _H2, _Hash,
1472 __constant_iterators::value,
1473 __hash_cached::value>;
1477 _ExtractKey, _H1, _H2, _Hash,
1478 __constant_iterators::value,
1479 __hash_cached::value>;
1481 using __ireturn_type =
typename std::conditional<__unique_keys::value,
1486 using _EqualHelper =
_Equal_helper<_Key, _Value, _ExtractKey, _Equal,
1487 __hash_code, __hash_cached::value>;
1491 using __bucket_type = __node_base*;
1493 _Hashtable_base(
const _ExtractKey& __ex,
const _H1& __h1,
const _H2& __h2,
1494 const _Hash& __hash,
const _Equal& __eq)
1495 : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq)
1499 _M_equals(
const _Key& __k, __hash_code __c, __node_type* __n)
const
1501 return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(),
1506 _M_swap(_Hashtable_base& __x)
1508 __hash_code_base::_M_swap(__x);
1509 std::swap(_M_eq(), __x._M_eq());
1513 _M_eq()
const {
return _EqualEBO::_S_cget(*
this); }
1516 _M_eq() {
return _EqualEBO::_S_get(*
this); }
1527 template<
typename _Uiterator>
1529 _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
1533 template<
typename _Uiterator>
1536 _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
1537 _Uiterator __first2)
1539 for (; __first1 != __last1; ++__first1, ++__first2)
1540 if (!(*__first1 == *__first2))
1543 if (__first1 == __last1)
1546 _Uiterator __last2 = __first2;
1549 for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
1551 _Uiterator __tmp = __first1;
1552 while (__tmp != __it1 && !
bool(*__tmp == *__it1))
1559 std::ptrdiff_t __n2 = 0;
1560 for (__tmp = __first2; __tmp != __last2; ++__tmp)
1561 if (*__tmp == *__it1)
1567 std::ptrdiff_t __n1 = 0;
1568 for (__tmp = __it1; __tmp != __last1; ++__tmp)
1569 if (*__tmp == *__it1)
1586 template<
typename _Key,
typename _Value,
typename _Alloc,
1587 typename _ExtractKey,
typename _Equal,
1588 typename _H1,
typename _H2,
typename _Hash,
1589 typename _RehashPolicy,
typename _Traits,
1590 bool _Unique_keys = _Traits::__unique_keys::value>
1594 template<
typename _Key,
typename _Value,
typename _Alloc,
1595 typename _ExtractKey,
typename _Equal,
1596 typename _H1,
typename _H2,
typename _Hash,
1597 typename _RehashPolicy,
typename _Traits>
1599 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
1602 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1608 template<
typename _Key,
typename _Value,
typename _Alloc,
1609 typename _ExtractKey,
typename _Equal,
1610 typename _H1,
typename _H2,
typename _Hash,
1611 typename _RehashPolicy,
typename _Traits>
1613 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1614 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
1615 _M_equal(
const __hashtable& __other)
const
1617 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1619 if (__this->size() != __other.size())
1622 for (
auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1624 const auto __ity = __other.find(_ExtractKey()(*__itx));
1625 if (__ity == __other.end() || !bool(*__ity == *__itx))
1632 template<
typename _Key,
typename _Value,
typename _Alloc,
1633 typename _ExtractKey,
typename _Equal,
1634 typename _H1,
typename _H2,
typename _Hash,
1635 typename _RehashPolicy,
typename _Traits>
1637 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
1641 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1647 template<
typename _Key,
typename _Value,
typename _Alloc,
1648 typename _ExtractKey,
typename _Equal,
1649 typename _H1,
typename _H2,
typename _Hash,
1650 typename _RehashPolicy,
typename _Traits>
1652 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1653 _H1, _H2, _Hash, _RehashPolicy, _Traits,
false>::
1654 _M_equal(
const __hashtable& __other)
const
1656 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1658 if (__this->size() != __other.size())
1661 for (
auto __itx = __this->begin(); __itx != __this->end();)
1663 const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
1664 const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
1670 if (!_S_is_permutation(__xrange.first, __xrange.second,
1674 __itx = __xrange.second;
1683 template<
typename _NodeAlloc>
1691 template<
typename _Alloc>
1693 : _NodeAlloc(std::forward<_Alloc>(__a))
1702 template<
typename _Key,
typename _Value,
typename _Alloc,
1703 typename _ExtractKey,
typename _Equal,
1704 typename _H1,
typename _H2,
typename _Hash,
1705 typename _RehashPolicy,
typename _Traits>
1710 _Equal, _H1, _H2, _Hash,
1711 _RehashPolicy, _Traits>;
1712 using __val_alloc_type =
typename __hashtable::_Value_alloc_type;
1715 using __node_type =
typename __hashtable::__node_type;
1719 : _M_nodes(__nodes), _M_h(__h) { }
1723 { _M_h._M_deallocate_nodes(_M_nodes); }
1726 operator()(
const __node_type* __n)
const
1730 __node_type* __node = _M_nodes;
1731 _M_nodes = _M_nodes->_M_next();
1732 __node->_M_nxt =
nullptr;
1733 __val_alloc_type __a(_M_h._M_node_allocator());
1734 __val_alloc_traits::destroy(__a, __node->_M_valptr());
1737 __val_alloc_traits::construct(__a, __node->_M_valptr(),
1742 __node->~__node_type();
1743 __node_alloc_traits::deallocate(_M_h._M_node_allocator(),
1745 __throw_exception_again;
1749 return _M_h._M_allocate_node(__n->_M_v());
1752 mutable __node_type* _M_nodes;
1757 template<
typename _Key,
typename _Value,
typename _Alloc,
1758 typename _ExtractKey,
typename _Equal,
1759 typename _H1,
typename _H2,
typename _Hash,
1760 typename _RehashPolicy,
typename _Traits>
1765 _Equal, _H1, _H2, _Hash,
1766 _RehashPolicy, _Traits>;
1767 using __val_alloc_type =
typename __hashtable::_Value_alloc_type;
1770 using __node_type =
typename __hashtable::__node_type;
1774 : _M_nodes(__nodes), _M_h(__h) { }
1778 { _M_h._M_deallocate_nodes(_M_nodes); }
1781 operator()(__node_type* __n)
const
1785 __node_type* __node = _M_nodes;
1786 _M_nodes = _M_nodes->_M_next();
1787 __node->_M_nxt =
nullptr;
1788 __val_alloc_type __a(_M_h._M_node_allocator());
1789 __val_alloc_traits::destroy(__a, __node->_M_valptr());
1792 __val_alloc_traits::construct(__a, __node->_M_valptr(),
1797 __node->~__node_type();
1798 __node_alloc_traits::deallocate(_M_h._M_node_allocator(),
1800 __throw_exception_again;
1807 mutable __node_type* _M_nodes;
1812 _GLIBCXX_END_NAMESPACE_VERSION
1816 #endif // _HASHTABLE_POLICY_H