8#ifndef INCLUDED_BSLSTP_HASHTABLE
9#define INCLUDED_BSLSTP_HASHTABLE
44/ * Hewlett-Packard Company
46/ * Copyright (c) 1996,1997
47/ * Silicon Graphics Computer Systems, Inc.
50/ * Moscow Center
for SPARC Technology
55/ * This material is provided
"as is", with absolutely no warranty expressed
56/ * or implied. Any use is at your own risk.
58/ * Permission to use or copy
this software
for any purpose is hereby granted
59/ * without fee, provided the above notices are retained on all copies.
60/ * Permission to modify the code and to distribute modified code is granted,
61/ * provided the above notices are retained, and a notice that the code was
62/ * modified is included with the above copyright notice.
84#ifdef BDE_OPENSOURCE_PUBLICATION
85#error "bslstp_hashtable is not for publication"
120template <
class _Val,
class _Key,
class _HF,
121 class _ExK,
class _EqK,
class _All>
124template <
class _Val,
class _Key,
class _HF,
125 class _ExK,
class _EqK,
class _All>
143template <
class _Val,
class _Traits,
class _Key,
class _HF,
144 class _ExK,
class _EqK,
class _All>
190template <
class _Val,
class _Traits,
class _Traits1,
class _Key,
class _HF,
191 class _ExK,
class _EqK,
class _All>
201template <
class _Val,
class _Key,
class _HF,
202 class _ExK,
class _EqK,
class _All>
209#define BSLSTP_STL_NUM_PRIMES 31
227template <
class _Val,
class _Key,
class _HF,
228 class _ExK,
class _EqK,
class _All>
269 v1._M_buckets.swap(v2._M_buckets);
271 v2._M_num_elements._M_data);
278 typedef vector<void*, _M_node_ptr_allocator_type> _BucketVector;
283 return (
const _M_node_allocator_type&)(_M_num_elements.get_allocator());
289 _BucketVector _M_buckets;
291 const _Node* _M_get_bucket(
size_t __n)
const {
return (_Node*)_M_buckets[__n]; }
315 _M_initialize_buckets(__n);
329 _M_initialize_buckets(__n);
343 _M_hash(__ht._M_hash),
344 _M_equals(__ht._M_equals),
345 _M_get_key(__ht._M_get_key),
347 _M_num_elements(BloombergLP::
bslstp::Util::copyContainerAllocator((const _M_node_allocator_type&)__ht._M_num_elements), (
size_type)0)
354 _M_hash(__ht._M_hash),
355 _M_equals(__ht._M_equals),
356 _M_get_key(__ht._M_get_key),
367 _M_hash = __ht._M_hash;
368 _M_equals = __ht._M_equals;
369 _M_get_key = __ht._M_get_key;
383 BloombergLP::bslstp::Util::swapContainers(*
this, __ht,
QuickSwap());
388 for (
size_type __n = 0; __n < _M_buckets.size(); ++__n)
398 for (
size_type __n = 0; __n < _M_buckets.size(); ++__n)
439 template <
class _InputIterator>
444 insert_unique(__f, __l,
typename bsl::iterator_traits<_InputIterator>::iterator_category());
447 template <
class _InputIterator>
454 insert_equal(__f, __l,
typename bsl::iterator_traits<_InputIterator>::iterator_category());
457 template <
class _InputIterator>
459 const std::input_iterator_tag &)
461 for ( ; __f != __l; ++__f)
465 template <
class _InputIterator>
467 const std::input_iterator_tag &)
469 for ( ; __f != __l; ++__f)
473 template <
class _ForwardIterator>
475 const std::forward_iterator_tag &)
479 for ( ; __n > 0; --__n, ++__f)
483 template <
class _ForwardIterator>
485 const std::forward_iterator_tag &)
489 for ( ; __n > 0; --__n, ++__f)
499 size_type __n = _M_hash(__key)% _M_buckets.size();
501 for ( __first = (
_Node*)_M_buckets[__n];
502 __first && !_M_equals(_M_get_key(__first->
_M_val), __key);
512 return iterator(_M_find(__key),
this);
523 const size_type __n = _M_bkt_num_key(__key);
526 for (
const _Node* __cur = (
_Node*)_M_buckets[__n]; __cur; __cur = __cur->
_M_next)
527 if (_M_equals(_M_get_key(__cur->_M_val), __key))
557 void _M_initialize_buckets(
size_type __n)
559 const size_type __n_buckets = _M_next_size(__n);
560 _M_buckets.reserve(__n_buckets);
561 _M_buckets.insert(_M_buckets.end(), __n_buckets, (
void*) 0);
567 return _M_bkt_num_key(__key, _M_buckets.size());
572 return _M_bkt_num_key(_M_get_key(__obj));
577 return _M_hash(__key) % __n;
582 return _M_bkt_num_key(_M_get_key(__obj), __n);
587 _Node* __n = _M_num_elements.allocatorRef().allocate(1);
590 BloombergLP::bslma::ConstructionUtil::construct(
597 (_M_num_elements.allocatorRef().deallocate(__n, 1));
603 void _M_delete_node(_Node* __n)
605 BloombergLP::bslma::DestructionUtil::destroy(
607 _M_num_elements.allocatorRef().deallocate(__n, 1);
610 void _M_erase_bucket(
const size_type __n, _Node* __first, _Node* __last);
611 void _M_erase_bucket(
const size_type __n, _Node* __last);
613 void _M_copy_from(
const _Self& __ht);
616template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
624template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
628 return !(__hm1 == __hm2);
661# define BSLSTP_STL_PRIME_LIST_BODY { \
663 53ul, 97ul, 193ul, 389ul, 769ul, \
664 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, \
665 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, \
666 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, \
667 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,\
668 1610612741ul, 3221225473ul, 4294967291ul \
674# undef BSLSTP_STL_PRIME_LIST_BODY
676template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
678_Hashtable_node<_Val>*
680 size_t __bucket = _M_ht->_M_bkt_num(_M_cur->_M_val);
682 __h_sz = this->_M_ht->bucket_count();
685 while (__i==0 && ++__bucket < __h_sz)
686 __i = (
_Node*)_M_ht->_M_buckets[__bucket];
690template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
692typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: size_type
697 const size_type* pos = ::std::lower_bound(__first, __last, __n, ::std::less<size_type>());
698 return (pos == __last ? *(__last - 1) : *pos);
701template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
710 for (
size_t __n = 0; __n < __ht1.
bucket_count(); ++__n) {
711 const _Node* __cur1 = __ht1._M_get_bucket(__n);
712 const _Node* __cur2 = __ht2._M_get_bucket(__n);
713 for ( ; __cur1 && __cur2 && __cur1->
_M_val == __cur2->
_M_val;
716 if (__cur1 || __cur2)
722template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
730 for (
_Node* __cur = __first; __cur; __cur = __cur->
_M_next)
731 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
734 _Node* __tmp = _M_new_node(__obj);
736 _M_buckets[__n] = __tmp;
741template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
742typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: iterator
749 for (
_Node* __cur = __first; __cur; __cur = __cur->
_M_next)
750 if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
751 _Node* __tmp = _M_new_node(__obj);
758 _Node* __tmp = _M_new_node(__obj);
760 _M_buckets[__n] = __tmp;
765template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
766typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: reference
769 resize(_M_num_elements.
_M_data + 1);
774 _Node* __tmp = _M_new_node(__obj);
776 _M_buckets[__n] = __tmp;
781template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
782typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: reference
786 _Node* __first = _M_find(_M_get_key(__obj));
790 return _M_insert(__obj);
793template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
799 const size_type __n = _M_bkt_num_key(__key);
801 for (
_Node* __first = (
_Node*)_M_buckets[__n]; __first; __first = __first->
_M_next)
802 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
803 for (
_Node* __cur = __first->
_M_next; __cur; __cur = __cur->_M_next)
804 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
807 for (
size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
809 return _Pii(
iterator(__first,
this),
813 return _Pii(
end(),
end());
816template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
823 const size_type __n = _M_bkt_num_key(__key);
825 for (
const _Node* __first = (
_Node*)_M_buckets[__n] ;
828 if (_M_equals(_M_get_key(__first->_M_val), __key)) {
831 __cur = __cur->_M_next)
832 if (!_M_equals(_M_get_key(__cur->_M_val), __key))
835 for (
size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
842 return _Pii(
end(),
end());
845template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
846typename hashtable < _Val , _Key , _HF , _ExK , _EqK , _All > :: size_type
849 const size_type __n = _M_bkt_num_key(__key);
854 _Node* __cur = __first;
857 if (_M_equals(_M_get_key(__next->
_M_val), __key)) {
859 _M_delete_node(__next);
869 if (_M_equals(_M_get_key(__first->
_M_val), __key)) {
870 _M_buckets[__n] = __first->
_M_next;
871 _M_delete_node(__first);
879template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
889 _M_buckets[__n] = __cur->
_M_next;
890 _M_delete_node(__cur);
898 _M_delete_node(__next);
911template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
923 else if (__f_bucket == __l_bucket)
924 _M_erase_bucket(__f_bucket, __first.
_M_cur, __last.
_M_cur);
926 _M_erase_bucket(__f_bucket, __first.
_M_cur, 0);
927 for (
size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
928 _M_erase_bucket(__n, 0);
929 if (__l_bucket != _M_buckets.size())
930 _M_erase_bucket(__l_bucket, __last.
_M_cur);
934template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
939 if (__num_elements_hint > __old_n) {
940 const size_type __n = _M_next_size(__num_elements_hint);
943 _M_buckets.get_allocator());
945 for (
size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
946 _Node* __first = (
_Node*)_M_buckets[__bucket];
949 _M_buckets[__bucket] = __first->
_M_next;
951 __tmp[__new_bucket] = __first;
952 __first = (
_Node*)_M_buckets[__bucket];
955 _M_buckets.swap(__tmp);
958 for (
size_type __bucket = 0; __bucket < __tmp.
size(); ++__bucket) {
959 while (__tmp[__bucket]) {
961 _M_delete_node((
_Node*)__tmp[__bucket]);
962 __tmp[__bucket] = __next;
971template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
975 _Node* __cur = (_Node*)_M_buckets[__n];
976 if (__cur == __first)
977 _M_erase_bucket(__n, __last);
980 for (__next = __cur->_M_next;
982 __cur = __next, __next = __cur->_M_next)
984 while (__next != __last) {
985 __cur->_M_next = __next->_M_next;
986 _M_delete_node(__next);
987 __next = __cur->_M_next;
993template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
994void hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>
995 ::_M_erase_bucket(
const size_type __n, _Node* __last)
997 _Node* __cur = (_Node*)_M_buckets[__n];
998 while (__cur && __cur != __last) {
999 _Node* __next = __cur->_M_next;
1000 _M_delete_node(__cur);
1002 _M_buckets[__n] = __cur;
1007template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
1010 for (
size_type __i = 0; __i < _M_buckets.size(); ++__i) {
1012 while (__cur != 0) {
1014 _M_delete_node(__cur);
1017 _M_buckets[__i] = 0;
1023template <
class _Val,
class _Key,
class _HF,
class _ExK,
class _EqK,
class _All>
1028 _M_buckets.reserve(__ht._M_buckets.
size());
1029 _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.
size(), (
void*) 0);
1031 for (size_type __i = 0; __i < __ht._M_buckets.
size(); ++__i) {
1032 const _Node* __cur = (_Node*)__ht._M_buckets[__i];
1034 _Node* __xcopy = _M_new_node(__cur->_M_val);
1035 _M_buckets[__i] = __xcopy;
1037 for (_Node* __next = __cur->_M_next;
1039 __cur = __next, __next = __cur->_M_next) {
1040 __xcopy->_M_next = _M_new_node(__next->_M_val);
1041 __xcopy = __xcopy->_M_next;
1045 _M_num_elements.
_M_data = __ht._M_num_elements._M_data;
#define BSLSTP_STL_PRIME_LIST_BODY
Definition bslstp_hashtable.h:661
#define BSLSTP_STL_NUM_PRIMES
Definition bslstp_hashtable.h:209
Definition bslstp_alloc.h:105
_Value _M_data
Definition bslstp_alloc.h:112
_MaybeReboundAlloc get_allocator() const
Definition bslstp_alloc.h:115
Definition bslstp_hashtable.h:212
static const size_t _M_list[BSLSTP_STL_NUM_PRIMES]
Definition bslstp_hashtable.h:214
Definition bslstp_hashtable.h:230
size_type max_bucket_count() const
Definition bslstp_hashtable.h:413
iterator insert_equal_noresize(const value_type &__obj)
Definition bslstp_hashtable.h:744
reference find_or_insert(const value_type &__obj)
Definition bslstp_hashtable.h:783
void erase(const_iterator __first, const_iterator __last)
Definition bslstp_hashtable.h:913
~hashtable()
Definition bslstp_hashtable.h:375
void insert_equal(_InputIterator __f, _InputIterator __l)
Definition bslstp_hashtable.h:448
size_type erase(const key_type &__key)
Definition bslstp_hashtable.h:847
hasher hash_funct() const
Definition bslstp_hashtable.h:247
iterator begin()
Definition bslstp_hashtable.h:386
_HF hasher
Definition bslstp_hashtable.h:236
size_type max_size() const
Definition bslstp_hashtable.h:378
value_type & reference
Definition bslstp_hashtable.h:243
void erase(const const_iterator &__it)
Definition bslstp_hashtable.h:880
pair< iterator, iterator > equal_range(const key_type &__key)
Definition bslstp_hashtable.h:796
_Ht_iterator< _Val, __nonconst_val_traits, _Key, _HF, _ExK, _EqK, _All > iterator
Definition bslstp_hashtable.h:297
ptrdiff_t difference_type
Definition bslstp_hashtable.h:240
allocator_type get_allocator() const
Definition bslstp_hashtable.h:281
_Key key_type
Definition bslstp_hashtable.h:234
iterator insert_equal(const value_type &__obj)
Definition bslstp_hashtable.h:430
void insert_unique(_InputIterator __f, _InputIterator __l)
Definition bslstp_hashtable.h:440
iterator end()
Definition bslstp_hashtable.h:394
void swap(_Self &__ht)
Definition bslstp_hashtable.h:381
_Nonconst_traits< _Val > __nonconst_val_traits
Definition bslstp_hashtable.h:295
size_type size() const
Definition bslstp_hashtable.h:377
static bool _M_equal(const hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > &, const hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > &)
Definition bslstp_hashtable.h:703
std::forward_iterator_tag _Iterator_category
Definition bslstp_hashtable.h:245
key_equal key_eq() const
Definition bslstp_hashtable.h:248
const_iterator find(const _KT &__key) const
Definition bslstp_hashtable.h:516
pair< iterator, bool > insert_unique(const value_type &__obj)
Definition bslstp_hashtable.h:424
_Const_traits< _Val > __const_val_traits
Definition bslstp_hashtable.h:294
_Self & operator=(const _Self &__ht)
Definition bslstp_hashtable.h:363
size_type count(const key_type &__key) const
Definition bslstp_hashtable.h:521
pair< iterator, bool > insert_unique_noresize(const value_type &__obj)
Definition bslstp_hashtable.h:725
const_iterator end() const
Definition bslstp_hashtable.h:404
value_type * pointer
Definition bslstp_hashtable.h:241
void resize(size_type __num_elements_hint)
Definition bslstp_hashtable.h:936
const value_type & const_reference
Definition bslstp_hashtable.h:244
size_type bucket_count() const
Definition bslstp_hashtable.h:411
_EqK key_equal
Definition bslstp_hashtable.h:237
size_type elems_in_bucket(size_type __bucket) const
Definition bslstp_hashtable.h:416
bool empty() const
Definition bslstp_hashtable.h:379
hashtable(size_type __n, const _HF &__hf, const _EqK &__eql, const allocator_type &__a=allocator_type())
Definition bslstp_hashtable.h:318
pair< const_iterator, const_iterator > equal_range(const key_type &__key) const
Definition bslstp_hashtable.h:820
hashtable(const _Self &__ht, const allocator_type &__a)
Definition bslstp_hashtable.h:352
void insert_unique(_InputIterator __f, _InputIterator __l, const std::input_iterator_tag &)
Definition bslstp_hashtable.h:458
hashtable(const _Self &__ht)
Definition bslstp_hashtable.h:341
_Ht_iterator< _Val, __const_val_traits, _Key, _HF, _ExK, _EqK, _All > const_iterator
Definition bslstp_hashtable.h:296
_Val value_type
Definition bslstp_hashtable.h:235
void insert_equal(_InputIterator __f, _InputIterator __l, const std::input_iterator_tag &)
Definition bslstp_hashtable.h:466
const value_type * const_pointer
Definition bslstp_hashtable.h:242
friend struct QuickSwap
Definition bslstp_hashtable.h:254
size_t size_type
Definition bslstp_hashtable.h:239
void insert_equal(_ForwardIterator __f, _ForwardIterator __l, const std::forward_iterator_tag &)
Definition bslstp_hashtable.h:484
reference _M_insert(const value_type &__obj)
Definition bslstp_hashtable.h:767
hashtable(size_type __n, const _HF &__hf, const _EqK &__eql, const _ExK &__ext, const allocator_type &__a=allocator_type())
Definition bslstp_hashtable.h:303
const_iterator begin() const
Definition bslstp_hashtable.h:396
iterator find(const _KT &__key)
Definition bslstp_hashtable.h:510
void insert_unique(_ForwardIterator __f, _ForwardIterator __l, const std::forward_iterator_tag &)
Definition bslstp_hashtable.h:474
_Alloc_traits< _Val, _All >::allocator_type allocator_type
Definition bslstp_hashtable.h:280
void clear()
Definition bslstp_hashtable.h:1008
Definition bslstl_pair.h:1210
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
#define BSLS_CATCH(X)
Definition bsls_exceptionutil.h:372
#define BSLS_TRY
Definition bsls_exceptionutil.h:370
#define BSLS_RETHROW
Definition bsls_exceptionutil.h:378
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
Definition bdlb_printmethods.h:283
_Stl_prime< bool > _Stl_prime_type
Definition bslstp_hashtable.h:217
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
Definition bslstp_exfunctional.h:323
void swap(TYPE &a, TYPE &b)
_Rebind_type::other allocator_type
Definition bslstp_alloc.h:98
Definition bslstp_iterator.h:96
Definition bslstp_hashtable.h:127
_Hashtable_node< _Val > _Node
Definition bslstp_hashtable.h:130
_Node * _M_skip_to_next()
Definition bslstp_hashtable.h:679
hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > _Hashtable
Definition bslstp_hashtable.h:129
_Hashtable_iterator(_Node *__n, _Hashtable *__tab)
Definition bslstp_hashtable.h:135
_Node * _M_cur
Definition bslstp_hashtable.h:132
_Hashtable_iterator()
Definition bslstp_hashtable.h:137
_Hashtable * _M_ht
Definition bslstp_hashtable.h:133
Definition bslstp_hashtable.h:113
_Hashtable_node< _Val > _Self
Definition bslstp_hashtable.h:114
_Val _M_val
Definition bslstp_hashtable.h:116
_Self * _M_next
Definition bslstp_hashtable.h:115
Definition bslstp_hashtable.h:146
reference operator*() const
Definition bslstp_hashtable.h:171
_Hashtable_iterator< _Val, _Key, _HF, _ExK, _EqK, _All > _Base
Definition bslstp_hashtable.h:148
_Ht_iterator()
Definition bslstp_hashtable.h:167
_Val value_type
Definition bslstp_hashtable.h:157
ptrdiff_t difference_type
Definition bslstp_hashtable.h:159
_Traits::reference reference
Definition bslstp_hashtable.h:161
_Ht_iterator(const _Node *__n, const _Hashtable *__tab)
Definition bslstp_hashtable.h:164
_Traits::pointer pointer
Definition bslstp_hashtable.h:162
_Self operator++(int)
Definition bslstp_hashtable.h:183
pointer operator->() const
Definition bslstp_hashtable.h:175
_Hashtable_node< _Val > _Node
Definition bslstp_hashtable.h:155
size_t size_type
Definition bslstp_hashtable.h:160
std::forward_iterator_tag iterator_category
Definition bslstp_hashtable.h:158
_Self & operator++()
Definition bslstp_hashtable.h:177
hashtable< _Val, _Key, _HF, _ExK, _EqK, _All > _Hashtable
Definition bslstp_hashtable.h:154
_Ht_iterator(const _Ht_iterator< _Val, _Nonconst_traits< _Val >, _Key, _HF, _ExK, _EqK, _All > &__it)
Definition bslstp_hashtable.h:168
_Ht_iterator< _Val, _Traits, _Key, _HF, _ExK, _EqK, _All > _Self
Definition bslstp_hashtable.h:152
Definition bslstp_iterator.h:104