00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef _GCONTAINER_H_
00058 #define _GCONTAINER_H_
00059 #ifdef HAVE_CONFIG_H
00060 #include "config.h"
00061 #endif
00062 #if NEED_GNUG_PRAGMAS
00063 # pragma interface
00064 #endif
00065
00066
00067 #include "GException.h"
00068 #include "GSmartPointer.h"
00069 #include <string.h>
00070
00071 #ifdef HAVE_NAMESPACES
00072 namespace DJVU {
00073 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00074 }
00075 #endif
00076 #endif
00077
00078
00079
00080 #ifndef GCONTAINER_OLD_ITERATORS
00081 #define GCONTAINER_OLD_ITERATORS 1
00082 #endif
00083
00084
00085 #ifndef GCONTAINER_BOUNDS_CHECK
00086 #define GCONTAINER_BOUNDS_CHECK 1
00087 #endif
00088
00089
00090 #ifndef GCONTAINER_ZERO_FILL
00091 #define GCONTAINER_ZERO_FILL 1
00092 #endif
00093
00094
00095 #ifndef GCONTAINER_NO_MEMBER_TEMPLATES
00096 #if defined(__GNUC__) && (__GNUC__==2) && (__GNUC_MINOR__<91)
00097 #define GCONTAINER_NO_MEMBER_TEMPLATES 1
00098 #elif defined(_MSC_VER) && !defined(__ICL)
00099 #define GCONTAINER_NO_MEMBER_TEMPLATES 1
00100 #elif defined(__MWERKS__)
00101 #define GCONTAINER_NO_MEMBER_TEMPLATES 1
00102 #else
00103 #define GCONTAINER_NO_MEMBER_TEMPLATES 0
00104 #endif
00105 #endif
00106
00107
00108 #ifndef GCONTAINER_NO_TYPENAME
00109 #define GCONTAINER_NO_TYPENAME 0
00110 #endif
00111 #if GCONTAINER_NO_TYPENAME
00112 #define typename
00113 #endif
00114
00115
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 #ifdef _MSC_VER
00151
00152
00153 #pragma warning( disable : 4243 )
00154 #endif
00155
00156
00157
00158 class GCont
00159 #if GCONTAINER_NO_MEMBER_TEMPLATES
00160 {
00161 };
00162 #else
00163 {
00164 public:
00165 #endif
00166
00167 struct Traits
00168 {
00169 int size;
00170 void *(*lea) (void *base, int n);
00171 void (*init) (void *dst, int n);
00172 void (*copy) (void *dst, const void* src, int n, int zap);
00173 void (*fini) (void *dst, int n);
00174 };
00175 #if !GCONTAINER_NO_MEMBER_TEMPLATES
00176 protected:
00177 #endif
00178
00179 template <int SZ> class TrivTraits
00180 {
00181 public:
00182
00183 static const Traits & traits();
00184
00185 static void * lea(void* base, int n)
00186 { return (void*)( ((char*)base) + SZ*n ); }
00187
00188 static void init(void* dst, int n) {}
00189
00190 static void copy(void* dst, const void* src, int n, int )
00191 { memcpy(dst, src, SZ*n); }
00192
00193 static void fini(void* dst, int n) {}
00194 };
00195
00196 template <class T> class NormTraits
00197 {
00198 public:
00199
00200 static const Traits & traits();
00201
00202 static void * lea(void* base, int n)
00203 { return (void*)( ((T*)base) + n ); }
00204
00205 static void init(void* dst, int n)
00206 { T* d = (T*)dst; while (--n>=0) { new ((void*)d) T; d++; } }
00207
00208 static void copy(void* dst, const void* src, int n, int zap)
00209 { T* d = (T*)dst; const T *s = (const T*)src;
00210 while (--n>=0) { new ((void*)d) T(*s); if (zap) { s->T::~T(); }; d++; s++; } }
00211
00212 static void fini(void* dst, int n)
00213 { T* d = (T*)dst; while (--n>=0) { d->T::~T(); d++; } }
00214 };
00215
00216 struct Node
00217 {
00218 Node *next;
00219 Node *prev;
00220 };
00221
00222 template <class T> struct ListNode : public Node
00223 {
00224 T val;
00225 };
00226
00227 struct HNode : public Node
00228 {
00229 HNode *hprev;
00230 unsigned int hashcode;
00231 };
00232
00233 template <class K> struct SetNode : public HNode
00234 {
00235 K key;
00236 };
00237
00238 template <class K, class T> struct MapNode : public SetNode<K>
00239 {
00240 T val;
00241 };
00242 #if !GCONTAINER_NO_MEMBER_TEMPLATES
00243 };
00244 #endif
00245
00246
00247 #if !GCONTAINER_NO_MEMBER_TEMPLATES
00248 #define GCONT GCont::
00249 #else
00250 #define GCONT
00251 #endif
00252
00253 template <int SZ> const GCONT Traits &
00254 GCONT TrivTraits<SZ>::traits()
00255 {
00256 static const Traits theTraits = {
00257 SZ,
00258 TrivTraits<SZ>::lea,
00259 TrivTraits<SZ>::init,
00260 TrivTraits<SZ>::copy,
00261 TrivTraits<SZ>::fini
00262 };
00263 return theTraits;
00264 }
00265
00266 template <class T> const GCONT Traits &
00267 GCONT NormTraits<T>::traits()
00268 {
00269 static const Traits theTraits = {
00270 sizeof(T),
00271 NormTraits<T>::lea,
00272 NormTraits<T>::init,
00273 NormTraits<T>::copy,
00274 NormTraits<T>::fini
00275 };
00276 return theTraits;
00277 }
00278
00279
00280
00281
00282
00283
00284
00312
00313 class GArrayBase : public GCont
00314 {
00315 public:
00316
00317 GArrayBase(const GArrayBase &ref);
00318 GArrayBase(const Traits &traits);
00319 GArrayBase(const Traits &traits, int lobound, int hibound);
00320
00321 ~GArrayBase();
00322
00323 GArrayBase& operator= (const GArrayBase &ga);
00324
00325 void empty();
00326 void touch(int n);
00327 void resize(int lobound, int hibound);
00328 void shift(int disp);
00329 void del(int n, int howmany=1);
00330 void ins(int n, const void *src, int howmany=1);
00331 void steal(GArrayBase &ga);
00332 protected:
00333 const Traits &traits;
00334 void *data;
00335 GPBufferBase gdata;
00336 int minlo;
00337 int maxhi;
00338 int lobound;
00339 int hibound;
00340 };
00341
00342
00349 template<class TYPE>
00350 class GArrayTemplate : protected GArrayBase
00351 {
00352 public:
00353
00354 GArrayTemplate(const Traits &traits) : GArrayBase(traits) {}
00355 GArrayTemplate(const Traits &traits, int lobound, int hibound)
00356 : GArrayBase(traits, lobound, hibound) {}
00357
00359 int size() const
00360 { return hibound-lobound+1; }
00362 int lbound() const
00363 { return lobound; }
00365 int hbound() const
00366 { return hibound; }
00372 inline TYPE& operator[](int const n);
00379 inline const TYPE& operator[](int n) const;
00380
00387 operator TYPE* ()
00388 { return ((TYPE*)data)-minlo; }
00395 operator const TYPE* () const
00396 { return ((const TYPE*)data)-minlo; }
00397 operator const TYPE* ()
00398 { return ((const TYPE*)data)-minlo; }
00399
00402 void empty()
00403 { GArrayBase::empty(); }
00418 void touch(int n)
00419 { if (n<lobound || n>hibound) GArrayBase::touch(n); }
00424 void resize(int hibound)
00425 { GArrayBase::resize(0, hibound); }
00430 void resize(int lobound, int hibound)
00431 { GArrayBase::resize(lobound, hibound); }
00435 void shift(int disp)
00436 { GArrayBase::shift(disp); }
00442 void del(int n, int howmany=1)
00443 { GArrayBase::del(n, howmany); }
00451 void ins(int n, int howmany=1)
00452 { GArrayBase::ins(n, 0, howmany); }
00456 void ins(int n, const TYPE &val, int howmany=1)
00457 { GArrayBase::ins(n, (const void*)&val, howmany); }
00460 void steal(GArrayTemplate &ga)
00461 { GArrayBase::steal(ga); }
00462
00466 void sort()
00467 { sort(lbound(), hbound()); }
00473 void sort(int lo, int hi);
00474 };
00475
00476
00477
00478
00479 template <class TYPE> void
00480 GArrayTemplate<TYPE>::sort(int lo, int hi)
00481 {
00482 if (hi <= lo)
00483 return;
00484 if (hi > hibound || lo<lobound)
00485 G_THROW( ERR_MSG("GContainer.illegal_subscript") );
00486 TYPE *data = (TYPE*)(*this);
00487
00488 if (hi <= lo + 50)
00489 {
00490 for (int i=lo+1; i<=hi; i++)
00491 {
00492 int j = i;
00493 TYPE tmp = data[i];
00494 while ((--j>=lo) && !(data[j]<=tmp))
00495 data[j+1] = data[j];
00496 data[j+1] = tmp;
00497 }
00498 return;
00499 }
00500
00501 TYPE tmp = data[lo];
00502 TYPE pivot = data[(lo+hi)/2];
00503 if (pivot <= tmp)
00504 { tmp = pivot; pivot=data[lo]; }
00505 if (data[hi] <= tmp)
00506 { pivot = tmp; }
00507 else if (data[hi] <= pivot)
00508 { pivot = data[hi]; }
00509
00510 int h = hi;
00511 int l = lo;
00512 while (l < h)
00513 {
00514 while (! (pivot <= data[l])) l++;
00515 while (! (data[h] <= pivot)) h--;
00516 if (l < h)
00517 {
00518 tmp = data[l];
00519 data[l] = data[h];
00520 data[h] = tmp;
00521 l = l+1;
00522 h = h-1;
00523 }
00524 }
00525
00526 sort(lo, h);
00527 sort(l, hi);
00528 }
00529
00530 template<class TYPE> inline TYPE&
00531 GArrayTemplate<TYPE>::operator[](int const n)
00532 {
00533 #if GCONTAINER_BOUNDS_CHECK
00534 if (n<lobound || n>hibound)
00535 {
00536 G_THROW( ERR_MSG("GContainer.illegal_subscript") );
00537 }
00538 #endif
00539 return ((TYPE*)data)[n-minlo];
00540 }
00541
00542
00543 template<class TYPE> inline const TYPE &
00544 GArrayTemplate<TYPE>::operator[](int const n) const
00545 {
00546 #if GCONTAINER_BOUNDS_CHECK
00547 if (n<lobound || n>hibound)
00548 {
00549 G_THROW( ERR_MSG("GContainer.illegal_subscript") );
00550 }
00551 #endif
00552 return ((const TYPE*)data)[n-minlo];
00553 }
00554
00555
00556
00569 template<class TYPE>
00570 class GArray : public GArrayTemplate<TYPE>
00571 {
00572 public:
00576 GArray()
00577 : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits() ) {}
00581 GArray(int hi)
00582 : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits(), 0, hi ) {}
00586 GArray(int lo, int hi)
00587 : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits(), lo, hi ) {}
00588
00589 GArray& operator=(const GArray &r)
00590 { GArrayBase::operator=(r); return *this; }
00591 };
00592
00593
00602 template<class TYPE>
00603 class GPArray : public GArrayTemplate<GP<TYPE> >
00604 {
00605 public:
00606 GPArray()
00607 : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits() ) {}
00608 GPArray(int hi)
00609 : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits(), 0, hi ) {}
00610 GPArray(int lo, int hi)
00611 : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits(), lo, hi ) {}
00612
00613 GPArray& operator=(const GPArray &r)
00614 { GArrayBase::operator=(r); return *this; }
00615 };
00616
00625 template<class TYPE>
00626 class GTArray : public GArrayTemplate<TYPE>
00627 {
00628 public:
00629 GTArray()
00630 : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits() ) {}
00631 GTArray(int hi)
00632 : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits(), 0, hi ) {}
00633 GTArray(int lo, int hi)
00634 : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits(), lo, hi ) {}
00635
00636 GTArray& operator=(const GTArray &r)
00637 { GArrayBase::operator=(r); return *this; }
00638 };
00639
00640
00642
00643
00644
00645
00646
00647
00648
00649
00665
00691 class GPosition : protected GCont
00692 {
00693 public:
00695 GPosition() : ptr(0), cont(0) {}
00697 GPosition(const GPosition &ref) : ptr(ref.ptr), cont(ref.cont) {}
00699 operator int() const
00700 { return !!ptr; }
00702 int operator !() const
00703 { return !ptr; }
00705 GPosition& operator ++()
00706 { if (ptr) ptr = ptr->next; return *this; }
00708 GPosition& operator --()
00709 { if (ptr) ptr = ptr->prev; return *this; }
00710
00711 GPosition(Node *p, void *c) : ptr(p), cont(c) {}
00712 #if GCONTAINER_BOUNDS_CHECK
00713 Node *check(void *c)
00714 { if (!ptr || c!=cont) throw_invalid(c); return ptr; }
00715 const Node *check(void *c) const
00716 { if (!ptr || c!=cont) throw_invalid(c); return ptr; }
00717 #else
00718 Node *check(void *c)
00719 { return ptr; }
00720 const Node *check(void *c) const
00721 { return ptr; }
00722 #endif
00723 protected:
00724 Node *ptr;
00725 void *cont;
00726 friend class GListBase;
00727 friend class GSetBase;
00728 void throw_invalid(void *c) const no_return;
00729 };
00730
00731
00732 class GListBase : public GCont
00733 {
00734 protected:
00735 GListBase(const Traits& traits);
00736 GListBase(const GListBase &ref);
00737 void append(Node *n);
00738 void prepend(Node *n);
00739 void insert_after(GPosition pos, Node *n);
00740 void insert_before(GPosition pos, Node *n);
00741 void insert_before(GPosition pos, GListBase &fromlist, GPosition &frompos);
00742 void del(GPosition &pos);
00743 protected:
00744 const Traits &traits;
00745 int nelem;
00746 Node head;
00747 public:
00748 ~GListBase();
00749 GListBase & operator= (const GListBase & gl);
00750 GPosition firstpos() const { return GPosition(head.next, (void*)this); }
00751 GPosition lastpos() const { return GPosition(head.prev, (void*)this); }
00752 int isempty() const { return nelem==0; };
00753 GPosition nth(unsigned int n) const;
00754 void empty();
00755 };
00756
00757
00758 template<class TI>
00759 class GListImpl : public GListBase
00760 {
00761 protected:
00762 GListImpl();
00763 typedef GCONT ListNode<TI> LNode;
00764 static Node * newnode(const TI &elt);
00765 int operator==(const GListImpl<TI> &l2) const;
00766 int search(const TI &elt, GPosition &pos) const;
00767 };
00768
00769 template<class TI>
00770 GListImpl<TI>::GListImpl()
00771 : GListBase( GCONT NormTraits<LNode>::traits() )
00772 {
00773 }
00774
00775 template<class TI> GCONT Node *
00776 GListImpl<TI>::newnode(const TI &elt)
00777 {
00778 LNode *n = (LNode *) operator new (sizeof(LNode ));
00779 #if GCONTAINER_ZERO_FILL
00780 memset(n, 0, sizeof(LNode ));
00781 #endif
00782 new ((void*)&(n->val)) TI(elt);
00783 return (Node*) n;
00784 }
00785
00786 template<class TI> int
00787 GListImpl<TI>::operator==(const GListImpl<TI> &l2) const
00788 {
00789 Node *p, *q;
00790 for (p=head.next, q=l2.head.next; p && q; p=p->next, q=q->next )
00791 if (((LNode*)p)->val != ((LNode*)q)->val)
00792 return 0;
00793 return p==0 && q==0;
00794 }
00795
00796 template<class TI> int
00797 GListImpl<TI>::search(const TI &elt, GPosition &pos) const
00798 {
00799 Node *n = (pos ? pos.check((void*)this) : head.next);
00800 for (; n; n=n->next)
00801 if ( ((LNode *)n)->val == elt )
00802 break;
00803 if (n) pos = GPosition(n, (void*)this);
00804 return (n != 0);
00805 }
00806
00807
00813 template <class TYPE, class TI>
00814 class GListTemplate : protected GListImpl<TI>
00815 {
00816 public:
00817
00819 int size() const
00820 { return this->nelem; }
00822 GPosition firstpos() const
00823 { return GListImpl<TI>::firstpos(); }
00825 GPosition lastpos() const
00826 { return GListImpl<TI>::lastpos(); }
00828 operator GPosition() const
00829 { return firstpos(); }
00835 TYPE& operator[](GPosition pos)
00836 { return (TYPE&) (((typename GListImpl<TI>::LNode *)pos.check((void*)this))->val); }
00843 const TYPE& operator[](GPosition pos) const
00844 { return (const TYPE&) (((const typename GListImpl<TI>::LNode *)pos.check((void*)this))->val); }
00845
00848 int isempty() const
00849 { return this->nelem==0; }
00853 int operator==(const GListTemplate<TYPE,TI> &l2) const
00854 { return GListImpl<TI>::operator==(l2); }
00855
00860 GPosition nth(unsigned int n) const
00861 { return GListImpl<TI>::nth(n); }
00862
00863 int nth(unsigned int n, GPosition &pos) const
00864 { GPosition npos=nth(n); if (npos) pos=npos; return !!pos; }
00869 GPosition contains(const TYPE &elt) const
00870 { GPosition pos; GListImpl<TI>::search((const TI&)elt, pos); return pos; }
00880 int search(const TYPE &elt, GPosition &pos) const
00881 { return GListImpl<TI>::search((const TI&)elt, pos); }
00882
00885 void empty()
00886 { GListImpl<TI>::empty(); }
00889 void append(const TYPE &elt)
00890 { GListImpl<TI>::append(newnode((const TI&)elt)); }
00893 void prepend(const TYPE &elt)
00894 { GListImpl<TI>::prepend(newnode((const TI&)elt)); }
00898 void insert_after(GPosition pos, const TYPE &elt)
00899 { GListImpl<TI>::insert_after(pos, newnode((const TI&)elt)); }
00903 void insert_before(GPosition pos, const TYPE &elt)
00904 { GListImpl<TI>::insert_before(pos, newnode((const TI&)elt)); }
00910 void insert_before(GPosition pos, GListTemplate<TYPE,TI> &fromlist, GPosition &frompos)
00911 { GListImpl<TI>::insert_before(pos, fromlist, frompos); }
00914 void del(GPosition &pos)
00915 { GListImpl<TI>::del(pos); }
00916
00917 #if GCONTAINER_OLD_ITERATORS
00918 void first(GPosition &pos) const { pos = firstpos(); }
00919 void last(GPosition &pos) const { pos = lastpos(); }
00920 const TYPE *next(GPosition &pos) const
00921 { if (!pos) return 0; const TYPE *x=&((*this)[pos]); ++pos; return x; }
00922 const TYPE *prev(GPosition &pos) const
00923 { if (!pos) return 0; const TYPE *x=&((*this)[pos]); --pos; return x; }
00924 TYPE *next(GPosition &pos)
00925 { if (!pos) return 0; TYPE *x=&((*this)[pos]); ++pos; return x; }
00926 TYPE *prev(GPosition &pos)
00927 { if (!pos) return 0; TYPE *x=&((*this)[pos]); --pos; return x; }
00928 #endif
00929 };
00930
00931
00937 template <class TYPE>
00938 class GList : public GListTemplate<TYPE,TYPE>
00939 {
00940 public:
00942 GList() : GListTemplate<TYPE,TYPE>() {}
00943 GList& operator=(const GList &r)
00944 { GListBase::operator=(r); return *this; }
00945 };
00946
00947
00956 template <class TYPE>
00957 class GPList : public GListTemplate<GP<TYPE>,GPBase>
00958 {
00959 public:
00961 GPList() : GListTemplate<GP<TYPE>,GPBase>() {}
00962 GPList& operator=(const GPList &r)
00963 { GListBase::operator=(r); return *this; }
00964 };
00965
00966
00968
00969
00970
00971
00972
00973
00974
01000
01001 class GSetBase : public GCont
01002 {
01003 protected:
01004 GSetBase(const Traits &traits);
01005 GSetBase(const GSetBase &ref);
01006 static GCONT HNode *newnode(const void *key);
01007 HNode *hashnode(unsigned int hashcode) const;
01008 HNode *installnode(HNode *n);
01009 void deletenode(HNode *n);
01010 protected:
01011 const Traits &traits;
01012 int nelems;
01013 int nbuckets;
01014 HNode **table;
01015 GPBuffer<HNode *> gtable;
01016 HNode *first;
01017 private:
01018 void insertnode(HNode *n);
01019 void rehash(int newbuckets);
01020 public:
01021 ~GSetBase();
01022 GSetBase& operator=(const GSetBase &ref);
01023 GPosition firstpos() const;
01024 void del(GPosition &pos);
01025 void empty();
01026 };
01027
01028 template <class K>
01029 class GSetImpl : public GSetBase
01030 {
01031 protected:
01032 GSetImpl();
01033 GSetImpl(const Traits &traits);
01034 typedef GCONT SetNode<K> SNode;
01035 HNode *get(const K &key) const;
01036 HNode *get_or_throw(const K &key) const;
01037 HNode *get_or_create(const K &key);
01038 public:
01039 GPosition contains(const K &key) const
01040 { return GPosition( get(key), (void*)this); }
01041 void del(const K &key)
01042 { deletenode(get(key)); }
01043 };
01044
01045 template<class K>
01046 GSetImpl<K>::GSetImpl()
01047 : GSetBase( GCONT NormTraits<GCONT SetNode<K> >::traits() )
01048 {
01049 }
01050
01051 template<class K>
01052 GSetImpl<K>::GSetImpl(const Traits &traits)
01053 : GSetBase(traits)
01054 {
01055 }
01056
01057 template<class K> GCONT HNode *
01058 GSetImpl<K>::get(const K &key) const
01059 {
01060 unsigned int hashcode = hash(key);
01061 for (SNode *s=(SNode*)hashnode(hashcode); s; s=(SNode*)(s->hprev))
01062 if (s->hashcode == hashcode && s->key == key) return s;
01063 return 0;
01064 }
01065
01066 #if GCONTAINER_BOUNDS_CHECK
01067 template<class K> GCONT HNode *
01068 GSetImpl<K>::get_or_throw(const K &key) const
01069 {
01070 HNode *m = get(key);
01071 if (!m)
01072 {
01073 G_THROW( ERR_MSG("GContainer.cannot_add") );
01074 }
01075 return m;
01076 }
01077 #else
01078 template<class K> inline GCONT HNode *
01079 GSetImpl<K>::get_or_throw(const K &key) const
01080 {
01081 return get(key);
01082 }
01083 #endif
01084
01085 template<class K> GCONT HNode *
01086 GSetImpl<K>::get_or_create(const K &key)
01087 {
01088 HNode *m = get(key);
01089 if (m) return m;
01090 SNode *n = (SNode*) operator new (sizeof(SNode));
01091 #if GCONTAINER_ZERO_FILL
01092 memset(n, 0, sizeof(SNode));
01093 #endif
01094 new ((void*)&(n->key)) K ( key );
01095 n->hashcode = hash((const K&)(n->key));
01096 installnode(n);
01097 return n;
01098 }
01099
01100 template <class K, class TI>
01101 class GMapImpl : public GSetImpl<K>
01102 {
01103 protected:
01104 GMapImpl();
01105 GMapImpl(const GCONT Traits &traits);
01106 typedef GCONT MapNode<K,TI> MNode;
01107 GCONT HNode* get_or_create(const K &key);
01108 };
01109
01110 template<class K, class TI>
01111 GMapImpl<K,TI>::GMapImpl()
01112 : GSetImpl<K> ( GCONT NormTraits<GCONT MapNode<K,TI> >::traits() )
01113 {
01114 }
01115
01116 template<class K, class TI>
01117 GMapImpl<K,TI>::GMapImpl(const GCONT Traits &traits)
01118 : GSetImpl<K>(traits)
01119 {
01120 }
01121
01122 template<class K, class TI> GCONT HNode *
01123 GMapImpl<K,TI>::get_or_create(const K &key)
01124 {
01125 GCONT HNode *m = get(key);
01126 if (m) return m;
01127 MNode *n = (MNode*) operator new (sizeof(MNode));
01128 #if GCONTAINER_ZERO_FILL
01129 memset(n, 0, sizeof(MNode));
01130 #endif
01131 new ((void*)&(n->key)) K (key);
01132 new ((void*)&(n->val)) TI ();
01133 n->hashcode = hash((const K&)(n->key));
01134 installnode(n);
01135 return n;
01136 }
01137
01138
01139
01146 template <class KTYPE, class VTYPE, class TI>
01147 class GMapTemplate : protected GMapImpl<KTYPE,TI>
01148 {
01149 public:
01151 int size() const
01152 { return this->nelems; }
01154 GPosition firstpos() const
01155 { return GMapImpl<KTYPE,TI>::firstpos(); }
01157 operator GPosition() const
01158 { return firstpos(); }
01161 int isempty() const
01162 { return this->nelems==0; }
01167 GPosition contains(const KTYPE &key) const
01168 { return GMapImpl<KTYPE,TI>::contains(key); }
01169
01170 GPosition contains(const KTYPE &key, GPosition &pos) const
01171 { return pos = GMapImpl<KTYPE,TI>::contains(key); }
01172
01175 void empty()
01176 { GMapImpl<KTYPE,TI>::empty(); }
01180 const KTYPE &key(const GPosition &pos) const
01181 { return (const KTYPE&)(((typename GMapImpl<KTYPE,TI>::MNode*)(pos.check((void*)this)))->key); }
01186 VTYPE& operator[](const GPosition &pos)
01187 { return (VTYPE&)(((typename GMapImpl<KTYPE,TI>::MNode*)(pos.check((void*)this)))->val); }
01192 const VTYPE& operator[](const GPosition &pos) const
01193 { return (const VTYPE&)(((typename GMapImpl<KTYPE,TI>::MNode*)(pos.check((void*)this)))->val); }
01199 const VTYPE& operator[](const KTYPE &key) const
01200 { return (const VTYPE&)(((const typename GMapImpl<KTYPE,TI>::MNode*)(get_or_throw(key)))->val); }
01205 VTYPE& operator[](const KTYPE &key)
01206 { return (VTYPE&)(((typename GMapImpl<KTYPE,TI>::MNode*)(get_or_create(key)))->val); }
01209 void del(GPosition &pos)
01210 { GSetBase::del(pos); }
01213 void del(const KTYPE &key)
01214 { GMapImpl<KTYPE,TI>::del(key); }
01215
01216 #if GCONTAINER_OLD_ITERATORS
01217 void first(GPosition &pos) const { pos = firstpos(); }
01218 const VTYPE *next(GPosition &pos) const
01219 { if (!pos) return 0; const VTYPE *x=&((*this)[pos]); ++pos; return x; }
01220 VTYPE *next(GPosition &pos)
01221 { if (!pos) return 0; VTYPE *x=&((*this)[pos]); ++pos; return x; }
01222 #endif
01223 };
01224
01225
01226
01237 template <class KTYPE, class VTYPE>
01238 class GMap : public GMapTemplate<KTYPE,VTYPE,VTYPE>
01239 {
01240 public:
01241
01242 GMap() : GMapTemplate<KTYPE,VTYPE,VTYPE>() {}
01243 GMap& operator=(const GMap &r)
01244 { GSetBase::operator=(r); return *this; }
01245 };
01246
01259 template <class KTYPE, class VTYPE>
01260 class GPMap : public GMapTemplate<KTYPE,GP<VTYPE>,GPBase>
01261 {
01262 public:
01263 GPMap() : GMapTemplate<KTYPE,GP<VTYPE>,GPBase>() {}
01264 GPMap& operator=(const GPMap &r)
01265 { GSetBase::operator=(r); return *this; }
01266 };
01267
01268
01269
01270
01271
01272
01273
01281
01283 static inline unsigned int
01284 hash(const unsigned int & x)
01285 {
01286 return x;
01287 }
01288
01290 static inline unsigned int
01291 hash(const int & x)
01292 {
01293 return (unsigned int)x;
01294 }
01295
01297 static inline unsigned int
01298 hash(const long & x)
01299 {
01300 return (unsigned int)x;
01301 }
01302
01304 static inline unsigned int
01305 hash(const unsigned long & x)
01306 {
01307 return (unsigned int)x;
01308 }
01309
01311 static inline unsigned int
01312 hash(void * const & x)
01313 {
01314 return (unsigned long) x;
01315 }
01316
01318 static inline unsigned int
01319 hash(const void * const & x)
01320 {
01321 return (unsigned long) x;
01322 }
01323
01325 static inline unsigned int
01326 hash(const float & x)
01327 {
01328
01329 unsigned int *addr = (unsigned int*)&x;
01330 if (sizeof(float)<2*sizeof(unsigned int))
01331 return addr[0];
01332 else
01333 return addr[0]^addr[1];
01334 }
01335
01337 static inline unsigned int
01338 hash(const double & x)
01339 {
01340
01341 unsigned int *addr = (unsigned int*)&x;
01342 if (sizeof(double)<2*sizeof(unsigned int))
01343 return addr[0];
01344 else if (sizeof(double)<4*sizeof(unsigned int))
01345 return addr[0]^addr[1];
01346 else
01347 return addr[0]^addr[1]^addr[2]^addr[3];
01348 }
01349
01350
01352
01353
01354
01355
01356
01357
01358 #ifdef HAVE_NAMESPACES
01359 }
01360 # ifndef NOT_USING_DJVU_NAMESPACE
01361 using namespace DJVU;
01362 # endif
01363 #endif
01364 #endif
01365
01366