31 #define _HASHTABLE_H 1
33 #pragma GCC system_header
37 namespace std _GLIBCXX_VISIBILITY(default)
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
98 template<
typename _Key,
typename _Value,
typename _Allocator,
99 typename _ExtractKey,
typename _Equal,
100 typename _H1,
typename _H2,
typename _Hash,
101 typename _RehashPolicy,
102 bool __cache_hash_code,
103 bool __constant_iterators,
106 :
public __detail::_Rehash_base<_RehashPolicy,
107 _Hashtable<_Key, _Value, _Allocator,
109 _Equal, _H1, _H2, _Hash,
112 __constant_iterators,
114 public __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
115 _H1, _H2, _Hash, __cache_hash_code>,
116 public __detail::_Map_base<_Key, _Value, _ExtractKey, __unique_keys,
117 _Hashtable<_Key, _Value, _Allocator,
119 _Equal, _H1, _H2, _Hash,
122 __constant_iterators,
124 public __detail::_Equality_base<_ExtractKey, __unique_keys,
125 _Hashtable<_Key, _Value, _Allocator,
127 _Equal, _H1, _H2, _Hash,
130 __constant_iterators,
134 typedef _Allocator allocator_type;
135 typedef _Value value_type;
136 typedef _Key key_type;
137 typedef _Equal key_equal;
140 typedef typename _Allocator::pointer pointer;
141 typedef typename _Allocator::const_pointer const_pointer;
142 typedef typename _Allocator::reference reference;
143 typedef typename _Allocator::const_reference const_reference;
145 typedef std::size_t size_type;
146 typedef std::ptrdiff_t difference_type;
147 typedef __detail::_Node_iterator<value_type, __constant_iterators,
150 typedef __detail::_Node_const_iterator<value_type,
151 __constant_iterators,
153 const_local_iterator;
155 typedef __detail::_Hashtable_iterator<value_type, __constant_iterators,
158 typedef __detail::_Hashtable_const_iterator<value_type,
159 __constant_iterators,
163 template<
typename _Key2,
typename _Value2,
typename _Ex2,
bool __unique2,
164 typename _Hashtable2>
165 friend struct __detail::_Map_base;
168 typedef __detail::_Hash_node<_Value, __cache_hash_code> _Node;
169 typedef typename _Allocator::template rebind<_Node>::other
170 _Node_allocator_type;
171 typedef typename _Allocator::template rebind<_Node*>::other
172 _Bucket_allocator_type;
174 typedef typename _Allocator::template rebind<_Value>::other
175 _Value_allocator_type;
177 _Node_allocator_type _M_node_allocator;
179 size_type _M_bucket_count;
180 size_type _M_begin_bucket_index;
181 size_type _M_element_count;
182 _RehashPolicy _M_rehash_policy;
184 template<
typename... _Args>
186 _M_allocate_node(_Args&&... __args);
189 _M_deallocate_node(_Node* __n);
192 _M_deallocate_nodes(_Node**, size_type);
195 _M_allocate_buckets(size_type __n);
198 _M_deallocate_buckets(_Node**, size_type __n);
202 _Hashtable(size_type __bucket_hint,
203 const _H1&,
const _H2&,
const _Hash&,
204 const _Equal&,
const _ExtractKey&,
205 const allocator_type&);
207 template<
typename _InputIterator>
208 _Hashtable(_InputIterator __first, _InputIterator __last,
209 size_type __bucket_hint,
210 const _H1&,
const _H2&,
const _Hash&,
211 const _Equal&,
const _ExtractKey&,
212 const allocator_type&);
214 _Hashtable(
const _Hashtable&);
216 _Hashtable(_Hashtable&&);
219 operator=(
const _Hashtable& __ht)
221 _Hashtable __tmp(__ht);
227 operator=(_Hashtable&& __ht)
238 void swap(_Hashtable&);
243 {
return iterator(_M_buckets + _M_begin_bucket_index); }
247 {
return const_iterator(_M_buckets + _M_begin_bucket_index); }
251 {
return iterator(_M_buckets + _M_bucket_count); }
255 {
return const_iterator(_M_buckets + _M_bucket_count); }
259 {
return const_iterator(_M_buckets + _M_begin_bucket_index); }
263 {
return const_iterator(_M_buckets + _M_bucket_count); }
267 {
return _M_element_count; }
271 {
return size() == 0; }
274 get_allocator()
const
275 {
return allocator_type(_M_node_allocator); }
279 {
return _M_node_allocator.max_size(); }
284 {
return this->_M_eq; }
291 {
return _M_bucket_count; }
294 max_bucket_count()
const
295 {
return max_size(); }
298 bucket_size(size_type __n)
const
302 bucket(
const key_type& __k)
const
304 return this->_M_bucket_index(__k, this->_M_hash_code(__k),
310 {
return local_iterator(_M_buckets[__n]); }
314 {
return local_iterator(0); }
317 begin(size_type __n)
const
318 {
return const_local_iterator(_M_buckets[__n]); }
322 {
return const_local_iterator(0); }
326 cbegin(size_type __n)
const
327 {
return const_local_iterator(_M_buckets[__n]); }
330 cend(size_type)
const
331 {
return const_local_iterator(0); }
336 return static_cast<float>(
size()) / static_cast<float>(bucket_count());
344 __rehash_policy()
const
345 {
return _M_rehash_policy; }
348 __rehash_policy(
const _RehashPolicy&);
352 find(
const key_type& __k);
355 find(
const key_type& __k)
const;
358 count(
const key_type& __k)
const;
361 equal_range(
const key_type& __k);
364 equal_range(
const key_type& __k)
const;
369 _M_find_node(_Node*,
const key_type&,
370 typename _Hashtable::_Hash_code_type)
const;
372 template<
typename _Arg>
374 _M_insert_bucket(_Arg&&, size_type,
375 typename _Hashtable::_Hash_code_type);
377 template<
typename _Arg>
381 template<
typename _Arg>
391 std::_Select1st<_Insert_Return_Type>,
392 std::_Identity<_Insert_Return_Type>
399 insert(
const value_type& __v)
403 insert(const_iterator,
const value_type& __v)
404 {
return _Insert_Conv_Type()(insert(__v)); }
407 insert(value_type&& __v)
408 {
return _M_insert(std::move(__v),
412 insert(const_iterator, value_type&& __v)
413 {
return _Insert_Conv_Type()(insert(std::move(__v))); }
415 template<
typename _Pair,
typename =
typename
418 value_type>::value>::type>
421 {
return _M_insert(std::forward<_Pair>(__v),
424 template<
typename _Pair,
typename =
typename
427 value_type>::value>::type>
429 insert(const_iterator, _Pair&& __v)
430 {
return _Insert_Conv_Type()(insert(std::forward<_Pair>(__v))); }
432 template<
typename _InputIterator>
434 insert(_InputIterator __first, _InputIterator __last);
437 insert(initializer_list<value_type> __l)
438 { this->insert(__l.begin(), __l.end()); }
441 erase(const_iterator);
446 {
return erase(const_iterator(__it)); }
449 erase(
const key_type&);
452 erase(const_iterator, const_iterator);
458 void rehash(size_type __n);
465 void _M_rehash(size_type __n);
470 template<
typename _Key,
typename _Value,
471 typename _Allocator,
typename _ExtractKey,
typename _Equal,
472 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
473 bool __chc,
bool __cit,
bool __uk>
474 template<
typename... _Args>
475 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
476 _H1, _H2, _Hash, _RehashPolicy,
477 __chc, __cit, __uk>::_Node*
478 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
479 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
480 _M_allocate_node(_Args&&... __args)
482 _Node* __n = _M_node_allocator.allocate(1);
485 _M_node_allocator.construct(__n, std::forward<_Args>(__args)...);
491 _M_node_allocator.deallocate(__n, 1);
492 __throw_exception_again;
496 template<
typename _Key,
typename _Value,
497 typename _Allocator,
typename _ExtractKey,
typename _Equal,
498 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
499 bool __chc,
bool __cit,
bool __uk>
501 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
502 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
503 _M_deallocate_node(_Node* __n)
505 _M_node_allocator.destroy(__n);
506 _M_node_allocator.deallocate(__n, 1);
509 template<
typename _Key,
typename _Value,
510 typename _Allocator,
typename _ExtractKey,
typename _Equal,
511 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
512 bool __chc,
bool __cit,
bool __uk>
514 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
515 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
516 _M_deallocate_nodes(_Node** __array, size_type __n)
518 for (size_type __i = 0; __i < __n; ++__i)
520 _Node* __p = __array[__i];
525 _M_deallocate_node(__tmp);
531 template<
typename _Key,
typename _Value,
532 typename _Allocator,
typename _ExtractKey,
typename _Equal,
533 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
534 bool __chc,
bool __cit,
bool __uk>
535 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
536 _H1, _H2, _Hash, _RehashPolicy,
537 __chc, __cit, __uk>::_Node**
538 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
539 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
540 _M_allocate_buckets(size_type __n)
542 _Bucket_allocator_type __alloc(_M_node_allocator);
546 _Node** __p = __alloc.allocate(__n + 1);
547 std::fill(__p, __p + __n, (_Node*) 0);
548 __p[__n] =
reinterpret_cast<_Node*
>(0x1000);
552 template<
typename _Key,
typename _Value,
553 typename _Allocator,
typename _ExtractKey,
typename _Equal,
554 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
555 bool __chc,
bool __cit,
bool __uk>
557 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
558 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
559 _M_deallocate_buckets(_Node** __p, size_type __n)
561 _Bucket_allocator_type __alloc(_M_node_allocator);
562 __alloc.deallocate(__p, __n + 1);
565 template<
typename _Key,
typename _Value,
566 typename _Allocator,
typename _ExtractKey,
typename _Equal,
567 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
568 bool __chc,
bool __cit,
bool __uk>
569 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
570 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
571 _Hashtable(size_type __bucket_hint,
572 const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
573 const _Equal& __eq,
const _ExtractKey& __exk,
574 const allocator_type& __a)
575 : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
576 __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
577 _H1, _H2, _Hash, __chc>(__exk, __eq,
579 __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
580 _M_node_allocator(__a),
585 _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint);
586 _M_buckets = _M_allocate_buckets(_M_bucket_count);
587 _M_begin_bucket_index = _M_bucket_count;
590 template<
typename _Key,
typename _Value,
591 typename _Allocator,
typename _ExtractKey,
typename _Equal,
592 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
593 bool __chc,
bool __cit,
bool __uk>
594 template<
typename _InputIterator>
595 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
596 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
597 _Hashtable(_InputIterator __f, _InputIterator __l,
598 size_type __bucket_hint,
599 const _H1& __h1,
const _H2& __h2,
const _Hash& __h,
600 const _Equal& __eq,
const _ExtractKey& __exk,
601 const allocator_type& __a)
602 : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
603 __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
604 _H1, _H2, _Hash, __chc>(__exk, __eq,
606 __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
607 _M_node_allocator(__a),
612 _M_bucket_count =
std::max(_M_rehash_policy._M_next_bkt(__bucket_hint),
614 _M_bkt_for_elements(__detail::
617 _M_buckets = _M_allocate_buckets(_M_bucket_count);
618 _M_begin_bucket_index = _M_bucket_count;
621 for (; __f != __l; ++__f)
627 _M_deallocate_buckets(_M_buckets, _M_bucket_count);
628 __throw_exception_again;
632 template<
typename _Key,
typename _Value,
633 typename _Allocator,
typename _ExtractKey,
typename _Equal,
634 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
635 bool __chc,
bool __cit,
bool __uk>
636 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
637 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
638 _Hashtable(
const _Hashtable& __ht)
639 : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
640 __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
641 _H1, _H2, _Hash, __chc>(__ht),
642 __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
643 _M_node_allocator(__ht._M_node_allocator),
644 _M_bucket_count(__ht._M_bucket_count),
645 _M_begin_bucket_index(__ht._M_begin_bucket_index),
646 _M_element_count(__ht._M_element_count),
647 _M_rehash_policy(__ht._M_rehash_policy)
649 _M_buckets = _M_allocate_buckets(_M_bucket_count);
652 for (size_type __i = 0; __i < __ht._M_bucket_count; ++__i)
654 _Node* __n = __ht._M_buckets[__i];
655 _Node** __tail = _M_buckets + __i;
658 *__tail = _M_allocate_node(__n->_M_v);
659 this->_M_copy_code(*__tail, __n);
660 __tail = &((*__tail)->_M_next);
668 _M_deallocate_buckets(_M_buckets, _M_bucket_count);
669 __throw_exception_again;
673 template<
typename _Key,
typename _Value,
674 typename _Allocator,
typename _ExtractKey,
typename _Equal,
675 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
676 bool __chc,
bool __cit,
bool __uk>
677 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
678 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
679 _Hashtable(_Hashtable&& __ht)
680 : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
681 __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
682 _H1, _H2, _Hash, __chc>(__ht),
683 __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
684 _M_node_allocator(__ht._M_node_allocator),
685 _M_buckets(__ht._M_buckets),
686 _M_bucket_count(__ht._M_bucket_count),
687 _M_begin_bucket_index(__ht._M_begin_bucket_index),
688 _M_element_count(__ht._M_element_count),
689 _M_rehash_policy(__ht._M_rehash_policy)
691 __ht._M_rehash_policy = _RehashPolicy();
692 __ht._M_bucket_count = __ht._M_rehash_policy._M_next_bkt(0);
693 __ht._M_buckets = __ht._M_allocate_buckets(__ht._M_bucket_count);
694 __ht._M_begin_bucket_index = __ht._M_bucket_count;
695 __ht._M_element_count = 0;
698 template<
typename _Key,
typename _Value,
699 typename _Allocator,
typename _ExtractKey,
typename _Equal,
700 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
701 bool __chc,
bool __cit,
bool __uk>
702 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
703 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
707 _M_deallocate_buckets(_M_buckets, _M_bucket_count);
710 template<
typename _Key,
typename _Value,
711 typename _Allocator,
typename _ExtractKey,
typename _Equal,
712 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
713 bool __chc,
bool __cit,
bool __uk>
715 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
716 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
717 swap(_Hashtable& __x)
722 __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
723 _H1, _H2, _Hash, __chc>::_M_swap(__x);
727 std::__alloc_swap<_Node_allocator_type>::_S_do_it(_M_node_allocator,
728 __x._M_node_allocator);
730 std::swap(_M_rehash_policy, __x._M_rehash_policy);
731 std::swap(_M_buckets, __x._M_buckets);
732 std::swap(_M_bucket_count, __x._M_bucket_count);
733 std::swap(_M_begin_bucket_index, __x._M_begin_bucket_index);
734 std::swap(_M_element_count, __x._M_element_count);
737 template<
typename _Key,
typename _Value,
738 typename _Allocator,
typename _ExtractKey,
typename _Equal,
739 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
740 bool __chc,
bool __cit,
bool __uk>
742 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
743 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
744 __rehash_policy(
const _RehashPolicy& __pol)
746 _M_rehash_policy = __pol;
747 size_type __n_bkt = __pol._M_bkt_for_elements(_M_element_count);
748 if (__n_bkt > _M_bucket_count)
752 template<
typename _Key,
typename _Value,
753 typename _Allocator,
typename _ExtractKey,
typename _Equal,
754 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
755 bool __chc,
bool __cit,
bool __uk>
756 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
757 _H1, _H2, _Hash, _RehashPolicy,
758 __chc, __cit, __uk>::iterator
759 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
760 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
761 find(
const key_type& __k)
763 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
764 std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
765 _Node* __p = _M_find_node(_M_buckets[__n], __k, __code);
766 return __p ? iterator(__p, _M_buckets + __n) : this->
end();
769 template<
typename _Key,
typename _Value,
770 typename _Allocator,
typename _ExtractKey,
typename _Equal,
771 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
772 bool __chc,
bool __cit,
bool __uk>
773 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
774 _H1, _H2, _Hash, _RehashPolicy,
775 __chc, __cit, __uk>::const_iterator
776 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
777 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
778 find(
const key_type& __k)
const
780 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
781 std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
782 _Node* __p = _M_find_node(_M_buckets[__n], __k, __code);
783 return __p ? const_iterator(__p, _M_buckets + __n) : this->
end();
786 template<
typename _Key,
typename _Value,
787 typename _Allocator,
typename _ExtractKey,
typename _Equal,
788 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
789 bool __chc,
bool __cit,
bool __uk>
790 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
791 _H1, _H2, _Hash, _RehashPolicy,
792 __chc, __cit, __uk>::size_type
793 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
794 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>
::
795 count(
const key_type& __k)
const
797 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
798 std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
799 std::size_t __result = 0;
800 for (_Node* __p = _M_buckets[__n]; __p; __p = __p->_M_next)
801 if (this->_M_compare(__k, __code, __p))
806 template<
typename _Key,
typename _Value,
807 typename _Allocator,
typename _ExtractKey,
typename _Equal,
808 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
809 bool __chc,
bool __cit,
bool __uk>
810 std::pair<
typename _Hashtable<_Key, _Value, _Allocator,
811 _ExtractKey, _Equal, _H1,
812 _H2, _Hash, _RehashPolicy,
813 __chc, __cit, __uk>::iterator,
814 typename _Hashtable<_Key, _Value, _Allocator,
815 _ExtractKey, _Equal, _H1,
816 _H2, _Hash, _RehashPolicy,
817 __chc, __cit, __uk>::iterator>
818 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
819 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
820 equal_range(
const key_type& __k)
822 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
823 std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
824 _Node** __head = _M_buckets + __n;
825 _Node* __p = _M_find_node(*__head, __k, __code);
829 _Node* __p1 = __p->_M_next;
830 for (; __p1; __p1 = __p1->_M_next)
831 if (!this->_M_compare(__k, __code, __p1))
834 iterator __first(__p, __head);
835 iterator __last(__p1, __head);
837 __last._M_incr_bucket();
844 template<
typename _Key,
typename _Value,
845 typename _Allocator,
typename _ExtractKey,
typename _Equal,
846 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
847 bool __chc,
bool __cit,
bool __uk>
848 std::pair<
typename _Hashtable<_Key, _Value, _Allocator,
849 _ExtractKey, _Equal, _H1,
850 _H2, _Hash, _RehashPolicy,
851 __chc, __cit, __uk>::const_iterator,
852 typename _Hashtable<_Key, _Value, _Allocator,
853 _ExtractKey, _Equal, _H1,
854 _H2, _Hash, _RehashPolicy,
855 __chc, __cit, __uk>::const_iterator>
856 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
857 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
858 equal_range(
const key_type& __k)
const
860 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
861 std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
862 _Node** __head = _M_buckets + __n;
863 _Node* __p = _M_find_node(*__head, __k, __code);
867 _Node* __p1 = __p->_M_next;
868 for (; __p1; __p1 = __p1->_M_next)
869 if (!this->_M_compare(__k, __code, __p1))
872 const_iterator __first(__p, __head);
873 const_iterator __last(__p1, __head);
875 __last._M_incr_bucket();
884 template<
typename _Key,
typename _Value,
885 typename _Allocator,
typename _ExtractKey,
typename _Equal,
886 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
887 bool __chc,
bool __cit,
bool __uk>
888 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey,
889 _Equal, _H1, _H2, _Hash, _RehashPolicy,
890 __chc, __cit, __uk>::_Node*
891 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
892 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
893 _M_find_node(_Node* __p,
const key_type& __k,
894 typename _Hashtable::_Hash_code_type __code)
const
896 for (; __p; __p = __p->_M_next)
897 if (this->_M_compare(__k, __code, __p))
903 template<
typename _Key,
typename _Value,
904 typename _Allocator,
typename _ExtractKey,
typename _Equal,
905 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
906 bool __chc,
bool __cit,
bool __uk>
907 template<
typename _Arg>
908 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
909 _H1, _H2, _Hash, _RehashPolicy,
910 __chc, __cit, __uk>::iterator
911 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
912 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
913 _M_insert_bucket(_Arg&& __v, size_type __n,
914 typename _Hashtable::_Hash_code_type __code)
917 = _M_rehash_policy._M_need_rehash(_M_bucket_count,
918 _M_element_count, 1);
920 if (__do_rehash.
first)
922 const key_type& __k = this->_M_extract(__v);
923 __n = this->_M_bucket_index(__k, __code, __do_rehash.
second);
928 _Node* __new_node = _M_allocate_node(std::forward<_Arg>(__v));
932 if (__do_rehash.
first)
933 _M_rehash(__do_rehash.
second);
935 __new_node->_M_next = _M_buckets[__n];
936 this->_M_store_code(__new_node, __code);
937 _M_buckets[__n] = __new_node;
939 if (__n < _M_begin_bucket_index)
940 _M_begin_bucket_index = __n;
941 return iterator(__new_node, _M_buckets + __n);
945 _M_deallocate_node(__new_node);
946 __throw_exception_again;
951 template<
typename _Key,
typename _Value,
952 typename _Allocator,
typename _ExtractKey,
typename _Equal,
953 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
954 bool __chc,
bool __cit,
bool __uk>
955 template<
typename _Arg>
956 std::pair<
typename _Hashtable<_Key, _Value, _Allocator,
957 _ExtractKey, _Equal, _H1,
958 _H2, _Hash, _RehashPolicy,
959 __chc, __cit, __uk>::iterator,
bool>
960 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
961 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
964 const key_type& __k = this->_M_extract(__v);
965 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
966 size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
968 if (_Node* __p = _M_find_node(_M_buckets[__n], __k, __code))
975 template<
typename _Key,
typename _Value,
976 typename _Allocator,
typename _ExtractKey,
typename _Equal,
977 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
978 bool __chc,
bool __cit,
bool __uk>
979 template<
typename _Arg>
980 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
981 _H1, _H2, _Hash, _RehashPolicy,
982 __chc, __cit, __uk>::iterator
983 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
984 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
988 = _M_rehash_policy._M_need_rehash(_M_bucket_count,
989 _M_element_count, 1);
990 if (__do_rehash.
first)
991 _M_rehash(__do_rehash.
second);
993 const key_type& __k = this->_M_extract(__v);
994 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
995 size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
998 _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code);
999 _Node* __new_node = _M_allocate_node(std::forward<_Arg>(__v));
1003 __new_node->_M_next = __prev->_M_next;
1004 __prev->_M_next = __new_node;
1008 __new_node->_M_next = _M_buckets[__n];
1009 _M_buckets[__n] = __new_node;
1010 if (__n < _M_begin_bucket_index)
1011 _M_begin_bucket_index = __n;
1013 this->_M_store_code(__new_node, __code);
1016 return iterator(__new_node, _M_buckets + __n);
1019 template<
typename _Key,
typename _Value,
1020 typename _Allocator,
typename _ExtractKey,
typename _Equal,
1021 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1022 bool __chc,
bool __cit,
bool __uk>
1023 template<
typename _InputIterator>
1025 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1026 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
1027 insert(_InputIterator __first, _InputIterator __last)
1029 size_type __n_elt = __detail::__distance_fw(__first, __last);
1031 = _M_rehash_policy._M_need_rehash(_M_bucket_count,
1032 _M_element_count, __n_elt);
1033 if (__do_rehash.
first)
1034 _M_rehash(__do_rehash.
second);
1036 for (; __first != __last; ++__first)
1037 this->insert(*__first);
1040 template<
typename _Key,
typename _Value,
1041 typename _Allocator,
typename _ExtractKey,
typename _Equal,
1042 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1043 bool __chc,
bool __cit,
bool __uk>
1044 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1045 _H1, _H2, _Hash, _RehashPolicy,
1046 __chc, __cit, __uk>::iterator
1047 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1048 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
1049 erase(const_iterator __it)
1051 iterator __result(__it._M_cur_node, __it._M_cur_bucket);
1054 _Node* __cur = *__it._M_cur_bucket;
1055 if (__cur == __it._M_cur_node)
1057 *__it._M_cur_bucket = __cur->_M_next;
1061 if (!_M_buckets[_M_begin_bucket_index])
1062 _M_begin_bucket_index = __result._M_cur_bucket - _M_buckets;
1066 _Node* __next = __cur->_M_next;
1067 while (__next != __it._M_cur_node)
1070 __next = __cur->_M_next;
1072 __cur->_M_next = __next->_M_next;
1075 _M_deallocate_node(__it._M_cur_node);
1081 template<
typename _Key,
typename _Value,
1082 typename _Allocator,
typename _ExtractKey,
typename _Equal,
1083 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1084 bool __chc,
bool __cit,
bool __uk>
1085 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1086 _H1, _H2, _Hash, _RehashPolicy,
1087 __chc, __cit, __uk>::size_type
1088 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1089 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
1090 erase(
const key_type& __k)
1092 typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
1093 std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
1094 size_type __result = 0;
1096 _Node** __slot = _M_buckets + __n;
1097 while (*__slot && !this->_M_compare(__k, __code, *__slot))
1098 __slot = &((*__slot)->_M_next);
1100 _Node** __saved_slot = 0;
1101 while (*__slot && this->_M_compare(__k, __code, *__slot))
1106 if (std::__addressof(this->_M_extract((*__slot)->_M_v))
1107 != std::__addressof(__k))
1109 _Node* __p = *__slot;
1110 *__slot = __p->_M_next;
1111 _M_deallocate_node(__p);
1117 __saved_slot = __slot;
1118 __slot = &((*__slot)->_M_next);
1124 _Node* __p = *__saved_slot;
1125 *__saved_slot = __p->_M_next;
1126 _M_deallocate_node(__p);
1133 if (!_M_buckets[_M_begin_bucket_index])
1135 if (!_M_element_count)
1136 _M_begin_bucket_index = _M_bucket_count;
1139 ++_M_begin_bucket_index;
1140 while (!_M_buckets[_M_begin_bucket_index])
1141 ++_M_begin_bucket_index;
1151 template<
typename _Key,
typename _Value,
1152 typename _Allocator,
typename _ExtractKey,
typename _Equal,
1153 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1154 bool __chc,
bool __cit,
bool __uk>
1155 typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1156 _H1, _H2, _Hash, _RehashPolicy,
1157 __chc, __cit, __uk>::iterator
1158 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1159 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
1160 erase(const_iterator __first, const_iterator __last)
1162 while (__first != __last)
1163 __first = this->erase(__first);
1164 return iterator(__last._M_cur_node, __last._M_cur_bucket);
1167 template<
typename _Key,
typename _Value,
1168 typename _Allocator,
typename _ExtractKey,
typename _Equal,
1169 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1170 bool __chc,
bool __cit,
bool __uk>
1172 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1173 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
1176 _M_deallocate_nodes(_M_buckets, _M_bucket_count);
1177 _M_element_count = 0;
1178 _M_begin_bucket_index = _M_bucket_count;
1181 template<
typename _Key,
typename _Value,
1182 typename _Allocator,
typename _ExtractKey,
typename _Equal,
1183 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1184 bool __chc,
bool __cit,
bool __uk>
1186 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1187 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
1188 rehash(size_type __n)
1190 _M_rehash(
std::max(_M_rehash_policy._M_next_bkt(__n),
1191 _M_rehash_policy._M_bkt_for_elements(_M_element_count
1195 template<
typename _Key,
typename _Value,
1196 typename _Allocator,
typename _ExtractKey,
typename _Equal,
1197 typename _H1,
typename _H2,
typename _Hash,
typename _RehashPolicy,
1198 bool __chc,
bool __cit,
bool __uk>
1200 _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
1201 _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
1202 _M_rehash(size_type __n)
1204 _Node** __new_array = _M_allocate_buckets(__n);
1207 _M_begin_bucket_index = __n;
1208 for (size_type __i = 0; __i < _M_bucket_count; ++__i)
1209 while (_Node* __p = _M_buckets[__i])
1211 std::size_t __new_index = this->_M_bucket_index(__p, __n);
1212 _M_buckets[__i] = __p->_M_next;
1213 __p->_M_next = __new_array[__new_index];
1214 __new_array[__new_index] = __p;
1215 if (__new_index < _M_begin_bucket_index)
1216 _M_begin_bucket_index = __new_index;
1218 _M_deallocate_buckets(_M_buckets, _M_bucket_count);
1219 _M_bucket_count = __n;
1220 _M_buckets = __new_array;
1228 _M_deallocate_nodes(__new_array, __n);
1229 _M_deallocate_buckets(__new_array, __n);
1230 _M_deallocate_nodes(_M_buckets, _M_bucket_count);
1231 _M_element_count = 0;
1232 _M_begin_bucket_index = _M_bucket_count;
1233 __throw_exception_again;
1237 _GLIBCXX_END_NAMESPACE_VERSION
1240 #endif // _HASHTABLE_H