• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kviewshell

GContainer.h

Go to the documentation of this file.
00001 //C-  -*- C++ -*-
00002 //C- -------------------------------------------------------------------
00003 //C- DjVuLibre-3.5
00004 //C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
00005 //C- Copyright (c) 2001  AT&T
00006 //C-
00007 //C- This software is subject to, and may be distributed under, the
00008 //C- GNU General Public License, Version 2. The license should have
00009 //C- accompanied the software or you may obtain a copy of the license
00010 //C- from the Free Software Foundation at http://www.fsf.org .
00011 //C-
00012 //C- This program is distributed in the hope that it will be useful,
00013 //C- but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //C- GNU General Public License for more details.
00016 //C- 
00017 //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
00018 //C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech 
00019 //C- Software authorized us to replace the original DjVu(r) Reference 
00020 //C- Library notice by the following text (see doc/lizard2002.djvu):
00021 //C-
00022 //C-  ------------------------------------------------------------------
00023 //C- | DjVu (r) Reference Library (v. 3.5)
00024 //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
00025 //C- | The DjVu Reference Library is protected by U.S. Pat. No.
00026 //C- | 6,058,214 and patents pending.
00027 //C- |
00028 //C- | This software is subject to, and may be distributed under, the
00029 //C- | GNU General Public License, Version 2. The license should have
00030 //C- | accompanied the software or you may obtain a copy of the license
00031 //C- | from the Free Software Foundation at http://www.fsf.org .
00032 //C- |
00033 //C- | The computer code originally released by LizardTech under this
00034 //C- | license and unmodified by other parties is deemed "the LIZARDTECH
00035 //C- | ORIGINAL CODE."  Subject to any third party intellectual property
00036 //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
00037 //C- | non-exclusive license to make, use, sell, or otherwise dispose of 
00038 //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
00039 //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
00040 //C- | General Public License.   This grant only confers the right to 
00041 //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
00042 //C- | the extent such infringement is reasonably necessary to enable 
00043 //C- | recipient to make, have made, practice, sell, or otherwise dispose 
00044 //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
00045 //C- | any greater extent that may be necessary to utilize further 
00046 //C- | modifications or combinations.
00047 //C- |
00048 //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
00049 //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
00050 //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
00051 //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
00052 //C- +------------------------------------------------------------------
00053 // 
00054 // $Id: GContainer.h,v 1.15 2004/05/13 15:16:34 leonb Exp $
00055 // $Name: release_3_5_15 $
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 // Supports old iterators (first/last/next/prev) on lists and maps?
00080 #ifndef GCONTAINER_OLD_ITERATORS
00081 #define GCONTAINER_OLD_ITERATORS 1
00082 #endif
00083 
00084 // Check array bounds at runtime ?
00085 #ifndef GCONTAINER_BOUNDS_CHECK
00086 #define GCONTAINER_BOUNDS_CHECK 1
00087 #endif
00088 
00089 // Clears allocated memory prior to running constructors ?
00090 #ifndef GCONTAINER_ZERO_FILL
00091 #define GCONTAINER_ZERO_FILL 1
00092 #endif
00093 
00094 // Avoid member templates (needed by old compilers)
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 // Define typename when needed
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 // HELPER CLASSES
00140 // ------------------------------------------------------------
00141 
00142 
00143 
00144 /* Namespace for containers support classes.  This class is used as a
00145    namespace for global identifiers related to the implementation of
00146    containers.  It is inherited by all container objects.  This is disabled by
00147    defining compilation symbol #GCONTAINER_NO_MEMBER_TEMPATES# to 1. */
00148 
00149 
00150 #ifdef _MSC_VER
00151 // Language lawyer say MS is wrong on that one. 
00152 // Cf section 5.4.7 in november 1997 draft.
00153 #pragma warning( disable : 4243 )
00154 #endif
00155 
00156 
00157 // GPEnabled inhertenced removed again so the code works on more machines.
00158 class GCont
00159 #if GCONTAINER_NO_MEMBER_TEMPLATES
00160 {
00161 };
00162 #else
00163 {
00164 public:
00165 #endif
00166   // --- Pointers to type management functions
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   // --- Management of simple types
00179   template <int SZ> class TrivTraits
00180   {
00181   public:
00182     // The unique object
00183     static const Traits & traits();
00184     // Offset in an array of T
00185     static void * lea(void* base, int n)
00186       { return (void*)( ((char*)base) + SZ*n ); }
00187     // Trivial default constructor
00188     static void   init(void* dst, int n) {}
00189     // Trivial copy constructor
00190     static void   copy(void* dst, const void* src, int n, int ) 
00191       { memcpy(dst, src, SZ*n); }
00192     // Trivial destructor
00193     static void   fini(void* dst, int n) {}
00194   };
00195   // --- Management of regular types
00196   template <class T> class NormTraits
00197   {
00198   public:
00199     // The unique object
00200     static const Traits & traits();
00201     // Offset in an array of T
00202     static void * lea(void* base, int n)
00203       { return (void*)( ((T*)base) + n ); }
00204     // Template based default constructor
00205     static void init(void* dst, int n) 
00206       { T* d = (T*)dst;   while (--n>=0) { new ((void*)d) T; d++; } }
00207     // Template based copy constructor
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     // Template based destructor
00212     static void fini(void* dst, int n) 
00213       { T* d = (T*)dst; while (--n>=0) { d->T::~T(); d++; } }
00214   };
00215   // --- Base class for list nodes
00216   struct Node
00217   {
00218     Node *next;
00219     Node *prev;
00220   };
00221   // -- Class for list nodes
00222   template <class T> struct ListNode : public Node
00223   { 
00224     T val;
00225   };
00226   // -- Class for map nodes showing the hash
00227   struct HNode : public Node
00228   {
00229     HNode *hprev;
00230     unsigned int hashcode;
00231   };
00232   // -- Class for map nodes showing the hash and the key
00233   template <class K> struct SetNode : public HNode
00234   { 
00235     K key;
00236   };
00237   // -- Class for map nodes with everything
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 // DYNAMIC ARRAYS
00282 // ------------------------------------------------------------
00283 
00284 
00312 
00313 class GArrayBase : public GCont
00314 {
00315 public:
00316   // -- CONSTRUCTORS
00317   GArrayBase(const GArrayBase &ref);
00318   GArrayBase(const Traits &traits);
00319   GArrayBase(const Traits &traits, int lobound, int hibound);
00320   // -- DESTRUCTOR
00321   ~GArrayBase();
00322   // -- ASSIGNMENT
00323   GArrayBase& operator= (const GArrayBase &ga);
00324   // -- ALTERATION
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   // -- CONSTRUCTORS
00354   GArrayTemplate(const Traits &traits) : GArrayBase(traits) {}
00355   GArrayTemplate(const Traits &traits, int lobound, int hibound)
00356     : GArrayBase(traits, lobound, hibound) {}
00357   // -- ACCESS
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   // -- CONVERSION
00387   operator TYPE* ()
00388     { return ((TYPE*)data)-minlo; }
00395   operator const TYPE* () const
00396     { return ((const TYPE*)data)-minlo; }
00397   operator const TYPE* ()  // suppress warning with gcc-2.95
00398     { return ((const TYPE*)data)-minlo; }
00399   // -- ALTERATION
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   // -- SORTING
00466   void sort()
00467     { sort(lbound(), hbound()); }
00473   void sort(int lo, int hi);
00474 };
00475 
00476 
00477 
00478 /* That one must be implemented as a regular template function. */
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   // Test for insertion sort
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   // -- determine suitable quick-sort pivot
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   // -- partition set
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   // -- recursively restart
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   // Copy operator
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   // Copy operator
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   // Copy operator
00636   GTArray& operator=(const GTArray &r)
00637     { GArrayBase::operator=(r); return *this; }
00638 };
00639 
00640 
00642 
00643 
00644 
00645 // ------------------------------------------------------------
00646 // DOUBLY LINKED LISTS
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   // Internal. Do not use.
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   // -- ACCESS
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   // -- TEST
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   // -- SEARCHING
00860   GPosition nth(unsigned int n) const
00861     { return GListImpl<TI>::nth(n); }
00862   /*  Compatibility */
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   // -- ALTERATION
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   /* Old iterators. Do not use. */
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 // ASSOCIATIVE MAPS
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   /*  Compatibility */
01170   GPosition contains(const KTYPE &key, GPosition &pos) const
01171     { return pos = GMapImpl<KTYPE,TI>::contains(key); }
01172   // -- ALTERATION
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   /* Old iterators. Do not use. */
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   // -- ACCESS
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 // HASH FUNCTIONS
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   // optimizer will get rid of unnecessary code  
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   // optimizer will get rid of unnecessary code
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 // ------------ THE END
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 

kviewshell

Skip menu "kviewshell"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • kviewshell
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal