31 #ifndef _HASHTABLE_POLICY_H
32 #define _HASHTABLE_POLICY_H 1
34 namespace std _GLIBCXX_VISIBILITY(default)
36 _GLIBCXX_BEGIN_NAMESPACE_VERSION
38 template<
typename _Key,
typename _Value,
typename _Alloc,
39 typename _ExtractKey,
typename _Equal,
40 typename _H1,
typename _H2,
typename _Hash,
41 typename _RehashPolicy,
typename _Traits>
44 _GLIBCXX_END_NAMESPACE_VERSION
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 template<
typename _Key,
typename _Value,
56 typename _ExtractKey,
typename _Equal,
57 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
62 template<
class _Iterator>
63 inline typename std::iterator_traits<_Iterator>::difference_type
64 __distance_fw(_Iterator __first, _Iterator __last,
68 template<
class _Iterator>
69 inline typename std::iterator_traits<_Iterator>::difference_type
70 __distance_fw(_Iterator __first, _Iterator __last,
74 template<
class _Iterator>
75 inline typename std::iterator_traits<_Iterator>::difference_type
76 __distance_fw(_Iterator __first, _Iterator __last)
78 typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
79 return __distance_fw(__first, __last, _Tag());
83 template <
typename _Key,
typename _Hash>
85 noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
90 template<
typename _Tp>
92 operator()(_Tp&& __x)
const
93 {
return std::forward<_Tp>(__x); }
98 template<
typename _Tp>
100 operator()(_Tp&& __x) const
101 -> decltype(std::get<0>(std::
forward<_Tp>(__x)))
102 {
return std::get<0>(std::forward<_Tp>(__x)); }
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;
165 template<
typename _NodeAlloc>
169 using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>;
170 using __node_type =
typename __hashtable_alloc::__node_type;
173 _AllocNode(__hashtable_alloc& __h)
176 template<
typename _Arg>
178 operator()(_Arg&& __arg)
const
179 {
return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); }
182 __hashtable_alloc& _M_h;
210 template<
bool _Cache_hash_code,
bool _Constant_iterators,
bool _Unique_keys>
243 template<
typename _Value>
246 typedef _Value value_type;
248 __gnu_cxx::__aligned_buffer<_Value> _M_storage;
252 {
return _M_storage._M_ptr(); }
255 _M_valptr()
const noexcept
256 {
return _M_storage._M_ptr(); }
260 {
return *_M_valptr(); }
263 _M_v()
const noexcept
264 {
return *_M_valptr(); }
270 template<
typename _Value,
bool _Cache_hash_code>
278 template<
typename _Value>
281 std::size_t _M_hash_code;
284 _M_next()
const noexcept
285 {
return static_cast<_Hash_node*
>(this->_M_nxt); }
293 template<
typename _Value>
297 _M_next()
const noexcept
298 {
return static_cast<_Hash_node*
>(this->_M_nxt); }
302 template<
typename _Value,
bool _Cache_hash_code>
314 { _M_cur = _M_cur->_M_next(); }
317 template<
typename _Value,
bool _Cache_hash_code>
322 {
return __x._M_cur == __y._M_cur; }
324 template<
typename _Value,
bool _Cache_hash_code>
326 operator!=(
const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
327 const _Node_iterator_base<_Value, _Cache_hash_code>& __y)
329 {
return __x._M_cur != __y._M_cur; }
332 template<
typename _Value,
bool __constant_iterators,
bool __cache>
341 typedef _Value value_type;
342 typedef std::ptrdiff_t difference_type;
345 using pointer =
typename std::conditional<__constant_iterators,
346 const _Value*, _Value*>::type;
348 using reference =
typename std::conditional<__constant_iterators,
349 const _Value&, _Value&>::type;
359 operator*()
const noexcept
360 {
return this->_M_cur->_M_v(); }
363 operator->()
const noexcept
364 {
return this->_M_cur->_M_valptr(); }
367 operator++() noexcept
374 operator++(
int) noexcept
383 template<
typename _Value,
bool __constant_iterators,
bool __cache>
392 typedef _Value value_type;
393 typedef std::ptrdiff_t difference_type;
396 typedef const _Value* pointer;
397 typedef const _Value& reference;
407 __cache>& __x) noexcept
411 operator*()
const noexcept
412 {
return this->_M_cur->_M_v(); }
415 operator->()
const noexcept
416 {
return this->_M_cur->_M_valptr(); }
419 operator++() noexcept
426 operator++(
int) noexcept
441 typedef std::size_t first_argument_type;
442 typedef std::size_t second_argument_type;
443 typedef std::size_t result_type;
446 operator()(first_argument_type __num,
447 second_argument_type __den)
const noexcept
448 {
return __num % __den; }
463 : _M_max_load_factor(__z), _M_next_resize(0) { }
466 max_load_factor()
const noexcept
467 {
return _M_max_load_factor; }
471 _M_next_bkt(std::size_t __n)
const;
475 _M_bkt_for_elements(std::size_t __n)
const
476 {
return __builtin_ceil(__n / (
long double)_M_max_load_factor); }
483 _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
484 std::size_t __n_ins)
const;
486 typedef std::size_t _State;
490 {
return _M_next_resize; }
494 { _M_next_resize = 0; }
497 _M_reset(_State __state)
498 { _M_next_resize = __state; }
500 enum { _S_n_primes =
sizeof(
unsigned long) != 8 ? 256 : 256 + 48 };
502 static const std::size_t _S_growth_factor = 2;
504 float _M_max_load_factor;
505 mutable std::size_t _M_next_resize;
526 template<
typename _Key,
typename _Value,
typename _Alloc,
527 typename _ExtractKey,
typename _Equal,
528 typename _H1,
typename _H2,
typename _Hash,
529 typename _RehashPolicy,
typename _Traits,
530 bool _Unique_keys = _Traits::__unique_keys::value>
534 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
535 typename _H1,
typename _H2,
typename _Hash,
536 typename _RehashPolicy,
typename _Traits>
537 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
538 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
544 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
545 typename _H1,
typename _H2,
typename _Hash,
546 typename _RehashPolicy,
typename _Traits>
547 struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
548 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
553 _Equal, _H1, _H2, _Hash,
558 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
560 using __hash_code =
typename __hashtable_base::__hash_code;
561 using __node_type =
typename __hashtable_base::__node_type;
564 using key_type =
typename __hashtable_base::key_type;
577 at(
const key_type& __k);
580 at(
const key_type& __k)
const;
583 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
584 typename _H1,
typename _H2,
typename _Hash,
585 typename _RehashPolicy,
typename _Traits>
586 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
587 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
589 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
590 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
591 operator[](
const key_type& __k)
593 __hashtable* __h =
static_cast<__hashtable*
>(
this);
594 __hash_code __code = __h->_M_hash_code(__k);
595 std::size_t __n = __h->_M_bucket_index(__k, __code);
596 __node_type* __p = __h->_M_find_node(__n, __k, __code);
603 return __h->_M_insert_unique_node(__n, __code, __p)->second;
606 return __p->_M_v().second;
609 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
610 typename _H1,
typename _H2,
typename _Hash,
611 typename _RehashPolicy,
typename _Traits>
612 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
613 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
615 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
616 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
617 operator[](key_type&& __k)
619 __hashtable* __h =
static_cast<__hashtable*
>(
this);
620 __hash_code __code = __h->_M_hash_code(__k);
621 std::size_t __n = __h->_M_bucket_index(__k, __code);
622 __node_type* __p = __h->_M_find_node(__n, __k, __code);
627 std::forward_as_tuple(std::move(__k)),
629 return __h->_M_insert_unique_node(__n, __code, __p)->second;
632 return __p->_M_v().second;
635 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
636 typename _H1,
typename _H2,
typename _Hash,
637 typename _RehashPolicy,
typename _Traits>
638 typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
639 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>
641 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
642 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
643 at(
const key_type& __k)
645 __hashtable* __h =
static_cast<__hashtable*
>(
this);
646 __hash_code __code = __h->_M_hash_code(__k);
647 std::size_t __n = __h->_M_bucket_index(__k, __code);
648 __node_type* __p = __h->_M_find_node(__n, __k, __code);
651 __throw_out_of_range(__N(
"_Map_base::at"));
652 return __p->_M_v().second;
655 template<
typename _Key,
typename _Pair,
typename _Alloc,
typename _Equal,
656 typename _H1,
typename _H2,
typename _Hash,
657 typename _RehashPolicy,
typename _Traits>
658 const typename _Map_base<_Key, _Pair, _Alloc, _Select1st,
659 _Equal, _H1, _H2, _Hash, _RehashPolicy,
660 _Traits,
true>::mapped_type&
661 _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal,
662 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
663 at(
const key_type& __k)
const
665 const __hashtable* __h =
static_cast<const __hashtable*
>(
this);
666 __hash_code __code = __h->_M_hash_code(__k);
667 std::size_t __n = __h->_M_bucket_index(__k, __code);
668 __node_type* __p = __h->_M_find_node(__n, __k, __code);
671 __throw_out_of_range(__N(
"_Map_base::at"));
672 return __p->_M_v().second;
680 template<
typename _Key,
typename _Value,
typename _Alloc,
681 typename _ExtractKey,
typename _Equal,
682 typename _H1,
typename _H2,
typename _Hash,
683 typename _RehashPolicy,
typename _Traits>
688 _Equal, _H1, _H2, _Hash,
689 _RehashPolicy, _Traits>;
692 _Equal, _H1, _H2, _Hash,
695 using value_type =
typename __hashtable_base::value_type;
698 using size_type =
typename __hashtable_base::size_type;
700 using __unique_keys =
typename __hashtable_base::__unique_keys;
701 using __ireturn_type =
typename __hashtable_base::__ireturn_type;
703 using __node_alloc_type =
704 typename __alloctr_rebind<_Alloc, __node_type>::__type;
705 using __node_gen_type = _AllocNode<__node_alloc_type>;
708 _M_conjure_hashtable()
711 template<
typename _InputIterator,
typename _NodeGetter>
713 _M_insert_range(_InputIterator __first, _InputIterator __last,
718 insert(
const value_type& __v)
721 __node_gen_type __node_gen(__h);
722 return __h._M_insert(__v, __node_gen, __unique_keys());
726 insert(const_iterator __hint,
const value_type& __v)
729 __node_gen_type __node_gen(__h);
730 return __h._M_insert(__hint, __v, __node_gen, __unique_keys());
735 { this->insert(__l.begin(), __l.end()); }
737 template<
typename _InputIterator>
739 insert(_InputIterator __first, _InputIterator __last)
742 __node_gen_type __node_gen(__h);
743 return _M_insert_range(__first, __last, __node_gen);
747 template<
typename _Key,
typename _Value,
typename _Alloc,
748 typename _ExtractKey,
typename _Equal,
749 typename _H1,
typename _H2,
typename _Hash,
750 typename _RehashPolicy,
typename _Traits>
751 template<
typename _InputIterator,
typename _NodeGetter>
753 _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
754 _RehashPolicy, _Traits>::
755 _M_insert_range(_InputIterator __first, _InputIterator __last,
756 const _NodeGetter& __node_gen)
758 using __rehash_type =
typename __hashtable::__rehash_type;
759 using __rehash_state =
typename __hashtable::__rehash_state;
762 size_type __n_elt = __detail::__distance_fw(__first, __last);
764 __hashtable& __h = _M_conjure_hashtable();
765 __rehash_type& __rehash = __h._M_rehash_policy;
766 const __rehash_state& __saved_state = __rehash._M_state();
767 pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count,
768 __h._M_element_count,
771 if (__do_rehash.first)
772 __h._M_rehash(__do_rehash.second, __saved_state);
774 for (; __first != __last; ++__first)
775 __h._M_insert(*__first, __node_gen, __unique_keys());
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 bool _Constant_iterators = _Traits::__constant_iterators::value,
788 bool _Unique_keys = _Traits::__unique_keys::value>
792 template<
typename _Key,
typename _Value,
typename _Alloc,
793 typename _ExtractKey,
typename _Equal,
794 typename _H1,
typename _H2,
typename _Hash,
795 typename _RehashPolicy,
typename _Traits>
796 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
797 _RehashPolicy, _Traits, true, true>
798 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
799 _H1, _H2, _Hash, _RehashPolicy, _Traits>
802 _Equal, _H1, _H2, _Hash,
803 _RehashPolicy, _Traits>;
804 using value_type =
typename __base_type::value_type;
805 using iterator =
typename __base_type::iterator;
806 using const_iterator =
typename __base_type::const_iterator;
808 using __unique_keys =
typename __base_type::__unique_keys;
810 using __node_gen_type =
typename __base_type::__node_gen_type;
812 using __base_type::insert;
815 insert(value_type&& __v)
818 __node_gen_type __node_gen(__h);
819 return __h._M_insert(std::move(__v), __node_gen, __unique_keys());
823 insert(const_iterator __hint, value_type&& __v)
826 __node_gen_type __node_gen(__h);
827 return __h._M_insert(__hint, std::move(__v), __node_gen,
833 template<
typename _Key,
typename _Value,
typename _Alloc,
834 typename _ExtractKey,
typename _Equal,
835 typename _H1,
typename _H2,
typename _Hash,
836 typename _RehashPolicy,
typename _Traits>
837 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
838 _RehashPolicy, _Traits, true, false>
839 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
840 _H1, _H2, _Hash, _RehashPolicy, _Traits>
843 _Equal, _H1, _H2, _Hash,
844 _RehashPolicy, _Traits>;
845 using value_type =
typename __base_type::value_type;
846 using iterator =
typename __base_type::iterator;
847 using const_iterator =
typename __base_type::const_iterator;
849 using __unique_keys =
typename __base_type::__unique_keys;
851 using __node_gen_type =
typename __base_type::__node_gen_type;
853 using __base_type::insert;
856 insert(value_type&& __v)
859 __node_gen_type __node_gen(__h);
860 return __h._M_insert(std::move(__v), __node_gen, __unique_keys());
864 insert(const_iterator __hint, value_type&& __v)
867 __node_gen_type __node_gen(__h);
868 return __h._M_insert(__hint, std::move(__v), __node_gen,
874 template<
typename _Key,
typename _Value,
typename _Alloc,
875 typename _ExtractKey,
typename _Equal,
876 typename _H1,
typename _H2,
typename _Hash,
877 typename _RehashPolicy,
typename _Traits,
bool _Unique_keys>
878 struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash,
879 _RehashPolicy, _Traits, false, _Unique_keys>
880 :
public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
881 _H1, _H2, _Hash, _RehashPolicy, _Traits>
884 _Equal, _H1, _H2, _Hash,
885 _RehashPolicy, _Traits>;
886 using value_type =
typename __base_type::value_type;
887 using iterator =
typename __base_type::iterator;
888 using const_iterator =
typename __base_type::const_iterator;
890 using __unique_keys =
typename __base_type::__unique_keys;
892 using __ireturn_type =
typename __base_type::__ireturn_type;
894 using __base_type::insert;
896 template<
typename _Pair>
897 using __is_cons = std::is_constructible<value_type, _Pair&&>;
899 template<
typename _Pair>
900 using _IFcons = std::enable_if<__is_cons<_Pair>::value>;
902 template<
typename _Pair>
903 using _IFconsp =
typename _IFcons<_Pair>::type;
905 template<
typename _Pair,
typename = _IFconsp<_Pair>>
910 return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v));
913 template<
typename _Pair,
typename = _IFconsp<_Pair>>
915 insert(const_iterator __hint, _Pair&& __v)
918 return __h._M_emplace(__hint, __unique_keys(),
919 std::forward<_Pair>(__v));
929 template<
typename _Key,
typename _Value,
typename _Alloc,
930 typename _ExtractKey,
typename _Equal,
931 typename _H1,
typename _H2,
typename _Hash,
932 typename _RehashPolicy,
typename _Traits>
936 template<
typename _Key,
typename _Value,
typename _Alloc,
937 typename _ExtractKey,
typename _Equal,
938 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
943 _Equal, _H1, _H2, _Hash,
947 max_load_factor()
const noexcept
950 return __this->__rehash_policy().max_load_factor();
954 max_load_factor(
float __z)
961 reserve(std::size_t __n)
964 __this->rehash(__builtin_ceil(__n / max_load_factor()));
974 template<
int _Nm,
typename _Tp,
975 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
979 template<
int _Nm,
typename _Tp>
985 template<
typename _OtherTp>
987 : _Tp(std::forward<_OtherTp>(__tp))
992 {
return static_cast<const _Tp&
>(__eboh); }
996 {
return static_cast<_Tp&
>(__eboh); }
1000 template<
int _Nm,
typename _Tp>
1005 template<
typename _OtherTp>
1007 : _M_tp(std::forward<_OtherTp>(__tp))
1012 {
return __eboh._M_tp; }
1016 {
return __eboh._M_tp; }
1028 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1029 typename _H1,
typename _H2,
typename _Hash,
1030 bool __cache_hash_code>
1053 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1054 typename _H1,
typename _H2,
typename _Hash,
1055 bool __cache_hash_code>
1060 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1061 typename _H1,
typename _H2,
typename _Hash>
1071 typedef void* __hash_code;
1082 _M_hash_code(
const _Key& __key)
const
1086 _M_bucket_index(
const _Key& __k, __hash_code, std::size_t __n)
const
1087 {
return _M_ranged_hash()(__k, __n); }
1090 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1091 noexcept( noexcept(declval<const _Hash&>()(declval<const _Key&>(), (std::size_t)0)) )
1092 {
return _M_ranged_hash()(_M_extract()(__p->_M_v()), __n); }
1105 std::swap(_M_extract(), __x._M_extract());
1106 std::swap(_M_ranged_hash(), __x._M_ranged_hash());
1110 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1113 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1116 _M_ranged_hash()
const {
return __ebo_hash::_S_cget(*
this); }
1119 _M_ranged_hash() {
return __ebo_hash::_S_get(*
this); }
1128 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1129 typename _H1,
typename _H2,
typename _Hash>
1130 struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>;
1135 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1136 typename _H1,
typename _H2>
1152 hash_function()
const
1156 typedef std::size_t __hash_code;
1163 const _H1& __h1,
const _H2& __h2,
1168 _M_hash_code(
const _Key& __k)
const
1169 {
return _M_h1()(__k); }
1172 _M_bucket_index(
const _Key&, __hash_code __c, std::size_t __n)
const
1173 {
return _M_h2()(__c, __n); }
1176 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1177 noexcept( noexcept(declval<const _H1&>()(declval<const _Key&>()))
1178 && noexcept(declval<const _H2&>()((__hash_code)0, (std::size_t)0)) )
1179 {
return _M_h2()(_M_h1()(_M_extract()(__p->_M_v())), __n); }
1192 std::swap(_M_extract(), __x._M_extract());
1198 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1201 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1204 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1207 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1210 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1213 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1219 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1220 typename _H1,
typename _H2>
1230 _Default_ranged_hash, true>;
1240 hash_function()
const
1244 typedef std::size_t __hash_code;
1248 const _H1& __h1,
const _H2& __h2,
1249 const _Default_ranged_hash&)
1253 _M_hash_code(
const _Key& __k)
const
1254 {
return _M_h1()(__k); }
1257 _M_bucket_index(
const _Key&, __hash_code __c,
1258 std::size_t __n)
const
1259 {
return _M_h2()(__c, __n); }
1262 _M_bucket_index(
const __node_type* __p, std::size_t __n)
const
1263 noexcept( noexcept(declval<const _H2&>()((__hash_code)0,
1265 {
return _M_h2()(__p->_M_hash_code, __n); }
1268 _M_store_code(
__node_type* __n, __hash_code __c)
const
1269 { __n->_M_hash_code = __c; }
1273 { __to->_M_hash_code = __from->_M_hash_code; }
1278 std::swap(_M_extract(), __x._M_extract());
1284 _M_extract()
const {
return __ebo_extract_key::_S_cget(*
this); }
1287 _M_extract() {
return __ebo_extract_key::_S_get(*
this); }
1290 _M_h1()
const {
return __ebo_h1::_S_cget(*
this); }
1293 _M_h1() {
return __ebo_h1::_S_get(*
this); }
1296 _M_h2()
const {
return __ebo_h2::_S_cget(*
this); }
1299 _M_h2() {
return __ebo_h2::_S_get(*
this); }
1306 template <
typename _Key,
typename _Value,
typename _ExtractKey,
1307 typename _Equal,
typename _HashCodeType,
1308 bool __cache_hash_code>
1312 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1313 typename _Equal,
typename _HashCodeType>
1317 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1319 {
return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); }
1323 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1324 typename _Equal,
typename _HashCodeType>
1328 _S_equals(
const _Equal& __eq,
const _ExtractKey& __extract,
1330 {
return __eq(__k, __extract(__n->_M_v())); }
1335 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1336 typename _H1,
typename _H2,
typename _Hash>
1338 _H1, _H2, _Hash, true>
1344 _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 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1375 typename _H1,
typename _H2,
typename _Hash>
1377 _H1, _H2, _Hash, false>
1379 _H1, _H2, _Hash, false>
1383 _H1, _H2, _Hash,
false>;
1389 std::size_t __bkt, std::size_t __bkt_count)
1391 _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
1396 _M_cur = _M_cur->_M_next();
1399 std::size_t __bkt = this->_M_bucket_index(_M_cur, _M_bucket_count);
1400 if (__bkt != _M_bucket)
1406 std::size_t _M_bucket;
1407 std::size_t _M_bucket_count;
1410 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1411 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1414 _H1, _H2, _Hash, __cache>& __x,
1416 _H1, _H2, _Hash, __cache>& __y)
1417 {
return __x._M_cur == __y._M_cur; }
1419 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1420 typename _H1,
typename _H2,
typename _Hash,
bool __cache>
1422 operator!=(
const _Local_iterator_base<_Key, _Value, _ExtractKey,
1423 _H1, _H2, _Hash, __cache>& __x,
1424 const _Local_iterator_base<_Key, _Value, _ExtractKey,
1425 _H1, _H2, _Hash, __cache>& __y)
1426 {
return __x._M_cur != __y._M_cur; }
1429 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1430 typename _H1,
typename _H2,
typename _Hash,
1431 bool __constant_iterators,
bool __cache>
1434 _H1, _H2, _Hash, __cache>
1438 _H1, _H2, _Hash, __cache>;
1439 using __hash_code_base =
typename __base_type::__hash_code_base;
1441 typedef _Value value_type;
1442 typedef typename std::conditional<__constant_iterators,
1443 const _Value*, _Value*>::type
1445 typedef typename std::conditional<__constant_iterators,
1446 const _Value&, _Value&>::type
1448 typedef std::ptrdiff_t difference_type;
1455 std::size_t __bkt, std::size_t __bkt_count)
1461 {
return this->_M_cur->_M_v(); }
1465 {
return this->_M_cur->_M_valptr(); }
1484 template<
typename _Key,
typename _Value,
typename _ExtractKey,
1485 typename _H1,
typename _H2,
typename _Hash,
1486 bool __constant_iterators,
bool __cache>
1489 _H1, _H2, _Hash, __cache>
1493 _H1, _H2, _Hash, __cache>;
1494 using __hash_code_base =
typename __base_type::__hash_code_base;
1497 typedef _Value value_type;
1498 typedef const _Value* pointer;
1499 typedef const _Value& reference;
1500 typedef std::ptrdiff_t difference_type;
1507 std::size_t __bkt, std::size_t __bkt_count)
1513 __constant_iterators,
1520 {
return this->_M_cur->_M_v(); }
1524 {
return this->_M_cur->_M_valptr(); }
1552 template<
typename _Key,
typename _Value,
1553 typename _ExtractKey,
typename _Equal,
1554 typename _H1,
typename _H2,
typename _Hash,
typename _Traits>
1557 _Traits::__hash_cached::value>,
1561 typedef _Key key_type;
1562 typedef _Value value_type;
1563 typedef _Equal key_equal;
1564 typedef std::size_t size_type;
1565 typedef std::ptrdiff_t difference_type;
1567 using __traits_type = _Traits;
1568 using __hash_cached =
typename __traits_type::__hash_cached;
1569 using __constant_iterators =
typename __traits_type::__constant_iterators;
1570 using __unique_keys =
typename __traits_type::__unique_keys;
1574 __hash_cached::value>;
1576 using __hash_code =
typename __hash_code_base::__hash_code;
1577 using __node_type =
typename __hash_code_base::__node_type;
1580 __constant_iterators::value,
1581 __hash_cached::value>;
1584 __constant_iterators::value,
1585 __hash_cached::value>;
1588 _ExtractKey, _H1, _H2, _Hash,
1589 __constant_iterators::value,
1590 __hash_cached::value>;
1594 _ExtractKey, _H1, _H2, _Hash,
1595 __constant_iterators::value,
1596 __hash_cached::value>;
1598 using __ireturn_type =
typename std::conditional<__unique_keys::value,
1603 using _EqualHelper =
_Equal_helper<_Key, _Value, _ExtractKey, _Equal,
1604 __hash_code, __hash_cached::value>;
1607 _Hashtable_base(
const _ExtractKey& __ex,
const _H1& __h1,
const _H2& __h2,
1608 const _Hash& __hash,
const _Equal& __eq)
1609 : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq)
1613 _M_equals(
const _Key& __k, __hash_code __c, __node_type* __n)
const
1615 return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(),
1620 _M_swap(_Hashtable_base& __x)
1622 __hash_code_base::_M_swap(__x);
1627 _M_eq()
const {
return _EqualEBO::_S_cget(*
this); }
1630 _M_eq() {
return _EqualEBO::_S_get(*
this); }
1641 template<
typename _Uiterator>
1643 _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
1647 template<
typename _Uiterator>
1650 _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
1651 _Uiterator __first2)
1653 for (; __first1 != __last1; ++__first1, ++__first2)
1654 if (!(*__first1 == *__first2))
1657 if (__first1 == __last1)
1660 _Uiterator __last2 = __first2;
1663 for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
1665 _Uiterator __tmp = __first1;
1666 while (__tmp != __it1 && !
bool(*__tmp == *__it1))
1673 std::ptrdiff_t __n2 = 0;
1674 for (__tmp = __first2; __tmp != __last2; ++__tmp)
1675 if (*__tmp == *__it1)
1681 std::ptrdiff_t __n1 = 0;
1682 for (__tmp = __it1; __tmp != __last1; ++__tmp)
1683 if (*__tmp == *__it1)
1700 template<
typename _Key,
typename _Value,
typename _Alloc,
1701 typename _ExtractKey,
typename _Equal,
1702 typename _H1,
typename _H2,
typename _Hash,
1703 typename _RehashPolicy,
typename _Traits,
1704 bool _Unique_keys = _Traits::__unique_keys::value>
1708 template<
typename _Key,
typename _Value,
typename _Alloc,
1709 typename _ExtractKey,
typename _Equal,
1710 typename _H1,
typename _H2,
typename _Hash,
1711 typename _RehashPolicy,
typename _Traits>
1713 _H1, _H2, _Hash, _RehashPolicy, _Traits, true>
1716 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1722 template<
typename _Key,
typename _Value,
typename _Alloc,
1723 typename _ExtractKey,
typename _Equal,
1724 typename _H1,
typename _H2,
typename _Hash,
1725 typename _RehashPolicy,
typename _Traits>
1727 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1728 _H1, _H2, _Hash, _RehashPolicy, _Traits,
true>::
1729 _M_equal(
const __hashtable& __other)
const
1731 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1733 if (__this->size() != __other.size())
1736 for (
auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
1738 const auto __ity = __other.find(_ExtractKey()(*__itx));
1739 if (__ity == __other.end() || !bool(*__ity == *__itx))
1746 template<
typename _Key,
typename _Value,
typename _Alloc,
1747 typename _ExtractKey,
typename _Equal,
1748 typename _H1,
typename _H2,
typename _Hash,
1749 typename _RehashPolicy,
typename _Traits>
1751 _H1, _H2, _Hash, _RehashPolicy, _Traits, false>
1755 _H1, _H2, _Hash, _RehashPolicy, _Traits>;
1761 template<
typename _Key,
typename _Value,
typename _Alloc,
1762 typename _ExtractKey,
typename _Equal,
1763 typename _H1,
typename _H2,
typename _Hash,
1764 typename _RehashPolicy,
typename _Traits>
1766 _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
1767 _H1, _H2, _Hash, _RehashPolicy, _Traits,
false>::
1768 _M_equal(
const __hashtable& __other)
const
1770 const __hashtable* __this =
static_cast<const __hashtable*
>(
this);
1772 if (__this->size() != __other.size())
1775 for (
auto __itx = __this->begin(); __itx != __this->end();)
1777 const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
1778 const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
1784 if (!_S_is_permutation(__xrange.first, __xrange.second,
1788 __itx = __xrange.second;
1797 template<
typename _NodeAlloc>
1798 struct _Hashtable_alloc :
private _Hashtable_ebo_helper<0, _NodeAlloc>
1801 using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>;
1803 using __node_type =
typename _NodeAlloc::value_type;
1804 using __node_alloc_type = _NodeAlloc;
1808 using __value_type =
typename __node_type::value_type;
1809 using __value_alloc_type =
1810 typename __alloctr_rebind<__node_alloc_type, __value_type>::__type;
1813 using __node_base = __detail::_Hash_node_base;
1814 using __bucket_type = __node_base*;
1815 using __bucket_alloc_type =
1816 typename __alloctr_rebind<__node_alloc_type, __bucket_type>::__type;
1819 _Hashtable_alloc(
const _Hashtable_alloc&) =
default;
1820 _Hashtable_alloc(_Hashtable_alloc&&) =
default;
1822 template<
typename _Alloc>
1823 _Hashtable_alloc(_Alloc&& __a)
1824 : __ebo_node_alloc(std::
forward<_Alloc>(__a))
1829 {
return __ebo_node_alloc::_S_get(*
this); }
1831 const __node_alloc_type&
1832 _M_node_allocator()
const
1833 {
return __ebo_node_alloc::_S_cget(*
this); }
1835 template<
typename... _Args>
1837 _M_allocate_node(_Args&&... __args);
1840 _M_deallocate_node(__node_type* __n);
1844 _M_deallocate_nodes(__node_type* __n);
1847 _M_allocate_buckets(std::size_t __n);
1850 _M_deallocate_buckets(__bucket_type*, std::size_t __n);
1855 template<
typename _NodeAlloc>
1856 template<
typename... _Args>
1857 typename _Hashtable_alloc<_NodeAlloc>::__node_type*
1858 _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
1860 auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
1864 __value_alloc_type __a(_M_node_allocator());
1865 ::new ((
void*)__n) __node_type;
1866 __value_alloc_traits::construct(__a, __n->_M_valptr(),
1867 std::
forward<_Args>(__args)...);
1872 __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
1873 __throw_exception_again;
1877 template<
typename _NodeAlloc>
1879 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n)
1881 typedef typename __node_alloc_traits::pointer _Ptr;
1883 __value_alloc_type __a(_M_node_allocator());
1884 __value_alloc_traits::destroy(__a, __n->_M_valptr());
1885 __n->~__node_type();
1886 __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
1889 template<
typename _NodeAlloc>
1891 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_type* __n)
1895 __node_type* __tmp = __n;
1896 __n = __n->_M_next();
1897 _M_deallocate_node(__tmp);
1901 template<
typename _NodeAlloc>
1902 typename _Hashtable_alloc<_NodeAlloc>::__bucket_type*
1903 _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __n)
1905 __bucket_alloc_type __alloc(_M_node_allocator());
1907 auto __ptr = __bucket_alloc_traits::allocate(__alloc, __n);
1909 __builtin_memset(__p, 0, __n *
sizeof(__bucket_type));
1913 template<
typename _NodeAlloc>
1915 _Hashtable_alloc<_NodeAlloc>::_M_deallocate_buckets(__bucket_type* __bkts,
1918 typedef typename __bucket_alloc_traits::pointer _Ptr;
1920 __bucket_alloc_type __alloc(_M_node_allocator());
1921 __bucket_alloc_traits::deallocate(__alloc, __ptr, __n);
1925 _GLIBCXX_END_NAMESPACE_VERSION
1929 #endif // _HASHTABLE_POLICY_H
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.
Uniform interface to all pointer-like types.
Default ranged hash function H. In principle it should be a function object composed from objects of ...
Primary class template, tuple.
constexpr piecewise_construct_t piecewise_construct
piecewise_construct
Forward iterators support a superset of input iterator operations.
Uniform interface to C++98 and C++0x allocators.
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.
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
Specialization: ranged hash function, no caching hash codes. H1 and H2 are provided but ignored...
Uniform interface to all allocator types.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Base class for node iterators.
void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.
void swap(function< _Res(_Args...)> &__x, function< _Res(_Args...)> &__y)
Swap the targets of two polymorphic function object wrappers.
complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
reference operator[](size_t __position)
Array-indexing support.