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 static const unsigned long __stl_prime_list[_S_num_primes] =
214 5ul, 53ul, 97ul, 193ul, 389ul,
215 769ul, 1543ul, 3079ul, 6151ul, 12289ul,
216 24593ul, 49157ul, 98317ul, 196613ul, 393241ul,
217 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul,
218 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul,
219 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul
223 __stl_next_prime(
unsigned long __n)
225 const unsigned long* __first = __stl_prime_list;
226 const unsigned long* __last = __stl_prime_list + (int)_S_num_primes;
228 return pos == __last ? *(__last - 1) : *pos;
232 template<
class _Val,
class _Key,
class _HF,
class _Ex,
233 class _Eq,
class _All>
236 template<
class _Val,
class _Key,
class _HF,
class _Ex,
237 class _Eq,
class _All>
239 operator==(
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
240 const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
250 template<
class _Val,
class _Key,
class _HashFcn,
251 class _ExtractKey,
class _EqualKey,
class _Alloc>
255 typedef _Key key_type;
256 typedef _Val value_type;
257 typedef _HashFcn hasher;
258 typedef _EqualKey key_equal;
260 typedef size_t size_type;
261 typedef ptrdiff_t difference_type;
262 typedef value_type* pointer;
263 typedef const value_type* const_pointer;
264 typedef value_type& reference;
265 typedef const value_type& const_reference;
273 {
return _M_equals; }
276 typedef _Hashtable_node<_Val> _Node;
279 typedef typename _Alloc::template rebind<value_type>::other allocator_type;
281 get_allocator()
const
282 {
return _M_node_allocator; }
285 typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
286 typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
287 typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
289 _Node_Alloc _M_node_allocator;
293 {
return _M_node_allocator.allocate(1); }
296 _M_put_node(_Node* __p)
297 { _M_node_allocator.deallocate(__p, 1); }
302 _ExtractKey _M_get_key;
303 _Vector_type _M_buckets;
304 size_type _M_num_elements;
307 typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
310 typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
315 _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>;
318 _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
322 hashtable(size_type __n,
const _HashFcn& __hf,
323 const _EqualKey& __eql,
const _ExtractKey& __ext,
324 const allocator_type& __a = allocator_type())
325 : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
326 _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0)
327 { _M_initialize_buckets(__n); }
329 hashtable(size_type __n,
const _HashFcn& __hf,
330 const _EqualKey& __eql,
331 const allocator_type& __a = allocator_type())
332 : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql),
333 _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0)
334 { _M_initialize_buckets(__n); }
336 hashtable(
const hashtable& __ht)
337 : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash),
338 _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key),
339 _M_buckets(__ht.get_allocator()), _M_num_elements(0)
340 { _M_copy_from(__ht); }
343 operator= (
const hashtable& __ht)
348 _M_hash = __ht._M_hash;
349 _M_equals = __ht._M_equals;
350 _M_get_key = __ht._M_get_key;
361 {
return _M_num_elements; }
365 {
return size_type(-1); }
369 {
return size() == 0; }
372 swap(hashtable& __ht)
374 std::swap(_M_hash, __ht._M_hash);
375 std::swap(_M_equals, __ht._M_equals);
376 std::swap(_M_get_key, __ht._M_get_key);
377 _M_buckets.swap(__ht._M_buckets);
378 std::swap(_M_num_elements, __ht._M_num_elements);
384 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
386 return iterator(_M_buckets[__n],
this);
392 {
return iterator(0,
this); }
397 for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
399 return const_iterator(_M_buckets[__n],
this);
405 {
return const_iterator(0,
this); }
407 template<
class _Vl,
class _Ky,
class _HF,
class _Ex,
class _Eq,
410 operator==(
const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&,
411 const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&);
416 {
return _M_buckets.size(); }
419 max_bucket_count()
const
420 {
return __stl_prime_list[(int)_S_num_primes - 1]; }
423 elems_in_bucket(size_type __bucket)
const
425 size_type __result = 0;
426 for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next)
432 insert_unique(
const value_type& __obj)
434 resize(_M_num_elements + 1);
435 return insert_unique_noresize(__obj);
439 insert_equal(
const value_type& __obj)
441 resize(_M_num_elements + 1);
442 return insert_equal_noresize(__obj);
446 insert_unique_noresize(
const value_type& __obj);
449 insert_equal_noresize(
const value_type& __obj);
451 template<
class _InputIterator>
453 insert_unique(_InputIterator __f, _InputIterator __l)
456 template<
class _InputIterator>
458 insert_equal(_InputIterator __f, _InputIterator __l)
461 template<
class _InputIterator>
463 insert_unique(_InputIterator __f, _InputIterator __l,
466 for ( ; __f != __l; ++__f)
470 template<
class _InputIterator>
472 insert_equal(_InputIterator __f, _InputIterator __l,
475 for ( ; __f != __l; ++__f)
479 template<
class _ForwardIterator>
481 insert_unique(_ForwardIterator __f, _ForwardIterator __l,
482 forward_iterator_tag)
485 resize(_M_num_elements + __n);
486 for ( ; __n > 0; --__n, ++__f)
487 insert_unique_noresize(*__f);
490 template<
class _ForwardIterator>
492 insert_equal(_ForwardIterator __f, _ForwardIterator __l,
493 forward_iterator_tag)
496 resize(_M_num_elements + __n);
497 for ( ; __n > 0; --__n, ++__f)
498 insert_equal_noresize(*__f);
502 find_or_insert(
const value_type& __obj);
505 find(
const key_type& __key)
507 size_type __n = _M_bkt_num_key(__key);
509 for (__first = _M_buckets[__n];
510 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
511 __first = __first->_M_next)
513 return iterator(__first,
this);
517 find(
const key_type& __key)
const
519 size_type __n = _M_bkt_num_key(__key);
520 const _Node* __first;
521 for (__first = _M_buckets[__n];
522 __first && !_M_equals(_M_get_key(__first->_M_val), __key);
523 __first = __first->_M_next)
525 return const_iterator(__first,
this);
529 count(
const key_type& __key)
const
531 const size_type __n = _M_bkt_num_key(__key);
532 size_type __result = 0;
534 for (
const _Node* __cur = _M_buckets[__n]; __cur;
535 __cur = __cur->_M_next)
536 if (_M_equals(_M_get_key(__cur->_M_val), __key))
541 pair<iterator, iterator>
542 equal_range(
const key_type& __key);
544 pair<const_iterator, const_iterator>
545 equal_range(
const key_type& __key)
const;
548 erase(
const key_type& __key);
551 erase(
const iterator& __it);
554 erase(iterator __first, iterator __last);
557 erase(
const const_iterator& __it);
560 erase(const_iterator __first, const_iterator __last);
563 resize(size_type __num_elements_hint);
570 _M_next_size(size_type __n)
const
571 {
return __stl_next_prime(__n); }
574 _M_initialize_buckets(size_type __n)
576 const size_type __n_buckets = _M_next_size(__n);
577 _M_buckets.reserve(__n_buckets);
578 _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
583 _M_bkt_num_key(
const key_type& __key)
const
584 {
return _M_bkt_num_key(__key, _M_buckets.size()); }
587 _M_bkt_num(
const value_type& __obj)
const
588 {
return _M_bkt_num_key(_M_get_key(__obj)); }
591 _M_bkt_num_key(
const key_type& __key,
size_t __n)
const
592 {
return _M_hash(__key) % __n; }
595 _M_bkt_num(
const value_type& __obj,
size_t __n)
const
596 {
return _M_bkt_num_key(_M_get_key(__obj), __n); }
599 _M_new_node(
const value_type& __obj)
601 _Node* __n = _M_get_node();
605 this->get_allocator().construct(&__n->_M_val, __obj);
611 __throw_exception_again;
616 _M_delete_node(_Node* __n)
618 this->get_allocator().destroy(&__n->_M_val);
623 _M_erase_bucket(
const size_type __n, _Node* __first, _Node* __last);
626 _M_erase_bucket(
const size_type __n, _Node* __last);
629 _M_copy_from(
const hashtable& __ht);
632 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
634 _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
635 _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
638 const _Node* __old = _M_cur;
639 _M_cur = _M_cur->_M_next;
642 size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
643 while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
644 _M_cur = _M_ht->_M_buckets[__bucket];
649 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
651 inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
652 _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
655 iterator __tmp = *
this;
660 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
662 _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
663 _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
666 const _Node* __old = _M_cur;
667 _M_cur = _M_cur->_M_next;
670 size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
671 while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
672 _M_cur = _M_ht->_M_buckets[__bucket];
677 template<
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
679 inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
680 _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::
683 const_iterator __tmp = *
this;
688 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
690 operator==(
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
691 const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
693 typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
695 if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
698 for (
size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n)
700 _Node* __cur1 = __ht1._M_buckets[__n];
701 _Node* __cur2 = __ht2._M_buckets[__n];
703 for (; __cur1 && __cur2;
704 __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
706 if (__cur1 || __cur2)
709 for (__cur1 = __ht1._M_buckets[__n] ; __cur1;
710 __cur1 = __cur1->_M_next)
712 bool _found__cur1 =
false;
713 for (__cur2 = __ht2._M_buckets[__n];
714 __cur2; __cur2 = __cur2->_M_next)
716 if (__cur1->_M_val == __cur2->_M_val)
729 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
731 operator!=(
const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
732 const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
733 {
return !(__ht1 == __ht2); }
735 template<
class _Val,
class _Key,
class _HF,
class _Extract,
class _EqKey,
738 swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
739 hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
740 { __ht1.swap(__ht2); }
742 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
743 pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
bool>
744 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
745 insert_unique_noresize(
const value_type& __obj)
747 const size_type __n = _M_bkt_num(__obj);
748 _Node* __first = _M_buckets[__n];
750 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
751 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
752 return pair<iterator, bool>(iterator(__cur,
this),
false);
754 _Node* __tmp = _M_new_node(__obj);
755 __tmp->_M_next = __first;
756 _M_buckets[__n] = __tmp;
758 return pair<iterator, bool>(iterator(__tmp,
this),
true);
761 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
762 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
763 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
764 insert_equal_noresize(
const value_type& __obj)
766 const size_type __n = _M_bkt_num(__obj);
767 _Node* __first = _M_buckets[__n];
769 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
770 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
772 _Node* __tmp = _M_new_node(__obj);
773 __tmp->_M_next = __cur->_M_next;
774 __cur->_M_next = __tmp;
776 return iterator(__tmp,
this);
779 _Node* __tmp = _M_new_node(__obj);
780 __tmp->_M_next = __first;
781 _M_buckets[__n] = __tmp;
783 return iterator(__tmp,
this);
786 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
787 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
788 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
789 find_or_insert(
const value_type& __obj)
791 resize(_M_num_elements + 1);
793 size_type __n = _M_bkt_num(__obj);
794 _Node* __first = _M_buckets[__n];
796 for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
797 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
798 return __cur->_M_val;
800 _Node* __tmp = _M_new_node(__obj);
801 __tmp->_M_next = __first;
802 _M_buckets[__n] = __tmp;
804 return __tmp->_M_val;
807 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
808 pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
809 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
810 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
811 equal_range(
const key_type& __key)
813 typedef pair<iterator, iterator> _Pii;
814 const size_type __n = _M_bkt_num_key(__key);
816 for (_Node* __first = _M_buckets[__n]; __first;
817 __first = __first->_M_next)
818 if (_M_equals(_M_get_key(__first->_M_val), __key))
820 for (_Node* __cur = __first->_M_next; __cur;
821 __cur = __cur->_M_next)
822 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
823 return _Pii(iterator(__first,
this), iterator(__cur,
this));
824 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
826 return _Pii(iterator(__first,
this),
827 iterator(_M_buckets[__m],
this));
828 return _Pii(iterator(__first,
this),
end());
830 return _Pii(
end(),
end());
833 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
834 pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
835 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
836 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
837 equal_range(
const key_type& __key)
const
839 typedef pair<const_iterator, const_iterator> _Pii;
840 const size_type __n = _M_bkt_num_key(__key);
842 for (
const _Node* __first = _M_buckets[__n]; __first;
843 __first = __first->_M_next)
845 if (_M_equals(_M_get_key(__first->_M_val), __key))
847 for (
const _Node* __cur = __first->_M_next; __cur;
848 __cur = __cur->_M_next)
849 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
850 return _Pii(const_iterator(__first,
this),
851 const_iterator(__cur,
this));
852 for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
854 return _Pii(const_iterator(__first,
this),
855 const_iterator(_M_buckets[__m],
this));
856 return _Pii(const_iterator(__first,
this),
end());
859 return _Pii(
end(),
end());
862 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
863 typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
864 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
865 erase(
const key_type& __key)
867 const size_type __n = _M_bkt_num_key(__key);
868 _Node* __first = _M_buckets[__n];
869 _Node* __saved_slot = 0;
870 size_type __erased = 0;
874 _Node* __cur = __first;
875 _Node* __next = __cur->_M_next;
878 if (_M_equals(_M_get_key(__next->_M_val), __key))
880 if (&_M_get_key(__next->_M_val) != &__key)
882 __cur->_M_next = __next->_M_next;
883 _M_delete_node(__next);
884 __next = __cur->_M_next;
890 __saved_slot = __cur;
892 __next = __cur->_M_next;
898 __next = __cur->_M_next;
901 if (_M_equals(_M_get_key(__first->_M_val), __key))
903 _M_buckets[__n] = __first->_M_next;
904 _M_delete_node(__first);
910 __next = __saved_slot->_M_next;
911 __saved_slot->_M_next = __next->_M_next;
912 _M_delete_node(__next);
920 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
921 void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
922 erase(
const iterator& __it)
924 _Node* __p = __it._M_cur;
927 const size_type __n = _M_bkt_num(__p->_M_val);
928 _Node* __cur = _M_buckets[__n];
932 _M_buckets[__n] = __cur->_M_next;
933 _M_delete_node(__cur);
938 _Node* __next = __cur->_M_next;
943 __cur->_M_next = __next->_M_next;
944 _M_delete_node(__next);
951 __next = __cur->_M_next;
958 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
960 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
961 erase(iterator __first, iterator __last)
963 size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val)
966 size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val)
969 if (__first._M_cur == __last._M_cur)
971 else if (__f_bucket == __l_bucket)
972 _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
975 _M_erase_bucket(__f_bucket, __first._M_cur, 0);
976 for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
977 _M_erase_bucket(__n, 0);
978 if (__l_bucket != _M_buckets.size())
979 _M_erase_bucket(__l_bucket, __last._M_cur);
983 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
985 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
986 erase(const_iterator __first, const_iterator __last)
988 erase(iterator(const_cast<_Node*>(__first._M_cur),
989 const_cast<hashtable*>(__first._M_ht)),
990 iterator(const_cast<_Node*>(__last._M_cur),
991 const_cast<hashtable*>(__last._M_ht)));
994 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
996 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
997 erase(
const const_iterator& __it)
998 { erase(iterator(const_cast<_Node*>(__it._M_cur),
999 const_cast<hashtable*>(__it._M_ht))); }
1001 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1003 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1004 resize(size_type __num_elements_hint)
1006 const size_type __old_n = _M_buckets.size();
1007 if (__num_elements_hint > __old_n)
1009 const size_type __n = _M_next_size(__num_elements_hint);
1012 _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
1015 for (size_type __bucket = 0; __bucket < __old_n; ++__bucket)
1017 _Node* __first = _M_buckets[__bucket];
1020 size_type __new_bucket = _M_bkt_num(__first->_M_val,
1022 _M_buckets[__bucket] = __first->_M_next;
1023 __first->_M_next = __tmp[__new_bucket];
1024 __tmp[__new_bucket] = __first;
1025 __first = _M_buckets[__bucket];
1028 _M_buckets.swap(__tmp);
1032 for (size_type __bucket = 0; __bucket < __tmp.size();
1035 while (__tmp[__bucket])
1037 _Node* __next = __tmp[__bucket]->_M_next;
1038 _M_delete_node(__tmp[__bucket]);
1039 __tmp[__bucket] = __next;
1042 __throw_exception_again;
1048 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1050 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1051 _M_erase_bucket(
const size_type __n, _Node* __first, _Node* __last)
1053 _Node* __cur = _M_buckets[__n];
1054 if (__cur == __first)
1055 _M_erase_bucket(__n, __last);
1059 for (__next = __cur->_M_next;
1061 __cur = __next, __next = __cur->_M_next)
1063 while (__next != __last)
1065 __cur->_M_next = __next->_M_next;
1066 _M_delete_node(__next);
1067 __next = __cur->_M_next;
1073 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1075 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1076 _M_erase_bucket(
const size_type __n, _Node* __last)
1078 _Node* __cur = _M_buckets[__n];
1079 while (__cur != __last)
1081 _Node* __next = __cur->_M_next;
1082 _M_delete_node(__cur);
1084 _M_buckets[__n] = __cur;
1089 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1091 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1094 if (_M_num_elements == 0)
1097 for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
1099 _Node* __cur = _M_buckets[__i];
1102 _Node* __next = __cur->_M_next;
1103 _M_delete_node(__cur);
1106 _M_buckets[__i] = 0;
1108 _M_num_elements = 0;
1111 template<
class _Val,
class _Key,
class _HF,
class _Ex,
class _Eq,
class _All>
1113 hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
1114 _M_copy_from(
const hashtable& __ht)
1117 _M_buckets.reserve(__ht._M_buckets.size());
1118 _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
1121 for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
1122 const _Node* __cur = __ht._M_buckets[__i];
1125 _Node* __local_copy = _M_new_node(__cur->_M_val);
1126 _M_buckets[__i] = __local_copy;
1128 for (_Node* __next = __cur->_M_next;
1130 __cur = __next, __next = __cur->_M_next)
1132 __local_copy->_M_next = _M_new_node(__next->_M_val);
1133 __local_copy = __local_copy->_M_next;
1137 _M_num_elements = __ht._M_num_elements;
1142 __throw_exception_again;
1146 _GLIBCXX_END_NAMESPACE_VERSION