31 #ifndef _HASHTABLE_POLICY_H
32 #define _HASHTABLE_POLICY_H 1
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>
58 struct _Hashtable_base;
62 template<
class _Iterator>
63 inline typename std::iterator_traits<_Iterator>::difference_type
64 __distance_fw(_Iterator __first, _Iterator __last,
65 std::input_iterator_tag)
68 template<
class _Iterator>
69 inline typename std::iterator_traits<_Iterator>::difference_type
70 __distance_fw(_Iterator __first, _Iterator __last,
71 std::forward_iterator_tag)
72 {
return std::distance(__first, __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>
84 struct __is_noexcept_hash : std::integral_constant<bool,
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>
131 struct _Hashtable_traits
134 using __bool_constant = integral_constant<bool, _Cond>;
136 using __hash_cached = __bool_constant<_Cache_hash_code>;
137 using __constant_iterators = __bool_constant<_Constant_iterators>;
138 using __unique_keys = __bool_constant<_Unique_keys>;
149 struct _Hash_node_base
151 _Hash_node_base* _M_nxt;
153 _Hash_node_base() : _M_nxt() { }
155 _Hash_node_base(_Hash_node_base* __next) : _M_nxt(__next) { }
161 template<
typename _Value,
bool _Cache_hash_code>
169 template<
typename _Value>
170 struct _Hash_node<_Value,
true> : _Hash_node_base
175 template<
typename... _Args>
176 _Hash_node(_Args&&... __args)
177 : _M_v(std::forward<_Args>(__args)...), _M_hash_code() { }
180 _M_next()
const {
return static_cast<_Hash_node*
>(_M_nxt); }
188 template<
typename _Value>
189 struct _Hash_node<_Value,
false> : _Hash_node_base
193 template<
typename... _Args>
194 _Hash_node(_Args&&... __args)
195 : _M_v(std::forward<_Args>(__args)...) { }
198 _M_next()
const {
return static_cast<_Hash_node*
>(_M_nxt); }
202 template<
typename _Value,
bool _Cache_hash_code>
203 struct _Node_iterator_base
205 using __node_type = _Hash_node<_Value, _Cache_hash_code>;
209 _Node_iterator_base(__node_type* __p)
214 { _M_cur = _M_cur->_M_next(); }
217 template<
typename _Value,
bool _Cache_hash_code>
219 operator==(
const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
220 const _Node_iterator_base<_Value, _Cache_hash_code >& __y)
221 {
return __x._M_cur == __y._M_cur; }
223 template<
typename _Value,
bool _Cache_hash_code>
225 operator!=(
const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
226 const _Node_iterator_base<_Value, _Cache_hash_code>& __y)
227 {
return __x._M_cur != __y._M_cur; }
230 template<
typename _Value,
bool __constant_iterators,
bool __cache>
231 struct _Node_iterator
232 :
public _Node_iterator_base<_Value, __cache>
235 using __base_type = _Node_iterator_base<_Value, __cache>;
236 using __node_type =
typename __base_type::__node_type;
239 typedef _Value value_type;
241 typedef std::forward_iterator_tag iterator_category;
243 using pointer =
typename std::conditional<__constant_iterators,
244 const _Value*, _Value*>::type;
246 using reference =
typename std::conditional<__constant_iterators,
247 const _Value&, _Value&>::type;
253 _Node_iterator(__node_type* __p)
254 : __base_type(__p) { }
258 {
return this->_M_cur->_M_v; }
262 {
return std::__addressof(this->_M_cur->_M_v); }
274 _Node_iterator __tmp(*
this);
281 template<
typename _Value,
bool __constant_iterators,
bool __cache>
282 struct _Node_const_iterator
283 :
public _Node_iterator_base<_Value, __cache>
286 using __base_type = _Node_iterator_base<_Value, __cache>;
287 using __node_type =
typename __base_type::__node_type;
290 typedef _Value value_type;
292 typedef std::forward_iterator_tag iterator_category;
294 typedef const _Value* pointer;
295 typedef const _Value& reference;
297 _Node_const_iterator()
301 _Node_const_iterator(__node_type* __p)
302 : __base_type(__p) { }
304 _Node_const_iterator(
const _Node_iterator<_Value, __constant_iterators,
306 : __base_type(__x._M_cur) { }
310 {
return this->_M_cur->_M_v; }
314 {
return std::__addressof(this->_M_cur->_M_v); }
316 _Node_const_iterator&
326 _Node_const_iterator __tmp(*
this);
337 struct _Mod_range_hashing
344 operator()(first_argument_type __num, second_argument_type __den)
const
345 {
return __num % __den; }
353 struct _Default_ranged_hash { };
357 struct _Prime_rehash_policy
359 _Prime_rehash_policy(
float __z = 1.0)
360 : _M_max_load_factor(__z), _M_next_resize(0) { }
363 max_load_factor() const noexcept
364 {
return _M_max_load_factor; }
373 {
return __builtin_ceil(__n / (
long double)_M_max_load_factor); }
379 std::pair<bool, std::size_t>
387 {
return _M_next_resize; }
390 _M_reset(_State __state)
391 { _M_next_resize = __state; }
393 enum { _S_n_primes =
sizeof(
unsigned long) != 8 ? 256 : 256 + 48 };
397 float _M_max_load_factor;
419 template<
typename _Key,
typename _Value,
typename _Alloc,
420 typename _ExtractKey,
typename _Equal,
421 typename _H1,
typename _H2,
typename _Hash,
422 typename _RehashPolicy,
typename _Traits,
423 bool _Unique_keys = _Traits::__unique_keys::value>
424 struct _Map_base { };
427 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
428 typename _H1,
typename _H2,
typename _Hash,
429 typename _RehashPolicy,
typename _Traits>
430 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
431 _H1, _H2, _Hash, _RehashPolicy, _Traits,
false>
433 using mapped_type =
typename std::tuple_element<1, _Pair>::type;
437 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
438 typename _H1,
typename _H2,
typename _Hash,
439 typename _RehashPolicy,
typename _Traits>
440 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
441 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
444 using __hashtable_base = __detail::_Hashtable_base<_Key, _Pair,
446 _Equal, _H1, _H2, _Hash,
449 using __hashtable = _Hashtable<_Key, _Pair, _Alloc,
451 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
453 using __hash_code =
typename __hashtable_base::__hash_code;
454 using __node_type =
typename __hashtable_base::__node_type;
457 using key_type =
typename __hashtable_base::key_type;
458 using iterator =
typename __hashtable_base::iterator;
459 using mapped_type =
typename std::tuple_element<1, _Pair>::type;
462 operator[](
const key_type& __k);
465 operator[](key_type&& __k);
470 at(
const key_type& __k);
473 at(
const key_type& __k)
const;
476 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
477 typename _H1,
typename _H2,
typename _Hash,
478 typename _RehashPolicy,
typename _Traits>
479 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
480 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
482 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
483 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
484 operator[](
const key_type& __k)
486 __hashtable* __h =
static_cast<__hashtable*
>(
this);
487 __hash_code __code = __h->_M_hash_code(__k);
488 std::size_t __n = __h->_M_bucket_index(__k, __code);
489 __node_type* __p = __h->_M_find_node(__n, __k, __code);
493 __p = __h->_M_allocate_node(std::piecewise_construct,
494 std::tuple<const key_type&>(__k),
496 return __h->_M_insert_unique_node(__n, __code, __p)->second;
499 return (__p->_M_v).second;
502 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
503 typename _H1,
typename _H2,
typename _Hash,
504 typename _RehashPolicy,
typename _Traits>
505 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
506 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
508 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
509 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
510 operator[](key_type&& __k)
512 __hashtable* __h =
static_cast<__hashtable*
>(
this);
513 __hash_code __code = __h->_M_hash_code(__k);
514 std::size_t __n = __h->_M_bucket_index(__k, __code);
515 __node_type* __p = __h->_M_find_node(__n, __k, __code);
519 __p = __h->_M_allocate_node(std::piecewise_construct,
520 std::forward_as_tuple(std::move(__k)),
522 return __h->_M_insert_unique_node(__n, __code, __p)->second;
525 return (__p->_M_v).second;
528 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
529 typename _H1,
typename _H2,
typename _Hash,
530 typename _RehashPolicy,
typename _Traits>
531 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
532 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
534 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
535 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
536 at(
const key_type& __k)
538 __hashtable* __h =
static_cast<__hashtable*
>(
this);
539 __hash_code __code = __h->_M_hash_code(__k);
540 std::size_t __n = __h->_M_bucket_index(__k, __code);
541 __node_type* __p = __h->_M_find_node(__n, __k, __code);
544 __throw_out_of_range(__N(
"_Map_base::at"));
545 return (__p->_M_v).second;
548 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
549 typename _H1,
typename _H2,
typename _Hash,
550 typename _RehashPolicy,
typename _Traits>
551 const typename _Map_base<_Key, _Pair, _Alloc, _Select1st,
552 _Equal, _H1, _H2, _Hash, _RehashPolicy,
553 _Traits,
true>::mapped_type&
554 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
555 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
556 at(
const key_type& __k)
const
558 const __hashtable* __h =
static_cast<const __hashtable*
>(
this);
559 __hash_code __code = __h->_M_hash_code(__k);
560 std::size_t __n = __h->_M_bucket_index(__k, __code);
561 __node_type* __p = __h->_M_find_node(__n, __k, __code);
564 __throw_out_of_range(__N(
"_Map_base::at"));
565 return (__p->_M_v).second;
573 template<
typename _Key,
typename _Value,
typename _Alloc,
574 typename _ExtractKey,
typename _Equal,
575 typename _H1,
typename _H2,
typename _Hash,
576 typename _RehashPolicy,
typename _Traits>
579 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
580 _Equal, _H1, _H2, _Hash,
581 _RehashPolicy, _Traits>;
583 using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey,
584 _Equal, _H1, _H2, _Hash,
587 using value_type =
typename __hashtable_base::value_type;
588 using iterator =
typename __hashtable_base::iterator;
589 using const_iterator =
typename __hashtable_base::const_iterator;
590 using size_type =
typename __hashtable_base::size_type;
592 using __unique_keys =
typename __hashtable_base::__unique_keys;
593 using __ireturn_type =
typename __hashtable_base::__ireturn_type;
594 using __iconv_type =
typename __hashtable_base::__iconv_type;
597 _M_conjure_hashtable()
598 {
return *(
static_cast<__hashtable*
>(
this)); }
601 insert(
const value_type& __v)
603 __hashtable& __h = _M_conjure_hashtable();
604 return __h._M_insert(__v, __unique_keys());
608 insert(const_iterator,
const value_type& __v)
609 {
return __iconv_type()(insert(__v)); }
612 insert(initializer_list<value_type> __l)
613 { this->insert(__l.begin(), __l.end()); }
615 template<
typename _InputIterator>
617 insert(_InputIterator __first, _InputIterator __last);
620 template<
typename _Key,
typename _Value,
typename _Alloc,
621 typename _ExtractKey,
typename _Equal,
622 typename _H1,
typename _H2,
typename _Hash,
623 typename _RehashPolicy,
typename _Traits>
624 template<
typename _InputIterator>
626 _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
627 _RehashPolicy, _Traits>::
628 insert(_InputIterator __first, _InputIterator __last)
630 using __rehash_type =
typename __hashtable::__rehash_type;
631 using __rehash_state =
typename __hashtable::__rehash_state;
632 using pair_type = std::pair<bool, std::size_t>;
634 size_type __n_elt = __detail::__distance_fw(__first, __last);
636 __hashtable& __h = _M_conjure_hashtable();
637 __rehash_type& __rehash = __h._M_rehash_policy;
638 const __rehash_state& __saved_state = __rehash._M_state();
639 pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
640 __h._M_element_count,
643 if (__do_rehash.first)
644 __h._M_rehash(__do_rehash.second, __saved_state);
646 for (; __first != __last; ++__first)
647 __h._M_insert(*__first, __unique_keys());
655 template<
typename _Key,
typename _Value,
typename _Alloc,
656 typename _ExtractKey,
typename _Equal,
657 typename _H1,
typename _H2,
typename _Hash,
658 typename _RehashPolicy,
typename _Traits,
659 bool _Constant_iterators = _Traits::__constant_iterators::value,
660 bool _Unique_keys = _Traits::__unique_keys::value>
664 template<
typename _Key,
typename _Value,
typename _Alloc,
665 typename _ExtractKey,
typename _Equal,
666 typename _H1,
typename _H2,
typename _Hash,
667 typename _RehashPolicy,
typename _Traits>
668 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
670 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
671 _H1, _H2, _Hash, _RehashPolicy, _Traits>
673 using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
674 _Equal, _H1, _H2, _Hash,
675 _RehashPolicy, _Traits>;
676 using value_type =
typename __base_type::value_type;
677 using iterator =
typename __base_type::iterator;
678 using const_iterator =
typename __base_type::const_iterator;
680 using __unique_keys =
typename __base_type::__unique_keys;
681 using __hashtable =
typename __base_type::__hashtable;
683 using __base_type::insert;
685 std::pair<iterator, bool>
686 insert(value_type&& __v)
688 __hashtable& __h = this->_M_conjure_hashtable();
689 return __h._M_insert(std::move(__v), __unique_keys());
693 insert(const_iterator, value_type&& __v)
694 {
return insert(std::move(__v)).first; }
698 template<
typename _Key,
typename _Value,
typename _Alloc,
699 typename _ExtractKey,
typename _Equal,
700 typename _H1,
typename _H2,
typename _Hash,
701 typename _RehashPolicy,
typename _Traits>
702 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
704 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
705 _H1, _H2, _Hash, _RehashPolicy, _Traits>
707 using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
708 _Equal, _H1, _H2, _Hash,
709 _RehashPolicy, _Traits>;
710 using value_type =
typename __base_type::value_type;
711 using iterator =
typename __base_type::iterator;
712 using const_iterator =
typename __base_type::const_iterator;
714 using __unique_keys =
typename __base_type::__unique_keys;
715 using __hashtable =
typename __base_type::__hashtable;
717 using __base_type::insert;
720 insert(value_type&& __v)
722 __hashtable& __h = this->_M_conjure_hashtable();
723 return __h._M_insert(std::move(__v), __unique_keys());
727 insert(const_iterator, value_type&& __v)
728 {
return insert(std::move(__v)); }
732 template<
typename _Key,
typename _Value,
typename _Alloc,
733 typename _ExtractKey,
typename _Equal,
734 typename _H1,
typename _H2,
typename _Hash,
735 typename _RehashPolicy,
typename _Traits,
bool _Unique_keys>
736 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
737 _RehashPolicy, _Traits,
false, _Unique_keys>
738 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
739 _H1, _H2, _Hash, _RehashPolicy, _Traits>
741 using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey,
742 _Equal, _H1, _H2, _Hash,
743 _RehashPolicy, _Traits>;
744 using value_type =
typename __base_type::value_type;
745 using iterator =
typename __base_type::iterator;
746 using const_iterator =
typename __base_type::const_iterator;
748 using __unique_keys =
typename __base_type::__unique_keys;
749 using __hashtable =
typename __base_type::__hashtable;
750 using __ireturn_type =
typename __base_type::__ireturn_type;
751 using __iconv_type =
typename __base_type::__iconv_type;
753 using __base_type::insert;
755 template<
typename _Pair>
756 using __is_cons = std::is_constructible<value_type, _Pair&&>;
758 template<
typename _Pair>
759 using _IFcons = std::enable_if<__is_cons<_Pair>::value>;
761 template<
typename _Pair>
762 using _IFconsp =
typename _IFcons<_Pair>::type;
764 template<
typename _Pair,
typename = _IFconsp<_Pair>>
768 __hashtable& __h = this->_M_conjure_hashtable();
769 return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v));
772 template<
typename _Pair,
typename = _IFconsp<_Pair>>
774 insert(const_iterator, _Pair&& __v)
775 {
return __iconv_type()(insert(std::forward<_Pair>(__v))); }
784 template<
typename _Key,
typename _Value,
typename _Alloc,
785 typename _ExtractKey,
typename _Equal,
786 typename _H1,
typename _H2,
typename _Hash,
787 typename _RehashPolicy,
typename _Traits>
791 template<
typename _Key,
typename _Value,
typename _Alloc,
792 typename _ExtractKey,
typename _Equal,
793 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
794 struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
795 _H1, _H2, _Hash, _Prime_rehash_policy, _Traits>
797 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
798 _Equal, _H1, _H2, _Hash,
799 _Prime_rehash_policy, _Traits>;
802 max_load_factor() const noexcept
804 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
805 return __this->__rehash_policy().max_load_factor();
809 max_load_factor(
float __z)
811 __hashtable* __this =
static_cast<__hashtable*
>(
this);
812 __this->__rehash_policy(_Prime_rehash_policy(__z));
818 __hashtable* __this =
static_cast<__hashtable*
>(
this);
819 __this->rehash(__builtin_ceil(__n / max_load_factor()));
829 template<
int _Nm,
typename _Tp,
830 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
831 struct _Hashtable_ebo_helper;
834 template<
int _Nm,
typename _Tp>
835 struct _Hashtable_ebo_helper<_Nm, _Tp,
true>
838 _Hashtable_ebo_helper() =
default;
840 _Hashtable_ebo_helper(
const _Tp& __tp) : _Tp(__tp)
844 _S_cget(
const _Hashtable_ebo_helper& __eboh)
845 {
return static_cast<const _Tp&
>(__eboh); }
848 _S_get(_Hashtable_ebo_helper& __eboh)
849 {
return static_cast<_Tp&
>(__eboh); }
853 template<
int _Nm,
typename _Tp>
854 struct _Hashtable_ebo_helper<_Nm, _Tp,
false>
856 _Hashtable_ebo_helper() =
default;
858 _Hashtable_ebo_helper(
const _Tp& __tp) : _M_tp(__tp)
862 _S_cget(
const _Hashtable_ebo_helper& __eboh)
863 {
return __eboh._M_tp; }
866 _S_get(_Hashtable_ebo_helper& __eboh)
867 {
return __eboh._M_tp; }
879 template<
typename _Key,
typename _Value,
typename _ExtractKey,
880 typename _H1,
typename _H2,
typename _Hash,
881 bool __cache_hash_code>
882 struct _Local_iterator_base;
904 template<
typename _Key,
typename _Value,
typename _ExtractKey,
905 typename _H1,
typename _H2,
typename _Hash,
906 bool __cache_hash_code>
907 struct _Hash_code_base;
911 template<
typename _Key,
typename _Value,
typename _ExtractKey,
912 typename _H1,
typename _H2,
typename _Hash>
913 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
false>
914 :
private _Hashtable_ebo_helper<0, _ExtractKey>,
915 private _Hashtable_ebo_helper<1, _Hash>
918 using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>;
919 using __ebo_hash = _Hashtable_ebo_helper<1, _Hash>;
922 typedef void* __hash_code;
923 typedef _Hash_node<_Value, false> __node_type;
926 _Hash_code_base() =
default;
928 _Hash_code_base(
const _ExtractKey& __ex,
const _H1&,
const _H2&,
930 : __ebo_extract_key(__ex), __ebo_hash(__h) { }
933 _M_hash_code(
const _Key& __key)
const
937 _M_bucket_index(
const _Key& __k, __hash_code,
std::size_t __n)
const
938 {
return _M_ranged_hash()(__k, __n); }
941 _M_bucket_index(
const __node_type* __p,
std::size_t __n)
const
942 {
return _M_ranged_hash()(_M_extract()(__p->_M_v), __n); }
945 _M_store_code(__node_type*, __hash_code)
const
949 _M_copy_code(__node_type*,
const __node_type*)
const
953 _M_swap(_Hash_code_base& __x)
955 std::swap(_M_extract(), __x._M_extract());
956 std::swap(_M_ranged_hash(), __x._M_ranged_hash());
960 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
963 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
966 _M_ranged_hash()
const {
return __ebo_hash::_S_cget(*
this); }
969 _M_ranged_hash() {
return __ebo_hash::_S_get(*
this); }
978 template<
typename _Key,
typename _Value,
typename _ExtractKey,
979 typename _H1,
typename _H2,
typename _Hash>
980 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
true>;
985 template<
typename _Key,
typename _Value,
typename _ExtractKey,
986 typename _H1,
typename _H2>
987 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
988 _Default_ranged_hash,
false>
989 :
private _Hashtable_ebo_helper<0, _ExtractKey>,
990 private _Hashtable_ebo_helper<1, _H1>,
991 private _Hashtable_ebo_helper<2, _H2>
994 using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>;
995 using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>;
996 using __ebo_h2 = _Hashtable_ebo_helper<2, _H2>;
1002 hash_function()
const
1007 typedef _Hash_node<_Value, false> __node_type;
1010 _Hash_code_base() =
default;
1012 _Hash_code_base(
const _ExtractKey& __ex,
1013 const _H1& __h1,
const _H2& __h2,
1014 const _Default_ranged_hash&)
1015 : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { }
1018 _M_hash_code(
const _Key& __k)
const
1019 {
return _M_h1()(__k); }
1022 _M_bucket_index(
const _Key&, __hash_code __c,
std::size_t __n)
const
1023 {
return _M_h2()(__c, __n); }
1026 _M_bucket_index(
const __node_type* __p,
1028 {
return _M_h2()(_M_h1()(_M_extract()(__p->_M_v)), __n); }
1031 _M_store_code(__node_type*, __hash_code)
const
1035 _M_copy_code(__node_type*,
const __node_type*)
const
1039 _M_swap(_Hash_code_base& __x)
1041 std::swap(_M_extract(), __x._M_extract());
1047 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1050 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1053 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1056 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1059 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1062 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1068 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1069 typename _H1,
typename _H2>
1070 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2,
1071 _Default_ranged_hash,
true>
1072 :
private _Hashtable_ebo_helper<0, _ExtractKey>,
1073 private _Hashtable_ebo_helper<1, _H1>,
1074 private _Hashtable_ebo_helper<2, _H2>
1078 friend struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2,
1079 _Default_ranged_hash,
true>;
1081 using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>;
1082 using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>;
1083 using __ebo_h2 = _Hashtable_ebo_helper<2, _H2>;
1089 hash_function()
const
1094 typedef _Hash_node<_Value, true> __node_type;
1096 _Hash_code_base(
const _ExtractKey& __ex,
1097 const _H1& __h1,
const _H2& __h2,
1098 const _Default_ranged_hash&)
1099 : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { }
1102 _M_hash_code(
const _Key& __k)
const
1103 {
return _M_h1()(__k); }
1106 _M_bucket_index(
const _Key&, __hash_code __c,
1108 {
return _M_h2()(__c, __n); }
1111 _M_bucket_index(
const __node_type* __p,
std::size_t __n)
const
1112 {
return _M_h2()(__p->_M_hash_code, __n); }
1115 _M_store_code(__node_type* __n, __hash_code __c)
const
1116 { __n->_M_hash_code = __c; }
1119 _M_copy_code(__node_type* __to,
const __node_type* __from)
const
1120 { __to->_M_hash_code = __from->_M_hash_code; }
1123 _M_swap(_Hash_code_base& __x)
1125 std::swap(_M_extract(), __x._M_extract());
1131 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1134 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1137 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1140 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1143 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1146 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1153 template <
typename _Key,
typename _Value,
typename _ExtractKey,
1154 typename _Equal,
typename _HashCodeType,
1155 bool __cache_hash_code>
1156 struct _Equal_helper;
1159 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1160 typename _Equal,
typename _HashCodeType>
1161 struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType,
true>
1164 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1165 const _Key& __k, _HashCodeType __c, _Hash_node<_Value, true>* __n)
1166 {
return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v)); }
1170 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1171 typename _Equal,
typename _HashCodeType>
1172 struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType,
false>
1175 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1176 const _Key& __k, _HashCodeType, _Hash_node<_Value, false>* __n)
1177 {
return __eq(__k, __extract(__n->_M_v)); }
1182 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1183 typename _H1,
typename _H2,
typename _Hash>
1184 struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1185 _H1, _H2, _Hash,
true>
1186 :
private _Hashtable_ebo_helper<0, _H2>
1189 using __base_type = _Hashtable_ebo_helper<0, _H2>;
1190 using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1191 _H1, _H2, _Hash,
true>;
1194 _Local_iterator_base() =
default;
1195 _Local_iterator_base(
const __hash_code_base&
__base,
1196 _Hash_node<_Value, true>* __p,
1198 : __base_type(__base._M_h2()),
1199 _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1204 _M_cur = _M_cur->_M_next();
1208 = __base_type::_S_get(*
this)(_M_cur->_M_hash_code,
1210 if (__bkt != _M_bucket)
1215 _Hash_node<_Value, true>* _M_cur;
1221 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1222 typename _H1,
typename _H2,
typename _Hash>
1223 struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1224 _H1, _H2, _Hash,
false>
1225 :
private _Hash_code_base<_Key, _Value, _ExtractKey,
1226 _H1, _H2, _Hash, false>
1229 using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1230 _H1, _H2, _Hash,
false>;
1233 _Local_iterator_base() =
default;
1234 _Local_iterator_base(
const __hash_code_base&
__base,
1235 _Hash_node<_Value, false>* __p,
1237 : __hash_code_base(__base),
1238 _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1243 _M_cur = _M_cur->_M_next();
1246 std::size_t __bkt = this->_M_bucket_index(_M_cur, _M_bucket_count);
1247 if (__bkt != _M_bucket)
1252 _Hash_node<_Value, false>* _M_cur;
1257 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1258 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1260 operator==(
const _Local_iterator_base<_Key, _Value, _ExtractKey,
1261 _H1, _H2, _Hash, __cache>& __x,
1262 const _Local_iterator_base<_Key, _Value, _ExtractKey,
1263 _H1, _H2, _Hash, __cache>& __y)
1264 {
return __x._M_cur == __y._M_cur; }
1266 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1267 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1269 operator!=(
const _Local_iterator_base<_Key, _Value, _ExtractKey,
1270 _H1, _H2, _Hash, __cache>& __x,
1271 const _Local_iterator_base<_Key, _Value, _ExtractKey,
1272 _H1, _H2, _Hash, __cache>& __y)
1273 {
return __x._M_cur != __y._M_cur; }
1276 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1277 typename _H1,
typename _H2,
typename _Hash,
1278 bool __constant_iterators,
bool __cache>
1279 struct _Local_iterator
1280 :
public _Local_iterator_base<_Key, _Value, _ExtractKey,
1281 _H1, _H2, _Hash, __cache>
1284 using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1285 _H1, _H2, _Hash, __cache>;
1286 using __hash_code_base =
typename __base_type::__hash_code_base;
1288 typedef _Value value_type;
1289 typedef typename std::conditional<__constant_iterators,
1290 const _Value*, _Value*>::type
1292 typedef typename std::conditional<__constant_iterators,
1293 const _Value&, _Value&>::type
1296 typedef std::forward_iterator_tag iterator_category;
1298 _Local_iterator() =
default;
1300 _Local_iterator(
const __hash_code_base&
__base,
1301 _Hash_node<_Value, __cache>* __p,
1303 : __base_type(__base, __p, __bkt, __bkt_count)
1308 {
return this->_M_cur->_M_v; }
1312 {
return std::__addressof(this->_M_cur->_M_v); }
1324 _Local_iterator __tmp(*
this);
1331 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1332 typename _H1,
typename _H2,
typename _Hash,
1333 bool __constant_iterators,
bool __cache>
1334 struct _Local_const_iterator
1335 :
public _Local_iterator_base<_Key, _Value, _ExtractKey,
1336 _H1, _H2, _Hash, __cache>
1339 using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
1340 _H1, _H2, _Hash, __cache>;
1341 using __hash_code_base =
typename __base_type::__hash_code_base;
1344 typedef _Value value_type;
1345 typedef const _Value* pointer;
1346 typedef const _Value& reference;
1348 typedef std::forward_iterator_tag iterator_category;
1350 _Local_const_iterator() =
default;
1352 _Local_const_iterator(
const __hash_code_base&
__base,
1353 _Hash_node<_Value, __cache>* __p,
1355 : __base_type(__base, __p, __bkt, __bkt_count)
1358 _Local_const_iterator(
const _Local_iterator<_Key, _Value, _ExtractKey,
1360 __constant_iterators,
1367 {
return this->_M_cur->_M_v; }
1371 {
return std::__addressof(this->_M_cur->_M_v); }
1373 _Local_const_iterator&
1380 _Local_const_iterator
1383 _Local_const_iterator __tmp(*
this);
1399 template<
typename _Key,
typename _Value,
1400 typename _ExtractKey,
typename _Equal,
1401 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
1402 struct _Hashtable_base
1403 :
public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
1404 _Traits::__hash_cached::value>,
1405 private _Hashtable_ebo_helper<0, _Equal>
1408 typedef _Key key_type;
1409 typedef _Value value_type;
1410 typedef _Equal key_equal;
1414 using __traits_type = _Traits;
1415 using __hash_cached =
typename __traits_type::__hash_cached;
1416 using __constant_iterators =
typename __traits_type::__constant_iterators;
1417 using __unique_keys =
typename __traits_type::__unique_keys;
1419 using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1421 __hash_cached::value>;
1423 using __hash_code =
typename __hash_code_base::__hash_code;
1424 using __node_type =
typename __hash_code_base::__node_type;
1426 using iterator = __detail::_Node_iterator<value_type,
1427 __constant_iterators::value,
1428 __hash_cached::value>;
1430 using const_iterator = __detail::_Node_const_iterator<value_type,
1431 __constant_iterators::value,
1432 __hash_cached::value>;
1434 using local_iterator = __detail::_Local_iterator<key_type, value_type,
1435 _ExtractKey, _H1, _H2, _Hash,
1436 __constant_iterators::value,
1437 __hash_cached::value>;
1439 using const_local_iterator = __detail::_Local_const_iterator<key_type,
1441 _ExtractKey, _H1, _H2, _Hash,
1442 __constant_iterators::value,
1443 __hash_cached::value>;
1445 using __ireturn_type =
typename std::conditional<__unique_keys::value,
1446 std::pair<iterator, bool>,
1449 using __iconv_type =
typename std::conditional<__unique_keys::value,
1450 _Select1st, _Identity
1453 using _EqualEBO = _Hashtable_ebo_helper<0, _Equal>;
1454 using _EqualHelper = _Equal_helper<_Key, _Value, _ExtractKey, _Equal,
1455 __hash_code, __hash_cached::value>;
1458 using __node_base = __detail::_Hash_node_base;
1459 using __bucket_type = __node_base*;
1461 _Hashtable_base(
const _ExtractKey& __ex,
const _H1& __h1,
const _H2& __h2,
1462 const _Hash& __hash,
const _Equal& __eq)
1463 : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq)
1467 _M_equals(
const _Key& __k, __hash_code __c, __node_type* __n)
const
1469 return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(),
1474 _M_swap(_Hashtable_base& __x)
1476 __hash_code_base::_M_swap(__x);
1481 _M_eq()
const {
return _EqualEBO::_S_cget(*
this); }
1484 _M_eq() {
return _EqualEBO::_S_get(*
this); }
1492 struct _Equality_base
1495 template<
typename _Uiterator>
1497 _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
1501 template<
typename _Uiterator>
1504 _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
1505 _Uiterator __first2)
1507 for (; __first1 != __last1; ++__first1, ++__first2)
1508 if (!(*__first1 == *__first2))
1511 if (__first1 == __last1)
1514 _Uiterator __last2 = __first2;
1515 std::advance(__last2, std::distance(__first1, __last1));
1517 for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
1519 _Uiterator __tmp = __first1;
1520 while (__tmp != __it1 && !
bool(*__tmp == *__it1))
1528 for (__tmp = __first2; __tmp != __last2; ++__tmp)
1529 if (*__tmp == *__it1)
1536 for (__tmp = __it1; __tmp != __last1; ++__tmp)
1537 if (*__tmp == *__it1)
1554 template<
typename _Key,
typename _Value,
typename _Alloc,
1555 typename _ExtractKey,
typename _Equal,
1556 typename _H1,
typename _H2,
typename _Hash,
1557 typename _RehashPolicy,
typename _Traits,
1558 bool _Unique_keys = _Traits::__unique_keys::value>
1562 template<
typename _Key,
typename _Value,
typename _Alloc,
1563 typename _ExtractKey,
typename _Equal,
1564 typename _H1,
typename _H2,
typename _Hash,
1565 typename _RehashPolicy,
typename _Traits>
1566 struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1567 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
1569 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1570 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1573 _M_equal(
const __hashtable&)
const;
1576 template<
typename _Key,
typename _Value,
typename _Alloc,
1577 typename _ExtractKey,
typename _Equal,
1578 typename _H1,
typename _H2,
typename _Hash,
1579 typename _RehashPolicy,
typename _Traits>
1581 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1582 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
1583 _M_equal(
const __hashtable& __other)
const
1585 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1587 if (__this->size() != __other.size())
1590 for (
auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1592 const auto __ity = __other.find(_ExtractKey()(*__itx));
1593 if (__ity == __other.end() || !
bool(*__ity == *__itx))
1600 template<
typename _Key,
typename _Value,
typename _Alloc,
1601 typename _ExtractKey,
typename _Equal,
1602 typename _H1,
typename _H2,
typename _Hash,
1603 typename _RehashPolicy,
typename _Traits>
1604 struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1605 _H1, _H2, _Hash, _RehashPolicy, _Traits,
false>
1606 :
public _Equality_base
1608 using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1609 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1612 _M_equal(
const __hashtable&)
const;
1615 template<
typename _Key,
typename _Value,
typename _Alloc,
1616 typename _ExtractKey,
typename _Equal,
1617 typename _H1,
typename _H2,
typename _Hash,
1618 typename _RehashPolicy,
typename _Traits>
1620 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1621 _H1, _H2, _Hash, _RehashPolicy, _Traits,
false>::
1622 _M_equal(
const __hashtable& __other)
const
1624 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1626 if (__this->size() != __other.size())
1629 for (
auto __itx = __this->begin(); __itx != __this->end();)
1631 const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
1632 const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
1634 if (std::distance(__xrange.first, __xrange.second)
1635 != std::distance(__yrange.first, __yrange.second))
1638 if (!_S_is_permutation(__xrange.first, __xrange.second,
1642 __itx = __xrange.second;
1651 template<
typename _NodeAlloc>
1652 struct _Before_begin :
public _NodeAlloc
1654 _Hash_node_base _M_node;
1656 _Before_begin(
const _Before_begin&) =
default;
1657 _Before_begin(_Before_begin&&) =
default;
1659 template<
typename _Alloc>
1660 _Before_begin(_Alloc&& __a)
1661 : _NodeAlloc(std::forward<_Alloc>(__a))
1666 _GLIBCXX_END_NAMESPACE_VERSION
1670 #endif // _HASHTABLE_POLICY_H
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
Definition: functions.h:446
bool operator==(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
#define false
Definition: stdbool.h:35
#define true
Definition: stdbool.h:34
#define bool
Definition: stdbool.h:33
namespace std _GLIBCXX_VISIBILITY(default)
Definition: hashtable_policy.h:31
bool operator!=(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
__SIZE_TYPE__ size_t
Definition: stddef.h:212
__PTRDIFF_TYPE__ ptrdiff_t
Definition: stddef.h:147
void swap(exception_ptr &__lhs, exception_ptr &__rhs)
Definition: exception_ptr.h:160