68 #ifndef __itk_hashtable_h
69 #define __itk_hashtable_h
73 #pragma warning ( disable : 4702 )
75 #pragma warning ( disable : 4512 )
78 #if (defined(__GNUC__) && (((__GNUC__==3) && (__GNUC_MINOR__>=1) || (__GNUC__>3) ) || ( (__GNUC__==4) && defined(__INTEL_COMPILER) ) )) || (defined(__IBMCPP__) && __IBMCPP__ >= 600)
91 #include "vcl_compiler.h"
99 template <
class Key>
struct hash { };
181 size_t operator()(
size_t x)
const {
return x; }
185 template <
class Value>
193 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey , VCL_DFL_TYPE_PARAM_STLDECL(Alloc,std::allocator<
char>)>
196 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
199 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
202 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
209 ExtractKey, EqualKey, Alloc>
235 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
269 #if ( __STL_STATIC_TEMPLATE_DATA > 0 ) && ! defined (WIN32)
270 # define prime_list prime<false>::list_
271 template <
bool dummy>
274 static const unsigned long list_[];
276 static const unsigned long prime_list_dummy[
num_primes] =
278 # if ( __STL_WEAK_ATTRIBUTE > 0 )
286 53, 97, 193, 389, 769,
287 1543, 3079, 6151, 12289, 24593,
288 49157, 98317, 196613, 393241, 786433,
289 1572869, 3145739, 6291469, 12582917, 25165843,
290 50331653, 100663319, 201326611, 402653189, 805306457,
291 1610612741, 3221225473U, 4294967291U
299 const unsigned long* pos = std::lower_bound(first, last, n);
300 return pos == last ? *(last - 1) : *pos;
303 template <
class Value,
class Alloc>
316 IUEi_STL_INLINE
void clear();
336 #define vcli_destroy(T, p) ((T*)p)->~T()
352 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
class hashtable;
353 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
354 bool operator== (hashtable<Value,Key,HashFcn,ExtractKey,EqualKey,Alloc>
const&,hashtable<Value,Key,HashFcn,ExtractKey,EqualKey,Alloc>
const&);
356 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
397 const ExtractKey& ext)
442 this->
buckets.swap(ht.buckets);
475 friend bool operator==ITK_FRIEND_TEMPLATE_FUNCTION_ARGUMENT(
self)(
const self&,
const self&);
488 for (
node* cur = this->
buckets[bucket]; cur; cur = cur->next)
533 std::distance(f, l, n);
544 std::distance(f, l, n);
558 for ( first = this->
buckets[n];
569 for ( first = this->
buckets[n];
581 for (
const node* cur = this->
buckets[n]; cur; cur = cur->next)
592 IUEi_STL_INLINE std::pair<const_iterator, const_iterator>
equal_range(
const key_type& key)
const;
607 next_prime( static_cast<unsigned long>(n) ) );
613 this->
buckets.reserve(n_buckets);
643 # if defined ( __STL_NESTED_TYPE_PARAM_BUG )
644 # define __difference_type__ ptrdiff_t
645 # define __size_type__ size_t
646 # define __value_type__ Value
647 # define __key_type__ Key
648 # define __node__ hashtable_node<Value>
649 # define __reference__ Value&
651 # define __difference_type__ typename hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::difference_type
652 # define __size_type__ typename hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::size_type
653 # define __value_type__ typename hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::value_type
654 # define __key_type__ typename hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::key_type
655 # define __node__ typename hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::node
656 # define __reference__ typename hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::reference
659 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
660 inline hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>&
663 const node* old = cur;
668 while (!cur && ++bucket < ht->buckets.size())
670 cur = ht->buckets[bucket];
676 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
685 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
689 const node* old = cur;
694 while (!cur && ++bucket < ht->buckets.size())
696 cur = ht->buckets[bucket];
702 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
711 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
712 inline std::forward_iterator_tag
715 return std::forward_iterator_tag();
718 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
725 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
729 return (ptrdiff_t*) 0;
732 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
733 inline std::forward_iterator_tag
736 return std::forward_iterator_tag();
739 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
746 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
750 return (ptrdiff_t*) 0;
755 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
764 for (
int n = 0; n < ht1.
buckets.size(); ++n)
768 for (; cur1 && cur2 && cur1->val == cur2->val;
769 cur1 = cur1->next, cur2 = cur2->next)
779 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
780 std::pair<hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>,
bool>
784 node* first = this->buckets[n];
786 for (
node* cur = first; cur; cur = cur->
next)
787 if (equals(get_key(cur->val), get_key(obj)))
788 return std::pair<iterator, bool>(
iterator(cur,
this),
false);
790 node* tmp = new_node(obj);
792 this->buckets[n] = tmp;
793 ++this->num_elements;
794 return std::pair<iterator, bool>(
iterator(tmp,
this),
true);
797 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
802 node* first = this->buckets[n];
804 for (
node* cur = first; cur; cur = cur->
next)
806 if (equals(get_key(cur->val), get_key(obj)))
808 node* tmp = new_node(obj);
811 ++this->num_elements;
815 node* tmp = new_node(obj);
817 this->buckets[n] = tmp;
818 ++this->num_elements;
822 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
826 resize(this->num_elements + 1);
829 node* first = this->buckets[n];
831 for (
node* cur = first; cur; cur = cur->
next)
832 if (equals(get_key(cur->val), get_key(obj)))
835 node* tmp = new_node(obj);
837 this->buckets[n] = tmp;
838 ++this->num_elements;
842 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
843 std::pair<hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>,
847 typedef std::pair<iterator, iterator> pii;
848 const size_type n = bkt_num_key(key);
850 for (node* first = this->buckets[n]; first; first = first->
next)
852 if (equals(get_key(first->
val), key))
854 for (node* cur = first->
next; cur; cur = cur->
next)
856 if (!equals(get_key(cur->val), key))
857 return pii(iterator(first,
this), iterator(cur,
this));
859 for (size_type m = n + 1; m < this->buckets.size(); ++m)
861 if (this->buckets[m])
863 return pii(iterator(first,
this),
864 iterator(this->buckets[m],
this));
867 return pii(iterator(first,
this), end());
870 return pii(end(), end());
873 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
874 std::pair<hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>,
875 hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> >
878 typedef std::pair<const_iterator, const_iterator> pii;
879 const size_type n = bkt_num_key(key);
881 for (
const node* first = this->buckets[n]; first; first = first->
next)
883 if (equals(get_key(first->
val), key))
885 for (
const node* cur = first->
next; cur; cur = cur->
next)
887 if (!equals(get_key(cur->val), key))
889 return pii(const_iterator(first,
this),
890 const_iterator(cur,
this));
893 for (size_type m = n + 1; m < this->buckets.size(); ++m)
895 if (this->buckets[m])
897 return pii(const_iterator(first,
this),
898 const_iterator(this->buckets[m],
this));
901 return pii(const_iterator(first,
this), end());
904 return pii(end(), end());
907 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
911 const size_type n = bkt_num_key(key);
912 node* first = this->buckets[n];
913 size_type erased = 0;
918 node* next = cur->
next;
921 if (equals(get_key(next->val), key))
934 if (equals(get_key(first->val), key))
936 this->buckets[n] = first->next;
941 this->num_elements -= erased;
945 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
947 hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::erase(
const hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>& it)
949 node*
const p = it.cur;
952 const size_type n = bkt_num(p->val);
953 node* cur = this->buckets[n];
957 this->buckets[n] = cur->next;
959 --this->num_elements;
963 node* next = cur->next;
968 cur->next = next->next;
970 --this->num_elements;
983 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
985 hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::erase(hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> first,
986 hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> last)
988 size_type f_bucket = first.cur ? bkt_num(first.cur->val) : this->buckets.size();
989 size_type l_bucket = last.cur ? bkt_num(last.cur->val) : this->buckets.size();
990 if (first.cur == last.cur)
992 else if (f_bucket == l_bucket)
993 erase_bucket(f_bucket, first.cur, last.cur);
996 erase_bucket(f_bucket, first.cur, 0);
997 for (size_type n = f_bucket + 1; n < l_bucket; ++n)
999 if (l_bucket != this->buckets.size())
1000 erase_bucket(l_bucket, last.cur);
1004 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
1006 hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::erase(hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> first,
1007 hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> last)
1009 erase(iterator(const_cast<node*>(first.cur),
1010 const_cast<self*>(first.ht)),
1011 iterator(const_cast<node*>(last.cur),
1012 const_cast<self*>(last.ht)));
1015 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
1017 hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>::erase(
const hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>& it)
1019 erase(iterator(const_cast<node*>(it.cur),
1020 const_cast<self*>(it.ht)));
1023 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
1027 const size_type old_n = this->buckets.size();
1028 if (num_elements_hint > old_n)
1030 const size_type n = next_size(num_elements_hint);
1034 for (
size_type bucket = 0; bucket < old_n; ++bucket)
1036 node* first = this->buckets[bucket];
1040 this->buckets[bucket] = first->
next;
1041 first->
next = tmp[new_bucket];
1042 tmp[new_bucket] = first;
1043 first = this->buckets[bucket];
1046 this->buckets.clear();
1047 this->buckets.swap(tmp);
1053 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
1059 node* cur = this->buckets[n];
1061 erase_bucket(n, last);
1065 for (next = cur->next; next != first; cur = next, next = cur->
next);
1068 cur->next = next->next;
1071 --this->num_elements;
1076 template <
class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
1079 hashtable_node<Value>* last)
1081 node* cur = this->buckets[n];
1084 node* next = cur->next;
1087 this->buckets[n] = cur;
1088 --this->num_elements;
1092 template <
class Value,
class Alloc>
1095 for (
size_type i = 0; i < buckets.size(); ++i)
1097 node* cur = buckets[i];
1110 template <
class Value,
class Alloc>
1113 buckets.reserve(ht.
buckets.size());
1114 buckets.insert(buckets.end(), ht.
buckets.size(), (
node*) 0);
1120 node* copy = new_node(cur->
val);
1124 for (
node* next = cur->
next; next; cur = next, next = cur->
next)
1126 copy->
next = new_node(next->val);
1137 # undef __difference_type__
1138 # undef __size_type__
1139 # undef __value_type__
1140 # undef __key_type__
1149 # if (defined (_MSC_VER)&&(_MSC_VER < 1600 )) || defined(__BORLANDC__) || ((defined(__ICC)||defined(__ECC)) && defined(linux))
1154 struct identity :
public std::unary_function<T, T> {
1156 const T& operator()(
const T& x)
const {
return x; }
1162 # if defined (_MSC_VER) || defined(__BORLANDC__) || ((defined(__ICC)||defined(__ECC)) && defined(linux))
1165 template <
class _Pair>
1166 struct itk_Select1st :
public std::unary_function<_Pair, typename _Pair::first_type> {
1167 typename _Pair::first_type
const & operator()(_Pair
const & __x)
const {
return __x.first; }
1170 template <
class _Pair>
1171 struct itk_Select2nd :
public std::unary_function<_Pair, typename _Pair::second_type> {
1172 typename _Pair::second_type
const & operator()(_Pair
const & __x)
const {
return __x.second; }
1177 template <
class _Pair>
1178 struct select1st :
public itk_Select1st<_Pair> {};
1179 template <
class _Pair>
struct select2nd :
public itk_Select2nd<_Pair> {};
1186 #endif // itk_emulation_hashtable_h