Blame libdjvu/Arrays.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 _ARRAYS_H_
Packit df99a1
#define _ARRAYS_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
#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
Packit df99a1
/** @name Arrays.h
Packit df99a1
Packit df99a1
    Files #"Arrays.h"# and #"Arrays.cpp"# implement three array template classes.
Packit df99a1
    Class \Ref{TArray} implements an array of objects of trivial types
Packit df99a1
    such as #char#, #int#, #float#, etc. It is faster than general implementation
Packit df99a1
    for any type done in \Ref{DArray} because it does not cope with
Packit df99a1
    element's constructors, destructors and copy operators. Although
Packit df99a1
    implemented as a template, which makes it possible to incorrectly use
Packit df99a1
    \Ref{TArray} with non-trivial classes, it should not be done.
Packit df99a1
Packit df99a1
    A lot of things is shared by these three arrays. That is why there are
Packit df99a1
    more base classes:
Packit df99a1
    \begin{itemize}
Packit df99a1
       \item \Ref{ArrayBase} defines functions independent of the elements type
Packit df99a1
       \item \Ref{ArrayBaseT} template class defining functions shared by
Packit df99a1
             \Ref{DArray} and \Ref{TArray}
Packit df99a1
    \end{itemize}
Packit df99a1
Packit df99a1
    The main difference between \Ref{GArray} (now obsolete) and these ones
Packit df99a1
    is the copy-on-demand strategy, which allows you to copy array objects
Packit df99a1
    without copying the real data. It's the same thing, which has been
Packit df99a1
    implemented in \Ref{GString} long ago: as long as you don't try to modify
Packit df99a1
    the underlying data, it may be shared between several copies of array
Packit df99a1
    objects. As soon as you attempt to make any changes, a private copy
Packit df99a1
    is created automatically and transparently for you - the procedure, that
Packit df99a1
    we call "copy-on-demand".
Packit df99a1
Packit df99a1
    Also, please note that now there is no separate class, which does fast
Packit df99a1
    sorting. Both \Ref{TArray} (dynamic array for trivial types) and
Packit df99a1
    \Ref{DArray} (dynamic array for arbitrary types) can sort their elements.
Packit df99a1
    
Packit df99a1
    {\bf Historical comments} --- Leon chose to implement his own arrays because
Packit df99a1
    the STL classes were not universally available and the compilers were
Packit df99a1
    rarely able to deal with such a template galore. Later it became clear
Packit df99a1
    that there is no really good reason why arrays should be derived from
Packit df99a1
    containers. It was also suggested to create separate arrays implementation
Packit df99a1
    for simple classes and do the copy-on-demand strategy, which would allow
Packit df99a1
    to assign array objects without immediate copying of their elements. 
Packit df99a1
Packit df99a1
    At this point \Ref{DArray} and \Ref{TArray} should only be used when
Packit df99a1
    it is critical to have the copy-on-demand feature.  The \Ref{GArray}
Packit df99a1
    implementation is a lot more efficient.
Packit df99a1
    
Packit df99a1
    @memo Template array classes.
Packit df99a1
    @author 
Packit df99a1
    Andrei Erofeev <eaf@geocities.com> -- Copy-on-demand implementation.
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
Packit df99a1
// Auxiliary classes: Will be used in place of GPBase and GPEnabled objects
Packit df99a1
class _ArrayRep
Packit df99a1
{
Packit df99a1
   friend class	_ArrayBase;
Packit df99a1
public:
Packit df99a1
   _ArrayRep(void) : count(0) {}
Packit df99a1
   _ArrayRep(const _ArrayRep &) {}
Packit df99a1
   virtual ~_ArrayRep(void) {}
Packit df99a1
Packit df99a1
   _ArrayRep & operator=(const _ArrayRep &) { return *this; }
Packit df99a1
Packit df99a1
   int		get_count(void) const { return count; }
Packit df99a1
private:
Packit df99a1
   int		count;
Packit df99a1
Packit df99a1
   void		ref(void) { count++; }
Packit df99a1
   void		unref(void) { if (--count==0) delete this; }
Packit df99a1
};
Packit df99a1
Packit df99a1
class _ArrayBase
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   _ArrayBase(void) : rep(0) {}
Packit df99a1
   _ArrayBase(const _ArrayBase & ab) : rep(0)
Packit df99a1
   {
Packit df99a1
      if (ab.rep) ab.rep->ref();
Packit df99a1
      rep=ab.rep;
Packit df99a1
   }
Packit df99a1
   _ArrayBase(_ArrayRep * ar) : rep(0)
Packit df99a1
   {
Packit df99a1
      if (ar) ar->ref();
Packit df99a1
      rep=ar;
Packit df99a1
   }
Packit df99a1
   virtual ~_ArrayBase(void)
Packit df99a1
   {
Packit df99a1
      if (rep) { rep->unref(); rep=0; }
Packit df99a1
   }
Packit df99a1
Packit df99a1
   _ArrayRep *	get(void) const { return rep; }
Packit df99a1
   _ArrayBase & assign(_ArrayRep * ar)
Packit df99a1
   {
Packit df99a1
      if (ar) ar->ref();
Packit df99a1
      if (rep) rep->unref();
Packit df99a1
      rep=ar;
Packit df99a1
      return *this;
Packit df99a1
   }
Packit df99a1
   _ArrayBase &	operator=(const _ArrayBase & ab) { return assign(ab.rep); }
Packit df99a1
   bool		operator==(const _ArrayBase & ab) { return rep==ab.rep; }
Packit df99a1
private:
Packit df99a1
   _ArrayRep	* rep;
Packit df99a1
};
Packit df99a1
Packit df99a1
// Internal "Array repository" holding the pointer to the actual data,
Packit df99a1
// data bounds, etc. It copes with data elements with the help of five
Packit df99a1
// static functions which pointers are supposed to be passed to the
Packit df99a1
// constructor.
Packit df99a1
class DJVUAPI ArrayRep : public _ArrayRep
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   ArrayRep(int elsize,
Packit df99a1
	    void (* xdestroy)(void *, int, int),
Packit df99a1
	    void (* xinit1)(void *, int, int),
Packit df99a1
	    void (* xinit2)(void *, int, int, const void *, int, int),
Packit df99a1
	    void (* xcopy)(void *, int, int, const void *, int, int),
Packit df99a1
	    void (* xinsert)(void *, int, int, const void *, int));
Packit df99a1
   ArrayRep(int elsize,
Packit df99a1
	    void (* xdestroy)(void *, int, int),
Packit df99a1
	    void (* xinit1)(void *, int, int),
Packit df99a1
	    void (* xinit2)(void *, int, int, const void *, int, int),
Packit df99a1
	    void (* xcopy)(void *, int, int, const void *, int, int),
Packit df99a1
	    void (* xinsert)(void *, int, int, const void *, int),
Packit df99a1
	    int hibound);
Packit df99a1
   ArrayRep(int elsize,
Packit df99a1
	    void (* xdestroy)(void *, int, int),
Packit df99a1
	    void (* xinit1)(void *, int, int),
Packit df99a1
	    void (* xinit2)(void *, int, int, const void *, int, int),
Packit df99a1
	    void (* xcopy)(void *, int, int, const void *, int, int),
Packit df99a1
	    void (* xinsert)(void *, int, int, const void *, int),
Packit df99a1
	    int lobound, int hibound);
Packit df99a1
   ArrayRep(const ArrayRep & rep);
Packit df99a1
   
Packit df99a1
   virtual ~ArrayRep();
Packit df99a1
   
Packit df99a1
      // Following is the standard interface to DArray. DArray will call these
Packit df99a1
      // functions to access data.
Packit df99a1
   int		size() const;
Packit df99a1
   int		lbound() const;
Packit df99a1
   int		hbound() const;
Packit df99a1
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, unsigned int howmany=1);
Packit df99a1
Packit df99a1
      // ins() is an exception. It does it job only partially.
Packit df99a1
      // The derived class is supposed to finish insertion.
Packit df99a1
   void		ins(int n, const void * what, unsigned int howmany);
Packit df99a1
Packit df99a1
   ArrayRep &	operator=(const ArrayRep & rep);
Packit df99a1
Packit df99a1
      // All data is public because DArray... classes will need access to it
Packit df99a1
   void		*data;
Packit df99a1
   int		minlo;
Packit df99a1
   int		maxhi;
Packit df99a1
   int		lobound;
Packit df99a1
   int		hibound;
Packit df99a1
   int		elsize;
Packit df99a1
private:
Packit df99a1
      // These functions can't be virtual as they're called from
Packit df99a1
      // constructors and destructors :((
Packit df99a1
      // destroy(): should destroy elements in data[] array from 'lo' to 'hi'
Packit df99a1
   void		(* destroy)(void * data, int lo, int hi);
Packit df99a1
      // init1(): should initialize elements in data[] from 'lo' to 'hi'
Packit df99a1
      // using default constructors
Packit df99a1
   void		(* init1)(void * data, int lo, int hi);
Packit df99a1
      // init2(): should initialize elements in data[] from 'lo' to 'hi'
Packit df99a1
      // using corresponding elements from src[] (copy constructor)
Packit df99a1
   void		(* init2)(void * data, int lo, int hi,
Packit df99a1
			  const void * src, int src_lo, int src_hi);
Packit df99a1
      // copy(): should copy elements from src[] to dst[] (copy operator)
Packit df99a1
   void		(* copy)(void * dst, int dst_lo, int dst_hi,
Packit df99a1
			 const void * src, int src_lo, int src_hi);
Packit df99a1
      // insert(): should insert '*what' at position 'where' 'howmany' times
Packit df99a1
      // into array data[] having 'els' initialized elements
Packit df99a1
   void		(* insert)(void * data, int els, int where, const void * what,
Packit df99a1
			   int howmany);
Packit df99a1
};
Packit df99a1
Packit df99a1
inline int
Packit df99a1
ArrayRep::size() const
Packit df99a1
{
Packit df99a1
   return hibound - lobound + 1;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
ArrayRep::lbound() const
Packit df99a1
{
Packit df99a1
  return lobound;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
ArrayRep::hbound() const
Packit df99a1
{
Packit df99a1
  return hibound;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayRep::empty()
Packit df99a1
{
Packit df99a1
  resize(0, -1);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayRep::touch(int n)
Packit df99a1
{
Packit df99a1
   if (hibound < lobound)
Packit df99a1
   {
Packit df99a1
      resize(n,n);
Packit df99a1
   } else
Packit df99a1
   {
Packit df99a1
      int nlo = lobound;
Packit df99a1
      int nhi = hibound;
Packit df99a1
      if (n < nlo) nlo = n;
Packit df99a1
      if (n > nhi) nhi = n;
Packit df99a1
      resize(nlo, nhi);
Packit df99a1
   }
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Dynamic array base class.
Packit df99a1
    This is an auxiliary base class for \Ref{DArray} and \Ref{TArray}
Packit df99a1
    implementing some shared functions independent of the type of array
Packit df99a1
    elements. It's not supposed to be constructed by hands. Use \Ref{DArray}
Packit df99a1
    and \Ref{TArray} instead.
Packit df99a1
    */
Packit df99a1
    
Packit df99a1
class DJVUAPI ArrayBase : protected _ArrayBase
Packit df99a1
{
Packit df99a1
protected:
Packit df99a1
   void		check(void);
Packit df99a1
   void		detach(void);
Packit df99a1
Packit df99a1
   ArrayBase(void) {};
Packit df99a1
public:
Packit df99a1
   /// Returns the number of elements in the array
Packit df99a1
   int		size() const;
Packit df99a1
   /** Returns the lower bound of the valid subscript range. */
Packit df99a1
   int		lbound() const;
Packit df99a1
   /** Returns the upper bound of the valid subscript range. */
Packit df99a1
   int		hbound() const;
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
   /** Extends the subscript range so that is 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
       DArray<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
   */
Packit df99a1
   void touch(int 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
       @param hibound upper bound of the new subscript range. */      
Packit df99a1
   void resize(int 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
       @param lobound lower bound of the new subscript range.
Packit df99a1
       @param hibound upper bound of the new subscript range. */
Packit df99a1
   void resize(int lobound, int 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
   /** 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
       @param n subscript of the first element to delete.
Packit df99a1
       @param howmany number of elements to delete. */
Packit df99a1
   void del(int n, unsigned int howmany=1);
Packit df99a1
Packit df99a1
   virtual ~ArrayBase(void) {};
Packit df99a1
};
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::detach(void)
Packit df99a1
{
Packit df99a1
   ArrayRep * new_rep=new ArrayRep(*(ArrayRep *) get());
Packit df99a1
   assign(new_rep);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::check(void)
Packit df99a1
{
Packit df99a1
   if (get()->get_count()>1) detach();
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
ArrayBase::size() const
Packit df99a1
{
Packit df99a1
   return ((const ArrayRep *) get())->size();
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
ArrayBase::lbound() const
Packit df99a1
{
Packit df99a1
   return ((const ArrayRep *) get())->lobound;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
ArrayBase::hbound() const
Packit df99a1
{
Packit df99a1
   return ((const ArrayRep *) get())->hibound;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::empty()
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
   ((ArrayRep *) get())->empty();
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::resize(int lo, int hi)
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
   ((ArrayRep *) get())->resize(lo, hi);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::resize(int hi)
Packit df99a1
{
Packit df99a1
   resize(0, hi);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::touch(int n)
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
   ((ArrayRep *) get())->touch(n);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::shift(int disp)
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
   ((ArrayRep *) get())->shift(disp);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
ArrayBase::del(int n, unsigned int howmany)
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
   
Packit df99a1
   ((ArrayRep *) get())->del(n, howmany);
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Dynamic array template base class.
Packit df99a1
    This is an auxiliary template base class for \Ref{DArray} and \Ref{TArray}
Packit df99a1
    implementing some shared functions which {\em depend} on the type of
Packit df99a1
    the array elements (this is contrary to \Ref{ArrayBase}).
Packit df99a1
    It's not supposed to be constructed by hands. Use \Ref{DArray} and
Packit df99a1
    \Ref{TArray} instead.
Packit df99a1
    */
Packit df99a1
Packit df99a1
template <class TYPE>
Packit df99a1
class ArrayBaseT : public ArrayBase
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   virtual ~ArrayBaseT(void) {};
Packit df99a1
   
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
   TYPE& operator[](int 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 DArray<TYPE>#. */
Packit df99a1
   const TYPE& operator[](int n) const;
Packit df99a1
   
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
   /** 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
   
Packit df99a1
   /** Insert new elements into an array. This function inserts
Packit df99a1
       #howmany# elements at position #n# into the array. The initial value #val#
Packit df99a1
       is copied into the new elements. All array elements previously located at subscripts
Packit df99a1
       #n# and higher are moved to subscripts #n+howmany# and higher. The upper bound of the 
Packit df99a1
       valid subscript range is increased in order to account for this shift.
Packit df99a1
       @param n subscript of the first inserted element.
Packit df99a1
       @param val initial value of the new elements.
Packit df99a1
       @param howmany number of elements to insert. */
Packit df99a1
   void ins(int n, const TYPE &val, unsigned int howmany=1);
Packit df99a1
Packit df99a1
   /** Sort array elements.  Sort all array elements in ascending order.  Array
Packit df99a1
       elements are compared using the less-or-equal comparison operator for
Packit df99a1
       type #TYPE#. */
Packit df99a1
   void sort();
Packit df99a1
   /** Sort array elements in subscript range #lo# to #hi#.  Sort all array
Packit df99a1
       elements whose subscripts are in range #lo#..#hi# in ascending order.
Packit df99a1
       The other elements of the array are left untouched.  An exception is
Packit df99a1
       thrown if arguments #lo# and #hi# are not in the valid subscript range.
Packit df99a1
       Array elements are compared using the less-or-equal comparison operator
Packit df99a1
       for type #TYPE#.  
Packit df99a1
       @param lo low bound for the subscripts of the elements to sort.  
Packit df99a1
       @param hi high bound for the subscripts of the elements to sort. */
Packit df99a1
   void sort(int lo, int hi);
Packit df99a1
protected:
Packit df99a1
   ArrayBaseT(void) {};
Packit df99a1
private:
Packit df99a1
      // Callbacks called from ArrayRep
Packit df99a1
   static void		destroy(void * data, int lo, int hi);
Packit df99a1
   static void		init1(void * data, int lo, int hi);
Packit df99a1
   static void		init2(void * data, int lo, int hi,
Packit df99a1
			     const void * src, int src_lo, int src_hi);
Packit df99a1
   static void		copy(void * dst, int dst_lo, int dst_hi,
Packit df99a1
			     const void * src, int src_lo, int src_hi);
Packit df99a1
   static void		insert(void * data, int els, int where,
Packit df99a1
			       const void * what, int howmany);
Packit df99a1
};
Packit df99a1
Packit df99a1
template <class TYPE> inline
Packit df99a1
ArrayBaseT<TYPE>::operator TYPE* ()
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
   
Packit df99a1
   ArrayRep * rep=(ArrayRep *) get();
Packit df99a1
   return &((TYPE *) rep->data)[-rep->minlo];
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline
Packit df99a1
ArrayBaseT<TYPE>::operator const TYPE* () const
Packit df99a1
{
Packit df99a1
   const ArrayRep * rep=(const ArrayRep *) get();
Packit df99a1
   return &((const TYPE *) rep->data)[-rep->minlo];
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline TYPE& 
Packit df99a1
ArrayBaseT<TYPE>::operator[](int n)
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
Packit df99a1
   ArrayRep * rep=(ArrayRep *) get();
Packit df99a1
   if (n<rep->lobound || n>rep->hibound)
Packit df99a1
      G_THROW( ERR_MSG("arrays.ill_sub") );
Packit df99a1
   return ((TYPE *) rep->data)[n - rep->minlo];
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline const TYPE& 
Packit df99a1
ArrayBaseT<TYPE>::operator[](int n) const
Packit df99a1
{
Packit df99a1
   const ArrayRep * rep=(const ArrayRep *) get();
Packit df99a1
   if (n<rep->lobound || n>rep->hibound)
Packit df99a1
      G_THROW( ERR_MSG("arrays.ill_sub") );
Packit df99a1
   return ((const TYPE *) rep->data)[n - rep->minlo];
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline void
Packit df99a1
ArrayBaseT<TYPE>::ins(int n, const TYPE &val, unsigned int howmany)
Packit df99a1
{
Packit df99a1
   check();
Packit df99a1
   
Packit df99a1
   ((ArrayRep *) get())->ins(n, &val, howmany);
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
ArrayBaseT<TYPE>::sort()
Packit df99a1
{
Packit df99a1
   sort(lbound(), hbound());
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
ArrayBaseT<TYPE>::sort(int lo, int hi)
Packit df99a1
{
Packit df99a1
   if (hi <= lo)
Packit df99a1
      return;
Packit df99a1
      // Test for insertion sort (optimize!)
Packit df99a1
   if (hi <= lo + 20)
Packit df99a1
   {
Packit df99a1
      for (int i=lo+1; i<=hi; i++)
Packit df99a1
      {
Packit df99a1
	 int j = i;
Packit df99a1
	 TYPE tmp = (*this)[i];
Packit df99a1
	 while ((--j>=lo) && !((*this)[j]<=tmp))
Packit df99a1
            (*this)[j+1] = (*this)[j];
Packit df99a1
	 (*this)[j+1] = tmp;
Packit df99a1
      }
Packit df99a1
      return;
Packit df99a1
   }
Packit df99a1
      // -- determine suitable quick-sort pivot
Packit df99a1
   TYPE tmp = (*this)[lo];
Packit df99a1
   TYPE pivot = (*this)[(lo+hi)/2];
Packit df99a1
   if (pivot <= tmp)
Packit df99a1
   { tmp = pivot; pivot=(*this)[lo]; }
Packit df99a1
   if ((*this)[hi] <= tmp)
Packit df99a1
   { pivot = tmp; }
Packit df99a1
   else if ((*this)[hi] <= pivot)
Packit df99a1
   { pivot = (*this)[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 <= (*this)[l])) l++;
Packit df99a1
      while (! ((*this)[h] <= pivot)) h--;
Packit df99a1
      if (l < h)
Packit df99a1
      {
Packit df99a1
	 tmp = (*this)[l];
Packit df99a1
	 (*this)[l] = (*this)[h];
Packit df99a1
	 (*this)[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
/** Dynamic array for simple types.  
Packit df99a1
    Template class #TArray<TYPE># implements an array of
Packit df99a1
    elements of {\em simple} type #TYPE#. {\em Simple} means that the type
Packit df99a1
    may be #char#, #int#, #float# etc. The limitation is imposed by the
Packit df99a1
    way in which the #TArray# is working with its elements: it's not trying
Packit df99a1
    to execute elements' constructors, destructors or copy operators. It's
Packit df99a1
    just doing bitwise copy. Except for this it's pretty much the same as
Packit df99a1
    \Ref{DArray}.
Packit df99a1
    
Packit df99a1
    Please note that most of the methods are implemented in the base classes
Packit df99a1
    \Ref{ArrayBase} and \Ref{ArrayBaseT}.
Packit df99a1
*/
Packit df99a1
Packit df99a1
template <class TYPE>
Packit df99a1
class TArray : public ArrayBaseT<TYPE> {
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
   TArray();
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
       @param hibound upper bound of the initial subscript range. */
Packit df99a1
   TArray(int hibound);
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
       @param lobound lower bound of the initial subscript range.
Packit df99a1
       @param hibound upper bound of the initial subscript range. */
Packit df99a1
   TArray(int lobound, int hibound);
Packit df99a1
   
Packit df99a1
   virtual ~TArray() {};
Packit df99a1
private:
Packit df99a1
      // Callbacks called from ArrayRep
Packit df99a1
   static void		destroy(void * data, int lo, int hi);
Packit df99a1
   static void		init1(void * data, int lo, int hi);
Packit df99a1
   static void		init2(void * data, int lo, int hi,
Packit df99a1
			     const void * src, int src_lo, int src_hi);
Packit df99a1
   static void		insert(void * data, int els, int where,
Packit df99a1
			       const void * what, int howmany);
Packit df99a1
};
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
TArray<TYPE>::destroy(void * data, int lo, int hi)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
TArray<TYPE>::init1(void * data, int lo, int hi)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
TArray<TYPE>::init2(void * data, int lo, int hi,
Packit df99a1
		    const void * src, int src_lo, int src_hi)
Packit df99a1
{
Packit df99a1
   if (data && src)
Packit df99a1
   {
Packit df99a1
      int els=hi-lo+1;
Packit df99a1
      if (els>src_hi-src_lo+1) els=src_hi-src_lo+1;
Packit df99a1
      if (els>0)
Packit df99a1
	 memmove((void *) &((TYPE *) data)[lo],
Packit df99a1
		 (void *) &((TYPE *) src)[src_lo], els*sizeof(TYPE));
Packit df99a1
   };
Packit df99a1
}
Packit df99a1
Packit df99a1
// inline removed
Packit df99a1
template <class TYPE> void
Packit df99a1
TArray<TYPE>::insert(void * data, int els, int where,
Packit df99a1
		     const void * what, int howmany)
Packit df99a1
{
Packit df99a1
   memmove(((TYPE *) data)+where+howmany,
Packit df99a1
	   ((TYPE *) data)+where, sizeof(TYPE)*(els-where));
Packit df99a1
   for(int i=0;i
Packit df99a1
      ((TYPE *) data)[where+i]=*(TYPE *) what;
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> 
Packit df99a1
TArray<TYPE>::TArray ()
Packit df99a1
{
Packit df99a1
   this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
Packit df99a1
		       init2, init2, insert));
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> 
Packit df99a1
TArray<TYPE>::TArray(int hi)
Packit df99a1
{
Packit df99a1
   this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
Packit df99a1
		       init2, init2, insert, hi));
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> 
Packit df99a1
TArray<TYPE>::TArray(int lo, int hi)
Packit df99a1
{
Packit df99a1
   this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
Packit df99a1
		       init2, init2, insert, lo, hi));
Packit df99a1
}
Packit df99a1
Packit df99a1
//inline removal ends
Packit df99a1
Packit df99a1
/** Dynamic array for general types.
Packit df99a1
    Template class #DArray<TYPE># implements an array of
Packit df99a1
    elements of type #TYPE#.  Each element is identified by an integer
Packit df99a1
    subscript.  The valid subscripts range is defined by dynamically
Packit df99a1
    adjustable lower- and upper-bounds.  Besides accessing and setting
Packit df99a1
    elements, member functions are provided to insert or delete elements at
Packit df99a1
    specified positions.
Packit df99a1
Packit df99a1
    This template class must be able to access
Packit df99a1
    \begin{itemize}
Packit df99a1
    \item a null constructor #TYPE::TYPE()#, 
Packit df99a1
    \item a copy constructor #TYPE::TYPE(const TYPE &)#,
Packit df99a1
    \item and a copy operator #TYPE & operator=(const TYPE &)#.
Packit df99a1
    \end{itemize}
Packit df99a1
    
Packit df99a1
    The class offers "copy-on-demand" policy, which means that when you
Packit df99a1
    copy the array object, array elements will stay intact as long as you
Packit df99a1
    don't try to modify them. As soon as you make an attempt to change
Packit df99a1
    array contents, the copying is done automatically and transparently
Packit df99a1
    for you - the procedure that we call "copy-on-demand". This is the main
Packit df99a1
    difference between this class and \Ref{GArray} (now obsolete)
Packit df99a1
        
Packit df99a1
    Please note that most of the methods are implemented in the base classes
Packit df99a1
    \Ref{ArrayBase} and \Ref{ArrayBaseT}.
Packit df99a1
*/
Packit df99a1
Packit df99a1
template <class TYPE>
Packit df99a1
class DArray : public ArrayBaseT<TYPE> {
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
   DArray(void);
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
       @param hibound upper bound of the initial subscript range. */
Packit df99a1
   DArray(const int hibound);
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
       @param lobound lower bound of the initial subscript range.
Packit df99a1
       @param hibound upper bound of the initial subscript range. */
Packit df99a1
   DArray(const int lobound, const int hibound);
Packit df99a1
   
Packit df99a1
   virtual ~DArray() {};
Packit df99a1
private:
Packit df99a1
      // Callbacks called from ArrayRep
Packit df99a1
   static void		destroy(void * data, int lo, int hi);
Packit df99a1
   static void		init1(void * data, int lo, int hi);
Packit df99a1
   static void		init2(void * data, int lo, int hi,
Packit df99a1
			     const void * src, int src_lo, int src_hi);
Packit df99a1
   static void		copy(void * dst, int dst_lo, int dst_hi,
Packit df99a1
			     const void * src, int src_lo, int src_hi);
Packit df99a1
   static void		insert(void * data, int els, int where,
Packit df99a1
			       const void * what, int howmany);
Packit df99a1
};
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
DArray<TYPE>::destroy(void * data, int lo, int hi)
Packit df99a1
{
Packit df99a1
   if (data)
Packit df99a1
      for(int i=lo;i<=hi;i++)
Packit df99a1
	 ((TYPE *) data)[i].TYPE::~TYPE();
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
DArray<TYPE>::init1(void * data, int lo, int hi)
Packit df99a1
{
Packit df99a1
   if (data)
Packit df99a1
      for(int i=lo;i<=hi;i++)
Packit df99a1
	 new ((void *) &((TYPE *) data)[i]) TYPE;
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
DArray<TYPE>::init2(void * data, int lo, int hi,
Packit df99a1
		    const void * src, int src_lo, int src_hi)
Packit df99a1
{
Packit df99a1
   if (data && src)
Packit df99a1
   {
Packit df99a1
      int i, j;
Packit df99a1
      for(i=lo, j=src_lo;i<=hi && j<=src_hi;i++, j++)
Packit df99a1
	 new ((void *) &((TYPE *) data)[i]) TYPE(((TYPE *) src)[j]);
Packit df99a1
   };
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> void
Packit df99a1
DArray<TYPE>::copy(void * dst, int dst_lo, int dst_hi,
Packit df99a1
		   const void * src, int src_lo, int src_hi)
Packit df99a1
{
Packit df99a1
   if (dst && src)
Packit df99a1
   {
Packit df99a1
      int i, j;
Packit df99a1
      for(i=dst_lo, j=src_lo;i<=dst_hi && j<=src_hi;i++, j++)
Packit df99a1
	 ((TYPE *) dst)[i]=((TYPE *) src)[j];
Packit df99a1
   };
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline void
Packit df99a1
DArray<TYPE>::insert(void * data, int els, int where,
Packit df99a1
		     const void * what, int howmany)
Packit df99a1
{
Packit df99a1
      // Now do the insertion
Packit df99a1
   TYPE * d=(TYPE *) data;
Packit df99a1
   
Packit df99a1
   int i;
Packit df99a1
   for (i=els+howmany-1; i>=els; i--)
Packit df99a1
   {
Packit df99a1
      if (i-where >= (int)howmany)
Packit df99a1
	 new ((void*) &d[i]) TYPE (d[i-howmany]);
Packit df99a1
      else
Packit df99a1
	 new ((void*) &d[i]) TYPE (*(TYPE *) what);
Packit df99a1
   }
Packit df99a1
   
Packit df99a1
   for (i=els-1; i>=where; i--)
Packit df99a1
   {
Packit df99a1
      if (i-where >= (int)howmany)
Packit df99a1
	 d[i] = d[i-howmany];
Packit df99a1
      else
Packit df99a1
	 d[i] = *(TYPE *) what;
Packit df99a1
   }
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline 
Packit df99a1
DArray<TYPE>::DArray ()
Packit df99a1
{
Packit df99a1
   this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
Packit df99a1
		       init2, copy, insert));
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline 
Packit df99a1
DArray<TYPE>::DArray(const int hi)
Packit df99a1
{
Packit df99a1
   this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
Packit df99a1
		       init2, copy, insert, hi));
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline 
Packit df99a1
DArray<TYPE>::DArray(const int lo, const int hi)
Packit df99a1
{
Packit df99a1
   this->assign(new ArrayRep(sizeof(TYPE), destroy, init1,
Packit df99a1
		       init2, copy, insert, lo, hi));
Packit df99a1
}
Packit df99a1
Packit df99a1
/** Dynamic array for \Ref{GPBase}d classes.
Packit df99a1
Packit df99a1
    There are many situations when it's necessary to create arrays of
Packit df99a1
    \Ref{GP} pointers. For example, #DArray<GP<Dialog> ># or #DArray<GP<Button> >#.
Packit df99a1
    This would result in compilation of two instances of \Ref{DArray} because
Packit df99a1
    from the viewpoint of the compiler there are two different classes used
Packit df99a1
    as array elements: #GP<Dialog># and #GP<Button>#. In reality though,
Packit df99a1
    all \Ref{GP} pointers have absolutely the same binary structure because
Packit df99a1
    they are derived from \Ref{GPBase} class and do not add any variables
Packit df99a1
    or virtual functions. That's why it's possible to instantiate \Ref{DArray}
Packit df99a1
    only once for \Ref{GPBase} elements and then just cast types.
Packit df99a1
Packit df99a1
    To implement this idea we have created this #DPArray<TYPE># class,
Packit df99a1
    which can be used instead of #DArray<GP<TYPE> >#. It behaves absolutely
Packit df99a1
    the same way as \Ref{DArray} but has one big advantage: overhead of
Packit df99a1
    using #DPArray# with one more type is negligible.
Packit df99a1
  */
Packit df99a1
template <class TYPE>
Packit df99a1
class DPArray : public DArray<GPBase> {
Packit df99a1
public:
Packit df99a1
  // -- CONSTRUCTORS
Packit df99a1
  DPArray();
Packit df99a1
  DPArray(int hibound);
Packit df99a1
  DPArray(int lobound, int hibound);
Packit df99a1
  DPArray(const DPArray<TYPE> &gc);
Packit df99a1
  // -- DESTRUCTOR
Packit df99a1
  virtual ~DPArray();
Packit df99a1
  // -- ACCESS
Packit df99a1
  GP<TYPE>& operator[](int n);
Packit df99a1
  const GP<TYPE>& operator[](int n) const;
Packit df99a1
  // -- CONVERSION
Packit df99a1
  operator GP<TYPE>* ();
Packit df99a1
  
Packit df99a1
#ifndef __MWERKS__ //MCW can't compile
Packit df99a1
  operator const GP<TYPE>* ();
Packit df99a1
#endif 
Packit df99a1
 
Packit df99a1
  operator const GP<TYPE>* () const;
Packit df99a1
  // -- ALTERATION
Packit df99a1
  void ins(int n, const GP<TYPE> &val, unsigned int howmany=1);
Packit df99a1
  DPArray<TYPE>& operator= (const DPArray &ga);
Packit df99a1
};
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
DPArray<TYPE>::DPArray() {}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
DPArray<TYPE>::DPArray(int hibound) :
Packit df99a1
      DArray<GPBase>(hibound) {}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
DPArray<TYPE>::DPArray(int lobound, int hibound) :
Packit df99a1
      DArray<GPBase>(lobound, hibound) {}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
DPArray<TYPE>::DPArray(const DPArray<TYPE> &gc) :
Packit df99a1
      DArray<GPBase>(gc) {}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
DPArray<TYPE>::~DPArray() {}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
inline GP<TYPE> &
Packit df99a1
DPArray<TYPE>::operator[](int n)
Packit df99a1
{
Packit df99a1
   return (GP<TYPE> &) DArray<GPBase>::operator[](n);
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
inline const GP<TYPE> &
Packit df99a1
DPArray<TYPE>::operator[](int n) const
Packit df99a1
{
Packit df99a1
   return (const GP<TYPE> &) DArray<GPBase>::operator[](n);
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
inline DPArray<TYPE>::operator GP<TYPE>* ()
Packit df99a1
{
Packit df99a1
   return (GP<TYPE> *) DArray<GPBase>::operator GPBase*();
Packit df99a1
}
Packit df99a1
Packit df99a1
#ifndef __MWERKS__ //MCW can't compile
Packit df99a1
template<class TYPE>
Packit df99a1
inline DPArray<TYPE>::operator const GP<TYPE>* ()
Packit df99a1
{
Packit df99a1
   return (const GP<TYPE> *) DArray<GPBase>::operator const GPBase*();
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
inline DPArray<TYPE>::operator const GP<TYPE>* () const
Packit df99a1
{
Packit df99a1
   return (const GP<TYPE> *) DArray<GPBase>::operator const GPBase*();
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
inline void
Packit df99a1
DPArray<TYPE>::ins(int n, const GP<TYPE> & val, unsigned int howmany)
Packit df99a1
{
Packit df99a1
   DArray<GPBase>::ins(n, val, howmany);
Packit df99a1
}
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
inline DPArray<TYPE> &
Packit df99a1
DPArray<TYPE>::operator= (const DPArray &ga)
Packit df99a1
{
Packit df99a1
   DArray<GPBase>::operator=(ga);
Packit df99a1
   return *this;
Packit df99a1
}
Packit df99a1
Packit df99a1
// ------------ THE END
Packit df99a1
Packit df99a1
//@}
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