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
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>
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>
241 template<
typename _Value>
244 typedef _Value value_type;
246 __gnu_cxx::__aligned_buffer<_Value> _M_storage;
250 {
return _M_storage._M_ptr(); }
253 _M_valptr()
const noexcept
254 {
return _M_storage._M_ptr(); }
258 {
return *_M_valptr(); }
261 _M_v()
const noexcept
262 {
return *_M_valptr(); }
268 template<
typename _Value,
bool _Cache_hash_code>
276 template<
typename _Value>
279 std::size_t _M_hash_code;
282 _M_next()
const noexcept
283 {
return static_cast<_Hash_node*
>(this->_M_nxt); }
291 template<
typename _Value>
295 _M_next()
const noexcept
296 {
return static_cast<_Hash_node*
>(this->_M_nxt); }
300 template<
typename _Value,
bool _Cache_hash_code>
312 { _M_cur = _M_cur->_M_next(); }
315 template<
typename _Value,
bool _Cache_hash_code>
320 {
return __x._M_cur == __y._M_cur; }
322 template<
typename _Value,
bool _Cache_hash_code>
327 {
return __x._M_cur != __y._M_cur; }
330 template<
typename _Value,
bool __constant_iterators,
bool __cache>
339 typedef _Value value_type;
340 typedef std::ptrdiff_t difference_type;
343 using pointer =
typename std::conditional<__constant_iterators,
344 const _Value*, _Value*>::type;
346 using reference =
typename std::conditional<__constant_iterators,
347 const _Value&, _Value&>::type;
358 {
return this->_M_cur->_M_v(); }
361 operator->()
const noexcept
362 {
return this->_M_cur->_M_valptr(); }
365 operator++() noexcept
372 operator++(
int) noexcept
381 template<
typename _Value,
bool __constant_iterators,
bool __cache>
390 typedef _Value value_type;
391 typedef std::ptrdiff_t difference_type;
394 typedef const _Value* pointer;
395 typedef const _Value& reference;
405 __cache>& __x) noexcept
410 {
return this->_M_cur->_M_v(); }
413 operator->()
const noexcept
414 {
return this->_M_cur->_M_valptr(); }
417 operator++() noexcept
424 operator++(
int) noexcept
439 typedef std::size_t first_argument_type;
440 typedef std::size_t second_argument_type;
441 typedef std::size_t result_type;
444 operator()(first_argument_type __num,
445 second_argument_type __den)
const noexcept
446 {
return __num % __den; }
461 : _M_max_load_factor(__z), _M_next_resize(0) { }
464 max_load_factor()
const noexcept
465 {
return _M_max_load_factor; }
469 _M_next_bkt(std::size_t __n)
const;
473 _M_bkt_for_elements(std::size_t __n)
const 474 {
return __builtin_ceil(__n / (
long double)_M_max_load_factor); }
481 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
482 std::size_t __n_ins)
const;
484 typedef std::size_t _State;
488 {
return _M_next_resize; }
492 { _M_next_resize = 0; }
495 _M_reset(_State __state)
496 { _M_next_resize = __state; }
498 static const std::size_t _S_growth_factor = 2;
500 float _M_max_load_factor;
501 mutable std::size_t _M_next_resize;
522 template<
typename _Key,
typename _Value,
typename _Alloc,
523 typename _ExtractKey,
typename _Equal,
524 typename _H1,
typename _H2,
typename _Hash,
525 typename _RehashPolicy,
typename _Traits,
526 bool _Unique_keys = _Traits::__unique_keys::value>
530 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
531 typename _H1,
typename _H2,
typename _Hash,
532 typename _RehashPolicy,
typename _Traits>
533 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
534 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
540 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
541 typename _H1,
typename _H2,
typename _Hash,
542 typename _RehashPolicy,
typename _Traits>
543 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
544 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
549 _Equal, _H1, _H2, _Hash,
554 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
556 using __hash_code =
typename __hashtable_base::__hash_code;
557 using __node_type =
typename __hashtable_base::__node_type;
560 using key_type =
typename __hashtable_base::key_type;
565 operator[](
const key_type& __k);
568 operator[](key_type&& __k);
573 at(
const key_type& __k);
576 at(
const key_type& __k)
const;
579 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
580 typename _H1,
typename _H2,
typename _Hash,
581 typename _RehashPolicy,
typename _Traits>
583 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
584 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
585 operator[](
const key_type& __k)
589 __hash_code __code = __h->_M_hash_code(__k);
590 std::size_t __n = __h->_M_bucket_index(__k, __code);
591 __node_type* __p = __h->_M_find_node(__n, __k, __code);
598 return __h->_M_insert_unique_node(__n, __code, __p)->second;
601 return __p->_M_v().second;
604 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
605 typename _H1,
typename _H2,
typename _Hash,
606 typename _RehashPolicy,
typename _Traits>
608 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
609 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
610 operator[](key_type&& __k)
614 __hash_code __code = __h->_M_hash_code(__k);
615 std::size_t __n = __h->_M_bucket_index(__k, __code);
616 __node_type* __p = __h->_M_find_node(__n, __k, __code);
621 std::forward_as_tuple(std::move(__k)),
623 return __h->_M_insert_unique_node(__n, __code, __p)->second;
626 return __p->_M_v().second;
629 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
630 typename _H1,
typename _H2,
typename _Hash,
631 typename _RehashPolicy,
typename _Traits>
633 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
634 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
635 at(
const key_type& __k)
639 __hash_code __code = __h->_M_hash_code(__k);
640 std::size_t __n = __h->_M_bucket_index(__k, __code);
641 __node_type* __p = __h->_M_find_node(__n, __k, __code);
644 __throw_out_of_range(__N(
"_Map_base::at"));
645 return __p->_M_v().second;
648 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
649 typename _H1,
typename _H2,
typename _Hash,
650 typename _RehashPolicy,
typename _Traits>
652 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
653 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
654 at(
const key_type& __k)
const 655 ->
const mapped_type&
658 __hash_code __code = __h->_M_hash_code(__k);
659 std::size_t __n = __h->_M_bucket_index(__k, __code);
660 __node_type* __p = __h->_M_find_node(__n, __k, __code);
663 __throw_out_of_range(__N(
"_Map_base::at"));
664 return __p->_M_v().second;
672 template<
typename _Key,
typename _Value,
typename _Alloc,
673 typename _ExtractKey,
typename _Equal,
674 typename _H1,
typename _H2,
typename _Hash,
675 typename _RehashPolicy,
typename _Traits>
680 _Equal, _H1, _H2, _Hash,
681 _RehashPolicy, _Traits>;
684 _Equal, _H1, _H2, _Hash,
687 using value_type =
typename __hashtable_base::value_type;
690 using size_type =
typename __hashtable_base::size_type;
692 using __unique_keys =
typename __hashtable_base::__unique_keys;
693 using __ireturn_type =
typename __hashtable_base::__ireturn_type;
695 using __node_alloc_type = __alloc_rebind<_Alloc, __node_type>;
696 using __node_gen_type = _AllocNode<__node_alloc_type>;
699 _M_conjure_hashtable()
702 template<
typename _InputIterator,
typename _NodeGetter>
704 _M_insert_range(_InputIterator __first, _InputIterator __last,
709 insert(
const value_type& __v)
712 __node_gen_type __node_gen(__h);
713 return __h._M_insert(__v, __node_gen, __unique_keys());
717 insert(const_iterator __hint,
const value_type& __v)
720 __node_gen_type __node_gen(__h);
721 return __h._M_insert(__hint, __v, __node_gen, __unique_keys());
726 { this->insert(__l.begin(), __l.end()); }
728 template<
typename _InputIterator>
730 insert(_InputIterator __first, _InputIterator __last)
733 __node_gen_type __node_gen(__h);
734 return _M_insert_range(__first, __last, __node_gen);
738 template<
typename _Key,
typename _Value,
typename _Alloc,
739 typename _ExtractKey,
typename _Equal,
740 typename _H1,
typename _H2,
typename _Hash,
741 typename _RehashPolicy,
typename _Traits>
742 template<
typename _InputIterator,
typename _NodeGetter>
744 _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
745 _RehashPolicy, _Traits>::
746 _M_insert_range(_InputIterator __first, _InputIterator __last,
747 const _NodeGetter& __node_gen)
749 using __rehash_type =
typename __hashtable::__rehash_type;
750 using __rehash_state =
typename __hashtable::__rehash_state;
753 size_type __n_elt = __detail::__distance_fw(__first, __last);
756 __rehash_type& __rehash = __h._M_rehash_policy;
757 const __rehash_state& __saved_state = __rehash._M_state();
758 pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
759 __h._M_element_count,
762 if (__do_rehash.first)
763 __h._M_rehash(__do_rehash.second, __saved_state);
765 for (; __first != __last; ++__first)
766 __h._M_insert(*__first, __node_gen, __unique_keys());
774 template<
typename _Key,
typename _Value,
typename _Alloc,
775 typename _ExtractKey,
typename _Equal,
776 typename _H1,
typename _H2,
typename _Hash,
777 typename _RehashPolicy,
typename _Traits,
778 bool _Constant_iterators = _Traits::__constant_iterators::value,
779 bool _Unique_keys = _Traits::__unique_keys::value>
783 template<
typename _Key,
typename _Value,
typename _Alloc,
784 typename _ExtractKey,
typename _Equal,
785 typename _H1,
typename _H2,
typename _Hash,
786 typename _RehashPolicy,
typename _Traits>
787 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
788 _RehashPolicy, _Traits, true, true>
789 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
790 _H1, _H2, _Hash, _RehashPolicy, _Traits>
793 _Equal, _H1, _H2, _Hash,
794 _RehashPolicy, _Traits>;
795 using value_type =
typename __base_type::value_type;
796 using iterator =
typename __base_type::iterator;
797 using const_iterator =
typename __base_type::const_iterator;
799 using __unique_keys =
typename __base_type::__unique_keys;
801 using __node_gen_type =
typename __base_type::__node_gen_type;
803 using __base_type::insert;
806 insert(value_type&& __v)
809 __node_gen_type __node_gen(__h);
810 return __h._M_insert(std::move(__v), __node_gen, __unique_keys());
814 insert(const_iterator __hint, value_type&& __v)
817 __node_gen_type __node_gen(__h);
818 return __h._M_insert(__hint, std::move(__v), __node_gen,
824 template<
typename _Key,
typename _Value,
typename _Alloc,
825 typename _ExtractKey,
typename _Equal,
826 typename _H1,
typename _H2,
typename _Hash,
827 typename _RehashPolicy,
typename _Traits>
828 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
829 _RehashPolicy, _Traits, true, false>
830 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
831 _H1, _H2, _Hash, _RehashPolicy, _Traits>
834 _Equal, _H1, _H2, _Hash,
835 _RehashPolicy, _Traits>;
836 using value_type =
typename __base_type::value_type;
837 using iterator =
typename __base_type::iterator;
838 using const_iterator =
typename __base_type::const_iterator;
840 using __unique_keys =
typename __base_type::__unique_keys;
842 using __node_gen_type =
typename __base_type::__node_gen_type;
844 using __base_type::insert;
847 insert(value_type&& __v)
850 __node_gen_type __node_gen(__h);
851 return __h._M_insert(std::move(__v), __node_gen, __unique_keys());
855 insert(const_iterator __hint, value_type&& __v)
858 __node_gen_type __node_gen(__h);
859 return __h._M_insert(__hint, std::move(__v), __node_gen,
865 template<
typename _Key,
typename _Value,
typename _Alloc,
866 typename _ExtractKey,
typename _Equal,
867 typename _H1,
typename _H2,
typename _Hash,
868 typename _RehashPolicy,
typename _Traits,
bool _Unique_keys>
869 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
870 _RehashPolicy, _Traits, false, _Unique_keys>
871 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
872 _H1, _H2, _Hash, _RehashPolicy, _Traits>
875 _Equal, _H1, _H2, _Hash,
876 _RehashPolicy, _Traits>;
877 using value_type =
typename __base_type::value_type;
878 using iterator =
typename __base_type::iterator;
879 using const_iterator =
typename __base_type::const_iterator;
881 using __unique_keys =
typename __base_type::__unique_keys;
883 using __ireturn_type =
typename __base_type::__ireturn_type;
885 using __base_type::insert;
887 template<
typename _Pair>
888 using __is_cons = std::is_constructible<value_type, _Pair&&>;
890 template<
typename _Pair>
891 using _IFcons = std::enable_if<__is_cons<_Pair>::value>;
893 template<
typename _Pair>
894 using _IFconsp =
typename _IFcons<_Pair>::type;
896 template<
typename _Pair,
typename = _IFconsp<_Pair>>
901 return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v));
904 template<
typename _Pair,
typename = _IFconsp<_Pair>>
906 insert(const_iterator __hint, _Pair&& __v)
909 return __h._M_emplace(__hint, __unique_keys(),
910 std::forward<_Pair>(__v));
920 template<
typename _Key,
typename _Value,
typename _Alloc,
921 typename _ExtractKey,
typename _Equal,
922 typename _H1,
typename _H2,
typename _Hash,
923 typename _RehashPolicy,
typename _Traits>
927 template<
typename _Key,
typename _Value,
typename _Alloc,
928 typename _ExtractKey,
typename _Equal,
929 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
934 _Equal, _H1, _H2, _Hash,
938 max_load_factor()
const noexcept
940 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
941 return __this->__rehash_policy().max_load_factor();
945 max_load_factor(
float __z)
947 __hashtable* __this =
static_cast<__hashtable*
>(
this);
948 __this->__rehash_policy(_Prime_rehash_policy(__z));
952 reserve(std::size_t __n)
954 __hashtable* __this =
static_cast<__hashtable*
>(
this);
955 __this->rehash(__builtin_ceil(__n / max_load_factor()));
965 template<
int _Nm,
typename _Tp,
966 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
970 template<
int _Nm,
typename _Tp>
976 template<
typename _OtherTp>
978 : _Tp(std::forward<_OtherTp>(__tp))
983 {
return static_cast<const _Tp&
>(__eboh); }
987 {
return static_cast<_Tp&
>(__eboh); }
991 template<
int _Nm,
typename _Tp>
996 template<
typename _OtherTp>
998 : _M_tp(std::forward<_OtherTp>(__tp))
1003 {
return __eboh._M_tp; }
1007 {
return __eboh._M_tp; }
1019 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1020 typename _H1,
typename _H2,
typename _Hash,
1021 bool __cache_hash_code>
1044 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1045 typename _H1,
typename _H2,
typename _Hash,
1046 bool __cache_hash_code>
1051 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1052 typename _H1,
typename _H2,
typename _Hash>
1062 typedef void* __hash_code;
1074 _M_hash_code(
const _Key& __key)
const 1078 _M_bucket_index(
const _Key& __k, __hash_code, std::size_t __n)
const 1079 {
return _M_ranged_hash()(__k, __n); }
1082 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const 1083 noexcept( noexcept(declval<const _Hash&>()(declval<const _Key&>(),
1085 {
return _M_ranged_hash()(_M_extract()(__p->_M_v()), __n); }
1088 _M_store_code(__node_type*, __hash_code)
const 1092 _M_copy_code(__node_type*,
const __node_type*)
const 1098 std::swap(_M_extract(), __x._M_extract());
1099 std::swap(_M_ranged_hash(), __x._M_ranged_hash());
1103 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1106 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1109 _M_ranged_hash()
const {
return __ebo_hash::_S_cget(*
this); }
1112 _M_ranged_hash() {
return __ebo_hash::_S_get(*
this); }
1121 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1122 typename _H1,
typename _H2,
typename _Hash>
1123 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>;
1128 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1129 typename _H1,
typename _H2>
1143 _Default_ranged_hash, false>;
1149 hash_function()
const 1153 typedef std::size_t __hash_code;
1161 const _H1& __h1,
const _H2& __h2,
1162 const _Default_ranged_hash&)
1166 _M_hash_code(
const _Key& __k)
const 1167 {
return _M_h1()(__k); }
1170 _M_bucket_index(
const _Key&, __hash_code __c, std::size_t __n)
const 1171 {
return _M_h2()(__c, __n); }
1174 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const 1175 noexcept( noexcept(declval<const _H1&>()(declval<const _Key&>()))
1176 && noexcept(declval<const _H2&>()((__hash_code)0,
1178 {
return _M_h2()(_M_h1()(_M_extract()(__p->_M_v())), __n); }
1181 _M_store_code(__node_type*, __hash_code)
const 1185 _M_copy_code(__node_type*,
const __node_type*)
const 1191 std::swap(_M_extract(), __x._M_extract());
1192 std::swap(_M_h1(), __x._M_h1());
1193 std::swap(_M_h2(), __x._M_h2());
1197 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1200 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1203 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1206 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1209 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1212 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1218 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1219 typename _H1,
typename _H2>
1229 _Default_ranged_hash, true>;
1239 hash_function()
const 1243 typedef std::size_t __hash_code;
1249 const _H1& __h1,
const _H2& __h2,
1250 const _Default_ranged_hash&)
1254 _M_hash_code(
const _Key& __k)
const 1255 {
return _M_h1()(__k); }
1258 _M_bucket_index(
const _Key&, __hash_code __c,
1259 std::size_t __n)
const 1260 {
return _M_h2()(__c, __n); }
1263 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const 1264 noexcept( noexcept(declval<const _H2&>()((__hash_code)0,
1266 {
return _M_h2()(__p->_M_hash_code, __n); }
1269 _M_store_code(__node_type* __n, __hash_code __c)
const 1270 { __n->_M_hash_code = __c; }
1273 _M_copy_code(__node_type* __to,
const __node_type* __from)
const 1274 { __to->_M_hash_code = __from->_M_hash_code; }
1279 std::swap(_M_extract(), __x._M_extract());
1280 std::swap(_M_h1(), __x._M_h1());
1281 std::swap(_M_h2(), __x._M_h2());
1285 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1288 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1291 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1294 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1297 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1300 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1307 template <
typename _Key,
typename _Value,
typename _ExtractKey,
1308 typename _Equal,
typename _HashCodeType,
1309 bool __cache_hash_code>
1313 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1314 typename _Equal,
typename _HashCodeType>
1318 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1320 {
return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); }
1324 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1325 typename _Equal,
typename _HashCodeType>
1329 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1331 {
return __eq(__k, __extract(__n->_M_v())); }
1336 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1337 typename _H1,
typename _H2,
typename _Hash>
1339 _H1, _H2, _Hash, true>
1345 _H1, _H2, _Hash,
true>;
1350 std::size_t __bkt, std::size_t __bkt_count)
1352 _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1357 _M_cur = _M_cur->_M_next();
1361 = __base_type::_S_get(*
this)(_M_cur->_M_hash_code,
1363 if (__bkt != _M_bucket)
1369 std::size_t _M_bucket;
1370 std::size_t _M_bucket_count;
1374 _M_curr()
const {
return _M_cur; }
1377 _M_get_bucket()
const {
return _M_bucket; }
1384 template<typename _Tp, bool _IsEmpty = std::is_empty<_Tp>::value>
1385 struct _Hash_code_storage
1387 __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
1390 _M_h() {
return _M_storage._M_ptr(); }
1393 _M_h()
const {
return _M_storage._M_ptr(); }
1397 template<
typename _Tp>
1398 struct _Hash_code_storage<_Tp, true>
1405 _M_h() {
return reinterpret_cast<_Tp*
>(
this); }
1408 _M_h()
const {
return reinterpret_cast<const _Tp*
>(
this); }
1411 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1412 typename _H1,
typename _H2,
typename _Hash>
1413 using __hash_code_for_local_iter
1415 _H1, _H2, _Hash,
false>>;
1418 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1419 typename _H1,
typename _H2,
typename _Hash>
1421 _H1, _H2, _Hash, false>
1422 : __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash>
1426 _H1, _H2, _Hash,
false>;
1432 std::size_t __bkt, std::size_t __bkt_count)
1433 : _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
1434 { _M_init(__base); }
1438 if (_M_bucket_count != -1)
1443 : _M_cur(__iter._M_cur), _M_bucket(__iter._M_bucket),
1444 _M_bucket_count(__iter._M_bucket_count)
1446 if (_M_bucket_count != -1)
1447 _M_init(*__iter._M_h());
1453 if (_M_bucket_count != -1)
1455 _M_cur = __iter._M_cur;
1456 _M_bucket = __iter._M_bucket;
1457 _M_bucket_count = __iter._M_bucket_count;
1458 if (_M_bucket_count != -1)
1459 _M_init(*__iter._M_h());
1466 _M_cur = _M_cur->_M_next();
1469 std::size_t __bkt = this->_M_h()->_M_bucket_index(_M_cur,
1471 if (__bkt != _M_bucket)
1477 std::size_t _M_bucket;
1478 std::size_t _M_bucket_count;
1485 _M_destroy() { this->_M_h()->~__hash_code_base(); }
1489 _M_curr()
const {
return _M_cur; }
1492 _M_get_bucket()
const {
return _M_bucket; }
1495 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1496 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1499 _H1, _H2, _Hash, __cache>& __x,
1501 _H1, _H2, _Hash, __cache>& __y)
1502 {
return __x._M_curr() == __y._M_curr(); }
1504 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1505 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1508 _H1, _H2, _Hash, __cache>& __x,
1510 _H1, _H2, _Hash, __cache>& __y)
1511 {
return __x._M_curr() != __y._M_curr(); }
1514 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1515 typename _H1,
typename _H2,
typename _Hash,
1516 bool __constant_iterators,
bool __cache>
1519 _H1, _H2, _Hash, __cache>
1523 _H1, _H2, _Hash, __cache>;
1524 using __hash_code_base =
typename __base_type::__hash_code_base;
1526 typedef _Value value_type;
1527 typedef typename std::conditional<__constant_iterators,
1528 const _Value*, _Value*>::type
1530 typedef typename std::conditional<__constant_iterators,
1531 const _Value&, _Value&>::type
1533 typedef std::ptrdiff_t difference_type;
1540 std::size_t __bkt, std::size_t __bkt_count)
1546 {
return this->_M_cur->_M_v(); }
1550 {
return this->_M_cur->_M_valptr(); }
1569 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1570 typename _H1,
typename _H2,
typename _Hash,
1571 bool __constant_iterators,
bool __cache>
1574 _H1, _H2, _Hash, __cache>
1578 _H1, _H2, _Hash, __cache>;
1579 using __hash_code_base =
typename __base_type::__hash_code_base;
1582 typedef _Value value_type;
1583 typedef const _Value* pointer;
1584 typedef const _Value& reference;
1585 typedef std::ptrdiff_t difference_type;
1592 std::size_t __bkt, std::size_t __bkt_count)
1598 __constant_iterators,
1605 {
return this->_M_cur->_M_v(); }
1609 {
return this->_M_cur->_M_valptr(); }
1637 template<
typename _Key,
typename _Value,
1638 typename _ExtractKey,
typename _Equal,
1639 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
1642 _Traits::__hash_cached::value>,
1646 typedef _Key key_type;
1647 typedef _Value value_type;
1648 typedef _Equal key_equal;
1649 typedef std::size_t size_type;
1650 typedef std::ptrdiff_t difference_type;
1652 using __traits_type = _Traits;
1653 using __hash_cached =
typename __traits_type::__hash_cached;
1654 using __constant_iterators =
typename __traits_type::__constant_iterators;
1655 using __unique_keys =
typename __traits_type::__unique_keys;
1659 __hash_cached::value>;
1661 using __hash_code =
typename __hash_code_base::__hash_code;
1662 using __node_type =
typename __hash_code_base::__node_type;
1665 __constant_iterators::value,
1666 __hash_cached::value>;
1669 __constant_iterators::value,
1670 __hash_cached::value>;
1673 _ExtractKey, _H1, _H2, _Hash,
1674 __constant_iterators::value,
1675 __hash_cached::value>;
1679 _ExtractKey, _H1, _H2, _Hash,
1680 __constant_iterators::value,
1681 __hash_cached::value>;
1683 using __ireturn_type =
typename std::conditional<__unique_keys::value,
1688 using _EqualHelper =
_Equal_helper<_Key, _Value, _ExtractKey, _Equal,
1689 __hash_code, __hash_cached::value>;
1693 _Hashtable_base(
const _ExtractKey& __ex,
const _H1& __h1,
const _H2& __h2,
1694 const _Hash& __hash,
const _Equal& __eq)
1695 : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq)
1699 _M_equals(
const _Key& __k, __hash_code __c, __node_type* __n)
const 1701 return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(),
1708 __hash_code_base::_M_swap(__x);
1709 std::swap(_M_eq(), __x._M_eq());
1713 _M_eq()
const {
return _EqualEBO::_S_cget(*
this); }
1716 _M_eq() {
return _EqualEBO::_S_get(*
this); }
1727 template<
typename _Uiterator>
1729 _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
1733 template<
typename _Uiterator>
1736 _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
1737 _Uiterator __first2)
1739 for (; __first1 != __last1; ++__first1, ++__first2)
1740 if (!(*__first1 == *__first2))
1743 if (__first1 == __last1)
1746 _Uiterator __last2 = __first2;
1749 for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
1751 _Uiterator __tmp = __first1;
1752 while (__tmp != __it1 && !
bool(*__tmp == *__it1))
1759 std::ptrdiff_t __n2 = 0;
1760 for (__tmp = __first2; __tmp != __last2; ++__tmp)
1761 if (*__tmp == *__it1)
1767 std::ptrdiff_t __n1 = 0;
1768 for (__tmp = __it1; __tmp != __last1; ++__tmp)
1769 if (*__tmp == *__it1)
1786 template<
typename _Key,
typename _Value,
typename _Alloc,
1787 typename _ExtractKey,
typename _Equal,
1788 typename _H1,
typename _H2,
typename _Hash,
1789 typename _RehashPolicy,
typename _Traits,
1790 bool _Unique_keys = _Traits::__unique_keys::value>
1794 template<
typename _Key,
typename _Value,
typename _Alloc,
1795 typename _ExtractKey,
typename _Equal,
1796 typename _H1,
typename _H2,
typename _Hash,
1797 typename _RehashPolicy,
typename _Traits>
1799 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
1802 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1805 _M_equal(
const __hashtable&)
const;
1808 template<
typename _Key,
typename _Value,
typename _Alloc,
1809 typename _ExtractKey,
typename _Equal,
1810 typename _H1,
typename _H2,
typename _Hash,
1811 typename _RehashPolicy,
typename _Traits>
1813 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1814 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
1819 if (__this->size() != __other.size())
1822 for (
auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1824 const auto __ity = __other.find(_ExtractKey()(*__itx));
1825 if (__ity == __other.end() || !bool(*__ity == *__itx))
1832 template<
typename _Key,
typename _Value,
typename _Alloc,
1833 typename _ExtractKey,
typename _Equal,
1834 typename _H1,
typename _H2,
typename _Hash,
1835 typename _RehashPolicy,
typename _Traits>
1837 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
1841 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1844 _M_equal(
const __hashtable&)
const;
1847 template<
typename _Key,
typename _Value,
typename _Alloc,
1848 typename _ExtractKey,
typename _Equal,
1849 typename _H1,
typename _H2,
typename _Hash,
1850 typename _RehashPolicy,
typename _Traits>
1852 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1853 _H1, _H2, _Hash, _RehashPolicy, _Traits,
false>::
1858 if (__this->size() != __other.size())
1861 for (
auto __itx = __this->begin(); __itx != __this->end();)
1863 const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
1864 const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
1870 if (!_S_is_permutation(__xrange.first, __xrange.second,
1874 __itx = __xrange.second;
1883 template<
typename _NodeAlloc>
1889 using __node_type =
typename _NodeAlloc::value_type;
1890 using __node_alloc_type = _NodeAlloc;
1894 using __value_type =
typename __node_type::value_type;
1895 using __value_alloc_type =
1896 __alloc_rebind<__node_alloc_type, __value_type>;
1900 using __bucket_type = __node_base*;
1901 using __bucket_alloc_type =
1902 __alloc_rebind<__node_alloc_type, __bucket_type>;
1909 template<
typename _Alloc>
1911 : __ebo_node_alloc(std::forward<_Alloc>(__a))
1916 {
return __ebo_node_alloc::_S_get(*
this); }
1918 const __node_alloc_type&
1919 _M_node_allocator()
const 1920 {
return __ebo_node_alloc::_S_cget(*
this); }
1922 template<
typename... _Args>
1924 _M_allocate_node(_Args&&... __args);
1927 _M_deallocate_node(__node_type* __n);
1931 _M_deallocate_nodes(__node_type* __n);
1934 _M_allocate_buckets(std::size_t __n);
1937 _M_deallocate_buckets(__bucket_type*, std::size_t __n);
1942 template<
typename _NodeAlloc>
1943 template<
typename... _Args>
1944 typename _Hashtable_alloc<_NodeAlloc>::__node_type*
1947 auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
1951 __value_alloc_type __a(_M_node_allocator());
1952 ::new ((
void*)__n) __node_type;
1953 __value_alloc_traits::construct(__a, __n->_M_valptr(),
1954 std::forward<_Args>(__args)...);
1959 __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
1960 __throw_exception_again;
1964 template<
typename _NodeAlloc>
1968 typedef typename __node_alloc_traits::pointer _Ptr;
1970 __value_alloc_type __a(_M_node_allocator());
1971 __value_alloc_traits::destroy(__a, __n->_M_valptr());
1972 __n->~__node_type();
1973 __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
1976 template<
typename _NodeAlloc>
1982 __node_type* __tmp = __n;
1983 __n = __n->_M_next();
1984 _M_deallocate_node(__tmp);
1988 template<
typename _NodeAlloc>
1992 __bucket_alloc_type __alloc(_M_node_allocator());
1994 auto __ptr = __bucket_alloc_traits::allocate(__alloc, __n);
1996 __builtin_memset(__p, 0, __n *
sizeof(__bucket_type));
2000 template<
typename _NodeAlloc>
2005 typedef typename __bucket_alloc_traits::pointer _Ptr;
2007 __bucket_alloc_type __alloc(_M_node_allocator());
2008 __bucket_alloc_traits::deallocate(__alloc, __ptr, __n);
2012 _GLIBCXX_END_NAMESPACE_VERSION
2016 #endif // _HASHTABLE_POLICY_H
complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Uniform interface to C++98 and C++11 allocators.
void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.
Default value for rehash policy. Bucket size is (usually) the smallest prime that keeps the load fact...
Primary class template, tuple.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
constexpr piecewise_construct_t piecewise_construct
piecewise_construct
Uniform interface to all pointer-like types.
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Node iterators, used to iterate through all the hashtable.
Default range hashing function: use division to fold a large number into the range [0...
Struct holding two objects of arbitrary type.
Uniform interface to all allocator types.
Forward iterators support a superset of input iterator operations.
Node const_iterators, used to iterate through all the hashtable.
ISO C++ entities toplevel namespace is std.
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
Default ranged hash function H. In principle it should be a function object composed from objects of ...
Base class for node iterators.