Blame libdjvu/GContainer.h

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifndef _GCONTAINER_H_
Packit df99a1
#define _GCONTAINER_H_
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
#include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma interface
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
#include "GException.h"
Packit df99a1
#include "GSmartPointer.h"
Packit df99a1
#include <string.h>
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
// Supports old iterators (first/last/next/prev) on lists and maps?
Packit df99a1
#ifndef GCONTAINER_OLD_ITERATORS
Packit df99a1
#define GCONTAINER_OLD_ITERATORS 1
Packit df99a1
#endif
Packit df99a1
Packit df99a1
// Check array bounds at runtime ?
Packit df99a1
#ifndef GCONTAINER_BOUNDS_CHECK
Packit df99a1
#define GCONTAINER_BOUNDS_CHECK 1
Packit df99a1
#endif
Packit df99a1
Packit df99a1
// Clears allocated memory prior to running constructors ?
Packit df99a1
#ifndef GCONTAINER_ZERO_FILL
Packit df99a1
#define GCONTAINER_ZERO_FILL 1
Packit df99a1
#endif
Packit df99a1
Packit df99a1
// Avoid member templates (needed by old compilers)
Packit df99a1
#ifndef GCONTAINER_NO_MEMBER_TEMPLATES
Packit df99a1
#if defined(__GNUC__) && (__GNUC__==2) && (__GNUC_MINOR__<91)
Packit df99a1
#define GCONTAINER_NO_MEMBER_TEMPLATES 1
Packit df99a1
#elif defined(_MSC_VER) && !defined(__ICL)
Packit df99a1
#define GCONTAINER_NO_MEMBER_TEMPLATES 1
Packit df99a1
#elif defined(__MWERKS__)
Packit df99a1
#define GCONTAINER_NO_MEMBER_TEMPLATES 1
Packit df99a1
#else
Packit df99a1
#define GCONTAINER_NO_MEMBER_TEMPLATES 0
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
// Define typename when needed
Packit df99a1
#ifndef GCONTAINER_NO_TYPENAME
Packit df99a1
#define GCONTAINER_NO_TYPENAME 0
Packit df99a1
#endif
Packit df99a1
#if GCONTAINER_NO_TYPENAME
Packit df99a1
#define typename /**/
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
/** @name GContainer.h
Packit df99a1
Packit df99a1
    Files #"GContainer.h"# and #"GContainer.cpp"# implement three main
Packit df99a1
    template class for generic containers.  
Packit df99a1
    Class #GArray# (see \Ref{Dynamic Arrays}) implements an array of objects
Packit df99a1
    with variable bounds. Class #GList# (see \Ref{Doubly Linked Lists})
Packit df99a1
    implements a doubly linked list of objects.  Class #GMap# (see
Packit df99a1
    \Ref{Associative Maps}) implements a hashed associative map.  The
Packit df99a1
    container templates are not thread-safe. Thread safety can be implemented
Packit df99a1
    using the facilities provided in \Ref{GThreads.h}.
Packit df99a1
    
Packit df99a1
    @memo 
Packit df99a1
    Template class for generic containers.
Packit df99a1
    @author 
Packit df99a1
    L\'eon Bottou <leonb@research.att.com> -- initial implementation.\\
Packit df99a1
    Andrei Erofeev <eaf@geocities.com> -- bug fixes.
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
// HASH FUNCTIONS
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
Packit df99a1
Packit df99a1
/** @name Hash functions
Packit df99a1
    These functions let you use template class \Ref{GMap} with the
Packit df99a1
    corresponding elementary types. The returned hash code may be reduced to
Packit df99a1
    an arbitrary range by computing its remainder modulo the upper bound of
Packit df99a1
    the range.
Packit df99a1
    @memo Hash functions for elementary types. */
Packit df99a1
//@{
Packit df99a1
Packit df99a1
/** Hashing function (unsigned int). */
Packit df99a1
static inline unsigned int 
Packit df99a1
hash(const unsigned int & x) 
Packit df99a1
{ 
Packit df99a1
  return x; 
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Hashing function (int). */
Packit df99a1
static inline unsigned int 
Packit df99a1
hash(const int & x) 
Packit df99a1
{ 
Packit df99a1
  return (unsigned int)x;
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Hashing function (long). */
Packit df99a1
static inline unsigned int
Packit df99a1
hash(const long & x) 
Packit df99a1
{ 
Packit df99a1
  return (unsigned int)x;
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Hashing function (unsigned long). */
Packit df99a1
static inline unsigned int
Packit df99a1
hash(const unsigned long & x) 
Packit df99a1
{ 
Packit df99a1
  return (unsigned int)x;
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Hashing function (const void *). */
Packit df99a1
static inline unsigned int 
Packit df99a1
hash(const void * const & x) 
Packit df99a1
{ 
Packit df99a1
  return (unsigned int)(size_t) x; 
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Hashing function (float). */
Packit df99a1
static inline unsigned int
Packit df99a1
hash(const float & x) 
Packit df99a1
{ 
Packit df99a1
  // optimizer will get rid of unnecessary code  
Packit df99a1
  unsigned int *addr = (unsigned int*)&x;
Packit df99a1
  if (sizeof(float)<2*sizeof(unsigned int))
Packit df99a1
    return addr[0];
Packit df99a1
  else
Packit df99a1
    return addr[0]^addr[1];
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Hashing function (double). */
Packit df99a1
static inline unsigned int
Packit df99a1
hash(const double & x) 
Packit df99a1
{ 
Packit df99a1
  // optimizer will get rid of unnecessary code
Packit df99a1
  unsigned int *addr = (unsigned int*)&x;
Packit df99a1
  if (sizeof(double)<2*sizeof(unsigned int))
Packit df99a1
    return addr[0];
Packit df99a1
  else if (sizeof(double)<4*sizeof(unsigned int))
Packit df99a1
    return addr[0]^addr[1];
Packit df99a1
  else
Packit df99a1
    return addr[0]^addr[1]^addr[2]^addr[3];    
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
// HELPER CLASSES
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/* Namespace for containers support classes.  This class is used as a
Packit df99a1
   namespace for global identifiers related to the implementation of
Packit df99a1
   containers.  It is inherited by all container objects.  This is disabled by
Packit df99a1
   defining compilation symbol #GCONTAINER_NO_MEMBER_TEMPATES# to 1. */
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef _MSC_VER
Packit df99a1
// Language lawyer say MS is wrong on that one. 
Packit df99a1
// Cf section 5.4.7 in november 1997 draft.
Packit df99a1
#pragma warning( disable : 4243 )
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
// GPEnabled inhertenced removed again so the code works on more machines.
Packit df99a1
class GCont
Packit df99a1
#if GCONTAINER_NO_MEMBER_TEMPLATES
Packit df99a1
{
Packit df99a1
};
Packit df99a1
#else
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
#endif
Packit df99a1
  // --- Pointers to type management functions
Packit df99a1
  struct Traits
Packit df99a1
  {
Packit df99a1
    int       size;
Packit df99a1
    void     *(*lea)     (void *base, int n);
Packit df99a1
    void      (*init)    (void *dst, int n); 
Packit df99a1
    void      (*copy)    (void *dst, const void* src, int n, int zap);
Packit df99a1
    void      (*fini)    (void *dst, int n);
Packit df99a1
  };
Packit df99a1
#if !GCONTAINER_NO_MEMBER_TEMPLATES
Packit df99a1
protected:
Packit df99a1
#endif
Packit df99a1
  // --- Management of simple types
Packit df99a1
  template <int SZ> class TrivTraits
Packit df99a1
  {
Packit df99a1
  public:
Packit df99a1
    // The unique object
Packit df99a1
    static const Traits & traits();
Packit df99a1
    // Offset in an array of T
Packit df99a1
    static void * lea(void* base, int n)
Packit df99a1
      { return (void*)( ((char*)base) + SZ*n ); }
Packit df99a1
    // Trivial default constructor
Packit df99a1
    static void   init(void* dst, int n) {}
Packit df99a1
    // Trivial copy constructor
Packit df99a1
    static void   copy(void* dst, const void* src, int n, int ) 
Packit df99a1
      { ::memcpy(dst, src, SZ*n); }
Packit df99a1
    // Trivial destructor
Packit df99a1
    static void   fini(void* dst, int n) {}
Packit df99a1
  };
Packit df99a1
  // --- Management of regular types
Packit df99a1
  template <class T> class NormTraits
Packit df99a1
  {
Packit df99a1
  public:
Packit df99a1
    // The unique object
Packit df99a1
    static const Traits & traits();
Packit df99a1
    // Offset in an array of T
Packit df99a1
    static void * lea(void* base, int n)
Packit df99a1
      { return (void*)( ((T*)base) + n ); }
Packit df99a1
    // Template based default constructor
Packit df99a1
    static void init(void* dst, int n) 
Packit df99a1
      { T* d = (T*)dst; while (--n>=0) { new ((void*)d) T; d++; } }
Packit df99a1
    // Template based copy constructor
Packit df99a1
    static void copy(void* dst, const void* src, int n, int zap)
Packit df99a1
      { T* d = (T*)dst; T* s = (T*)src; while (--n>=0) { 
Packit df99a1
          new ((void*)d) T(*s); if (zap) { s->~T(); }; d++; s++; } }
Packit df99a1
    // Template based destructor
Packit df99a1
    static void fini(void* dst, int n) 
Packit df99a1
      { T* d = (T*)dst; while (--n>=0) { d->~T(); d++; } }
Packit df99a1
  };
Packit df99a1
  // --- Base class for list nodes
Packit df99a1
  struct Node
Packit df99a1
  {
Packit df99a1
    Node *next;
Packit df99a1
    Node *prev;
Packit df99a1
  };
Packit df99a1
  // -- Class for list nodes
Packit df99a1
  template <class T> struct ListNode : public Node
Packit df99a1
  { 
Packit df99a1
    T val;
Packit df99a1
  };
Packit df99a1
  // -- Class for map nodes showing the hash
Packit df99a1
  struct HNode : public Node
Packit df99a1
  {
Packit df99a1
    HNode *hprev;
Packit df99a1
    unsigned int hashcode;
Packit df99a1
  };
Packit df99a1
  // -- Class for map nodes showing the hash and the key
Packit df99a1
  template <class K> struct SetNode : public HNode
Packit df99a1
  { 
Packit df99a1
    K key;
Packit df99a1
  };
Packit df99a1
  // -- Class for map nodes with everything
Packit df99a1
  template <class K, class T> struct MapNode : public SetNode<K>
Packit df99a1
  {
Packit df99a1
    T val;
Packit df99a1
  };
Packit df99a1
#if !GCONTAINER_NO_MEMBER_TEMPLATES
Packit df99a1
};
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
#if !GCONTAINER_NO_MEMBER_TEMPLATES
Packit df99a1
#define GCONT GCont::
Packit df99a1
#else
Packit df99a1
#define GCONT
Packit df99a1
#endif
Packit df99a1
Packit df99a1
template <int SZ> const GCONT Traits & 
Packit df99a1
GCONT TrivTraits<SZ>::traits()
Packit df99a1
{
Packit df99a1
  static const Traits theTraits = {
Packit df99a1
    SZ,
Packit df99a1
    TrivTraits<SZ>::lea,
Packit df99a1
    TrivTraits<SZ>::init,
Packit df99a1
    TrivTraits<SZ>::copy,
Packit df99a1
    TrivTraits<SZ>::fini
Packit df99a1
  };
Packit df99a1
  return theTraits;
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class T> const GCONT Traits & 
Packit df99a1
GCONT NormTraits<T>::traits()
Packit df99a1
{
Packit df99a1
  static const Traits theTraits = {
Packit df99a1
    sizeof(T),
Packit df99a1
    NormTraits<T>::lea,
Packit df99a1
    NormTraits<T>::init,
Packit df99a1
    NormTraits<T>::copy,
Packit df99a1
    NormTraits<T>::fini
Packit df99a1
  };
Packit df99a1
  return theTraits;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
// DYNAMIC ARRAYS
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
Packit df99a1
Packit df99a1
/** @name Dynamic Arrays
Packit df99a1
Packit df99a1
    These class implement arrays of objects of any type.  Each element is
Packit df99a1
    identified by an integer subscript.  The valid subscripts range is defined
Packit df99a1
    by dynamically adjustable lower- and upper-bounds.  Besides accessing and
Packit df99a1
    setting elements, member functions are provided to insert or delete
Packit df99a1
    elements at specified positions.
Packit df99a1
Packit df99a1
    Class \Ref{GArrayTemplate} implements all methods for manipulating arrays
Packit df99a1
    of type #TYPE#.  You should not however create instances of this class.
Packit df99a1
    You should instead use one of the following classes:
Packit df99a1
    \begin{itemize}
Packit df99a1
    \item Class \Ref{GArray<TYPE>} is the most general class,
Packit df99a1
    \item Class \Ref{GTArray<TYPE>} is more efficient, but only works for
Packit df99a1
          types that do not require sophisticated constructors or destructors,
Packit df99a1
          such as the plain old C types (e.g. #int# or #char# ...).
Packit df99a1
    \item Class \Ref{GPArray<TYPE>} implements an array of smart-pointers
Packit df99a1
          \Ref{GP<TYPE>} to objects of type #TYPE#.  Using this class 
Packit df99a1
          reduces the size of the code generated by the template instanciation.
Packit df99a1
    \end{itemize}
Packit df99a1
Packit df99a1
    Another variant of dynamic arrays is implemented in file \Ref{Arrays.h}.
Packit df99a1
    The main difference is that class \Ref{TArray}, \Ref{DArray} and
Packit df99a1
    \Ref{DPArray} implement a copy-on-demand scheme.
Packit df99a1
Packit df99a1
    @memo Dynamic arrays.  */
Packit df99a1
//@{
Packit df99a1
Packit df99a1
class DJVUAPI GArrayBase : public GCont
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  // -- CONSTRUCTORS
Packit df99a1
  GArrayBase(const GArrayBase &ref;;
Packit df99a1
  GArrayBase(const Traits &traits);
Packit df99a1
  GArrayBase(const Traits &traits, int lobound, int hibound);
Packit df99a1
  // -- DESTRUCTOR
Packit df99a1
  ~GArrayBase();
Packit df99a1
  // -- ASSIGNMENT
Packit df99a1
  GArrayBase& operator= (const GArrayBase &ga);
Packit df99a1
  // -- ALTERATION
Packit df99a1
  void empty();
Packit df99a1
  void touch(int n);
Packit df99a1
  void resize(int lobound, int hibound);
Packit df99a1
  void shift(int disp);
Packit df99a1
  void del(int n, int howmany=1);
Packit df99a1
  void ins(int n, const void *src, int howmany=1);
Packit df99a1
  void steal(GArrayBase &ga);
Packit df99a1
protected:
Packit df99a1
  const Traits &traits;
Packit df99a1
  void  *data;
Packit df99a1
  int   minlo;
Packit df99a1
  int   maxhi;
Packit df99a1
  int   lobound;
Packit df99a1
  int   hibound;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/** Common base class for all dynamic arrays.  
Packit df99a1
    Class \Ref{GArrayTemplate} implements all methods for manipulating arrays
Packit df99a1
    of type #TYPE#.  You should not however create instances of this class.
Packit df99a1
    You should instead use class \Ref{GArray}, \Ref{GTArray} or
Packit df99a1
    \Ref{GPArray}. */
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
class GArrayTemplate : protected GArrayBase
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  // -- CONSTRUCTORS
Packit df99a1
  GArrayTemplate(const Traits &traits) : GArrayBase(traits) {}
Packit df99a1
  GArrayTemplate(const Traits &traits, int lobound, int hibound)
Packit df99a1
    : GArrayBase(traits, lobound, hibound) {}
Packit df99a1
  // -- ACCESS
Packit df99a1
  /** Returns the number of elements in the array. */
Packit df99a1
  int size() const
Packit df99a1
    { return hibound-lobound+1; }
Packit df99a1
  /** Returns the lower bound of the valid subscript range. */
Packit df99a1
  int lbound() const
Packit df99a1
    { return lobound; }
Packit df99a1
  /** Returns the upper bound of the valid subscript range. */
Packit df99a1
  int hbound() const
Packit df99a1
    { return hibound; }
Packit df99a1
  /** Returns a reference to the array element for subscript #n#.  This
Packit df99a1
      reference can be used for both reading (as "#a[n]#") and writing (as
Packit df99a1
      "#a[n]=v#") an array element.  This operation will not extend the valid
Packit df99a1
      subscript range: an exception \Ref{GException} is thrown if argument #n#
Packit df99a1
      is not in the valid subscript range. */
Packit df99a1
  inline TYPE& operator[](int const n);
Packit df99a1
  /** Returns a constant reference to the array element for subscript #n#.
Packit df99a1
      This reference can only be used for reading (as "#a[n]#") an array
Packit df99a1
      element.  This operation will not extend the valid subscript range: an
Packit df99a1
      exception \Ref{GException} is thrown if argument #n# is not in the valid
Packit df99a1
      subscript range.  This variant of #operator[]# is necessary when dealing
Packit df99a1
      with a #const GArray<TYPE>#. */
Packit df99a1
  inline const TYPE& operator[](int n) const;
Packit df99a1
  // -- CONVERSION
Packit df99a1
  /** Returns a pointer for reading or writing the array elements.  This
Packit df99a1
      pointer can be used to access the array elements with the same
Packit df99a1
      subscripts and the usual bracket syntax.  This pointer remains valid as
Packit df99a1
      long as the valid subscript range is unchanged. If you change the
Packit df99a1
      subscript range, you must stop using the pointers returned by prior
Packit df99a1
      invocation of this conversion operator. */
Packit df99a1
  operator TYPE* ()
Packit df99a1
    { return ((TYPE*)data)-minlo; }
Packit df99a1
  /** Returns a pointer for reading (but not modifying) the array elements.
Packit df99a1
      This pointer can be used to access the array elements with the same
Packit df99a1
      subscripts and the usual bracket syntax.  This pointer remains valid as
Packit df99a1
      long as the valid subscript range is unchanged. If you change the
Packit df99a1
      subscript range, you must stop using the pointers returned by prior
Packit df99a1
      invocation of this conversion operator. */
Packit df99a1
  operator const TYPE* () const
Packit df99a1
    { return ((const TYPE*)data)-minlo; }
Packit df99a1
  // -- ALTERATION
Packit df99a1
  /** Erases the array contents. All elements in the array are destroyed.  
Packit df99a1
      The valid subscript range is set to the empty range. */
Packit df99a1
  void empty()
Packit df99a1
    { GArrayBase::empty(); }
Packit df99a1
  /** Extends the subscript range so that it contains #n#.
Packit df99a1
      This function does nothing if #n# is already int the valid subscript range.
Packit df99a1
      If the valid range was empty, both the lower bound and the upper bound
Packit df99a1
      are set to #n#.  Otherwise the valid subscript range is extended
Packit df99a1
      to encompass #n#. This function is very handy when called before setting
Packit df99a1
      an array element:
Packit df99a1
      \begin{verbatim}
Packit df99a1
       int lineno=1;
Packit df99a1
       GArray<GString> a;
Packit df99a1
       while (! end_of_file()) { 
Packit df99a1
         a.touch(lineno); 
Packit df99a1
         a[lineno++] = read_a_line(); 
Packit df99a1
       }
Packit df99a1
      \end{verbatim} */
Packit df99a1
  void touch(int n)
Packit df99a1
    { if (n<lobound || n>hibound) GArrayBase::touch(n); }
Packit df99a1
  /** Resets the valid subscript range to #0#---#hibound#.
Packit df99a1
      This function may destroy some array elements and may construct
Packit df99a1
      new array elements with the null constructor. Setting #hibound# to
Packit df99a1
      #-1# resets the valid subscript range to the empty range. */
Packit df99a1
  void resize(int hibound)
Packit df99a1
    { GArrayBase::resize(0, hibound); }
Packit df99a1
  /** Resets the valid subscript range to #lobound#---#hibound#. 
Packit df99a1
      This function may destroy some array elements and may construct
Packit df99a1
      new array elements with the null constructor. Setting #lobound# to #0# and
Packit df99a1
      #hibound# to #-1# resets the valid subscript range to the empty range. */
Packit df99a1
  void resize(int lobound, int hibound)
Packit df99a1
    { GArrayBase::resize(lobound, hibound); }
Packit df99a1
  /** Shifts the valid subscript range. Argument #disp# is added to both 
Packit df99a1
      bounds of the valid subscript range. Array elements previously
Packit df99a1
      located at subscript #x# will now be located at subscript #x+disp#. */
Packit df99a1
  void shift(int disp)
Packit df99a1
    { GArrayBase::shift(disp); }
Packit df99a1
  /** Deletes array elements. The array elements corresponding to
Packit df99a1
      subscripts #n#...#n+howmany-1# are destroyed. All array elements
Packit df99a1
      previously located at subscripts greater or equal to #n+howmany#
Packit df99a1
      are moved to subscripts starting with #n#. The new subscript upper
Packit df99a1
      bound is reduced in order to account for this shift. */
Packit df99a1
  void del(int n, int howmany=1)
Packit df99a1
    { GArrayBase::del(n, howmany); }
Packit df99a1
  /** Insert new elements into an array. This function inserts
Packit df99a1
      #howmany# elements at position #n# into the array. These
Packit df99a1
      elements are constructed using the default constructor for type
Packit df99a1
      #TYPE#.  All array elements previously located at subscripts #n#
Packit df99a1
      and higher are moved to subscripts #n+howmany# and higher. The
Packit df99a1
      upper bound of the valid subscript range is increased in order
Packit df99a1
      to account for this shift. */
Packit df99a1
  void ins(int n, int howmany=1)
Packit df99a1
    { GArrayBase::ins(n, 0, howmany); }
Packit df99a1
  /** Insert new elements into an array. The new elements are
Packit df99a1
      constructed by copying element #val# using the copy constructor
Packit df99a1
      for type #TYPE#. See \Ref{ins(int n, unsigned int howmany=1)}. */
Packit df99a1
  void ins(int n, const TYPE &val, int howmany=1)
Packit df99a1
    { GArrayBase::ins(n, (const void*)&val, howmany); }
Packit df99a1
  /** Steals contents from array #ga#.  After this call, array #ga# is empty,
Packit df99a1
      and this array contains everything previously contained in #ga#. */
Packit df99a1
  void steal(GArrayTemplate &ga)
Packit df99a1
    { GArrayBase::steal(ga); }
Packit df99a1
  // -- SORTING
Packit df99a1
  /** Sort array elements.  Sort all array elements in ascending
Packit df99a1
      order according to the less-or-equal comparison
Packit df99a1
      operator for type #TYPE#. */
Packit df99a1
  void sort()
Packit df99a1
    { sort(lbound(), hbound()); }
Packit df99a1
  /** Sort array elements in subscript range #lo# to #hi#.  Sort all array
Packit df99a1
      elements whose subscripts are in range #lo# to #hi# in ascending order
Packit df99a1
      according to the less-or-equal comparison operator for type #TYPE#.  The
Packit df99a1
      other elements of the array are left untouched.  An exception is thrown
Packit df99a1
      if arguments #lo# and #hi# are not in the valid subscript range.  */
Packit df99a1
  void sort(int lo, int hi);
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/* That one must be implemented as a regular template function. */
Packit df99a1
template <class TYPE> void
Packit df99a1
GArrayTemplate<TYPE>::sort(int lo, int hi)
Packit df99a1
{
Packit df99a1
  if (hi <= lo)
Packit df99a1
    return;
Packit df99a1
  if (hi > hibound || lo
Packit df99a1
    G_THROW( ERR_MSG("GContainer.illegal_subscript") );
Packit df99a1
  TYPE *data = (TYPE*)(*this);
Packit df99a1
  // Test for insertion sort
Packit df99a1
  if (hi <= lo + 50)
Packit df99a1
    {
Packit df99a1
      for (int i=lo+1; i<=hi; i++)
Packit df99a1
        {
Packit df99a1
          int j = i;
Packit df99a1
          TYPE tmp = data[i];
Packit df99a1
          while ((--j>=lo) && !(data[j]<=tmp))
Packit df99a1
            data[j+1] = data[j];
Packit df99a1
          data[j+1] = tmp;
Packit df99a1
        }
Packit df99a1
      return;
Packit df99a1
    }
Packit df99a1
  // -- determine suitable quick-sort pivot
Packit df99a1
  TYPE tmp = data[lo];
Packit df99a1
  TYPE pivot = data[(lo+hi)/2];
Packit df99a1
  if (pivot <= tmp)
Packit df99a1
    { tmp = pivot; pivot=data[lo]; }
Packit df99a1
  if (data[hi] <= tmp)
Packit df99a1
    { pivot = tmp; }
Packit df99a1
  else if (data[hi] <= pivot)
Packit df99a1
    { pivot = data[hi]; }
Packit df99a1
  // -- partition set
Packit df99a1
  int h = hi;
Packit df99a1
  int l = lo;
Packit df99a1
  while (l < h)
Packit df99a1
    {
Packit df99a1
      while (! (pivot <= data[l])) l++;
Packit df99a1
      while (! (data[h] <= pivot)) h--;
Packit df99a1
      if (l < h)
Packit df99a1
        {
Packit df99a1
          tmp = data[l];
Packit df99a1
          data[l] = data[h];
Packit df99a1
          data[h] = tmp;
Packit df99a1
          l = l+1;
Packit df99a1
          h = h-1;
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  // -- recursively restart
Packit df99a1
  sort(lo, h);
Packit df99a1
  sort(l, hi);
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TYPE> inline TYPE&
Packit df99a1
GArrayTemplate<TYPE>::operator[](int const n)
Packit df99a1
{
Packit df99a1
#if GCONTAINER_BOUNDS_CHECK
Packit df99a1
  if (n<lobound || n>hibound)
Packit df99a1
  {
Packit df99a1
    G_THROW( ERR_MSG("GContainer.illegal_subscript") ); 
Packit df99a1
  }
Packit df99a1
#endif
Packit df99a1
  return ((TYPE*)data)[n-minlo];
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
template<class TYPE> inline const TYPE &
Packit df99a1
GArrayTemplate<TYPE>::operator[](int const n) const
Packit df99a1
{
Packit df99a1
#if GCONTAINER_BOUNDS_CHECK
Packit df99a1
  if (n<lobound || n>hibound)
Packit df99a1
  {
Packit df99a1
    G_THROW( ERR_MSG("GContainer.illegal_subscript") ); 
Packit df99a1
  }
Packit df99a1
#endif
Packit df99a1
  return ((const TYPE*)data)[n-minlo];
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** Dynamic array for general types.  
Packit df99a1
    Template class #GArray<TYPE># implements an array of elements of type
Packit df99a1
    #TYPE#. This template class must be able to access the following
Packit df99a1
    functions.
Packit df99a1
    \begin{itemize}
Packit df99a1
    \item a default constructor #TYPE::TYPE()#, 
Packit df99a1
    \item a copy constructor #TYPE::TYPE(const TYPE &)#,
Packit df99a1
    \item and optionally a destructor #TYPE::~TYPE()#.
Packit df99a1
    \end{itemize}
Packit df99a1
    This class only implement constructors.  See class \Ref{GArrayTemplate}
Packit df99a1
    for a description of all access methods. */
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
class GArray : public GArrayTemplate<TYPE>
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Constructs an empty array. The valid subscript range is initially
Packit df99a1
      empty. Member function #touch# and #resize# provide convenient ways
Packit df99a1
      to enlarge the subscript range. */
Packit df99a1
  GArray() 
Packit df99a1
    : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits() ) {}
Packit df99a1
  /** Constructs an array with subscripts in range 0 to #hibound#. 
Packit df99a1
      The subscript range can be subsequently modified with member functions
Packit df99a1
      #touch# and #resize#. */
Packit df99a1
  GArray(int hi) 
Packit df99a1
    : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits(), 0, hi ) {}
Packit df99a1
  /** Constructs an array with subscripts in range #lobound# to #hibound#.  
Packit df99a1
      The subscript range can be subsequently modified with member functions
Packit df99a1
      #touch# and #resize#. */
Packit df99a1
  GArray(int lo, int hi) 
Packit df99a1
    : GArrayTemplate<TYPE>(GCONT NormTraits<TYPE>::traits(), lo, hi ) {}
Packit df99a1
  // Copy operator
Packit df99a1
  GArray& operator=(const GArray &r)
Packit df99a1
    { GArrayBase::operator=(r); return *this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/** Dynamic array for smart pointers.  
Packit df99a1
    Template class #GPArray<TYPE># implements an array of elements of type
Packit df99a1
    #GP<TYPE># (see \Ref{GSmartPointer.h}).  Significantly smaller code sizes
Packit df99a1
    can be achieved by using this class instead of the more general
Packit df99a1
    #GArray<GP<TYPE>>#.  
Packit df99a1
    This class only implement constructors.  See class \Ref{GArrayTemplate}
Packit df99a1
    for a description of all access methods.  */
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
class GPArray : public GArrayTemplate<GP<TYPE> >
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  GPArray() 
Packit df99a1
    : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits() ) {}
Packit df99a1
  GPArray(int hi) 
Packit df99a1
    : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits(), 0, hi ) {}
Packit df99a1
  GPArray(int lo, int hi) 
Packit df99a1
    : GArrayTemplate<GP<TYPE> >(GCONT NormTraits<GPBase>::traits(), lo, hi ) {}
Packit df99a1
  // Copy operator
Packit df99a1
  GPArray& operator=(const GPArray &r)
Packit df99a1
    { GArrayBase::operator=(r); return *this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
/** Dynamic array for simple types.  
Packit df99a1
    Template class #GTArray<TYPE># implements an array of elements of {\em
Packit df99a1
    simple} type #TYPE#.  {\em Simple} means that objects of type #TYPE# can
Packit df99a1
    be created, copied, moved or destroyed without using specific constructors
Packit df99a1
    or destructor functions.  Class #GTArray<TYPE># will move or copy objects
Packit df99a1
    using simple bitwise copies.  Otherwise you must use class #GArray<TYPE>#. 
Packit df99a1
    This class only implement constructors.  See class \Ref{GArrayTemplate}
Packit df99a1
    for a description of all access methods.  */
Packit df99a1
template<class TYPE>
Packit df99a1
class GTArray : public GArrayTemplate<TYPE>
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  GTArray() 
Packit df99a1
    : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits() ) {}
Packit df99a1
  GTArray(int hi) 
Packit df99a1
    : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits(), 0, hi ) {}
Packit df99a1
  GTArray(int lo, int hi) 
Packit df99a1
    : GArrayTemplate<TYPE>(GCONT TrivTraits<sizeof(TYPE)>::traits(), lo, hi ) {}
Packit df99a1
  // Copy operator
Packit df99a1
  GTArray& operator=(const GTArray &r)
Packit df99a1
    { GArrayBase::operator=(r); return *this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
//@}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
// DOUBLY LINKED LISTS
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
Packit df99a1
Packit df99a1
/** @name Doubly Linked Lists
Packit df99a1
Packit df99a1
    The template classes \Ref{GList} and \Ref{GPList} implement a doubly
Packit df99a1
    linked list of objects of arbitrary types. Member functions are provided
Packit df99a1
    to search the list for an element, to insert or delete elements at
Packit df99a1
    specified positions.  Theses template class must be able to access
Packit df99a1
    \begin{itemize}
Packit df99a1
    \item a default constructor #TYPE::TYPE()#,
Packit df99a1
    \item a copy constructor #TYPE::TYPE(const TYPE &)#,
Packit df99a1
    \item optionally a destructor #TYPE::~TYPE()#,
Packit df99a1
    \item and optionally a comparison operator #TYPE::operator==(const TYPE &)#.
Packit df99a1
    \end{itemize} 
Packit df99a1
    @memo Doubly linked lists.  
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
Packit df99a1
/** Generic iterator class.
Packit df99a1
    This class represents a position in a list (see \Ref{GList}) or a map
Packit df99a1
    (see \Ref{GMap}).   As demonstrated by the following examples,
Packit df99a1
    this class should be used to iterate over the objects contained
Packit df99a1
    in a list or a map:
Packit df99a1
    \begin{verbatim}
Packit df99a1
    void print_list(GList<GString> a)
Packit df99a1
    {
Packit df99a1
      for (GPosition i = a ; i; ++i) 
Packit df99a1
        DjVuPrintMessage("%s\n", (const char*) a[i] );
Packit df99a1
    }
Packit df99a1
Packit df99a1
    void print_list_backwards(GList<GString> a)
Packit df99a1
    {
Packit df99a1
      for (GPosition i = a.lastpos() ; i; --i) 
Packit df99a1
        DjVuPrintMessage("%s\n", (const char*) a[i] );
Packit df99a1
    }
Packit df99a1
    \end{verbatim}
Packit df99a1
    GPosition objects should only be used with the list or map for which they
Packit df99a1
    have been created (using the member functions #firstpos# or #lastpos# of
Packit df99a1
    the container).  Furthermore, you should never use a GPosition object
Packit df99a1
    which designates a list element which has been removed from the list
Packit df99a1
    (using member function #del# or by other means.)
Packit df99a1
*/
Packit df99a1
Packit df99a1
class DJVUAPI GPosition : protected GCont
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Creates a null GPosition object. */
Packit df99a1
  GPosition() : ptr(0), cont(0) {}
Packit df99a1
  /** Creates a copy of a GPosition object. */
Packit df99a1
  GPosition(const GPosition &ref) : ptr(ref.ptr), cont(ref.cont) {}
Packit df99a1
  /** Tests whether this GPosition object is non null. */
Packit df99a1
  operator int() const 
Packit df99a1
    { return !!ptr; }
Packit df99a1
  /** Tests whether this GPosition object is null. */
Packit df99a1
  int operator !() const 
Packit df99a1
    { return !ptr; }
Packit df99a1
  /** Moves this GPosition object to the next object in the container. */
Packit df99a1
  GPosition& operator ++() 
Packit df99a1
    { if (ptr) ptr = ptr->next; return *this; }
Packit df99a1
  /** Moves this GPosition object to the previous object in the container. */
Packit df99a1
  GPosition& operator --() 
Packit df99a1
    { if (ptr) ptr = ptr->prev; return *this; }
Packit df99a1
  // Internal. Do not use.
Packit df99a1
  GPosition(Node *p, void *c) : ptr(p), cont(c) {}
Packit df99a1
#if GCONTAINER_BOUNDS_CHECK
Packit df99a1
  Node *check(void *c) 
Packit df99a1
    { if (!ptr || c!=cont) throw_invalid(c); return ptr; }
Packit df99a1
  const Node *check(void *c) const
Packit df99a1
    { if (!ptr || c!=cont) throw_invalid(c); return ptr; }
Packit df99a1
#else
Packit df99a1
  Node *check(void *c) 
Packit df99a1
    { return ptr; }
Packit df99a1
  const Node *check(void *c) const
Packit df99a1
    { return ptr; }
Packit df99a1
#endif
Packit df99a1
protected:
Packit df99a1
  Node *ptr;
Packit df99a1
  void *cont;
Packit df99a1
  friend class GListBase;
Packit df99a1
  friend class GSetBase;
Packit df99a1
  void throw_invalid(void *c) const no_return;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
class DJVUAPI GListBase : public GCont
Packit df99a1
{
Packit df99a1
protected:
Packit df99a1
  GListBase(const Traits& traits);
Packit df99a1
  GListBase(const GListBase &ref;;
Packit df99a1
  void append(Node *n);
Packit df99a1
  void prepend(Node *n);
Packit df99a1
  void insert_after(GPosition pos, Node *n);
Packit df99a1
  void insert_before(GPosition pos, Node *n);
Packit df99a1
  void insert_before(GPosition pos, GListBase &fromlist, GPosition &frompos);
Packit df99a1
  void del(GPosition &pos;;
Packit df99a1
protected:
Packit df99a1
  const Traits &traits;
Packit df99a1
  int nelem;
Packit df99a1
  Node head;
Packit df99a1
public:
Packit df99a1
  ~GListBase();
Packit df99a1
  GListBase & operator= (const GListBase & gl);
Packit df99a1
  GPosition firstpos() const { return GPosition(head.next, (void*)this); }
Packit df99a1
  GPosition lastpos() const { return GPosition(head.prev, (void*)this); }
Packit df99a1
  bool isempty() const { return nelem==0; };
Packit df99a1
  GPosition nth(unsigned int n) const;
Packit df99a1
  void empty();
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
template<class TI>
Packit df99a1
class GListImpl : public GListBase
Packit df99a1
{
Packit df99a1
  typedef GCONT ListNode<TI> LNode;
Packit df99a1
protected:
Packit df99a1
  GListImpl();
Packit df99a1
  static Node * newnode(const TI &elt;;
Packit df99a1
  int operator==(const GListImpl<TI> &l2) const;
Packit df99a1
  int search(const TI &elt, GPosition &pos) const;
Packit df99a1
};
Packit df99a1
Packit df99a1
template<class TI> 
Packit df99a1
GListImpl<TI>::GListImpl() 
Packit df99a1
  : GListBase( GCONT NormTraits<LNode>::traits() ) 
Packit df99a1
{ 
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TI> GCONT Node *
Packit df99a1
GListImpl<TI>::newnode(const TI &elt)
Packit df99a1
{
Packit df99a1
  LNode  *n = (LNode *) operator new (sizeof(LNode ));
Packit df99a1
#if GCONTAINER_ZERO_FILL
Packit df99a1
  memset(n, 0, sizeof(LNode ));
Packit df99a1
#endif
Packit df99a1
  new ((void*)&(n->val)) TI(elt);
Packit df99a1
  return (Node*) n;
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TI> int
Packit df99a1
GListImpl<TI>::operator==(const GListImpl<TI> &l2) const
Packit df99a1
{
Packit df99a1
  Node *p, *q;
Packit df99a1
  for (p=head.next, q=l2.head.next; p && q; p=p->next, q=q->next )
Packit df99a1
    if (((LNode*)p)->val != ((LNode*)q)->val)
Packit df99a1
      return 0;
Packit df99a1
  return p==0 && q==0;
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TI> int
Packit df99a1
GListImpl<TI>::search(const TI &elt, GPosition &pos) const
Packit df99a1
{
Packit df99a1
  Node *n = (pos ? pos.check((void*)this) : head.next);
Packit df99a1
  for (; n; n=n->next) 
Packit df99a1
    if ( ((LNode *)n)->val == elt ) 
Packit df99a1
      break;
Packit df99a1
  if (n) pos = GPosition(n, (void*)this);
Packit df99a1
  return (n != 0);
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
/** Common base class for all doubly linked lists.  
Packit df99a1
    Class \Ref{GListTemplate} implements all methods for manipulating lists 
Packit df99a1
    of of objects of type #TYPE#.  You should not however create instances of 
Packit df99a1
    this class. You should instead use class \Ref{GList} or \Ref{GPList}. */
Packit df99a1
Packit df99a1
template <class TYPE, class TI>
Packit df99a1
class GListTemplate : protected GListImpl<TI>
Packit df99a1
{
Packit df99a1
  typedef GCONT ListNode<TI> LNode;
Packit df99a1
public:
Packit df99a1
  // -- ACCESS
Packit df99a1
  /** Returns the number of elements in the list. */
Packit df99a1
  int size() const
Packit df99a1
    { return this->nelem; }
Packit df99a1
  /** Returns the first position in the list. See \Ref{GPosition}. */
Packit df99a1
  GPosition firstpos() const
Packit df99a1
    { return GListImpl<TI>::firstpos(); }
Packit df99a1
  /** Returns the last position in the list. See \Ref{GPosition}. */
Packit df99a1
  GPosition lastpos() const
Packit df99a1
    { return GListImpl<TI>::lastpos(); }
Packit df99a1
  /** Implicit notation for GList::firstpos(). */
Packit df99a1
  operator GPosition() const
Packit df99a1
    { return firstpos(); }    
Packit df99a1
  /** Returns a reference to the list element at position #pos#.  This
Packit df99a1
      reference can be used for both reading (as "#a[n]#") and modifying (as
Packit df99a1
      "#a[n]=v#") a list element.  Using an invalid position will cause a
Packit df99a1
      segmentation violation. See \Ref{GPosition} for efficient operations on
Packit df99a1
      positions. */
Packit df99a1
  TYPE& operator[](GPosition pos)
Packit df99a1
    { return (TYPE&) (((LNode *)pos.check((void*)this))->val); }
Packit df99a1
  /** Returns a constant reference to the list element at position #pos#.
Packit df99a1
      This reference only be used for reading a list element.  An exception
Packit df99a1
      \Ref{GException} is thrown if #pos# is not a valid position. This
Packit df99a1
      variant of #operator[]# is necessary when dealing with a #const
Packit df99a1
      GList<TYPE>#.  See \Ref{GPosition} for efficient operations on
Packit df99a1
      positions. */
Packit df99a1
  const TYPE& operator[](GPosition pos) const
Packit df99a1
    { return (const TYPE&) (((const LNode *)pos.check((void*)this))->val); }
Packit df99a1
  // -- TEST
Packit df99a1
  /** Tests whether a list is empty.  
Packit df99a1
      Returns a non zero value if the list contains no elements. */
Packit df99a1
  bool isempty() const 
Packit df99a1
    { return this->nelem==0; }
Packit df99a1
  /** Compares two lists. Returns a non zero value if and only if both lists
Packit df99a1
      contain the same elements (as tested by #TYPE::operator==(const TYPE&)#
Packit df99a1
      in the same order. */
Packit df99a1
  int operator==(const GListTemplate<TYPE,TI> &l2) const
Packit df99a1
    { return GListImpl<TI>::operator==(l2); }
Packit df99a1
  // -- SEARCHING
Packit df99a1
  /** Returns the position #pos# of the #n#-th list element.  An invalid
Packit df99a1
      position is returned if the list contains less than #n# elements. The
Packit df99a1
      operation works by sequentially scanning the list until reaching the
Packit df99a1
      #n#-th element. */
Packit df99a1
  GPosition nth(unsigned int n) const
Packit df99a1
    { return GListImpl<TI>::nth(n); }
Packit df99a1
  /*  Compatibility */
Packit df99a1
  int nth(unsigned int n, GPosition &pos) const
Packit df99a1
    { GPosition npos=nth(n); if (npos) pos=npos; return !!pos; }
Packit df99a1
  /** Tests whether the list contains a given element.  If the list contains
Packit df99a1
      #elt#, the position of the the first list element equal to #elt# as
Packit df99a1
      checked by #TYPE::operator==(const TYPE&)# is returned.  Otherwise an
Packit df99a1
      invalid position is returned. */
Packit df99a1
  GPosition contains(const TYPE &elt) const
Packit df99a1
    { GPosition pos; GListImpl<TI>::search((const TI&)elt, pos); return pos; }
Packit df99a1
  /** Searches the list for a given element. If position #pos# is a valid
Packit df99a1
      position for this list, the search starts at the specified position. If
Packit df99a1
      position #pos# is not a valid position, the search starts at the
Packit df99a1
      beginning of the list.  The list elements are sequentially compared with
Packit df99a1
      #elt# using #TYPE::operator==(const TYPE&)#.  As soon as a list element
Packit df99a1
      is equal to #elt#, function #search# sets argument #pos# with the
Packit df99a1
      position of this list element and returns 1.  If however the search
Packit df99a1
      reaches the end of the list, function #search# returns 0 and leaves
Packit df99a1
      #pos# unchanged. */
Packit df99a1
  int search(const TYPE &elt, GPosition &pos) const
Packit df99a1
    { return GListImpl<TI>::search((const TI&)elt, pos); }
Packit df99a1
  // -- ALTERATION
Packit df99a1
  /** Erases the list contents.  All list elements are destroyed and
Packit df99a1
      unlinked. The list is left with zero elements. */
Packit df99a1
  void empty()
Packit df99a1
    { GListImpl<TI>::empty(); }
Packit df99a1
  /** Inserts an element after the last element of the list. 
Packit df99a1
      The new element is initialized with a copy of argument #elt#. */
Packit df99a1
  void append(const TYPE &elt)
Packit df99a1
    { GListImpl<TI>::append(this->newnode((const TI&)elt)); }
Packit df99a1
  /** Inserts an element before the first element of the list. 
Packit df99a1
      The new element is initialized with a copy of argument #elt#. */
Packit df99a1
  void prepend(const TYPE &elt)
Packit df99a1
    { GListImpl<TI>::prepend(this->newnode((const TI&)elt)); }
Packit df99a1
  /** Inserts a new element after the list element at position #pos#.  When
Packit df99a1
      position #pos# is null the element is inserted at the beginning of the
Packit df99a1
      list.  The new element is initialized with a copy of #elt#. */
Packit df99a1
  void insert_after(GPosition pos, const TYPE &elt)
Packit df99a1
    { GListImpl<TI>::insert_after(pos, this->newnode((const TI&)elt)); }
Packit df99a1
  /** Inserts a new element before the list element at position #pos#. When
Packit df99a1
      position #pos# is null the element is inserted at the end of the
Packit df99a1
      list. The new element is initialized with a copy of #elt#. */
Packit df99a1
  void insert_before(GPosition pos, const TYPE &elt)
Packit df99a1
    { GListImpl<TI>::insert_before(pos, this->newnode((const TI&)elt)); }
Packit df99a1
  /** Inserts an element of another list into this list.  This function
Packit df99a1
      removes the element at position #frompos# in list #frompos#, inserts it
Packit df99a1
      in the current list before the element at position #pos#, and advances
Packit df99a1
      #frompos# to the next element in list #fromlist#. When position #pos# is
Packit df99a1
      null the element is inserted at the end of the list. */
Packit df99a1
  void insert_before(GPosition pos, GListTemplate<TYPE,TI> &fromlist, GPosition &frompos)
Packit df99a1
    { GListImpl<TI>::insert_before(pos, fromlist, frompos); }
Packit df99a1
  /** Destroys the list element at position #pos#.  This function does 
Packit df99a1
      nothing unless position #pos# is a valid position. */
Packit df99a1
  void del(GPosition &pos)
Packit df99a1
    { GListImpl<TI>::del(pos); }
Packit df99a1
  /* Old iterators. Do not use. */
Packit df99a1
#if GCONTAINER_OLD_ITERATORS
Packit df99a1
  void first(GPosition &pos) const { pos = firstpos(); }
Packit df99a1
  void last(GPosition &pos) const { pos = lastpos(); }
Packit df99a1
  const TYPE *next(GPosition &pos) const 
Packit df99a1
    { if (!pos) return 0; const TYPE *x=&((*this)[pos]); ++pos; return x; }
Packit df99a1
  const TYPE *prev(GPosition &pos) const 
Packit df99a1
    { if (!pos) return 0; const TYPE *x=&((*this)[pos]); --pos; return x; }
Packit df99a1
  TYPE *next(GPosition &pos)
Packit df99a1
    { if (!pos) return 0; TYPE *x=&((*this)[pos]); ++pos; return x; }
Packit df99a1
  TYPE *prev(GPosition &pos)
Packit df99a1
    { if (!pos) return 0; TYPE *x=&((*this)[pos]); --pos; return x; }
Packit df99a1
#endif
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/** Doubly linked lists.  Template class #GList<TYPE># implements a doubly
Packit df99a1
    linked list of elements of type #TYPE#.  This class only implement
Packit df99a1
    constructors.  See class \Ref{GListTemplate} and \Ref{GPosition} for a
Packit df99a1
    description of all access methods. */
Packit df99a1
Packit df99a1
template <class TYPE>
Packit df99a1
class GList : public GListTemplate<TYPE,TYPE>
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Null Constructor. Constructs a list with zero elements. */
Packit df99a1
  GList() : GListTemplate<TYPE,TYPE>() {}
Packit df99a1
  GList& operator=(const GList &r) 
Packit df99a1
    { GListBase::operator=(r); return *this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/** Doubly linked lists for smart pointers. 
Packit df99a1
    Template class #GList<TYPE># implements a doubly linked list of elements
Packit df99a1
    of type #GP<TYPE># (see \Ref{GSmartPointer.h}).  Significantly smaller
Packit df99a1
    code sizes can be achieved by using this class instead of the more general
Packit df99a1
    #GArray<GP<TYPE>>#.  
Packit df99a1
    This class only implement constructors.  See class \Ref{GListTemplate} and
Packit df99a1
    \Ref{GPosition} for a description of all access methods. */
Packit df99a1
Packit df99a1
template <class TYPE>
Packit df99a1
class GPList : public GListTemplate<GP<TYPE>,GPBase>
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Null Constructor. Constructs a list with zero elements. */
Packit df99a1
  GPList() : GListTemplate<GP<TYPE>,GPBase>() {}
Packit df99a1
  GPList& operator=(const GPList &r) 
Packit df99a1
    { GListBase::operator=(r); return *this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
//@}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
// ASSOCIATIVE MAPS
Packit df99a1
// ------------------------------------------------------------
Packit df99a1
Packit df99a1
/** @name Associative Maps
Packit df99a1
Packit df99a1
    These template classes implements a associative maps.  The associative map
Packit df99a1
    contains an arbitrary number of entries. Each entry is a pair containing
Packit df99a1
    one element of type #KTYPE# (named the "key") and one element of type
Packit df99a1
    #VTYPE# (named the "value").  All entries have distinct keys. 
Packit df99a1
    These template class must be able to access the following functions:
Packit df99a1
    \begin{itemize}
Packit df99a1
    \item a #VTYPE# default constructor #VTYPE::VTYPE()#, 
Packit df99a1
    \item a #VTYPE# copy constructor #VTYPE::VTYPE(const VTYPE &)#, 
Packit df99a1
    \item optionally a #VTYPE# destructor #VTYPE::~VTYPE()#,
Packit df99a1
    \item a #KTYPE# default constructor #KTYPE::KTYPE()#, 
Packit df99a1
    \item a #KTYPE# copy constructor #KTYPE::KTYPE(const KTYPE &)#, 
Packit df99a1
    \item optionally a #KTYPE# destructor #KTYPE::~KTYPE()#,
Packit df99a1
    \item a #KTYPE# comparison operator #KTYPE::operator==(const KTYPE &)#,
Packit df99a1
    \item and a #KTYPE# hashing function #hash(const KTYPE&)#.
Packit df99a1
    \end{itemize} 
Packit df99a1
    The hashing function must return an #unsigned int# number. Multiple
Packit df99a1
    invocations of the hashing function with equal arguments (in the sense of
Packit df99a1
    #KTYPE::operator==#) must always return the same number.  
Packit df99a1
    Position objects (see \Ref{GPosition}) may be used to iterate over the
Packit df99a1
    entries contained by an associative map. 
Packit df99a1
    @memo Associative maps.
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
Packit df99a1
class DJVUAPI GSetBase : public GCont
Packit df99a1
{
Packit df99a1
protected:
Packit df99a1
  GSetBase(const Traits &traits);
Packit df99a1
  GSetBase(const GSetBase &ref;;
Packit df99a1
  static GCONT HNode *newnode(const void *key);
Packit df99a1
  HNode *hashnode(unsigned int hashcode) const;
Packit df99a1
  HNode *installnode(HNode *n);
Packit df99a1
  void   deletenode(HNode *n);
Packit df99a1
protected:
Packit df99a1
  const Traits &traits;
Packit df99a1
  int nelems;
Packit df99a1
  int nbuckets;
Packit df99a1
  HNode **table;
Packit df99a1
  GPBuffer<HNode *> gtable;
Packit df99a1
  HNode *first;
Packit df99a1
private:
Packit df99a1
  void insertnode(HNode *n);
Packit df99a1
  void rehash(int newbuckets);
Packit df99a1
public:
Packit df99a1
  ~GSetBase();
Packit df99a1
  GSetBase& operator=(const GSetBase &ref;;
Packit df99a1
  GPosition firstpos() const;
Packit df99a1
  void del(GPosition &pos;; 
Packit df99a1
  void empty();
Packit df99a1
};
Packit df99a1
Packit df99a1
template <class K>
Packit df99a1
class GSetImpl : public GSetBase
Packit df99a1
{
Packit df99a1
  typedef GCONT SetNode<K> SNode;
Packit df99a1
protected:
Packit df99a1
  GSetImpl();
Packit df99a1
  GSetImpl(const Traits &traits);
Packit df99a1
  HNode *get(const K &key) const;
Packit df99a1
  HNode *get_or_throw(const K &key) const;
Packit df99a1
  HNode *get_or_create(const K &key);
Packit df99a1
public:
Packit df99a1
  GPosition contains(const K &key) const 
Packit df99a1
    { return GPosition( get(key), (void*)this); }
Packit df99a1
  void del(const K &key) 
Packit df99a1
    { deletenode(get(key)); }
Packit df99a1
};
Packit df99a1
Packit df99a1
template<class K>
Packit df99a1
GSetImpl<K>::GSetImpl()
Packit df99a1
  : GSetBase( GCONT NormTraits<GCONT SetNode<K> >::traits() )
Packit df99a1
{ 
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class K>
Packit df99a1
GSetImpl<K>::GSetImpl(const Traits &traits)
Packit df99a1
  : GSetBase(traits) 
Packit df99a1
{ 
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class K> GCONT HNode *
Packit df99a1
GSetImpl<K>::get(const K &key) const
Packit df99a1
{ 
Packit df99a1
  unsigned int hashcode = hash(key);
Packit df99a1
  for (SNode *s=(SNode*)hashnode(hashcode); s; s=(SNode*)(s->hprev))
Packit df99a1
    if (s->hashcode == hashcode && s->key == key) return s;
Packit df99a1
  return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
#if GCONTAINER_BOUNDS_CHECK
Packit df99a1
template<class K> GCONT HNode *
Packit df99a1
GSetImpl<K>::get_or_throw(const K &key) const
Packit df99a1
{ 
Packit df99a1
  HNode *m = get(key);
Packit df99a1
  if (!m)
Packit df99a1
  {
Packit df99a1
    G_THROW( ERR_MSG("GContainer.cannot_add") );
Packit df99a1
  }
Packit df99a1
  return m;
Packit df99a1
}
Packit df99a1
#else
Packit df99a1
template<class K> inline GCONT HNode *
Packit df99a1
GSetImpl<K>::get_or_throw(const K &key) const
Packit df99a1
{ 
Packit df99a1
  return get(key);
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
Packit df99a1
template<class K> GCONT HNode *
Packit df99a1
GSetImpl<K>::get_or_create(const K &key)
Packit df99a1
{
Packit df99a1
  HNode *m = get(key);
Packit df99a1
  if (m) return m;
Packit df99a1
  SNode *n = (SNode*) operator new (sizeof(SNode));
Packit df99a1
#if GCONTAINER_ZERO_FILL
Packit df99a1
  memset(n, 0, sizeof(SNode));
Packit df99a1
#endif
Packit df99a1
  new ((void*)&(n->key)) K ( key );
Packit df99a1
  n->hashcode = hash((const K&)(n->key));
Packit df99a1
  installnode(n);
Packit df99a1
  return n;
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class K, class TI>
Packit df99a1
class GMapImpl : public GSetImpl<K>
Packit df99a1
{
Packit df99a1
  typedef GCONT MapNode<K,TI> MNode;
Packit df99a1
protected:
Packit df99a1
  GMapImpl();
Packit df99a1
  GMapImpl(const GCONT Traits &traits);
Packit df99a1
  GCONT HNode* get_or_create(const K &key);
Packit df99a1
};
Packit df99a1
Packit df99a1
template<class K, class TI>
Packit df99a1
GMapImpl<K,TI>::GMapImpl()
Packit df99a1
  : GSetImpl<K> ( GCONT NormTraits<GCONT MapNode<K,TI> >::traits() ) 
Packit df99a1
{ 
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class K, class TI>
Packit df99a1
GMapImpl<K,TI>::GMapImpl(const GCONT Traits &traits)
Packit df99a1
  : GSetImpl<K>(traits) 
Packit df99a1
{ 
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class K, class TI> GCONT HNode *
Packit df99a1
GMapImpl<K,TI>::get_or_create(const K &key)
Packit df99a1
{
Packit df99a1
  GCONT HNode *m = this->get(key);
Packit df99a1
  if (m) return m;
Packit df99a1
  MNode *n = (MNode*) operator new (sizeof(MNode));
Packit df99a1
#if GCONTAINER_ZERO_FILL
Packit df99a1
  memset(n, 0, sizeof(MNode));
Packit df99a1
#endif
Packit df99a1
  new ((void*)&(n->key)) K  (key);
Packit df99a1
  new ((void*)&(n->val)) TI ();
Packit df99a1
  n->hashcode = hash((const K&)(n->key));
Packit df99a1
  this->installnode(n);
Packit df99a1
  return n;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** Common base class for all associative maps.
Packit df99a1
    Class \Ref{GArrayTemplate} implements all methods for manipulating 
Packit df99a1
    associative maps with key type #KTYPE# and value type #VTYPE#. 
Packit df99a1
    You should not however create instances of this class.
Packit df99a1
    You should instead use class \Ref{GMap} or \Ref{GPMap}. */
Packit df99a1
Packit df99a1
template <class KTYPE, class VTYPE, class TI>
Packit df99a1
class GMapTemplate : protected GMapImpl<KTYPE,TI>
Packit df99a1
{
Packit df99a1
  typedef GCONT MapNode<KTYPE,TI> MNode;
Packit df99a1
public:
Packit df99a1
  /** Returns the number of elements in the map. */
Packit df99a1
  int size() const
Packit df99a1
    { return this->nelems; }
Packit df99a1
  /** Returns the first position in the map. */
Packit df99a1
  GPosition firstpos() const
Packit df99a1
    { return GMapImpl<KTYPE,TI>::firstpos(); }
Packit df99a1
  /** Implicit notation for GMap::firstpos(). */
Packit df99a1
  operator GPosition() const
Packit df99a1
    { return firstpos(); }    
Packit df99a1
  /** Tests whether the associative map is empty.  
Packit df99a1
      Returns a non zero value if and only if the map contains zero entries. */
Packit df99a1
  bool isempty() const
Packit df99a1
    { return this->nelems==0; }
Packit df99a1
  /** Searches an entry for key #key#.  If the map contains an entry whose key
Packit df99a1
      is equal to #key# according to #KTYPE::operator==(const KTYPE&)#, this
Packit df99a1
      function returns its position.  Otherwise it returns an invalid
Packit df99a1
      position. */
Packit df99a1
  GPosition contains(const KTYPE &key) const
Packit df99a1
    { return GMapImpl<KTYPE,TI>::contains(key); }
Packit df99a1
  /*  Compatibility */
Packit df99a1
  GPosition contains(const KTYPE &key, GPosition &pos) const
Packit df99a1
    { return pos = GMapImpl<KTYPE,TI>::contains(key); }
Packit df99a1
  // -- ALTERATION
Packit df99a1
  /** Erases the associative map contents.  All entries are destroyed and
Packit df99a1
      removed. The map is left with zero entries. */
Packit df99a1
  void empty()
Packit df99a1
    { GMapImpl<KTYPE,TI>::empty(); }
Packit df99a1
  /** Returns a constant reference to the key of the map entry at position
Packit df99a1
      #pos#.  An exception \Ref{GException} is thrown if position #pos# is not
Packit df99a1
      valid.  There is no direct way to change the key of a map entry. */
Packit df99a1
  const KTYPE &key(const GPosition &pos) const
Packit df99a1
    { return (const KTYPE&)(((MNode*)(pos.check((void*)this)))->key); }
Packit df99a1
  /** Returns a reference to the value of the map entry at position #pos#.
Packit df99a1
      This reference can be used for both reading (as "#a[n]#") and modifying
Packit df99a1
      (as "#a[n]=v#").  An exception \Ref{GException} is thrown if position
Packit df99a1
      #pos# is not valid. */
Packit df99a1
  VTYPE& operator[](const GPosition &pos)
Packit df99a1
    { return (VTYPE&)(((MNode*)(pos.check((void*)this)))->val); }
Packit df99a1
  /** Returns a constant reference to the value of the map entry at position
Packit df99a1
      #pos#.  This reference can only be used for reading (as "#a[n]#") the
Packit df99a1
      entry value.  An exception \Ref{GException} is thrown if position #pos#
Packit df99a1
      is not valid. */
Packit df99a1
  const VTYPE& operator[](const GPosition &pos) const
Packit df99a1
    { return (const VTYPE&)(((MNode*)(pos.check((void*)this)))->val); }
Packit df99a1
  /** Returns a constant reference to the value of the map entry for key
Packit df99a1
      #key#.  This reference can only be used for reading (as "#a[n]#") the
Packit df99a1
      entry value.  An exception \Ref{GException} is thrown if no entry
Packit df99a1
      contains key #key#. This variant of #operator[]# is necessary when
Packit df99a1
      dealing with a #const GMAP<KTYPE,VTYPE>#. */
Packit df99a1
  const VTYPE& operator[](const KTYPE &key) const
Packit df99a1
    { return (const VTYPE&)(((const MNode*)(this->get_or_throw(key)))->val); }
Packit df99a1
  /** Returns a reference to the value of the map entry for key #key#.  This
Packit df99a1
      reference can be used for both reading (as "#a[n]#") and modifying (as
Packit df99a1
      "#a[n]=v#"). If there is no entry for key #key#, a new entry is created
Packit df99a1
      for that key with the null constructor #VTYPE::VTYPE()#. */
Packit df99a1
  VTYPE& operator[](const KTYPE &key)
Packit df99a1
    { return (VTYPE&)(((MNode*)(this->get_or_create(key)))->val); }
Packit df99a1
  /** Destroys the map entry for position #pos#.  
Packit df99a1
      Nothing is done if position #pos# is not a valid position. */
Packit df99a1
  void del(GPosition &pos)
Packit df99a1
    { GSetBase::del(pos); }
Packit df99a1
  /** Destroys the map entry for key #key#.  
Packit df99a1
      Nothing is done if there is no entry for key #key#. */
Packit df99a1
  void del(const KTYPE &key)
Packit df99a1
    { GMapImpl<KTYPE,TI>::del(key); }
Packit df99a1
  /* Old iterators. Do not use. */
Packit df99a1
#if GCONTAINER_OLD_ITERATORS
Packit df99a1
  void first(GPosition &pos) const { pos = firstpos(); }
Packit df99a1
  const VTYPE *next(GPosition &pos) const 
Packit df99a1
    { if (!pos) return 0; const VTYPE *x=&((*this)[pos]); ++pos; return x; }
Packit df99a1
  VTYPE *next(GPosition &pos)
Packit df99a1
    { if (!pos) return 0; VTYPE *x=&((*this)[pos]); ++pos; return x; }
Packit df99a1
#endif
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** Associative maps.  
Packit df99a1
    Template class #GMap<KTYPE,VTYPE># implements an associative map.
Packit df99a1
    The map contains an arbitrary number of entries. Each entry is a
Packit df99a1
    pair containing one element of type #KTYPE# (named the "key") and one
Packit df99a1
    element of type #VTYPE# (named the "value").  
Packit df99a1
    The entry associated to a particular value of the key can retrieved
Packit df99a1
    very efficiently.
Packit df99a1
    This class only implement constructors.  See class \Ref{GMapTemplate} and
Packit df99a1
    \Ref{GPosition} for a description of all access methods.*/
Packit df99a1
Packit df99a1
template <class KTYPE, class VTYPE>
Packit df99a1
class GMap : public GMapTemplate<KTYPE,VTYPE,VTYPE>
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  // -- ACCESS
Packit df99a1
  GMap() : GMapTemplate<KTYPE,VTYPE,VTYPE>() {}
Packit df99a1
  GMap& operator=(const GMap &r) 
Packit df99a1
    { GSetBase::operator=(r); return *this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
/** Associative maps for smart-pointers.  
Packit df99a1
    Template class #GMap<KTYPE,VTYPE># implements an associative map for key
Packit df99a1
    type #KTYPE# and value type #GP<VTYPE># (see \Ref{GSmartPointer.h}).  The
Packit df99a1
    map contains an arbitrary number of entries. Each entry is a pair
Packit df99a1
    containing one element of type #KTYPE# (named the "key") and one aelement
Packit df99a1
    of type #VTYPE# (named the "value").  The entry associated to a particular
Packit df99a1
    value of the key can retrieved very efficiently.
Packit df99a1
    Significantly smaller code sizes can be achieved by using this class
Packit df99a1
    instead of the more general #GMap<KTYPE,GP<VTYPE>># (see \Ref{GMap}).
Packit df99a1
    This class only implement constructors.  See class \Ref{GMapTemplate} and
Packit df99a1
    \Ref{GPosition} for a description of all access methods.*/
Packit df99a1
Packit df99a1
template <class KTYPE, class VTYPE>
Packit df99a1
class GPMap : public GMapTemplate<KTYPE,GP<VTYPE>,GPBase>
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  GPMap() : GMapTemplate<KTYPE,GP<VTYPE>,GPBase>() {}
Packit df99a1
  GPMap& operator=(const GPMap &r) 
Packit df99a1
    { GSetBase::operator=(r); return *this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
//@}
Packit df99a1
//@}
Packit df99a1
//@}
Packit df99a1
Packit df99a1
// ------------ THE END
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1