1 //C-  -*- C++ -*-
2 //C- -------------------------------------------------------------------
3 //C- DjVuLibre-3.5
4 //C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5 //C- Copyright (c) 2001  AT&T
6 //C-
7 //C- This software is subject to, and may be distributed under, the
8 //C- GNU General Public License, either Version 2 of the license,
9 //C- or (at your option) any later version. The license should have
10 //C- accompanied the software or you may obtain a copy of the license
11 //C- from the Free Software Foundation at http://www.fsf.org .
12 //C-
13 //C- This program is distributed in the hope that it will be useful,
14 //C- but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //C- GNU General Public License for more details.
17 //C-
18 //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
19 //C- Lizardtech Software.  Lizardtech Software has authorized us to
20 //C- replace the original DjVu(r) Reference Library notice by the following
21 //C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
22 //C-
23 //C-  ------------------------------------------------------------------
24 //C- | DjVu (r) Reference Library (v. 3.5)
25 //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
26 //C- | The DjVu Reference Library is protected by U.S. Pat. No.
27 //C- | 6,058,214 and patents pending.
28 //C- |
29 //C- | This software is subject to, and may be distributed under, the
30 //C- | GNU General Public License, either Version 2 of the license,
31 //C- | or (at your option) any later version. The license should have
32 //C- | accompanied the software or you may obtain a copy of the license
33 //C- | from the Free Software Foundation at http://www.fsf.org .
34 //C- |
35 //C- | The computer code originally released by LizardTech under this
36 //C- | license and unmodified by other parties is deemed "the LIZARDTECH
37 //C- | ORIGINAL CODE."  Subject to any third party intellectual property
38 //C- | claims, LizardTech grants recipient a worldwide, royalty-free,
39 //C- | non-exclusive license to make, use, sell, or otherwise dispose of
40 //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
41 //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
42 //C- | General Public License.   This grant only confers the right to
43 //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
44 //C- | the extent such infringement is reasonably necessary to enable
45 //C- | recipient to make, have made, practice, sell, or otherwise dispose
46 //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
47 //C- | any greater extent that may be necessary to utilize further
48 //C- | modifications or combinations.
49 //C- |
50 //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
51 //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
52 //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
53 //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
54 //C- +------------------------------------------------------------------
55 
56 #ifndef _GCONTAINER_H_
57 #define _GCONTAINER_H_
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif
61 #if NEED_GNUG_PRAGMAS
62 # pragma interface
63 #endif
64 
65 
66 #include "GException.h"
67 #include "GSmartPointer.h"
68 #include <string.h>
69 
70 #ifdef HAVE_NAMESPACES
71 namespace DJVU {
72 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
73 }
74 #endif
75 #endif
76 
77 
78 // Supports old iterators (first/last/next/prev) on lists and maps?
79 #ifndef GCONTAINER_OLD_ITERATORS
80 #define GCONTAINER_OLD_ITERATORS 1
81 #endif
82 
83 // Check array bounds at runtime ?
84 #ifndef GCONTAINER_BOUNDS_CHECK
85 #define GCONTAINER_BOUNDS_CHECK 1
86 #endif
87 
88 // Clears allocated memory prior to running constructors ?
89 #ifndef GCONTAINER_ZERO_FILL
90 #define GCONTAINER_ZERO_FILL 1
91 #endif
92 
93 // Avoid member templates (needed by old compilers)
94 #ifndef GCONTAINER_NO_MEMBER_TEMPLATES
95 #if defined(__GNUC__) && (__GNUC__==2) && (__GNUC_MINOR__<91)
96 #define GCONTAINER_NO_MEMBER_TEMPLATES 1
97 #elif defined(_MSC_VER) && !defined(__ICL)
98 #define GCONTAINER_NO_MEMBER_TEMPLATES 1
99 #elif defined(__MWERKS__)
100 #define GCONTAINER_NO_MEMBER_TEMPLATES 1
101 #else
102 #define GCONTAINER_NO_MEMBER_TEMPLATES 0
103 #endif
104 #endif
105 
106 // Define typename when needed
107 #ifndef GCONTAINER_NO_TYPENAME
108 #define GCONTAINER_NO_TYPENAME 0
109 #endif
110 #if GCONTAINER_NO_TYPENAME
111 #define typename /**/
112 #endif
113 
114 
115 /** @name GContainer.h
116 
117     Files #"GContainer.h"# and #"GContainer.cpp"# implement three main
118     template class for generic containers.
119     Class #GArray# (see \Ref{Dynamic Arrays}) implements an array of objects
120     with variable bounds. Class #GList# (see \Ref{Doubly Linked Lists})
121     implements a doubly linked list of objects.  Class #GMap# (see
122     \Ref{Associative Maps}) implements a hashed associative map.  The
123     container templates are not thread-safe. Thread safety can be implemented
124     using the facilities provided in \Ref{GThreads.h}.
125 
126     @memo
127     Template class for generic containers.
128     @author
129     L\'eon Bottou <leonb@research.att.com> -- initial implementation.\\
130     Andrei Erofeev <eaf@geocities.com> -- bug fixes.
131 */
132 //@{
133 
134 
135 
136 // ------------------------------------------------------------
137 // HASH FUNCTIONS
138 // ------------------------------------------------------------
139 
140 
141 /** @name Hash functions
142     These functions let you use template class \Ref{GMap} with the
143     corresponding elementary types. The returned hash code may be reduced to
144     an arbitrary range by computing its remainder modulo the upper bound of
145     the range.
146     @memo Hash functions for elementary types. */
147 //@{
148 
149 /** Hashing function (unsigned int). */
150 static inline unsigned int
hash(const unsigned int & x)151 hash(const unsigned int & x)
152 {
153   return x;
154 }
155 
156 /** Hashing function (int). */
157 static inline unsigned int
hash(const int & x)158 hash(const int & x)
159 {
160   return (unsigned int)x;
161 }
162 
163 /** Hashing function (long). */
164 static inline unsigned int
hash(const long & x)165 hash(const long & x)
166 {
167   return (unsigned int)x;
168 }
169 
170 /** Hashing function (unsigned long). */
171 static inline unsigned int
hash(const unsigned long & x)172 hash(const unsigned long & x)
173 {
174   return (unsigned int)x;
175 }
176 
177 /** Hashing function (const void *). */
178 static inline unsigned int
hash(const void * const & x)179 hash(const void * const & x)
180 {
181   return (unsigned int)(size_t) x;
182 }
183 
184 /** Hashing function (float). */
185 static inline unsigned int
hash(const float & x)186 hash(const float & x)
187 {
188   // optimizer will get rid of unnecessary code
189   unsigned int *addr = (unsigned int*)&x;
190   if (sizeof(float)<2*sizeof(unsigned int))
191     return addr[0];
192   else
193     return addr[0]^addr[1];
194 }
195 
196 /** Hashing function (double). */
197 static inline unsigned int
hash(const double & x)198 hash(const double & x)
199 {
200   // optimizer will get rid of unnecessary code
201   unsigned int *addr = (unsigned int*)&x;
202   if (sizeof(double)<2*sizeof(unsigned int))
203     return addr[0];
204   else if (sizeof(double)<4*sizeof(unsigned int))
205     return addr[0]^addr[1];
206   else
207     return addr[0]^addr[1]^addr[2]^addr[3];
208 }
209 
210 
211 
212 // ------------------------------------------------------------
213 // HELPER CLASSES
214 // ------------------------------------------------------------
215 
216 
217 
218 /* Namespace for containers support classes.  This class is used as a
219    namespace for global identifiers related to the implementation of
220    containers.  It is inherited by all container objects.  This is disabled by
221    defining compilation symbol #GCONTAINER_NO_MEMBER_TEMPATES# to 1. */
222 
223 
224 #ifdef _MSC_VER
225 // Language lawyer say MS is wrong on that one.
226 // Cf section 5.4.7 in november 1997 draft.
227 #pragma warning( disable : 4243 )
228 #endif
229 
230 
231 // GPEnabled inhertenced removed again so the code works on more machines.
232 class GCont
233 #if GCONTAINER_NO_MEMBER_TEMPLATES
234 {
235 };
236 #else
237 {
238 public:
239 #endif
240   // --- Pointers to type management functions
241   struct Traits
242   {
243     int       size;
244     void     *(*lea)     (void *base, int n);
245     void      (*init)    (void *dst, int n);
246     void      (*copy)    (void *dst, const void* src, int n, int zap);
247     void      (*fini)    (void *dst, int n);
248   };
249 #if !GCONTAINER_NO_MEMBER_TEMPLATES
250 protected:
251 #endif
252   // --- Management of simple types
253   template <int SZ> class TrivTraits
254   {
255   public:
256     // The unique object
257     static const Traits & traits();
258     // Offset in an array of T
lea(void * base,int n)259     static void * lea(void* base, int n)
260       { return (void*)( ((char*)base) + SZ*n ); }
261     // Trivial default constructor
init(void * dst,int n)262     static void   init(void* dst, int n) {}
263     // Trivial copy constructor
copy(void * dst,const void * src,int n,int)264     static void   copy(void* dst, const void* src, int n, int )
265       { ::memcpy(dst, src, SZ*n); }
266     // Trivial destructor
fini(void * dst,int n)267     static void   fini(void* dst, int n) {}
268   };
269   // --- Management of regular types
270   template <class T> class NormTraits
271   {
272   public:
273     // The unique object
274     static const Traits & traits();
275     // Offset in an array of T
lea(void * base,int n)276     static void * lea(void* base, int n)
277       { return (void*)( ((T*)base) + n ); }
278     // Template based default constructor
init(void * dst,int n)279     static void init(void* dst, int n)
280       { T* d = (T*)dst; while (--n>=0) { new ((void*)d) T; d++; } }
281     // Template based copy constructor
copy(void * dst,const void * src,int n,int zap)282     static void copy(void* dst, const void* src, int n, int zap)
283       { T* d = (T*)dst; T* s = (T*)src; while (--n>=0) {
284           new ((void*)d) T(*s); if (zap) { s->~T(); }; d++; s++; } }
285     // Template based destructor
fini(void * dst,int n)286     static void fini(void* dst, int n)
287       { T* d = (T*)dst; while (--n>=0) { d->~T(); d++; } }
288   };
289   // --- Base class for list nodes
290   struct Node
291   {
292     Node *next;
293     Node *prev;
294   };
295   // -- Class for list nodes
296   template <class T> struct ListNode : public Node
297   {
298     T val;
299   };
300   // -- Class for map nodes showing the hash
301   struct HNode : public Node
302   {
303     HNode *hprev;
304     unsigned int hashcode;
305   };
306   // -- Class for map nodes showing the hash and the key
307   template <class K> struct SetNode : public HNode
308   {
309     K key;
310   };
311   // -- Class for map nodes with everything
312   template <class K, class T> struct MapNode : public SetNode<K>
313   {
314     T val;
315   };
316 #if !GCONTAINER_NO_MEMBER_TEMPLATES
317 };
318 #endif
319 
320 
321 #if !GCONTAINER_NO_MEMBER_TEMPLATES
322 #define GCONT GCont::
323 #else
324 #define GCONT
325 #endif
326 
327 template <int SZ> const GCONT Traits &
328 GCONT TrivTraits<SZ>::traits()
329 {
330   static const Traits theTraits = {
331     SZ,
332     TrivTraits<SZ>::lea,
333     TrivTraits<SZ>::init,
334     TrivTraits<SZ>::copy,
335     TrivTraits<SZ>::fini
336   };
337   return theTraits;
338 }
339 
340 template <class T> const GCONT Traits &
341 GCONT NormTraits<T>::traits()
342 {
343   static const Traits theTraits = {
344     sizeof(T),
345     NormTraits<T>::lea,
346     NormTraits<T>::init,
347     NormTraits<T>::copy,
348     NormTraits<T>::fini
349   };
350   return theTraits;
351 }
352 
353 
354 // ------------------------------------------------------------
355 // DYNAMIC ARRAYS
356 // ------------------------------------------------------------
357 
358 
359 /** @name Dynamic Arrays
360 
361     These class implement arrays of objects of any type.  Each element is
362     identified by an integer subscript.  The valid subscripts range is defined
363     by dynamically adjustable lower- and upper-bounds.  Besides accessing and
364     setting elements, member functions are provided to insert or delete
365     elements at specified positions.
366 
367     Class \Ref{GArrayTemplate} implements all methods for manipulating arrays
368     of type #TYPE#.  You should not however create instances of this class.
369     You should instead use one of the following classes:
370     \begin{itemize}
371     \item Class \Ref{GArray<TYPE>} is the most general class,
372     \item Class \Ref{GTArray<TYPE>} is more efficient, but only works for
373           types that do not require sophisticated constructors or destructors,
374           such as the plain old C types (e.g. #int# or #char# ...).
375     \item Class \Ref{GPArray<TYPE>} implements an array of smart-pointers
376           \Ref{GP<TYPE>} to objects of type #TYPE#.  Using this class
377           reduces the size of the code generated by the template instanciation.
378     \end{itemize}
379 
380     Another variant of dynamic arrays is implemented in file \Ref{Arrays.h}.
381     The main difference is that class \Ref{TArray}, \Ref{DArray} and
382     \Ref{DPArray} implement a copy-on-demand scheme.
383 
384     @memo Dynamic arrays.  */
385 //@{
386 
387 class DJVUAPI GArrayBase : public GCont
388 {
389 public:
390   // -- CONSTRUCTORS
391   GArrayBase(const GArrayBase &ref);
392   GArrayBase(const Traits &traits);
393   GArrayBase(const Traits &traits, int lobound, int hibound);
394   // -- DESTRUCTOR
395   ~GArrayBase();
396   // -- ASSIGNMENT
397   GArrayBase& operator= (const GArrayBase &ga);
398   // -- ALTERATION
399   void empty();
400   void touch(int n);
401   void resize(int lobound, int hibound);
402   void shift(int disp);
403   void del(int n, int howmany=1);
404   void ins(int n, const void *src, int howmany=1);
405   void steal(GArrayBase &ga);
406 protected:
407   const Traits &traits;
408   void  *data;
409   int   minlo;
410   int   maxhi;
411   int   lobound;
412   int   hibound;
413 };
414 
415 
416 /** Common base class for all dynamic arrays.
417     Class \Ref{GArrayTemplate} implements all methods for manipulating arrays
418     of type #TYPE#.  You should not however create instances of this class.
419     You should instead use class \Ref{GArray}, \Ref{GTArray} or
420     \Ref{GPArray}. */
421 
422 template<class TYPE>
423 class GArrayTemplate : protected GArrayBase
424 {
425 public:
426   // -- CONSTRUCTORS
427   GArrayTemplate(const Traits &traits) : GArrayBase(traits) {}
428   GArrayTemplate(const Traits &traits, int lobound, int hibound)
429     : GArrayBase(traits, lobound, hibound) {}
430   // -- ACCESS
431   /** Returns the number of elements in the array. */
432   int size() const
433     { return hibound-lobound+1; }
434   /** Returns the lower bound of the valid subscript range. */
435   int lbound() const
436     { return lobound; }
437   /** Returns the upper bound of the valid subscript range. */
438   int hbound() const
439     { return hibound; }
440   /** Returns a reference to the array element for subscript #n#.  This
441       reference can be used for both reading (as "#a[n]#") and writing (as
442       "#a[n]=v#") an array element.  This operation will not extend the valid
443       subscript range: an exception \Ref{GException} is thrown if argument #n#
444       is not in the valid subscript range. */
445   inline TYPE& operator[](int const n);
446   /** Returns a constant reference to the array element for subscript #n#.
447       This reference can only be used for reading (as "#a[n]#") an array
448       element.  This operation will not extend the valid subscript range: an
449       exception \Ref{GException} is thrown if argument #n# is not in the valid
450       subscript range.  This variant of #operator[]# is necessary when dealing
451       with a #const GArray<TYPE>#. */
452   inline const TYPE& operator[](int n) const;
453   // -- CONVERSION
454   /** Returns a pointer for reading or writing the array elements.  This
455       pointer can be used to access the array elements with the same
456       subscripts and the usual bracket syntax.  This pointer remains valid as
457       long as the valid subscript range is unchanged. If you change the
458       subscript range, you must stop using the pointers returned by prior
459       invocation of this conversion operator. */
460   operator TYPE* ()
461     { return ((TYPE*)data)-minlo; }
462   /** Returns a pointer for reading (but not modifying) the array elements.
463       This pointer can be used to access the array elements with the same
464       subscripts and the usual bracket syntax.  This pointer remains valid as
465       long as the valid subscript range is unchanged. If you change the
466       subscript range, you must stop using the pointers returned by prior
467       invocation of this conversion operator. */
468   operator const TYPE* () const
469     { return ((const TYPE*)data)-minlo; }
470   // -- ALTERATION
471   /** Erases the array contents. All elements in the array are destroyed.
472       The valid subscript range is set to the empty range. */
473   void empty()
474     { GArrayBase::empty(); }
475   /** Extends the subscript range so that it contains #n#.
476       This function does nothing if #n# is already int the valid subscript range.
477       If the valid range was empty, both the lower bound and the upper bound
478       are set to #n#.  Otherwise the valid subscript range is extended
479       to encompass #n#. This function is very handy when called before setting
480       an array element:
481       \begin{verbatim}
482        int lineno=1;
483        GArray<GString> a;
484        while (! end_of_file()) {
485          a.touch(lineno);
486          a[lineno++] = read_a_line();
487        }
488       \end{verbatim} */
489   void touch(int n)
490     { if (n<lobound || n>hibound) GArrayBase::touch(n); }
491   /** Resets the valid subscript range to #0#---#hibound#.
492       This function may destroy some array elements and may construct
493       new array elements with the null constructor. Setting #hibound# to
494       #-1# resets the valid subscript range to the empty range. */
495   void resize(int hibound)
496     { GArrayBase::resize(0, hibound); }
497   /** Resets the valid subscript range to #lobound#---#hibound#.
498       This function may destroy some array elements and may construct
499       new array elements with the null constructor. Setting #lobound# to #0# and
500       #hibound# to #-1# resets the valid subscript range to the empty range. */
501   void resize(int lobound, int hibound)
502     { GArrayBase::resize(lobound, hibound); }
503   /** Shifts the valid subscript range. Argument #disp# is added to both
504       bounds of the valid subscript range. Array elements previously
505       located at subscript #x# will now be located at subscript #x+disp#. */
506   void shift(int disp)
507     { GArrayBase::shift(disp); }
508   /** Deletes array elements. The array elements corresponding to
509       subscripts #n#...#n+howmany-1# are destroyed. All array elements
510       previously located at subscripts greater or equal to #n+howmany#
511       are moved to subscripts starting with #n#. The new subscript upper
512       bound is reduced in order to account for this shift. */
513   void del(int n, int howmany=1)
514     { GArrayBase::del(n, howmany); }
515   /** Insert new elements into an array. This function inserts
516       #howmany# elements at position #n# into the array. These
517       elements are constructed using the default constructor for type
518       #TYPE#.  All array elements previously located at subscripts #n#
519       and higher are moved to subscripts #n+howmany# and higher. The
520       upper bound of the valid subscript range is increased in order
521       to account for this shift. */
522   void ins(int n, int howmany=1)
523     { GArrayBase::ins(n, 0, howmany); }
524   /** Insert new elements into an array. The new elements are
525       constructed by copying element #val# using the copy constructor
526       for type #TYPE#. See \Ref{ins(int n, unsigned int howmany=1)}. */
527   void ins(int n, const TYPE &val, int howmany=1)
528     { GArrayBase::ins(n, (const void*)&val, howmany); }
529   /** Steals contents from array #ga#.  After this call, array #ga# is empty,
530       and this array contains everything previously contained in #ga#. */
531   void steal(GArrayTemplate &ga)
532     { GArrayBase::steal(ga); }
533   // -- SORTING
534   /** Sort array elements.  Sort all array elements in ascending
535       order according to the less-or-equal comparison
536       operator for type #TYPE#. */
537   void sort()
538     { sort(lbound(), hbound()); }
539   /** Sort array elements in subscript range #lo# to #hi#.  Sort all array
540       elements whose subscripts are in range #lo# to #hi# in ascending order
541       according to the less-or-equal comparison operator for type #TYPE#.  The
542       other elements of the array are left untouched.  An exception is thrown
543       if arguments #lo# and #hi# are not in the valid subscript range.  */
544   void sort(int lo, int hi);
545 };
546 
547 
548 
549 /* That one must be implemented as a regular template function. */
550 template <class TYPE> void
551 GArrayTemplate<TYPE>::sort(int lo, int hi)
552 {
553   TYPE *data = (TYPE*)(*this);
554   while(true)
555     {
556       if (hi <= lo)
557         return;
558       if (hi > hibound || lo<lobound)
559         G_THROW( ERR_MSG("GContainer.illegal_subscript") );
560       // Test for insertion sort
561       if (hi <= lo + 50)
562         {
563           for (int i=lo+1; i<=hi; i++)
564             {
565               int j = i;
566               TYPE tmp = data[i];
567               while ((--j>=lo) && !(data[j]<=tmp))
568                 data[j+1] = data[j];
569               data[j+1] = tmp;
570             }
571           return;
572         }
573       // -- determine median-of-three pivot
574       TYPE tmp = data[lo];
575       TYPE pivot = data[(lo+hi)/2];
576       if (pivot <= tmp)
577         { tmp = pivot; pivot=data[lo]; }
578       if (data[hi] <= tmp)
579         { pivot = tmp; }
580       else if (data[hi] <= pivot)
581         { pivot = data[hi]; }
582       // -- partition set
583       int h = hi;
584       int l = lo;
585       while (l < h)
586         {
587           while (! (pivot <= data[l])) l++;
588           while (! (data[h] <= pivot)) h--;
589           if (l < h)
590             {
591               tmp = data[l];
592               data[l] = data[h];
593               data[h] = tmp;
594               l = l+1;
595               h = h-1;
596             }
597         }
598       // -- recurse, small partition first
599       //    tail-recursion elimination
600       if (h - lo <= hi - l) {
601         sort(lo,h);
602         lo = l; // sort(l,hi)
603       } else {
604         sort(l,hi);
605         hi = h; // sort(lo,h)
606       }
607     }
608 }
609 
610 template<class TYPE> inline TYPE&
611 GArrayTemplate<TYPE>::operator[](int const n)
612 {
613 #if GCONTAINER_BOUNDS_CHECK
614   if (n<lobound || n>hibound)
615   {
616     G_THROW( ERR_MSG("GContainer.illegal_subscript") );
617   }
618 #endif
619   return ((TYPE*)data)[n-minlo];
620 }
621 
622 
623 template<class TYPE> inline const TYPE &
624 GArrayTemplate<TYPE>::operator[](int const n) const
625 {
626 #if GCONTAINER_BOUNDS_CHECK
627   if (n<lobound || n>hibound)
628   {
629     G_THROW( ERR_MSG("GContainer.illegal_subscript") );
630   }
631 #endif
632   return ((const TYPE*)data)[n-minlo];
633 }
634 
635 
636 
637 /** Dynamic array for general types.
638     Template class #GArray<TYPE># implements an array of elements of type
639     #TYPE#. This template class must be able to access the following
640     functions.
641     \begin{itemize}
642     \item a default constructor #TYPE::TYPE()#,
643     \item a copy constructor #TYPE::TYPE(const TYPE &)#,
644     \item and optionally a destructor #TYPE::~TYPE()#.
645     \end{itemize}
646     This class only implement constructors.  See class \Ref{GArrayTemplate}
647     for a description of all access methods. */
648 
649 template<class TYPE>
650 class GArray : public GArrayTemplate<TYPE>
651 {
652 public:
653   /** Constructs an empty array. The valid subscript range is initially
654       empty. Member function #touch# and #resize# provide convenient ways
655       to enlarge the subscript range. */
656   GArray()
657     : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits() ) {}
658   /** Constructs an array with subscripts in range 0 to #hibound#.
659       The subscript range can be subsequently modified with member functions
660       #touch# and #resize#. */
661   GArray(int hi)
662     : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits(), 0, hi ) {}
663   /** Constructs an array with subscripts in range #lobound# to #hibound#.
664       The subscript range can be subsequently modified with member functions
665       #touch# and #resize#. */
666   GArray(int lo, int hi)
667     : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits(), lo, hi ) {}
668   // Copy operator
669   GArray& operator=(const GArray &r)
670     { GArrayBase::operator=(r); return *this; }
671 };
672 
673 
674 /** Dynamic array for smart pointers.
675     Template class #GPArray<TYPE># implements an array of elements of type
676     #GP<TYPE># (see \Ref{GSmartPointer.h}).  Significantly smaller code sizes
677     can be achieved by using this class instead of the more general
678     #GArray<GP<TYPE>>#.
679     This class only implement constructors.  See class \Ref{GArrayTemplate}
680     for a description of all access methods.  */
681 
682 template<class TYPE>
683 class GPArray : public GArrayTemplate<GP<TYPE> >
684 {
685 public:
686   GPArray()
687     : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits() ) {}
688   GPArray(int hi)
689     : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits(), 0, hi ) {}
690   GPArray(int lo, int hi)
691     : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits(), lo, hi ) {}
692   // Copy operator
693   GPArray& operator=(const GPArray &r)
694     { GArrayBase::operator=(r); return *this; }
695 };
696 
697 /** Dynamic array for simple types.
698     Template class #GTArray<TYPE># implements an array of elements of {\em
699     simple} type #TYPE#.  {\em Simple} means that objects of type #TYPE# can
700     be created, copied, moved or destroyed without using specific constructors
701     or destructor functions.  Class #GTArray<TYPE># will move or copy objects
702     using simple bitwise copies.  Otherwise you must use class #GArray<TYPE>#.
703     This class only implement constructors.  See class \Ref{GArrayTemplate}
704     for a description of all access methods.  */
705 template<class TYPE>
706 class GTArray : public GArrayTemplate<TYPE>
707 {
708 public:
709   GTArray()
710     : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits() ) {}
711   GTArray(int hi)
712     : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits(), 0, hi ) {}
713   GTArray(int lo, int hi)
714     : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits(), lo, hi ) {}
715   // Copy operator
716   GTArray& operator=(const GTArray &r)
717     { GArrayBase::operator=(r); return *this; }
718 };
719 
720 
721 //@}
722 
723 
724 
725 // ------------------------------------------------------------
726 // DOUBLY LINKED LISTS
727 // ------------------------------------------------------------
728 
729 
730 /** @name Doubly Linked Lists
731 
732     The template classes \Ref{GList} and \Ref{GPList} implement a doubly
733     linked list of objects of arbitrary types. Member functions are provided
734     to search the list for an element, to insert or delete elements at
735     specified positions.  Theses template class must be able to access
736     \begin{itemize}
737     \item a default constructor #TYPE::TYPE()#,
738     \item a copy constructor #TYPE::TYPE(const TYPE &)#,
739     \item optionally a destructor #TYPE::~TYPE()#,
740     \item and optionally a comparison operator #TYPE::operator==(const TYPE &)#.
741     \end{itemize}
742     @memo Doubly linked lists.
743 */
744 //@{
745 
746 /** Generic iterator class.
747     This class represents a position in a list (see \Ref{GList}) or a map
748     (see \Ref{GMap}).   As demonstrated by the following examples,
749     this class should be used to iterate over the objects contained
750     in a list or a map:
751     \begin{verbatim}
752     void print_list(GList<GString> a)
753     {
754       for (GPosition i = a ; i; ++i)
755         DjVuPrintMessage("%s\n", (const char*) a[i] );
756     }
757 
758     void print_list_backwards(GList<GString> a)
759     {
760       for (GPosition i = a.lastpos() ; i; --i)
761         DjVuPrintMessage("%s\n", (const char*) a[i] );
762     }
763     \end{verbatim}
764     GPosition objects should only be used with the list or map for which they
765     have been created (using the member functions #firstpos# or #lastpos# of
766     the container).  Furthermore, you should never use a GPosition object
767     which designates a list element which has been removed from the list
768     (using member function #del# or by other means.)
769 */
770 
771 class DJVUAPI GPosition : protected GCont
772 {
773 public:
774   /** Creates a null GPosition object. */
775   GPosition() : ptr(0), cont(0) {}
776   /** Creates a copy of a GPosition object. */
777   GPosition(const GPosition &ref) : ptr(ref.ptr), cont(ref.cont) {}
778   /** Tests whether this GPosition object is non null. */
779   operator int() const
780     { return !!ptr; }
781   /** Tests whether this GPosition object is null. */
782   int operator !() const
783     { return !ptr; }
784   /** Moves this GPosition object to the next object in the container. */
785   GPosition& operator ++()
786     { if (ptr) ptr = ptr->next; return *this; }
787   /** Moves this GPosition object to the previous object in the container. */
788   GPosition& operator --()
789     { if (ptr) ptr = ptr->prev; return *this; }
790   // Internal. Do not use.
791   GPosition(Node *p, void *c) : ptr(p), cont(c) {}
792 #if GCONTAINER_BOUNDS_CHECK
793   Node *check(void *c)
794     { if (!ptr || c!=cont) throw_invalid(c); return ptr; }
795   const Node *check(void *c) const
796     { if (!ptr || c!=cont) throw_invalid(c); return ptr; }
797 #else
798   Node *check(void *c)
799     { return ptr; }
800   const Node *check(void *c) const
801     { return ptr; }
802 #endif
803 protected:
804   Node *ptr;
805   void *cont;
806   friend class GListBase;
807   friend class GSetBase;
808   void throw_invalid(void *c) const no_return;
809 };
810 
811 
812 class DJVUAPI GListBase : public GCont
813 {
814 protected:
815   GListBase(const Traits& traits);
816   GListBase(const GListBase &ref);
817   void append(Node *n);
818   void prepend(Node *n);
819   void insert_after(GPosition pos, Node *n);
820   void insert_before(GPosition pos, Node *n);
821   void insert_before(GPosition pos, GListBase &fromlist, GPosition &frompos);
822   void del(GPosition &pos);
823 protected:
824   const Traits &traits;
825   int nelem;
826   Node head;
827 public:
828   ~GListBase();
829   GListBase & operator= (const GListBase & gl);
830   GPosition firstpos() const { return GPosition(head.next, (void*)this); }
831   GPosition lastpos() const { return GPosition(head.prev, (void*)this); }
832   bool isempty() const { return nelem==0; };
833   GPosition nth(unsigned int n) const;
834   void empty();
835 };
836 
837 
838 template<class TI>
839 class GListImpl : public GListBase
840 {
841   typedef GCONT ListNode<TI> LNode;
842 protected:
843   GListImpl();
844   static Node * newnode(const TI &elt);
845   int operator==(const GListImpl<TI> &l2) const;
846   int search(const TI &elt, GPosition &pos) const;
847 };
848 
849 template<class TI>
850 GListImpl<TI>::GListImpl()
851   : GListBase( GCONT NormTraits<LNode>::traits() )
852 {
853 }
854 
855 template<class TI> GCONT Node *
856 GListImpl<TI>::newnode(const TI &elt)
857 {
858   LNode  *n = (LNode *) operator new (sizeof(LNode ));
859 #if GCONTAINER_ZERO_FILL
860   memset((void*)n, 0, sizeof(LNode ));
861 #endif
862   new ((void*)&(n->val)) TI(elt);
863   return (Node*) n;
864 }
865 
866 template<class TI> int
867 GListImpl<TI>::operator==(const GListImpl<TI> &l2) const
868 {
869   Node *p, *q;
870   for (p=head.next, q=l2.head.next; p && q; p=p->next, q=q->next )
871     if (((LNode*)p)->val != ((LNode*)q)->val)
872       return 0;
873   return p==0 && q==0;
874 }
875 
876 template<class TI> int
877 GListImpl<TI>::search(const TI &elt, GPosition &pos) const
878 {
879   Node *n = (pos ? pos.check((void*)this) : head.next);
880   for (; n; n=n->next)
881     if ( ((LNode *)n)->val == elt )
882       break;
883   if (n) pos = GPosition(n, (void*)this);
884   return (n != 0);
885 }
886 
887 
888 /** Common base class for all doubly linked lists.
889     Class \Ref{GListTemplate} implements all methods for manipulating lists
890     of of objects of type #TYPE#.  You should not however create instances of
891     this class. You should instead use class \Ref{GList} or \Ref{GPList}. */
892 
893 template <class TYPE, class TI>
894 class GListTemplate : protected GListImpl<TI>
895 {
896   typedef GCONT ListNode<TI> LNode;
897 public:
898   // -- ACCESS
899   /** Returns the number of elements in the list. */
900   int size() const
901     { return this->nelem; }
902   /** Returns the first position in the list. See \Ref{GPosition}. */
903   GPosition firstpos() const
904     { return GListImpl<TI>::firstpos(); }
905   /** Returns the last position in the list. See \Ref{GPosition}. */
906   GPosition lastpos() const
907     { return GListImpl<TI>::lastpos(); }
908   /** Implicit notation for GList::firstpos(). */
909   operator GPosition() const
910     { return firstpos(); }
911   /** Returns a reference to the list element at position #pos#.  This
912       reference can be used for both reading (as "#a[n]#") and modifying (as
913       "#a[n]=v#") a list element.  Using an invalid position will cause a
914       segmentation violation. See \Ref{GPosition} for efficient operations on
915       positions. */
916   TYPE& operator[](GPosition pos)
917     { return (TYPE&) (((LNode *)pos.check((void*)this))->val); }
918   /** Returns a constant reference to the list element at position #pos#.
919       This reference only be used for reading a list element.  An exception
920       \Ref{GException} is thrown if #pos# is not a valid position. This
921       variant of #operator[]# is necessary when dealing with a #const
922       GList<TYPE>#.  See \Ref{GPosition} for efficient operations on
923       positions. */
924   const TYPE& operator[](GPosition pos) const
925     { return (const TYPE&) (((const LNode *)pos.check((void*)this))->val); }
926   // -- TEST
927   /** Tests whether a list is empty.
928       Returns a non zero value if the list contains no elements. */
929   bool isempty() const
930     { return this->nelem==0; }
931   /** Compares two lists. Returns a non zero value if and only if both lists
932       contain the same elements (as tested by #TYPE::operator==(const TYPE&)#
933       in the same order. */
934   int operator==(const GListTemplate<TYPE,TI> &l2) const
935     { return GListImpl<TI>::operator==(l2); }
936   // -- SEARCHING
937   /** Returns the position #pos# of the #n#-th list element.  An invalid
938       position is returned if the list contains less than #n# elements. The
939       operation works by sequentially scanning the list until reaching the
940       #n#-th element. */
941   GPosition nth(unsigned int n) const
942     { return GListImpl<TI>::nth(n); }
943   /*  Compatibility */
944   int nth(unsigned int n, GPosition &pos) const
945     { GPosition npos=nth(n); if (npos) pos=npos; return !!pos; }
946   /** Tests whether the list contains a given element.  If the list contains
947       #elt#, the position of the the first list element equal to #elt# as
948       checked by #TYPE::operator==(const TYPE&)# is returned.  Otherwise an
949       invalid position is returned. */
950   GPosition contains(const TYPE &elt) const
951     { GPosition pos; GListImpl<TI>::search((const TI&)elt, pos); return pos; }
952   /** Searches the list for a given element. If position #pos# is a valid
953       position for this list, the search starts at the specified position. If
954       position #pos# is not a valid position, the search starts at the
955       beginning of the list.  The list elements are sequentially compared with
956       #elt# using #TYPE::operator==(const TYPE&)#.  As soon as a list element
957       is equal to #elt#, function #search# sets argument #pos# with the
958       position of this list element and returns 1.  If however the search
959       reaches the end of the list, function #search# returns 0 and leaves
960       #pos# unchanged. */
961   int search(const TYPE &elt, GPosition &pos) const
962     { return GListImpl<TI>::search((const TI&)elt, pos); }
963   // -- ALTERATION
964   /** Erases the list contents.  All list elements are destroyed and
965       unlinked. The list is left with zero elements. */
966   void empty()
967     { GListImpl<TI>::empty(); }
968   /** Inserts an element after the last element of the list.
969       The new element is initialized with a copy of argument #elt#. */
970   void append(const TYPE &elt)
971     { GListImpl<TI>::append(this->newnode((const TI&)elt)); }
972   /** Inserts an element before the first element of the list.
973       The new element is initialized with a copy of argument #elt#. */
974   void prepend(const TYPE &elt)
975     { GListImpl<TI>::prepend(this->newnode((const TI&)elt)); }
976   /** Inserts a new element after the list element at position #pos#.  When
977       position #pos# is null the element is inserted at the beginning of the
978       list.  The new element is initialized with a copy of #elt#. */
979   void insert_after(GPosition pos, const TYPE &elt)
980     { GListImpl<TI>::insert_after(pos, this->newnode((const TI&)elt)); }
981   /** Inserts a new element before the list element at position #pos#. When
982       position #pos# is null the element is inserted at the end of the
983       list. The new element is initialized with a copy of #elt#. */
984   void insert_before(GPosition pos, const TYPE &elt)
985     { GListImpl<TI>::insert_before(pos, this->newnode((const TI&)elt)); }
986   /** Inserts an element of another list into this list.  This function
987       removes the element at position #frompos# in list #frompos#, inserts it
988       in the current list before the element at position #pos#, and advances
989       #frompos# to the next element in list #fromlist#. When position #pos# is
990       null the element is inserted at the end of the list. */
991   void insert_before(GPosition pos, GListTemplate<TYPE,TI> &fromlist, GPosition &frompos)
992     { GListImpl<TI>::insert_before(pos, fromlist, frompos); }
993   /** Destroys the list element at position #pos#.  This function does
994       nothing unless position #pos# is a valid position. */
995   void del(GPosition &pos)
996     { GListImpl<TI>::del(pos); }
997   /* Old iterators. Do not use. */
998 #if GCONTAINER_OLD_ITERATORS
999   void first(GPosition &pos) const { pos = firstpos(); }
1000   void last(GPosition &pos) const { pos = lastpos(); }
1001   const TYPE *next(GPosition &pos) const
1002     { if (!pos) return 0; const TYPE *x=&((*this)[pos]); ++pos; return x; }
1003   const TYPE *prev(GPosition &pos) const
1004     { if (!pos) return 0; const TYPE *x=&((*this)[pos]); --pos; return x; }
1005   TYPE *next(GPosition &pos)
1006     { if (!pos) return 0; TYPE *x=&((*this)[pos]); ++pos; return x; }
1007   TYPE *prev(GPosition &pos)
1008     { if (!pos) return 0; TYPE *x=&((*this)[pos]); --pos; return x; }
1009 #endif
1010 };
1011 
1012 
1013 /** Doubly linked lists.  Template class #GList<TYPE># implements a doubly
1014     linked list of elements of type #TYPE#.  This class only implement
1015     constructors.  See class \Ref{GListTemplate} and \Ref{GPosition} for a
1016     description of all access methods. */
1017 
1018 template <class TYPE>
1019 class GList : public GListTemplate<TYPE,TYPE>
1020 {
1021 public:
1022   /** Null Constructor. Constructs a list with zero elements. */
1023   GList() : GListTemplate<TYPE,TYPE>() {}
1024   GList& operator=(const GList &r)
1025     { GListBase::operator=(r); return *this; }
1026 };
1027 
1028 
1029 /** Doubly linked lists for smart pointers.
1030     Template class #GList<TYPE># implements a doubly linked list of elements
1031     of type #GP<TYPE># (see \Ref{GSmartPointer.h}).  Significantly smaller
1032     code sizes can be achieved by using this class instead of the more general
1033     #GArray<GP<TYPE>>#.
1034     This class only implement constructors.  See class \Ref{GListTemplate} and
1035     \Ref{GPosition} for a description of all access methods. */
1036 
1037 template <class TYPE>
1038 class GPList : public GListTemplate<GP<TYPE>,GPBase>
1039 {
1040 public:
1041   /** Null Constructor. Constructs a list with zero elements. */
1042   GPList() : GListTemplate<GP<TYPE>,GPBase>() {}
1043   GPList& operator=(const GPList &r)
1044     { GListBase::operator=(r); return *this; }
1045 };
1046 
1047 
1048 //@}
1049 
1050 
1051 
1052 // ------------------------------------------------------------
1053 // ASSOCIATIVE MAPS
1054 // ------------------------------------------------------------
1055 
1056 /** @name Associative Maps
1057 
1058     These template classes implements a associative maps.  The associative map
1059     contains an arbitrary number of entries. Each entry is a pair containing
1060     one element of type #KTYPE# (named the "key") and one element of type
1061     #VTYPE# (named the "value").  All entries have distinct keys.
1062     These template class must be able to access the following functions:
1063     \begin{itemize}
1064     \item a #VTYPE# default constructor #VTYPE::VTYPE()#,
1065     \item a #VTYPE# copy constructor #VTYPE::VTYPE(const VTYPE &)#,
1066     \item optionally a #VTYPE# destructor #VTYPE::~VTYPE()#,
1067     \item a #KTYPE# default constructor #KTYPE::KTYPE()#,
1068     \item a #KTYPE# copy constructor #KTYPE::KTYPE(const KTYPE &)#,
1069     \item optionally a #KTYPE# destructor #KTYPE::~KTYPE()#,
1070     \item a #KTYPE# comparison operator #KTYPE::operator==(const KTYPE &)#,
1071     \item and a #KTYPE# hashing function #hash(const KTYPE&)#.
1072     \end{itemize}
1073     The hashing function must return an #unsigned int# number. Multiple
1074     invocations of the hashing function with equal arguments (in the sense of
1075     #KTYPE::operator==#) must always return the same number.
1076     Position objects (see \Ref{GPosition}) may be used to iterate over the
1077     entries contained by an associative map.
1078     @memo Associative maps.
1079 */
1080 //@{
1081 
1082 class DJVUAPI GSetBase : public GCont
1083 {
1084 protected:
1085   GSetBase(const Traits &traits);
1086   GSetBase(const GSetBase &ref);
1087   static GCONT HNode *newnode(const void *key);
1088   HNode *hashnode(unsigned int hashcode) const;
1089   HNode *installnode(HNode *n);
1090   void   deletenode(HNode *n);
1091 protected:
1092   const Traits &traits;
1093   int nelems;
1094   int nbuckets;
1095   HNode **table;
1096   GPBuffer<HNode *> gtable;
1097   HNode *first;
1098 private:
1099   void insertnode(HNode *n);
1100   void rehash(int newbuckets);
1101 public:
1102   ~GSetBase();
1103   GSetBase& operator=(const GSetBase &ref);
1104   GPosition firstpos() const;
1105   void del(GPosition &pos);
1106   void empty();
1107 };
1108 
1109 template <class K>
1110 class GSetImpl : public GSetBase
1111 {
1112   typedef GCONT SetNode<K> SNode;
1113 protected:
1114   GSetImpl();
1115   GSetImpl(const Traits &traits);
1116   HNode *get(const K &key) const;
1117   HNode *get_or_throw(const K &key) const;
1118   HNode *get_or_create(const K &key);
1119 public:
1120   GPosition contains(const K &key) const
1121     { return GPosition( get(key), (void*)this); }
1122   void del(const K &key)
1123     { deletenode(get(key)); }
1124 };
1125 
1126 template<class K>
1127 GSetImpl<K>::GSetImpl()
1128   : GSetBase( GCONT NormTraits<GCONT SetNode<K> >::traits() )
1129 {
1130 }
1131 
1132 template<class K>
1133 GSetImpl<K>::GSetImpl(const Traits &traits)
1134   : GSetBase(traits)
1135 {
1136 }
1137 
1138 template<class K> GCONT HNode *
1139 GSetImpl<K>::get(const K &key) const
1140 {
1141   unsigned int hashcode = hash(key);
1142   for (SNode *s=(SNode*)hashnode(hashcode); s; s=(SNode*)(s->hprev))
1143     if (s->hashcode == hashcode && s->key == key) return s;
1144   return 0;
1145 }
1146 
1147 #if GCONTAINER_BOUNDS_CHECK
1148 template<class K> GCONT HNode *
1149 GSetImpl<K>::get_or_throw(const K &key) const
1150 {
1151   HNode *m = get(key);
1152   if (!m)
1153   {
1154     G_THROW( ERR_MSG("GContainer.cannot_add") );
1155   }
1156   return m;
1157 }
1158 #else
1159 template<class K> inline GCONT HNode *
1160 GSetImpl<K>::get_or_throw(const K &key) const
1161 {
1162   return get(key);
1163 }
1164 #endif
1165 
1166 template<class K> GCONT HNode *
1167 GSetImpl<K>::get_or_create(const K &key)
1168 {
1169   HNode *m = get(key);
1170   if (m) return m;
1171   SNode *n = (SNode*) operator new (sizeof(SNode));
1172 #if GCONTAINER_ZERO_FILL
1173   memset((void*)n, 0, sizeof(SNode));
1174 #endif
1175   new ((void*)&(n->key)) K ( key );
1176   n->hashcode = hash((const K&)(n->key));
1177   installnode(n);
1178   return n;
1179 }
1180 
1181 template <class K, class TI>
1182 class GMapImpl : public GSetImpl<K>
1183 {
1184   typedef GCONT MapNode<K,TI> MNode;
1185 protected:
1186   GMapImpl();
1187   GMapImpl(const GCONT Traits &traits);
1188   GCONT HNode* get_or_create(const K &key);
1189 };
1190 
1191 template<class K, class TI>
1192 GMapImpl<K,TI>::GMapImpl()
1193   : GSetImpl<K> ( GCONT NormTraits<GCONT MapNode<K,TI> >::traits() )
1194 {
1195 }
1196 
1197 template<class K, class TI>
1198 GMapImpl<K,TI>::GMapImpl(const GCONT Traits &traits)
1199   : GSetImpl<K>(traits)
1200 {
1201 }
1202 
1203 template<class K, class TI> GCONT HNode *
1204 GMapImpl<K,TI>::get_or_create(const K &key)
1205 {
1206   GCONT HNode *m = this->get(key);
1207   if (m) return m;
1208   MNode *n = (MNode*) operator new (sizeof(MNode));
1209 #if GCONTAINER_ZERO_FILL
1210   memset((void*)n, 0, sizeof(MNode));
1211 #endif
1212   new ((void*)&(n->key)) K  (key);
1213   new ((void*)&(n->val)) TI ();
1214   n->hashcode = hash((const K&)(n->key));
1215   this->installnode(n);
1216   return n;
1217 }
1218 
1219 
1220 
1221 /** Common base class for all associative maps.
1222     Class \Ref{GArrayTemplate} implements all methods for manipulating
1223     associative maps with key type #KTYPE# and value type #VTYPE#.
1224     You should not however create instances of this class.
1225     You should instead use class \Ref{GMap} or \Ref{GPMap}. */
1226 
1227 template <class KTYPE, class VTYPE, class TI>
1228 class GMapTemplate : protected GMapImpl<KTYPE,TI>
1229 {
1230   typedef GCONT MapNode<KTYPE,TI> MNode;
1231 public:
1232   /** Returns the number of elements in the map. */
1233   int size() const
1234     { return this->nelems; }
1235   /** Returns the first position in the map. */
1236   GPosition firstpos() const
1237     { return GMapImpl<KTYPE,TI>::firstpos(); }
1238   /** Implicit notation for GMap::firstpos(). */
1239   operator GPosition() const
1240     { return firstpos(); }
1241   /** Tests whether the associative map is empty.
1242       Returns a non zero value if and only if the map contains zero entries. */
1243   bool isempty() const
1244     { return this->nelems==0; }
1245   /** Searches an entry for key #key#.  If the map contains an entry whose key
1246       is equal to #key# according to #KTYPE::operator==(const KTYPE&)#, this
1247       function returns its position.  Otherwise it returns an invalid
1248       position. */
1249   GPosition contains(const KTYPE &key) const
1250     { return GMapImpl<KTYPE,TI>::contains(key); }
1251   /*  Compatibility */
1252   GPosition contains(const KTYPE &key, GPosition &pos) const
1253     { return pos = GMapImpl<KTYPE,TI>::contains(key); }
1254   // -- ALTERATION
1255   /** Erases the associative map contents.  All entries are destroyed and
1256       removed. The map is left with zero entries. */
1257   void empty()
1258     { GMapImpl<KTYPE,TI>::empty(); }
1259   /** Returns a constant reference to the key of the map entry at position
1260       #pos#.  An exception \Ref{GException} is thrown if position #pos# is not
1261       valid.  There is no direct way to change the key of a map entry. */
1262   const KTYPE &key(const GPosition &pos) const
1263     { return (const KTYPE&)(((MNode*)(pos.check((void*)this)))->key); }
1264   /** Returns a reference to the value of the map entry at position #pos#.
1265       This reference can be used for both reading (as "#a[n]#") and modifying
1266       (as "#a[n]=v#").  An exception \Ref{GException} is thrown if position
1267       #pos# is not valid. */
1268   VTYPE& operator[](const GPosition &pos)
1269     { return (VTYPE&)(((MNode*)(pos.check((void*)this)))->val); }
1270   /** Returns a constant reference to the value of the map entry at position
1271       #pos#.  This reference can only be used for reading (as "#a[n]#") the
1272       entry value.  An exception \Ref{GException} is thrown if position #pos#
1273       is not valid. */
1274   const VTYPE& operator[](const GPosition &pos) const
1275     { return (const VTYPE&)(((MNode*)(pos.check((void*)this)))->val); }
1276   /** Returns a constant reference to the value of the map entry for key
1277       #key#.  This reference can only be used for reading (as "#a[n]#") the
1278       entry value.  An exception \Ref{GException} is thrown if no entry
1279       contains key #key#. This variant of #operator[]# is necessary when
1280       dealing with a #const GMAP<KTYPE,VTYPE>#. */
1281   const VTYPE& operator[](const KTYPE &key) const
1282     { return (const VTYPE&)(((const MNode*)(this->get_or_throw(key)))->val); }
1283   /** Returns a reference to the value of the map entry for key #key#.  This
1284       reference can be used for both reading (as "#a[n]#") and modifying (as
1285       "#a[n]=v#"). If there is no entry for key #key#, a new entry is created
1286       for that key with the null constructor #VTYPE::VTYPE()#. */
1287   VTYPE& operator[](const KTYPE &key)
1288     { return (VTYPE&)(((MNode*)(this->get_or_create(key)))->val); }
1289   /** Destroys the map entry for position #pos#.
1290       Nothing is done if position #pos# is not a valid position. */
1291   void del(GPosition &pos)
1292     { GSetBase::del(pos); }
1293   /** Destroys the map entry for key #key#.
1294       Nothing is done if there is no entry for key #key#. */
1295   void del(const KTYPE &key)
1296     { GMapImpl<KTYPE,TI>::del(key); }
1297   /* Old iterators. Do not use. */
1298 #if GCONTAINER_OLD_ITERATORS
1299   void first(GPosition &pos) const { pos = firstpos(); }
1300   const VTYPE *next(GPosition &pos) const
1301     { if (!pos) return 0; const VTYPE *x=&((*this)[pos]); ++pos; return x; }
1302   VTYPE *next(GPosition &pos)
1303     { if (!pos) return 0; VTYPE *x=&((*this)[pos]); ++pos; return x; }
1304 #endif
1305 };
1306 
1307 
1308 
1309 /** Associative maps.
1310     Template class #GMap<KTYPE,VTYPE># implements an associative map.
1311     The map contains an arbitrary number of entries. Each entry is a
1312     pair containing one element of type #KTYPE# (named the "key") and one
1313     element of type #VTYPE# (named the "value").
1314     The entry associated to a particular value of the key can retrieved
1315     very efficiently.
1316     This class only implement constructors.  See class \Ref{GMapTemplate} and
1317     \Ref{GPosition} for a description of all access methods.*/
1318 
1319 template <class KTYPE, class VTYPE>
1320 class GMap : public GMapTemplate<KTYPE,VTYPE,VTYPE>
1321 {
1322 public:
1323   // -- ACCESS
1324   GMap() : GMapTemplate<KTYPE,VTYPE,VTYPE>() {}
1325   GMap& operator=(const GMap &r)
1326     { GSetBase::operator=(r); return *this; }
1327 };
1328 
1329 /** Associative maps for smart-pointers.
1330     Template class #GMap<KTYPE,VTYPE># implements an associative map for key
1331     type #KTYPE# and value type #GP<VTYPE># (see \Ref{GSmartPointer.h}).  The
1332     map contains an arbitrary number of entries. Each entry is a pair
1333     containing one element of type #KTYPE# (named the "key") and one aelement
1334     of type #VTYPE# (named the "value").  The entry associated to a particular
1335     value of the key can retrieved very efficiently.
1336     Significantly smaller code sizes can be achieved by using this class
1337     instead of the more general #GMap<KTYPE,GP<VTYPE>># (see \Ref{GMap}).
1338     This class only implement constructors.  See class \Ref{GMapTemplate} and
1339     \Ref{GPosition} for a description of all access methods.*/
1340 
1341 template <class KTYPE, class VTYPE>
1342 class GPMap : public GMapTemplate<KTYPE,GP<VTYPE>,GPBase>
1343 {
1344 public:
1345   GPMap() : GMapTemplate<KTYPE,GP<VTYPE>,GPBase>() {}
1346   GPMap& operator=(const GPMap &r)
1347     { GSetBase::operator=(r); return *this; }
1348 };
1349 
1350 
1351 
1352 //@}
1353 //@}
1354 //@}
1355 
1356 // ------------ THE END
1357 
1358 
1359 #ifdef HAVE_NAMESPACES
1360 }
1361 # ifndef NOT_USING_DJVU_NAMESPACE
1362 using namespace DJVU;
1363 # endif
1364 #endif
1365 #endif
1366 
1367 
1368