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>
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
102 {
return std::get<0>(std::forward<_Tp>(__x)); }
105 template<
typename _NodeAlloc>
110 template<
typename _NodeAlloc>
111 struct _ReuseOrAllocNode
114 using __node_alloc_type = _NodeAlloc;
116 using __value_alloc_type =
typename __hashtable_alloc::__value_alloc_type;
118 typename __hashtable_alloc::__value_alloc_traits;
120 typename __hashtable_alloc::__node_alloc_traits;
121 using __node_type =
typename __hashtable_alloc::__node_type;
124 _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h)
125 : _M_nodes(__nodes), _M_h(__h) { }
126 _ReuseOrAllocNode(
const _ReuseOrAllocNode&) =
delete;
129 { _M_h._M_deallocate_nodes(_M_nodes); }
131 template<
typename _Arg>
133 operator()(_Arg&& __arg)
const
137 __node_type* __node = _M_nodes;
138 _M_nodes = _M_nodes->_M_next();
139 __node->_M_nxt =
nullptr;
140 __value_alloc_type __a(_M_h._M_node_allocator());
141 __value_alloc_traits::destroy(__a, __node->_M_valptr());
144 __value_alloc_traits::construct(__a, __node->_M_valptr(),
145 std::forward<_Arg>(__arg));
149 __node->~__node_type();
150 __node_alloc_traits::deallocate(_M_h._M_node_allocator(),
152 __throw_exception_again;
156 return _M_h._M_allocate_node(std::forward<_Arg>(__arg));
160 mutable __node_type* _M_nodes;
161 __hashtable_alloc& _M_h;
166 template<
typename _NodeAlloc>
170 using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>;
171 using __node_type =
typename __hashtable_alloc::__node_type;
174 _AllocNode(__hashtable_alloc& __h)
177 template<
typename _Arg>
179 operator()(_Arg&& __arg)
const
180 {
return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); }
183 __hashtable_alloc& _M_h;
211 template<
bool _Cache_hash_code,
bool _Constant_iterators,
bool _Unique_keys>
215 using __bool_constant = integral_constant<bool, _Cond>;
217 using __hash_cached = __bool_constant<_Cache_hash_code>;
218 using __constant_iterators = __bool_constant<_Constant_iterators>;
219 using __unique_keys = __bool_constant<_Unique_keys>;
244 template<
typename _Value>
247 typedef _Value value_type;
249 __gnu_cxx::__aligned_buffer<_Value> _M_storage;
253 {
return _M_storage._M_ptr(); }
256 _M_valptr()
const noexcept
257 {
return _M_storage._M_ptr(); }
261 {
return *_M_valptr(); }
264 _M_v()
const noexcept
265 {
return *_M_valptr(); }
271 template<
typename _Value,
bool _Cache_hash_code>
279 template<
typename _Value>
282 std::size_t _M_hash_code;
285 _M_next()
const noexcept
286 {
return static_cast<_Hash_node*
>(this->_M_nxt); }
294 template<
typename _Value>
298 _M_next()
const noexcept
299 {
return static_cast<_Hash_node*
>(this->_M_nxt); }
303 template<
typename _Value,
bool _Cache_hash_code>
315 { _M_cur = _M_cur->_M_next(); }
318 template<
typename _Value,
bool _Cache_hash_code>
323 {
return __x._M_cur == __y._M_cur; }
325 template<
typename _Value,
bool _Cache_hash_code>
327 operator!=(
const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
328 const _Node_iterator_base<_Value, _Cache_hash_code>& __y)
330 {
return __x._M_cur != __y._M_cur; }
333 template<
typename _Value,
bool __constant_iterators,
bool __cache>
342 typedef _Value value_type;
343 typedef std::ptrdiff_t difference_type;
346 using pointer =
typename std::conditional<__constant_iterators,
347 const _Value*, _Value*>::type;
349 using reference =
typename std::conditional<__constant_iterators,
350 const _Value&, _Value&>::type;
360 operator*()
const noexcept
361 {
return this->_M_cur->_M_v(); }
364 operator->()
const noexcept
365 {
return this->_M_cur->_M_valptr(); }
368 operator++() noexcept
375 operator++(
int) noexcept
384 template<
typename _Value,
bool __constant_iterators,
bool __cache>
393 typedef _Value value_type;
394 typedef std::ptrdiff_t difference_type;
397 typedef const _Value* pointer;
398 typedef const _Value& reference;
408 __cache>& __x) noexcept
412 operator*()
const noexcept
413 {
return this->_M_cur->_M_v(); }
416 operator->()
const noexcept
417 {
return this->_M_cur->_M_valptr(); }
420 operator++() noexcept
427 operator++(
int) noexcept
442 typedef std::size_t first_argument_type;
443 typedef std::size_t second_argument_type;
444 typedef std::size_t result_type;
447 operator()(first_argument_type __num,
448 second_argument_type __den)
const noexcept
449 {
return __num % __den; }
464 : _M_max_load_factor(__z), _M_next_resize(0) { }
467 max_load_factor()
const noexcept
468 {
return _M_max_load_factor; }
472 _M_next_bkt(std::size_t __n)
const;
476 _M_bkt_for_elements(std::size_t __n)
const
477 {
return __builtin_ceil(__n / (
long double)_M_max_load_factor); }
484 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
485 std::size_t __n_ins)
const;
487 typedef std::size_t _State;
491 {
return _M_next_resize; }
495 { _M_next_resize = 0; }
498 _M_reset(_State __state)
499 { _M_next_resize = __state; }
501 enum { _S_n_primes =
sizeof(
unsigned long) != 8 ? 256 : 256 + 48 };
503 static const std::size_t _S_growth_factor = 2;
505 float _M_max_load_factor;
506 mutable std::size_t _M_next_resize;
527 template<
typename _Key,
typename _Value,
typename _Alloc,
528 typename _ExtractKey,
typename _Equal,
529 typename _H1,
typename _H2,
typename _Hash,
530 typename _RehashPolicy,
typename _Traits,
531 bool _Unique_keys = _Traits::__unique_keys::value>
535 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
536 typename _H1,
typename _H2,
typename _Hash,
537 typename _RehashPolicy,
typename _Traits>
538 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
539 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
541 using mapped_type =
typename std::tuple_element<1, _Pair>::type;
545 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
546 typename _H1,
typename _H2,
typename _Hash,
547 typename _RehashPolicy,
typename _Traits>
548 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
549 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
554 _Equal, _H1, _H2, _Hash,
559 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
561 using __hash_code =
typename __hashtable_base::__hash_code;
562 using __node_type =
typename __hashtable_base::__node_type;
565 using key_type =
typename __hashtable_base::key_type;
567 using mapped_type =
typename std::tuple_element<1, _Pair>::type;
570 operator[](
const key_type& __k);
573 operator[](key_type&& __k);
578 at(
const key_type& __k);
581 at(
const key_type& __k)
const;
584 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
585 typename _H1,
typename _H2,
typename _Hash,
586 typename _RehashPolicy,
typename _Traits>
587 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
588 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
590 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
591 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
592 operator[](
const key_type& __k)
594 __hashtable* __h =
static_cast<__hashtable*
>(
this);
595 __hash_code __code = __h->_M_hash_code(__k);
596 std::size_t __n = __h->_M_bucket_index(__k, __code);
597 __node_type* __p = __h->_M_find_node(__n, __k, __code);
602 std::tuple<const key_type&>(__k),
604 return __h->_M_insert_unique_node(__n, __code, __p)->second;
607 return __p->_M_v().second;
610 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
611 typename _H1,
typename _H2,
typename _Hash,
612 typename _RehashPolicy,
typename _Traits>
613 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
614 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
616 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
617 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
618 operator[](key_type&& __k)
620 __hashtable* __h =
static_cast<__hashtable*
>(
this);
621 __hash_code __code = __h->_M_hash_code(__k);
622 std::size_t __n = __h->_M_bucket_index(__k, __code);
623 __node_type* __p = __h->_M_find_node(__n, __k, __code);
630 return __h->_M_insert_unique_node(__n, __code, __p)->second;
633 return __p->_M_v().second;
636 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
637 typename _H1,
typename _H2,
typename _Hash,
638 typename _RehashPolicy,
typename _Traits>
639 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
640 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
642 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
643 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
644 at(
const key_type& __k)
646 __hashtable* __h =
static_cast<__hashtable*
>(
this);
647 __hash_code __code = __h->_M_hash_code(__k);
648 std::size_t __n = __h->_M_bucket_index(__k, __code);
649 __node_type* __p = __h->_M_find_node(__n, __k, __code);
652 __throw_out_of_range(__N(
"_Map_base::at"));
653 return __p->_M_v().second;
656 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
657 typename _H1,
typename _H2,
typename _Hash,
658 typename _RehashPolicy,
typename _Traits>
659 const typename _Map_base<_Key, _Pair, _Alloc, _Select1st,
660 _Equal, _H1, _H2, _Hash, _RehashPolicy,
661 _Traits,
true>::mapped_type&
662 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
663 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
664 at(
const key_type& __k)
const
666 const __hashtable* __h =
static_cast<const __hashtable*
>(
this);
667 __hash_code __code = __h->_M_hash_code(__k);
668 std::size_t __n = __h->_M_bucket_index(__k, __code);
669 __node_type* __p = __h->_M_find_node(__n, __k, __code);
672 __throw_out_of_range(__N(
"_Map_base::at"));
673 return __p->_M_v().second;
681 template<
typename _Key,
typename _Value,
typename _Alloc,
682 typename _ExtractKey,
typename _Equal,
683 typename _H1,
typename _H2,
typename _Hash,
684 typename _RehashPolicy,
typename _Traits>
689 _Equal, _H1, _H2, _Hash,
690 _RehashPolicy, _Traits>;
693 _Equal, _H1, _H2, _Hash,
696 using value_type =
typename __hashtable_base::value_type;
699 using size_type =
typename __hashtable_base::size_type;
701 using __unique_keys =
typename __hashtable_base::__unique_keys;
702 using __ireturn_type =
typename __hashtable_base::__ireturn_type;
704 using __node_alloc_type =
705 typename __alloctr_rebind<_Alloc, __node_type>::__type;
706 using __node_gen_type = _AllocNode<__node_alloc_type>;
709 _M_conjure_hashtable()
712 template<
typename _InputIterator,
typename _NodeGetter>
714 _M_insert_range(_InputIterator __first, _InputIterator __last,
719 insert(
const value_type& __v)
722 __node_gen_type __node_gen(__h);
723 return __h._M_insert(__v, __node_gen, __unique_keys());
727 insert(const_iterator __hint,
const value_type& __v)
730 __node_gen_type __node_gen(__h);
731 return __h._M_insert(__hint, __v, __node_gen, __unique_keys());
735 insert(initializer_list<value_type> __l)
736 { this->insert(__l.begin(), __l.end()); }
738 template<
typename _InputIterator>
740 insert(_InputIterator __first, _InputIterator __last)
743 __node_gen_type __node_gen(__h);
744 return _M_insert_range(__first, __last, __node_gen);
748 template<
typename _Key,
typename _Value,
typename _Alloc,
749 typename _ExtractKey,
typename _Equal,
750 typename _H1,
typename _H2,
typename _Hash,
751 typename _RehashPolicy,
typename _Traits>
752 template<
typename _InputIterator,
typename _NodeGetter>
754 _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
755 _RehashPolicy, _Traits>::
756 _M_insert_range(_InputIterator __first, _InputIterator __last,
757 const _NodeGetter& __node_gen)
759 using __rehash_type =
typename __hashtable::__rehash_type;
760 using __rehash_state =
typename __hashtable::__rehash_state;
763 size_type __n_elt = __detail::__distance_fw(__first, __last);
765 __hashtable& __h = _M_conjure_hashtable();
766 __rehash_type& __rehash = __h._M_rehash_policy;
767 const __rehash_state& __saved_state = __rehash._M_state();
768 pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
769 __h._M_element_count,
772 if (__do_rehash.first)
773 __h._M_rehash(__do_rehash.second, __saved_state);
775 for (; __first != __last; ++__first)
776 __h._M_insert(*__first, __node_gen, __unique_keys());
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,
788 bool _Constant_iterators = _Traits::__constant_iterators::value,
789 bool _Unique_keys = _Traits::__unique_keys::value>
793 template<
typename _Key,
typename _Value,
typename _Alloc,
794 typename _ExtractKey,
typename _Equal,
795 typename _H1,
typename _H2,
typename _Hash,
796 typename _RehashPolicy,
typename _Traits>
797 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
798 _RehashPolicy, _Traits, true, true>
799 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
800 _H1, _H2, _Hash, _RehashPolicy, _Traits>
803 _Equal, _H1, _H2, _Hash,
804 _RehashPolicy, _Traits>;
805 using value_type =
typename __base_type::value_type;
806 using iterator =
typename __base_type::iterator;
807 using const_iterator =
typename __base_type::const_iterator;
809 using __unique_keys =
typename __base_type::__unique_keys;
811 using __node_gen_type =
typename __base_type::__node_gen_type;
813 using __base_type::insert;
816 insert(value_type&& __v)
819 __node_gen_type __node_gen(__h);
820 return __h._M_insert(
std::move(__v), __node_gen, __unique_keys());
824 insert(const_iterator __hint, value_type&& __v)
827 __node_gen_type __node_gen(__h);
828 return __h._M_insert(__hint,
std::move(__v), __node_gen,
834 template<
typename _Key,
typename _Value,
typename _Alloc,
835 typename _ExtractKey,
typename _Equal,
836 typename _H1,
typename _H2,
typename _Hash,
837 typename _RehashPolicy,
typename _Traits>
838 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
839 _RehashPolicy, _Traits, true, false>
840 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
841 _H1, _H2, _Hash, _RehashPolicy, _Traits>
844 _Equal, _H1, _H2, _Hash,
845 _RehashPolicy, _Traits>;
846 using value_type =
typename __base_type::value_type;
847 using iterator =
typename __base_type::iterator;
848 using const_iterator =
typename __base_type::const_iterator;
850 using __unique_keys =
typename __base_type::__unique_keys;
852 using __node_gen_type =
typename __base_type::__node_gen_type;
854 using __base_type::insert;
857 insert(value_type&& __v)
860 __node_gen_type __node_gen(__h);
861 return __h._M_insert(
std::move(__v), __node_gen, __unique_keys());
865 insert(const_iterator __hint, value_type&& __v)
868 __node_gen_type __node_gen(__h);
869 return __h._M_insert(__hint,
std::move(__v), __node_gen,
875 template<
typename _Key,
typename _Value,
typename _Alloc,
876 typename _ExtractKey,
typename _Equal,
877 typename _H1,
typename _H2,
typename _Hash,
878 typename _RehashPolicy,
typename _Traits,
bool _Unique_keys>
879 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
880 _RehashPolicy, _Traits, false, _Unique_keys>
881 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
882 _H1, _H2, _Hash, _RehashPolicy, _Traits>
885 _Equal, _H1, _H2, _Hash,
886 _RehashPolicy, _Traits>;
887 using value_type =
typename __base_type::value_type;
888 using iterator =
typename __base_type::iterator;
889 using const_iterator =
typename __base_type::const_iterator;
891 using __unique_keys =
typename __base_type::__unique_keys;
893 using __ireturn_type =
typename __base_type::__ireturn_type;
895 using __base_type::insert;
897 template<
typename _Pair>
898 using __is_cons = std::is_constructible<value_type, _Pair&&>;
900 template<
typename _Pair>
901 using _IFcons = std::enable_if<__is_cons<_Pair>::value>;
903 template<
typename _Pair>
904 using _IFconsp =
typename _IFcons<_Pair>::type;
906 template<
typename _Pair,
typename = _IFconsp<_Pair>>
911 return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v));
914 template<
typename _Pair,
typename = _IFconsp<_Pair>>
916 insert(const_iterator __hint, _Pair&& __v)
919 return __h._M_emplace(__hint, __unique_keys(),
920 std::forward<_Pair>(__v));
930 template<
typename _Key,
typename _Value,
typename _Alloc,
931 typename _ExtractKey,
typename _Equal,
932 typename _H1,
typename _H2,
typename _Hash,
933 typename _RehashPolicy,
typename _Traits>
937 template<
typename _Key,
typename _Value,
typename _Alloc,
938 typename _ExtractKey,
typename _Equal,
939 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
944 _Equal, _H1, _H2, _Hash,
948 max_load_factor()
const noexcept
950 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
951 return __this->__rehash_policy().max_load_factor();
955 max_load_factor(
float __z)
957 __hashtable* __this =
static_cast<__hashtable*
>(
this);
958 __this->__rehash_policy(_Prime_rehash_policy(__z));
962 reserve(std::size_t __n)
964 __hashtable* __this =
static_cast<__hashtable*
>(
this);
965 __this->rehash(__builtin_ceil(__n / max_load_factor()));
975 template<
int _Nm,
typename _Tp,
976 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
980 template<
int _Nm,
typename _Tp>
986 template<
typename _OtherTp>
988 : _Tp(std::forward<_OtherTp>(__tp))
993 {
return static_cast<const _Tp&
>(__eboh); }
997 {
return static_cast<_Tp&
>(__eboh); }
1001 template<
int _Nm,
typename _Tp>
1006 template<
typename _OtherTp>
1008 : _M_tp(std::forward<_OtherTp>(__tp))
1013 {
return __eboh._M_tp; }
1017 {
return __eboh._M_tp; }
1029 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1030 typename _H1,
typename _H2,
typename _Hash,
1031 bool __cache_hash_code>
1054 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1055 typename _H1,
typename _H2,
typename _Hash,
1056 bool __cache_hash_code>
1061 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1062 typename _H1,
typename _H2,
typename _Hash>
1072 typedef void* __hash_code;
1083 _M_hash_code(
const _Key& __key)
const
1087 _M_bucket_index(
const _Key& __k, __hash_code, std::size_t __n)
const
1088 {
return _M_ranged_hash()(__k, __n); }
1091 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1092 noexcept( noexcept(declval<const _Hash&>()(declval<const _Key&>(),
1094 {
return _M_ranged_hash()(_M_extract()(__p->_M_v()), __n); }
1097 _M_store_code(__node_type*, __hash_code)
const
1101 _M_copy_code(__node_type*,
const __node_type*)
const
1107 std::swap(_M_extract(), __x._M_extract());
1108 std::swap(_M_ranged_hash(), __x._M_ranged_hash());
1112 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1115 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1118 _M_ranged_hash()
const {
return __ebo_hash::_S_cget(*
this); }
1121 _M_ranged_hash() {
return __ebo_hash::_S_get(*
this); }
1130 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1131 typename _H1,
typename _H2,
typename _Hash>
1132 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>;
1137 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1138 typename _H1,
typename _H2>
1152 _Default_ranged_hash, false>;
1158 hash_function()
const
1162 typedef std::size_t __hash_code;
1169 const _H1& __h1,
const _H2& __h2,
1170 const _Default_ranged_hash&)
1174 _M_hash_code(
const _Key& __k)
const
1175 {
return _M_h1()(__k); }
1178 _M_bucket_index(
const _Key&, __hash_code __c, std::size_t __n)
const
1179 {
return _M_h2()(__c, __n); }
1182 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1183 noexcept( noexcept(declval<const _H1&>()(declval<const _Key&>()))
1184 && noexcept(declval<const _H2&>()((__hash_code)0,
1186 {
return _M_h2()(_M_h1()(_M_extract()(__p->_M_v())), __n); }
1189 _M_store_code(__node_type*, __hash_code)
const
1193 _M_copy_code(__node_type*,
const __node_type*)
const
1199 std::swap(_M_extract(), __x._M_extract());
1205 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1208 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1211 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1214 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1217 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1220 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1226 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1227 typename _H1,
typename _H2>
1237 _Default_ranged_hash, true>;
1247 hash_function()
const
1251 typedef std::size_t __hash_code;
1255 const _H1& __h1,
const _H2& __h2,
1256 const _Default_ranged_hash&)
1260 _M_hash_code(
const _Key& __k)
const
1261 {
return _M_h1()(__k); }
1264 _M_bucket_index(
const _Key&, __hash_code __c,
1265 std::size_t __n)
const
1266 {
return _M_h2()(__c, __n); }
1269 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1270 noexcept( noexcept(declval<const _H2&>()((__hash_code)0,
1272 {
return _M_h2()(__p->_M_hash_code, __n); }
1275 _M_store_code(__node_type* __n, __hash_code __c)
const
1276 { __n->_M_hash_code = __c; }
1279 _M_copy_code(__node_type* __to,
const __node_type* __from)
const
1280 { __to->_M_hash_code = __from->_M_hash_code; }
1285 std::swap(_M_extract(), __x._M_extract());
1291 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1294 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1297 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1300 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1303 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1306 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1313 template <
typename _Key,
typename _Value,
typename _ExtractKey,
1314 typename _Equal,
typename _HashCodeType,
1315 bool __cache_hash_code>
1319 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1320 typename _Equal,
typename _HashCodeType>
1324 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1326 {
return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); }
1330 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1331 typename _Equal,
typename _HashCodeType>
1335 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1337 {
return __eq(__k, __extract(__n->_M_v())); }
1342 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1343 typename _H1,
typename _H2,
typename _Hash>
1345 _H1, _H2, _Hash, true>
1351 _H1, _H2, _Hash,
true>;
1356 std::size_t __bkt, std::size_t __bkt_count)
1358 _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1363 _M_cur = _M_cur->_M_next();
1367 = __base_type::_S_get(*
this)(_M_cur->_M_hash_code,
1369 if (__bkt != _M_bucket)
1375 std::size_t _M_bucket;
1376 std::size_t _M_bucket_count;
1380 _M_curr()
const {
return _M_cur; }
1383 _M_get_bucket()
const {
return _M_bucket; }
1390 template<typename _Tp, bool _IsEmpty = std::is_empty<_Tp>::value>
1391 struct _Hash_code_storage
1393 __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
1396 _M_h() {
return _M_storage._M_ptr(); }
1399 _M_h()
const {
return _M_storage._M_ptr(); }
1403 template<
typename _Tp>
1404 struct _Hash_code_storage<_Tp, true>
1406 static_assert( std::is_empty<_Tp>::value,
"Type must be empty" );
1411 _M_h() {
return reinterpret_cast<_Tp*
>(
this); }
1414 _M_h()
const {
return reinterpret_cast<const _Tp*
>(
this); }
1417 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1418 typename _H1,
typename _H2,
typename _Hash>
1419 using __hash_code_for_local_iter
1420 = _Hash_code_storage<_Hash_code_base<_Key, _Value, _ExtractKey,
1421 _H1, _H2, _Hash,
false>>;
1424 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1425 typename _H1,
typename _H2,
typename _Hash>
1426 struct _Local_iterator_base<_Key, _Value, _ExtractKey,
1427 _H1, _H2, _Hash, false>
1428 : __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash>
1431 using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
1432 _H1, _H2, _Hash,
false>;
1434 _Local_iterator_base() : _M_bucket_count(-1) { }
1436 _Local_iterator_base(
const __hash_code_base&
__base,
1437 _Hash_node<_Value, false>* __p,
1438 std::size_t __bkt, std::size_t __bkt_count)
1439 : _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
1440 { _M_init(__base); }
1442 ~_Local_iterator_base()
1444 if (_M_bucket_count != -1)
1448 _Local_iterator_base(
const _Local_iterator_base& __iter)
1449 : _M_cur(__iter._M_cur), _M_bucket(__iter._M_bucket),
1450 _M_bucket_count(__iter._M_bucket_count)
1452 if (_M_bucket_count != -1)
1453 _M_init(*__iter._M_h());
1456 _Local_iterator_base&
1457 operator=(
const _Local_iterator_base& __iter)
1459 if (_M_bucket_count != -1)
1461 _M_cur = __iter._M_cur;
1462 _M_bucket = __iter._M_bucket;
1463 _M_bucket_count = __iter._M_bucket_count;
1464 if (_M_bucket_count != -1)
1465 _M_init(*__iter._M_h());
1472 _M_cur = _M_cur->_M_next();
1475 std::size_t __bkt = this->_M_h()->_M_bucket_index(_M_cur,
1477 if (__bkt != _M_bucket)
1482 _Hash_node<_Value, false>* _M_cur;
1483 std::size_t _M_bucket;
1484 std::size_t _M_bucket_count;
1487 _M_init(
const __hash_code_base&
__base)
1488 { ::new(this->_M_h()) __hash_code_base(__base); }
1491 _M_destroy() { this->_M_h()->~__hash_code_base(); }
1495 _M_curr()
const {
return _M_cur; }
1498 _M_get_bucket()
const {
return _M_bucket; }
1501 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1502 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1504 operator==(
const _Local_iterator_base<_Key, _Value, _ExtractKey,
1505 _H1, _H2, _Hash, __cache>& __x,
1506 const _Local_iterator_base<_Key, _Value, _ExtractKey,
1507 _H1, _H2, _Hash, __cache>& __y)
1508 {
return __x._M_curr() == __y._M_curr(); }
1510 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1511 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1513 operator!=(
const _Local_iterator_base<_Key, _Value, _ExtractKey,
1514 _H1, _H2, _Hash, __cache>& __x,
1515 const _Local_iterator_base<_Key, _Value, _ExtractKey,
1516 _H1, _H2, _Hash, __cache>& __y)
1517 {
return __x._M_curr() != __y._M_curr(); }
1520 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1521 typename _H1,
typename _H2,
typename _Hash,
1522 bool __constant_iterators,
bool __cache>
1525 _H1, _H2, _Hash, __cache>
1529 _H1, _H2, _Hash, __cache>;
1530 using __hash_code_base =
typename __base_type::__hash_code_base;
1532 typedef _Value value_type;
1533 typedef typename std::conditional<__constant_iterators,
1534 const _Value*, _Value*>::type
1536 typedef typename std::conditional<__constant_iterators,
1537 const _Value&, _Value&>::type
1539 typedef std::ptrdiff_t difference_type;
1546 std::size_t __bkt, std::size_t __bkt_count)
1552 {
return this->_M_cur->_M_v(); }
1556 {
return this->_M_cur->_M_valptr(); }
1575 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1576 typename _H1,
typename _H2,
typename _Hash,
1577 bool __constant_iterators,
bool __cache>
1580 _H1, _H2, _Hash, __cache>
1584 _H1, _H2, _Hash, __cache>;
1585 using __hash_code_base =
typename __base_type::__hash_code_base;
1588 typedef _Value value_type;
1589 typedef const _Value* pointer;
1590 typedef const _Value& reference;
1591 typedef std::ptrdiff_t difference_type;
1598 std::size_t __bkt, std::size_t __bkt_count)
1604 __constant_iterators,
1611 {
return this->_M_cur->_M_v(); }
1615 {
return this->_M_cur->_M_valptr(); }
1643 template<
typename _Key,
typename _Value,
1644 typename _ExtractKey,
typename _Equal,
1645 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
1648 _Traits::__hash_cached::value>,
1652 typedef _Key key_type;
1653 typedef _Value value_type;
1654 typedef _Equal key_equal;
1655 typedef std::size_t size_type;
1656 typedef std::ptrdiff_t difference_type;
1658 using __traits_type = _Traits;
1659 using __hash_cached =
typename __traits_type::__hash_cached;
1660 using __constant_iterators =
typename __traits_type::__constant_iterators;
1661 using __unique_keys =
typename __traits_type::__unique_keys;
1665 __hash_cached::value>;
1667 using __hash_code =
typename __hash_code_base::__hash_code;
1668 using __node_type =
typename __hash_code_base::__node_type;
1671 __constant_iterators::value,
1672 __hash_cached::value>;
1675 __constant_iterators::value,
1676 __hash_cached::value>;
1679 _ExtractKey, _H1, _H2, _Hash,
1680 __constant_iterators::value,
1681 __hash_cached::value>;
1685 _ExtractKey, _H1, _H2, _Hash,
1686 __constant_iterators::value,
1687 __hash_cached::value>;
1689 using __ireturn_type =
typename std::conditional<__unique_keys::value,
1694 using _EqualHelper =
_Equal_helper<_Key, _Value, _ExtractKey, _Equal,
1695 __hash_code, __hash_cached::value>;
1698 _Hashtable_base(
const _ExtractKey& __ex,
const _H1& __h1,
const _H2& __h2,
1699 const _Hash& __hash,
const _Equal& __eq)
1700 : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq)
1704 _M_equals(
const _Key& __k, __hash_code __c, __node_type* __n)
const
1706 return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(),
1711 _M_swap(_Hashtable_base& __x)
1713 __hash_code_base::_M_swap(__x);
1718 _M_eq()
const {
return _EqualEBO::_S_cget(*
this); }
1721 _M_eq() {
return _EqualEBO::_S_get(*
this); }
1732 template<
typename _Uiterator>
1734 _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
1738 template<
typename _Uiterator>
1741 _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
1742 _Uiterator __first2)
1744 for (; __first1 != __last1; ++__first1, ++__first2)
1745 if (!(*__first1 == *__first2))
1748 if (__first1 == __last1)
1751 _Uiterator __last2 = __first2;
1754 for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
1756 _Uiterator __tmp = __first1;
1757 while (__tmp != __it1 && !
bool(*__tmp == *__it1))
1764 std::ptrdiff_t __n2 = 0;
1765 for (__tmp = __first2; __tmp != __last2; ++__tmp)
1766 if (*__tmp == *__it1)
1772 std::ptrdiff_t __n1 = 0;
1773 for (__tmp = __it1; __tmp != __last1; ++__tmp)
1774 if (*__tmp == *__it1)
1791 template<
typename _Key,
typename _Value,
typename _Alloc,
1792 typename _ExtractKey,
typename _Equal,
1793 typename _H1,
typename _H2,
typename _Hash,
1794 typename _RehashPolicy,
typename _Traits,
1795 bool _Unique_keys = _Traits::__unique_keys::value>
1799 template<
typename _Key,
typename _Value,
typename _Alloc,
1800 typename _ExtractKey,
typename _Equal,
1801 typename _H1,
typename _H2,
typename _Hash,
1802 typename _RehashPolicy,
typename _Traits>
1804 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
1807 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1810 _M_equal(
const __hashtable&)
const;
1813 template<
typename _Key,
typename _Value,
typename _Alloc,
1814 typename _ExtractKey,
typename _Equal,
1815 typename _H1,
typename _H2,
typename _Hash,
1816 typename _RehashPolicy,
typename _Traits>
1818 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1819 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
1820 _M_equal(
const __hashtable& __other)
const
1822 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1824 if (__this->size() != __other.size())
1827 for (
auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1829 const auto __ity = __other.find(_ExtractKey()(*__itx));
1830 if (__ity == __other.end() || !bool(*__ity == *__itx))
1837 template<
typename _Key,
typename _Value,
typename _Alloc,
1838 typename _ExtractKey,
typename _Equal,
1839 typename _H1,
typename _H2,
typename _Hash,
1840 typename _RehashPolicy,
typename _Traits>
1842 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
1846 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1849 _M_equal(
const __hashtable&)
const;
1852 template<
typename _Key,
typename _Value,
typename _Alloc,
1853 typename _ExtractKey,
typename _Equal,
1854 typename _H1,
typename _H2,
typename _Hash,
1855 typename _RehashPolicy,
typename _Traits>
1857 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1858 _H1, _H2, _Hash, _RehashPolicy, _Traits,
false>::
1859 _M_equal(
const __hashtable& __other)
const
1861 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1863 if (__this->size() != __other.size())
1866 for (
auto __itx = __this->begin(); __itx != __this->end();)
1868 const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
1869 const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
1875 if (!_S_is_permutation(__xrange.first, __xrange.second,
1879 __itx = __xrange.second;
1888 template<
typename _NodeAlloc>
1889 struct _Hashtable_alloc :
private _Hashtable_ebo_helper<0, _NodeAlloc>
1892 using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>;
1894 using __node_type =
typename _NodeAlloc::value_type;
1895 using __node_alloc_type = _NodeAlloc;
1899 using __value_type =
typename __node_type::value_type;
1900 using __value_alloc_type =
1901 typename __alloctr_rebind<__node_alloc_type, __value_type>::__type;
1904 using __node_base = __detail::_Hash_node_base;
1905 using __bucket_type = __node_base*;
1906 using __bucket_alloc_type =
1907 typename __alloctr_rebind<__node_alloc_type, __bucket_type>::__type;
1910 _Hashtable_alloc(
const _Hashtable_alloc&) =
default;
1911 _Hashtable_alloc(_Hashtable_alloc&&) =
default;
1913 template<
typename _Alloc>
1914 _Hashtable_alloc(_Alloc&& __a)
1915 : __ebo_node_alloc(
std::
forward<_Alloc>(__a))
1920 {
return __ebo_node_alloc::_S_get(*
this); }
1922 const __node_alloc_type&
1923 _M_node_allocator()
const
1924 {
return __ebo_node_alloc::_S_cget(*
this); }
1926 template<
typename... _Args>
1928 _M_allocate_node(_Args&&... __args);
1931 _M_deallocate_node(__node_type* __n);
1935 _M_deallocate_nodes(__node_type* __n);
1938 _M_allocate_buckets(std::size_t __n);
1941 _M_deallocate_buckets(__bucket_type*, std::size_t __n);
1946 template<
typename _NodeAlloc>
1947 template<
typename... _Args>
1948 typename _Hashtable_alloc<_NodeAlloc>::__node_type*
1949 _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
1951 auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
1955 __value_alloc_type __a(_M_node_allocator());
1956 ::new ((
void*)__n) __node_type;
1957 __value_alloc_traits::construct(__a, __n->_M_valptr(),
1963 __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
1964 __throw_exception_again;
1968 template<
typename _NodeAlloc>
1970 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n)
1972 typedef typename __node_alloc_traits::pointer _Ptr;
1974 __value_alloc_type __a(_M_node_allocator());
1975 __value_alloc_traits::destroy(__a, __n->_M_valptr());
1976 __n->~__node_type();
1977 __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
1980 template<
typename _NodeAlloc>
1982 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_type* __n)
1986 __node_type* __tmp = __n;
1987 __n = __n->_M_next();
1988 _M_deallocate_node(__tmp);
1992 template<
typename _NodeAlloc>
1993 typename _Hashtable_alloc<_NodeAlloc>::__bucket_type*
1994 _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __n)
1996 __bucket_alloc_type __alloc(_M_node_allocator());
1998 auto __ptr = __bucket_alloc_traits::allocate(__alloc, __n);
2000 __builtin_memset(__p, 0, __n *
sizeof(__bucket_type));
2004 template<
typename _NodeAlloc>
2006 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_buckets(__bucket_type* __bkts,
2009 typedef typename __bucket_alloc_traits::pointer _Ptr;
2011 __bucket_alloc_type __alloc(_M_node_allocator());
2012 __bucket_alloc_traits::deallocate(__alloc, __ptr, __n);
2016 _GLIBCXX_END_NAMESPACE_VERSION
2020 #endif // _HASHTABLE_POLICY_H
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Base class for node iterators.
Uniform interface to C++98 and C++0x allocators.
Forward iterators support a superset of input iterator operations.
constexpr piecewise_construct_t piecewise_construct
piecewise_construct
Uniform interface to all pointer-like types.
Uniform interface to all allocator types.
Default ranged hash function H. In principle it should be a function object composed from objects of ...
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
ISO C++ entities toplevel namespace is std.
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Default value for rehash policy. Bucket size is (usually) the smallest prime that keeps the load fact...
Node const_iterators, used to iterate through all the hashtable.
Struct holding two objects of arbitrary type.
void swap(_Tp &, _Tp &) noexcept(__and_< is_nothrow_move_constructible< _Tp >, is_nothrow_move_assignable< _Tp >>::value)
Swaps two values.
Node iterators, used to iterate through all the hashtable.
Default range hashing function: use division to fold a large number into the range [0...
void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.