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