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