57 #ifndef _BACKWARD_HASHTABLE_H
58 #define _BACKWARD_HASHTABLE_H 1
69 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
85 struct _Hashtable_node
87 _Hashtable_node* _M_next;
91 template<
class _Val,
class _Key,
class _HashFcn,
class _ExtractKey,
95 template<
class _Val,
class _Key,
class _HashFcn,
96 class _ExtractKey,
class _EqualKey,
class _Alloc>
97 struct _Hashtable_iterator;
99 template<
class _Val,
class _Key,
class _HashFcn,
100 class _ExtractKey,
class _EqualKey,
class _Alloc>
101 struct _Hashtable_const_iterator;
103 template<
class _Val,
class _Key,
class _HashFcn,
104 class _ExtractKey,
class _EqualKey,
class _Alloc>
105 struct _Hashtable_iterator
107 typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
109 typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
110 _ExtractKey, _EqualKey, _Alloc>
112 typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
113 _ExtractKey, _EqualKey, _Alloc>
115 typedef _Hashtable_node<_Val> _Node;
116 typedef forward_iterator_tag iterator_category;
117 typedef _Val value_type;
118 typedef ptrdiff_t difference_type;
119 typedef size_t size_type;
120 typedef _Val& reference;
121 typedef _Val* pointer;
126 _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
127 : _M_cur(__n), _M_ht(__tab) { }
129 _Hashtable_iterator() { }
133 {
return _M_cur->_M_val; }
137 {
return &(operator*()); }
146 operator==(
const iterator& __it)
const
147 {
return _M_cur == __it._M_cur; }
150 operator!=(
const iterator& __it)
const
151 {
return _M_cur != __it._M_cur; }
154 template<
class _Val,
class _Key,
class _HashFcn,
155 class _ExtractKey,
class _EqualKey,
class _Alloc>
156 struct _Hashtable_const_iterator
158 typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
160 typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
161 _ExtractKey,_EqualKey,_Alloc>
163 typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
164 _ExtractKey, _EqualKey, _Alloc>
166 typedef _Hashtable_node<_Val> _Node;
168 typedef forward_iterator_tag iterator_category;
169 typedef _Val value_type;
170 typedef ptrdiff_t difference_type;
171 typedef size_t size_type;
172 typedef const _Val& reference;
173 typedef const _Val* pointer;
176 const _Hashtable* _M_ht;
178 _Hashtable_const_iterator(
const _Node* __n,
const _Hashtable* __tab)
179 : _M_cur(__n), _M_ht(__tab) { }
181 _Hashtable_const_iterator() { }
183 _Hashtable_const_iterator(
const iterator& __it)
184 : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { }
188 {
return _M_cur->_M_val; }
192 {
return &(operator*()); }
201 operator==(
const const_iterator& __it)
const
202 {
return _M_cur == __it._M_cur; }
205 operator!=(
const const_iterator& __it)
const
206 {
return _M_cur != __it._M_cur; }
210 enum { _S_num_primes = 29 };
212 template<
typename _PrimeType>
213 struct _Hashtable_prime_list
215 static const _PrimeType __stl_prime_list[_S_num_primes];
217 static const _PrimeType*
221 template<
typename _PrimeType>
const _PrimeType
222 _Hashtable_prime_list<_PrimeType>::__stl_prime_list[_S_num_primes] =
224 5ul, 53ul, 97ul, 193ul, 389ul,
225 769ul, 1543ul, 3079ul, 6151ul, 12289ul,
226 24593ul, 49157ul, 98317ul, 196613ul, 393241ul,
227 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul,
228 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul,
229 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul
232 template<
class _PrimeType>
inline const _PrimeType*
233 _Hashtable_prime_list<_PrimeType>::_S_get_prime_list()
235 return __stl_prime_list;
239 __stl_next_prime(
unsigned long __n)
241 const unsigned long* __first = _Hashtable_prime_list<unsigned long>::_S_get_prime_list();
242 const unsigned long* __last = __first + (int)_S_num_primes;
244 return pos == __last ? *(__last - 1) : *pos;
248 template<
class _Val,
class _Key,
class _HF,
class _Ex,
249 class _Eq,
class _All>
252 template<
class _Val,
class _Key,
class _HF,
class _Ex,
253 class _Eq,
class _All>
255 operator==(
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
256 const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
266 template<
class _Val,
class _Key,
class _HashFcn,
267 class _ExtractKey,
class _EqualKey,
class _Alloc>
271 typedef _Key key_type;
272 typedef _Val value_type;
273 typedef _HashFcn hasher;
274 typedef _EqualKey key_equal;
276 typedef size_t size_type;
277 typedef ptrdiff_t difference_type;
278 typedef value_type* pointer;
279 typedef const value_type* const_pointer;
280 typedef value_type& reference;
281 typedef const value_type& const_reference;
289 {
return _M_equals; }
292 typedef _Hashtable_node<_Val> _Node;
295 typedef typename _Alloc::template rebind<value_type>::other allocator_type;
297 get_allocator()
const
298 {
return _M_node_allocator; }
301 typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
302 typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
303 typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
305 _Node_Alloc _M_node_allocator;
309 {
return _M_node_allocator.allocate(1); }
312 _M_put_node(_Node* __p)
313 { _M_node_allocator.deallocate(__p, 1); }
318 _ExtractKey _M_get_key;
319 _Vector_type _M_buckets;
320 size_type _M_num_elements;
323 typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
326 typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
331 _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;
334 _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
338 hashtable(size_type __n,
const _HashFcn& __hf,
339 const _EqualKey& __eql,
const _ExtractKey& __ext,
340 const allocator_type& __a = allocator_type())
341 : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
342 _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
343 { _M_initialize_buckets(__n); }
345 hashtable(size_type __n,
const _HashFcn& __hf,
346 const _EqualKey& __eql,
347 const allocator_type& __a = allocator_type())
348 : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
349 _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
350 { _M_initialize_buckets(__n); }
352 hashtable(
const hashtable& __ht)
353 : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
354 _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
355 _M_buckets(__ht.get_allocator()), _M_num_elements(0)
356 { _M_copy_from(__ht); }
359 operator= (
const hashtable& __ht)
364 _M_hash = __ht._M_hash;
365 _M_equals = __ht._M_equals;
366 _M_get_key = __ht._M_get_key;
377 {
return _M_num_elements; }
381 {
return size_type(-1); }
385 {
return size() == 0; }
388 swap(hashtable& __ht)
390 std::swap(_M_hash, __ht._M_hash);
391 std::swap(_M_equals, __ht._M_equals);
392 std::swap(_M_get_key, __ht._M_get_key);
393 _M_buckets.swap(__ht._M_buckets);
394 std::swap(_M_num_elements, __ht._M_num_elements);
400 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
402 return iterator(_M_buckets[__n],
this);
408 {
return iterator(0,
this); }
413 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
415 return const_iterator(_M_buckets[__n],
this);
421 {
return const_iterator(0,
this); }
423 template<
class _Vl,
class _Ky,
class _HF,
class _Ex,
class _Eq,
426 operator==(
const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
427 const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
432 {
return _M_buckets.size(); }
435 max_bucket_count()
const
436 {
return _Hashtable_prime_list<unsigned long>::
437 _S_get_prime_list()[(int)_S_num_primes - 1];
441 elems_in_bucket(size_type __bucket)
const
443 size_type __result = 0;
444 for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
450 insert_unique(
const value_type& __obj)
452 resize(_M_num_elements + 1);
453 return insert_unique_noresize(__obj);
457 insert_equal(
const value_type& __obj)
459 resize(_M_num_elements + 1);
460 return insert_equal_noresize(__obj);
464 insert_unique_noresize(
const value_type& __obj);
467 insert_equal_noresize(
const value_type& __obj);
469 template<
class _InputIterator>
471 insert_unique(_InputIterator __f, _InputIterator __l)
474 template<
class _InputIterator>
476 insert_equal(_InputIterator __f, _InputIterator __l)
479 template<
class _InputIterator>
481 insert_unique(_InputIterator __f, _InputIterator __l,
484 for ( ; __f != __l; ++__f)
488 template<
class _InputIterator>
490 insert_equal(_InputIterator __f, _InputIterator __l,
493 for ( ; __f != __l; ++__f)
497 template<
class _ForwardIterator>
499 insert_unique(_ForwardIterator __f, _ForwardIterator __l,
500 forward_iterator_tag)
503 resize(_M_num_elements + __n);
504 for ( ; __n > 0; --__n, ++__f)
505 insert_unique_noresize(*__f);
508 template<
class _ForwardIterator>
510 insert_equal(_ForwardIterator __f, _ForwardIterator __l,
511 forward_iterator_tag)
514 resize(_M_num_elements + __n);
515 for ( ; __n > 0; --__n, ++__f)
516 insert_equal_noresize(*__f);
520 find_or_insert(
const value_type& __obj);
523 find(
const key_type& __key)
525 size_type __n = _M_bkt_num_key(__key);
527 for (__first = _M_buckets[__n];
528 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
529 __first = __first->_M_next)
531 return iterator(__first,
this);
535 find(
const key_type& __key)
const
537 size_type __n = _M_bkt_num_key(__key);
538 const _Node* __first;
539 for (__first = _M_buckets[__n];
540 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
541 __first = __first->_M_next)
543 return const_iterator(__first,
this);
547 count(
const key_type& __key)
const
549 const size_type __n = _M_bkt_num_key(__key);
550 size_type __result = 0;
552 for (
const _Node* __cur = _M_buckets[__n]; __cur;
553 __cur = __cur->_M_next)
554 if (_M_equals(_M_get_key(__cur->_M_val), __key))
559 pair<iterator, iterator>
560 equal_range(
const key_type& __key);
562 pair<const_iterator, const_iterator>
563 equal_range(
const key_type& __key)
const;
566 erase(
const key_type& __key);
569 erase(
const iterator& __it);
572 erase(iterator __first, iterator __last);
575 erase(
const const_iterator& __it);
578 erase(const_iterator __first, const_iterator __last);
581 resize(size_type __num_elements_hint);
588 _M_next_size(size_type __n)
const
589 {
return __stl_next_prime(__n); }
592 _M_initialize_buckets(size_type __n)
594 const size_type __n_buckets = _M_next_size(__n);
595 _M_buckets.reserve(__n_buckets);
596 _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
601 _M_bkt_num_key(
const key_type& __key)
const
602 {
return _M_bkt_num_key(__key, _M_buckets.size()); }
605 _M_bkt_num(
const value_type& __obj)
const
606 {
return _M_bkt_num_key(_M_get_key(__obj)); }
609 _M_bkt_num_key(
const key_type& __key,
size_t __n)
const
610 {
return _M_hash(__key) % __n; }
613 _M_bkt_num(
const value_type& __obj,
size_t __n)
const
614 {
return _M_bkt_num_key(_M_get_key(__obj), __n); }
617 _M_new_node(
const value_type& __obj)
619 _Node* __n = _M_get_node();
623 this->get_allocator().construct(&__n->_M_val, __obj);
629 __throw_exception_again;
634 _M_delete_node(_Node* __n)
636 this->get_allocator().destroy(&__n->_M_val);
641 _M_erase_bucket(
const size_type __n, _Node* __first, _Node* __last);
644 _M_erase_bucket(
const size_type __n, _Node* __last);
647 _M_copy_from(
const hashtable& __ht);
650 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
652 _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
653 _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
656 const _Node* __old = _M_cur;
657 _M_cur = _M_cur->_M_next;
660 size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
661 while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
662 _M_cur = _M_ht->_M_buckets[__bucket];
667 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
669 inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
670 _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
673 iterator __tmp = *
this;
678 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
680 _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
681 _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
684 const _Node* __old = _M_cur;
685 _M_cur = _M_cur->_M_next;
688 size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
689 while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
690 _M_cur = _M_ht->_M_buckets[__bucket];
695 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
697 inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
698 _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
701 const_iterator __tmp = *
this;
706 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
708 operator==(
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
709 const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
711 typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
713 if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
716 for (
size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
718 _Node* __cur1 = __ht1._M_buckets[__n];
719 _Node* __cur2 = __ht2._M_buckets[__n];
721 for (; __cur1 && __cur2;
722 __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
724 if (__cur1 || __cur2)
727 for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
728 __cur1 = __cur1->_M_next)
730 bool _found__cur1 =
false;
731 for (__cur2 = __ht2._M_buckets[__n];
732 __cur2; __cur2 = __cur2->_M_next)
734 if (__cur1->_M_val == __cur2->_M_val)
747 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
749 operator!=(
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
750 const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
751 {
return !(__ht1 == __ht2); }
753 template<
class _Val,
class _Key,
class _HF,
class _Extract,
class _EqKey,
756 swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
757 hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
758 { __ht1.swap(__ht2); }
760 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
761 pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
bool>
762 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
763 insert_unique_noresize(
const value_type& __obj)
765 const size_type __n = _M_bkt_num(__obj);
766 _Node* __first = _M_buckets[__n];
768 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
769 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
770 return pair<iterator, bool>(iterator(__cur,
this),
false);
772 _Node* __tmp = _M_new_node(__obj);
773 __tmp->_M_next = __first;
774 _M_buckets[__n] = __tmp;
776 return pair<iterator, bool>(iterator(__tmp,
this),
true);
779 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
780 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
781 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
782 insert_equal_noresize(
const value_type& __obj)
784 const size_type __n = _M_bkt_num(__obj);
785 _Node* __first = _M_buckets[__n];
787 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
788 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
790 _Node* __tmp = _M_new_node(__obj);
791 __tmp->_M_next = __cur->_M_next;
792 __cur->_M_next = __tmp;
794 return iterator(__tmp,
this);
797 _Node* __tmp = _M_new_node(__obj);
798 __tmp->_M_next = __first;
799 _M_buckets[__n] = __tmp;
801 return iterator(__tmp,
this);
804 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
805 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
806 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
807 find_or_insert(
const value_type& __obj)
809 resize(_M_num_elements + 1);
811 size_type __n = _M_bkt_num(__obj);
812 _Node* __first = _M_buckets[__n];
814 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
815 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
816 return __cur->_M_val;
818 _Node* __tmp = _M_new_node(__obj);
819 __tmp->_M_next = __first;
820 _M_buckets[__n] = __tmp;
822 return __tmp->_M_val;
825 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
826 pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
827 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
828 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
829 equal_range(
const key_type& __key)
831 typedef pair<iterator, iterator> _Pii;
832 const size_type __n = _M_bkt_num_key(__key);
834 for (_Node* __first = _M_buckets[__n]; __first;
835 __first = __first->_M_next)
836 if (_M_equals(_M_get_key(__first->_M_val), __key))
838 for (_Node* __cur = __first->_M_next; __cur;
839 __cur = __cur->_M_next)
840 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
841 return _Pii(iterator(__first,
this), iterator(__cur,
this));
842 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
844 return _Pii(iterator(__first,
this),
845 iterator(_M_buckets[__m],
this));
846 return _Pii(iterator(__first,
this),
end());
848 return _Pii(
end(),
end());
851 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
852 pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
853 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
854 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
855 equal_range(
const key_type& __key)
const
857 typedef pair<const_iterator, const_iterator> _Pii;
858 const size_type __n = _M_bkt_num_key(__key);
860 for (
const _Node* __first = _M_buckets[__n]; __first;
861 __first = __first->_M_next)
863 if (_M_equals(_M_get_key(__first->_M_val), __key))
865 for (
const _Node* __cur = __first->_M_next; __cur;
866 __cur = __cur->_M_next)
867 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
868 return _Pii(const_iterator(__first,
this),
869 const_iterator(__cur,
this));
870 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
872 return _Pii(const_iterator(__first,
this),
873 const_iterator(_M_buckets[__m],
this));
874 return _Pii(const_iterator(__first,
this),
end());
877 return _Pii(
end(),
end());
880 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
881 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
882 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
883 erase(
const key_type& __key)
885 const size_type __n = _M_bkt_num_key(__key);
886 _Node* __first = _M_buckets[__n];
887 _Node* __saved_slot = 0;
888 size_type __erased = 0;
892 _Node* __cur = __first;
893 _Node* __next = __cur->_M_next;
896 if (_M_equals(_M_get_key(__next->_M_val), __key))
898 if (&_M_get_key(__next->_M_val) != &__key)
900 __cur->_M_next = __next->_M_next;
901 _M_delete_node(__next);
902 __next = __cur->_M_next;
908 __saved_slot = __cur;
910 __next = __cur->_M_next;
916 __next = __cur->_M_next;
919 bool __delete_first = _M_equals(_M_get_key(__first->_M_val), __key);
922 __next = __saved_slot->_M_next;
923 __saved_slot->_M_next = __next->_M_next;
924 _M_delete_node(__next);
930 _M_buckets[__n] = __first->_M_next;
931 _M_delete_node(__first);
939 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
940 void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
941 erase(
const iterator& __it)
943 _Node* __p = __it._M_cur;
946 const size_type __n = _M_bkt_num(__p->_M_val);
947 _Node* __cur = _M_buckets[__n];
951 _M_buckets[__n] = __cur->_M_next;
952 _M_delete_node(__cur);
957 _Node* __next = __cur->_M_next;
962 __cur->_M_next = __next->_M_next;
963 _M_delete_node(__next);
970 __next = __cur->_M_next;
977 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
979 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
980 erase(iterator __first, iterator __last)
982 size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
985 size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
988 if (__first._M_cur == __last._M_cur)
990 else if (__f_bucket == __l_bucket)
991 _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
994 _M_erase_bucket(__f_bucket, __first._M_cur, 0);
995 for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
996 _M_erase_bucket(__n, 0);
997 if (__l_bucket != _M_buckets.size())
998 _M_erase_bucket(__l_bucket, __last._M_cur);
1002 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1004 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1005 erase(const_iterator __first, const_iterator __last)
1007 erase(iterator(const_cast<_Node*>(__first._M_cur),
1008 const_cast<hashtable*>(__first._M_ht)),
1009 iterator(const_cast<_Node*>(__last._M_cur),
1010 const_cast<hashtable*>(__last._M_ht)));
1013 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1015 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1016 erase(
const const_iterator& __it)
1017 { erase(iterator(const_cast<_Node*>(__it._M_cur),
1018 const_cast<hashtable*>(__it._M_ht))); }
1020 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1022 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1023 resize(size_type __num_elements_hint)
1025 const size_type __old_n = _M_buckets.size();
1026 if (__num_elements_hint > __old_n)
1028 const size_type __n = _M_next_size(__num_elements_hint);
1031 _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
1034 for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
1036 _Node* __first = _M_buckets[__bucket];
1039 size_type __new_bucket = _M_bkt_num(__first->_M_val,
1041 _M_buckets[__bucket] = __first->_M_next;
1042 __first->_M_next = __tmp[__new_bucket];
1043 __tmp[__new_bucket] = __first;
1044 __first = _M_buckets[__bucket];
1047 _M_buckets.swap(__tmp);
1051 for (size_type __bucket = 0; __bucket < __tmp.size();
1054 while (__tmp[__bucket])
1056 _Node* __next = __tmp[__bucket]->_M_next;
1057 _M_delete_node(__tmp[__bucket]);
1058 __tmp[__bucket] = __next;
1061 __throw_exception_again;
1067 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1069 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1070 _M_erase_bucket(
const size_type __n, _Node* __first, _Node* __last)
1072 _Node* __cur = _M_buckets[__n];
1073 if (__cur == __first)
1074 _M_erase_bucket(__n, __last);
1078 for (__next = __cur->_M_next;
1080 __cur = __next, __next = __cur->_M_next)
1082 while (__next != __last)
1084 __cur->_M_next = __next->_M_next;
1085 _M_delete_node(__next);
1086 __next = __cur->_M_next;
1092 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1094 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1095 _M_erase_bucket(
const size_type __n, _Node* __last)
1097 _Node* __cur = _M_buckets[__n];
1098 while (__cur != __last)
1100 _Node* __next = __cur->_M_next;
1101 _M_delete_node(__cur);
1103 _M_buckets[__n] = __cur;
1108 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1110 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1113 if (_M_num_elements == 0)
1116 for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
1118 _Node* __cur = _M_buckets[__i];
1121 _Node* __next = __cur->_M_next;
1122 _M_delete_node(__cur);
1125 _M_buckets[__i] = 0;
1127 _M_num_elements = 0;
1130 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1132 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1133 _M_copy_from(
const hashtable& __ht)
1136 _M_buckets.reserve(__ht._M_buckets.size());
1137 _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
1140 for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
1141 const _Node* __cur = __ht._M_buckets[__i];
1144 _Node* __local_copy = _M_new_node(__cur->_M_val);
1145 _M_buckets[__i] = __local_copy;
1147 for (_Node* __next = __cur->_M_next;
1149 __cur = __next, __next = __cur->_M_next)
1151 __local_copy->_M_next = _M_new_node(__next->_M_val);
1152 __local_copy = __local_copy->_M_next;
1156 _M_num_elements = __ht._M_num_elements;
1161 __throw_exception_again;
1165 _GLIBCXX_END_NAMESPACE_VERSION
The standard allocator, as per [20.4].
void _Destroy(_Tp *__pointer)
void distance(_InputIterator __first, _InputIterator __last, _Distance &__n)
size_t count() const _GLIBCXX_NOEXCEPT
Returns the number of bits which are set.
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to one past the last element of the initilizer_list.
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
Struct holding two objects of arbitrary type.
Forward iterators support a superset of input iterator operations.
void _Construct(_T1 *__p, _Args &&...__args)
iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__val)
Finds the first position in which val could be inserted without changing the ordering.
constexpr const _Tp * begin(initializer_list< _Tp > __ils) noexcept
Return an iterator pointing to the first element of the initilizer_list.
constexpr size_t size() const _GLIBCXX_NOEXCEPT
Returns the total number of bits.
A standard container which offers fixed time access to individual elements in any order...