Blame libdjvu/GSmartPointer.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 _GSMARTPOINTER_H_
Packit df99a1
#define _GSMARTPOINTER_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 6bff67
#include <cstddef>
Packit 6bff67
Packit df99a1
/** @name GSmartPointer.h
Packit df99a1
Packit df99a1
    Files #"GSmartPointer.h"# and #"GSmartPointer.cpp"# define a smart-pointer
Packit df99a1
    class which automatically performs thread-safe reference counting.  Class
Packit df99a1
    \Ref{GP} implements smart-pointers by overloading the usual pointer
Packit df99a1
    assignment and dereferencing operators. The overloaded operators maintain
Packit df99a1
    the reference counters and destroy the pointed objects as soon as their
Packit df99a1
    reference counter reaches zero.  Transparent type conversions are provided
Packit df99a1
    between smart-pointers and regular pointers.  Objects referenced by
Packit df99a1
    smart-pointers must be derived from class \Ref{GPEnabled}.
Packit df99a1
Packit df99a1
    @memo 
Packit df99a1
    Thread-Safe reference counting smart-pointers.
Packit df99a1
    @author 
Packit df99a1
    L\'eon Bottou <leonb@research.att.com> -- initial implementation\\
Packit df99a1
    Andrei Erofeev <eaf@geocities.com> -- bug fix.
Packit df99a1
Packit df99a1
// From: Leon Bottou, 1/31/2002
Packit df99a1
// Class GPBuffer has been added (but not documented) by Lizardtech.
Packit df99a1
// Our original implementation consisted of multiple classes.
Packit df99a1
// <http://prdownloads.sourceforge.net/djvu/DjVu2_2b-src.tgz>.
Packit df99a1
Packit df99a1
    @args
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
Packit df99a1
#if defined(_MSC_VER)
Packit df99a1
// Language lawyer say MSVC6 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
#include "DjVuGlobal.h"
Packit df99a1
#include "atomic.h"
Packit df99a1
Packit df99a1
#include <stddef.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
/** Base class for reference counted objects.  
Packit df99a1
    This is the base class for all reference counted objects.
Packit df99a1
    Any instance of a subclass of #GPEnabled# can be used with 
Packit df99a1
    smart-pointers (see \Ref{GP}).  
Packit df99a1
 */
Packit df99a1
class DJVUAPI GPEnabled
Packit df99a1
{
Packit df99a1
  friend class GPBase;
Packit df99a1
  void destroy();
Packit df99a1
  void unref();
Packit df99a1
  void ref();
Packit df99a1
public:
Packit df99a1
  /// Null constructor.
Packit df99a1
  GPEnabled();
Packit df99a1
  /// Copy construcotr
Packit df99a1
  GPEnabled(const GPEnabled & obj);
Packit df99a1
  /// Virtual destructor.
Packit df99a1
  virtual ~GPEnabled();
Packit df99a1
  /// Copy operator
Packit df99a1
  GPEnabled & operator=(const GPEnabled & obj);
Packit df99a1
  /** Returns the number of references to this object.  This should be only
Packit df99a1
      used for debugging purposes. Other uses are not thread-safe. */
Packit df99a1
  int get_count(void) const;
Packit df99a1
protected:
Packit df99a1
  /// The reference counter
Packit df99a1
  volatile int count;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** Base class for all smart-pointers.
Packit df99a1
    This class implements common mechanisms for all
Packit df99a1
    smart-pointers (see \Ref{GP}). There should be no need
Packit df99a1
    to use this class directly.  Its sole purpose consists
Packit df99a1
    in reducing the template expansion overhead.
Packit df99a1
*/
Packit df99a1
Packit df99a1
class DJVUAPI GPBase
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Null Constructor. */
Packit df99a1
  GPBase();
Packit df99a1
  /** Copy Constructor.
Packit df99a1
      Increments the reference count. 
Packit df99a1
      @param sptr reference to a #GPBase# object. */
Packit df99a1
  GPBase(const GPBase &sptr);
Packit df99a1
  /** Construct a GPBase from a pointer.
Packit df99a1
      Increments the reference count.
Packit df99a1
      @param nptr pointer to a #GPEnabled# object. */
Packit df99a1
  GPBase(GPEnabled *nptr);
Packit df99a1
  /** Destructor. Decrements the reference count. */
Packit df99a1
  ~GPBase();
Packit df99a1
  /** Accesses the actual pointer. */
Packit df99a1
  GPEnabled* get() const;
Packit df99a1
  /** Assignment from smartpointer. 
Packit df99a1
      Increments the counter of the new value of the pointer.
Packit df99a1
      Decrements the counter of the previous value of the pointer. */
Packit df99a1
  GPBase& assign(const GPBase &sptr);
Packit df99a1
  /** Assignment from pointer. 
Packit df99a1
      Checks that the object is not being destroyed.
Packit df99a1
      Increments the counter of the new value of the pointer.
Packit df99a1
      Decrements the counter of the previous value of the pointer. */
Packit df99a1
  GPBase& assign(GPEnabled *nptr);
Packit df99a1
  /** Assignment operator. */
Packit df99a1
  GPBase & operator=(const GPBase & obj);
Packit df99a1
  /** Comparison operator. */
Packit df99a1
  int operator==(const GPBase & g2) const;
Packit df99a1
protected:
Packit df99a1
  /** Actual pointer */
Packit df99a1
  GPEnabled *ptr;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/** Reference counting pointer.
Packit df99a1
    Class #GP<TYPE># represents a smart-pointer to an object of type #TYPE#.
Packit df99a1
    Type #TYPE# must be a subclass of #GPEnabled#.  This class overloads the
Packit df99a1
    usual pointer assignment and dereferencing operators. The overloaded
Packit df99a1
    operators maintain the reference counters and destroy the pointed object
Packit df99a1
    as soon as their reference counter reaches zero.  Transparent type
Packit df99a1
    conversions are provided between smart-pointers and regular pointers.
Packit df99a1
Packit df99a1
    Using a smart-pointer is a convenience and not an obligation.  There is no
Packit df99a1
    need to use a smart-pointer to access a #GPEnabled# object.  As long as
Packit df99a1
    you never use a smart-pointer to access a #GPEnabled# object, its
Packit df99a1
    reference counter remains zero.  Since the reference counter is never
Packit df99a1
    decremented from one to zero, the object is never destroyed by the
Packit df99a1
    reference counting code.  You can therefore choose to only use regular
Packit df99a1
    pointers to access objects allocated on the stack (automatic variables) or
Packit df99a1
    objects allocated dynamically.  In the latter case you must explicitly
Packit df99a1
    destroy the dynamically allocated object with operator #delete#.
Packit df99a1
Packit df99a1
    The first time you use a smart-pointer to access #GPEnabled# object, the
Packit df99a1
    reference counter is incremented to one. Object destruction will then
Packit df99a1
    happen automatically when the reference counter is decremented back to
Packit df99a1
    zero (i.e. when the last smart-pointer referencing 
Packit df99a1
    this object stops doing so).
Packit df99a1
    This will happen regardless of how many regular pointers 
Packit df99a1
    reference this object.
Packit df99a1
    In other words, if you start using smart-pointers with a #GPEnabled#
Packit df99a1
    object, you engage automatic mode for this object.  You should only do
Packit df99a1
    this with objects dynamically allocated with operator #new#.  You should
Packit df99a1
    never destroy the object yourself, but let the smart-pointers control the
Packit df99a1
    life of the object.
Packit df99a1
    
Packit df99a1
    {\bf Performance considerations} --- Thread safe reference counting incurs
Packit df99a1
    a significant overhead. Smart-pointer are best used with sizeable objects
Packit df99a1
    for which the cost of maintaining the counters represent a small fraction
Packit df99a1
    of the processing time.  It is always possible to cache a smart-pointer
Packit df99a1
    into a regular pointer.  The cached pointer will remain valid until the
Packit df99a1
    smart-pointer object is destroyed or the smart-pointer value is changed.
Packit df99a1
Packit df99a1
    {\bf Safety considerations} --- As explained above, a #GPEnabled# object
Packit df99a1
    switches to automatic mode as soon as it becomes referenced by a
Packit df99a1
    smart-pointer.  There is no way to switch the object back to manual mode.
Packit df99a1
    Suppose that you have decided to only use regular pointers with a
Packit df99a1
    particular #GPEnabled# object.  You therefore plan to destroy the object
Packit df99a1
    explicitly when you no longer need it.  When you pass a regular pointer to
Packit df99a1
    this object as argument to a function, you really need to be certain that
Packit df99a1
    the function implementation will not assign this pointer to a
Packit df99a1
    smart-pointer.  Doing so would indeed destroy the object as soon as the
Packit df99a1
    function returns.  The bad news is that the fact that a function assigns a
Packit df99a1
    pointer argument to a smart-pointer does not necessarily appear in the
Packit df99a1
    function prototype.  Such a behavior must be {\em documented} with the
Packit df99a1
    function public interface.  As a convention, we usually write such
Packit df99a1
    functions with smart-pointer arguments instead of a regular pointer
Packit df99a1
    arguments.  This is not enough to catch the error at compile time, but
Packit df99a1
    this is a simple way to document such a behavior.  We still believe that
Packit df99a1
    this is a small problem in regard to the benefits of the smart-pointer.
Packit df99a1
    But one has to be aware of its existence.  */
Packit df99a1
Packit df99a1
template <class TYPE>
Packit df99a1
class GP : protected GPBase
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Constructs a null smart-pointer. */
Packit df99a1
  GP();
Packit df99a1
  /** Constructs a copy of a smart-pointer.
Packit df99a1
      @param sptr smart-pointer to copy. */
Packit df99a1
  GP(const GP<TYPE> &sptr);
Packit df99a1
  /** Constructs a smart-pointer from a regular pointer.
Packit df99a1
      The pointed object must be dynamically allocated (with operator #new#).
Packit df99a1
      You should no longer explicitly destroy the object referenced by #sptr#
Packit df99a1
      since the object life is now controlled by smart-pointers.  
Packit df99a1
      @param nptr regular pointer to a {\em dynamically allocated object}. */
Packit df99a1
  GP(TYPE *nptr);
Packit df99a1
  /** Converts a smart-pointer into a regular pointer.  
Packit df99a1
      This is useful for caching the value of a smart-pointer for performances
Packit df99a1
      purposes.  The cached pointer will remain valid until the smart-pointer
Packit df99a1
      is destroyed or until the smart-pointer value is changed. */
Packit df99a1
  operator TYPE* () const;
Packit df99a1
  /** Assigns a regular pointer to a smart-pointer lvalue.
Packit df99a1
      The pointed object must be dynamically allocated (with operator #new#).
Packit df99a1
      You should no longer explicitly destroy the object referenced by #sptr#
Packit df99a1
      since the object life is now controlled by smart-pointers.  
Packit df99a1
      @param nptr regular pointer to a {\em dynamically allocated object}. */
Packit df99a1
  GP<TYPE>& operator= (TYPE *nptr);
Packit df99a1
  /** Assigns a smart-pointer to a smart-pointer lvalue.
Packit df99a1
      @param sptr smart-pointer copied into this smart-pointer. */
Packit df99a1
  GP<TYPE>& operator= (const GP<TYPE> &sptr);
Packit df99a1
  /** Indirection operator.
Packit df99a1
      This operator provides a convenient access to the members
Packit df99a1
      of a smart-pointed object. Operator #-># works with smart-pointers
Packit df99a1
      exactly as with regular pointers. */
Packit df99a1
  TYPE* operator->() const;
Packit df99a1
  /** Dereferencement operator.
Packit df99a1
      This operator provides a convenient access to the smart-pointed object. 
Packit df99a1
      Operator #*# works with smart-pointers exactly as with regular pointers. */
Packit df99a1
  TYPE& operator*() const;
Packit df99a1
  /** Comparison operator. 
Packit df99a1
      Returns true if both this smart-pointer and pointer #nptr# point to the
Packit df99a1
      same object.  The automatic conversion from smart-pointers to regular
Packit df99a1
      pointers allows you to compare two smart-pointers as well.  
Packit df99a1
      @param nptr pointer to compare with. */
Packit df99a1
  int operator== (TYPE *nptr) const;
Packit df99a1
  /** Comparison operator.  
Packit df99a1
      Returns true if this smart-pointer and pointer #nptr# point to different
Packit df99a1
      objects. The automatic conversion from smart-pointers to regular
Packit df99a1
      pointers allows you to compare two smart-pointers as well.  
Packit df99a1
      @param nptr pointer to compare with. */
Packit df99a1
  int operator!= (TYPE *nptr) const;
Packit df99a1
  /** Test operator.
Packit df99a1
      Returns true if the smart-pointer is null.  The automatic conversion 
Packit df99a1
      from smart-pointers to regular pointers allows you to test whether 
Packit df99a1
      a smart-pointer is non-null.  You can use both following constructs:
Packit df99a1
      \begin{verbatim}
Packit df99a1
      if (gp) { ... }
Packit df99a1
      while (! gp) { ... }
Packit df99a1
      \end{verbatim} */
Packit df99a1
  int operator! () const;
Packit df99a1
};
Packit df99a1
Packit df99a1
//@}
Packit df99a1
Packit df99a1
// INLINE FOR GPENABLED
Packit df99a1
Packit df99a1
inline
Packit df99a1
GPEnabled::GPEnabled()
Packit df99a1
  : count(0)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
inline
Packit df99a1
GPEnabled::GPEnabled(const GPEnabled & obj) 
Packit df99a1
  : count(0) 
Packit df99a1
{
Packit df99a1
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
GPEnabled::get_count(void) const
Packit df99a1
{
Packit df99a1
   return count;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GPEnabled & 
Packit df99a1
GPEnabled::operator=(const GPEnabled & obj)
Packit df99a1
{ 
Packit df99a1
  /* The copy operator should do nothing because the count should not be
Packit df99a1
     changed.  Subclasses of GPEnabled will call this version of the copy
Packit df99a1
     operator as part of the default 'memberwise copy' strategy. */
Packit df99a1
  return *this; 
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void 
Packit df99a1
GPEnabled::ref()
Packit df99a1
{
Packit df99a1
#if PARANOID_DEBUG
Packit df99a1
  assert (count >= 0);
Packit df99a1
#endif
Packit df99a1
  atomicIncrement(&count);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void 
Packit df99a1
GPEnabled::unref()
Packit df99a1
{
Packit df99a1
#if PARANOID_DEBUG
Packit df99a1
  assert (count > 0);
Packit df99a1
#endif
Packit df99a1
  if (! atomicDecrement(&count))
Packit df99a1
    destroy();
Packit df99a1
}
Packit df99a1
Packit df99a1
// INLINE FOR GPBASE
Packit df99a1
Packit df99a1
inline
Packit df99a1
GPBase::GPBase()
Packit df99a1
  : ptr(0)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
inline
Packit df99a1
GPBase::GPBase(GPEnabled *nptr)
Packit df99a1
  : ptr(0)
Packit df99a1
{
Packit df99a1
  assign(nptr);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline
Packit df99a1
GPBase::GPBase(const GPBase &sptr)
Packit df99a1
{
Packit df99a1
  if (sptr.ptr)
Packit df99a1
    sptr.ptr->ref();
Packit df99a1
  ptr = sptr.ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline
Packit df99a1
GPBase::~GPBase()
Packit df99a1
{
Packit df99a1
  GPEnabled *old = ptr;
Packit df99a1
  ptr = 0;
Packit df99a1
  if (old)
Packit df99a1
    old->unref();
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GPEnabled* 
Packit df99a1
GPBase::get() const
Packit df99a1
{
Packit df99a1
#if PARANOID_DEBUG
Packit df99a1
  if (ptr && ptr->get_count() <= 0)
Packit df99a1
    *(int*)0=0;
Packit df99a1
#endif
Packit df99a1
  return ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GPBase &
Packit df99a1
GPBase::operator=(const GPBase & obj)
Packit df99a1
{
Packit df99a1
  return assign(obj);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int 
Packit df99a1
GPBase::operator==(const GPBase & g2) const
Packit df99a1
{
Packit df99a1
  return ptr == g2.ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// INLINE FOR GP<TYPE>
Packit df99a1
Packit df99a1
template <class TYPE> inline
Packit df99a1
GP<TYPE>::GP()
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline
Packit df99a1
GP<TYPE>::GP(TYPE *nptr)
Packit df99a1
: GPBase((GPEnabled*)nptr)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline
Packit df99a1
GP<TYPE>::GP(const GP<TYPE> &sptr)
Packit df99a1
: GPBase((const GPBase&) sptr)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline
Packit df99a1
GP<TYPE>::operator TYPE* () const
Packit df99a1
{
Packit df99a1
  return (TYPE*) ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline TYPE*
Packit df99a1
GP<TYPE>::operator->() const
Packit df99a1
{
Packit df99a1
#if PARANOID_DEBUG
Packit df99a1
  if (ptr && ptr->get_count() <= 0)
Packit df99a1
    *(int*)0=0;
Packit df99a1
#endif
Packit df99a1
  return (TYPE*) ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline TYPE&
Packit df99a1
GP<TYPE>::operator*() const
Packit df99a1
{
Packit df99a1
#if PARANOID_DEBUG
Packit df99a1
  if (ptr && ptr->get_count() <= 0)
Packit df99a1
    *(int*)0=0;
Packit df99a1
#endif
Packit df99a1
  return *(TYPE*) ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline GP<TYPE>& 
Packit df99a1
GP<TYPE>::operator= (TYPE *nptr)
Packit df99a1
{
Packit df99a1
  return (GP<TYPE>&)( assign(nptr) );
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline GP<TYPE>& 
Packit df99a1
GP<TYPE>::operator= (const GP<TYPE> &sptr)
Packit df99a1
{
Packit df99a1
  return (GP<TYPE>&)( assign((const GPBase&)sptr) );
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline int
Packit df99a1
GP<TYPE>::operator== (TYPE *nptr) const
Packit df99a1
{
Packit df99a1
  return ( (TYPE*)ptr == nptr );
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline int
Packit df99a1
GP<TYPE>::operator!= (TYPE *nptr) const
Packit df99a1
{
Packit df99a1
  return ( (TYPE*)ptr != nptr );
Packit df99a1
}
Packit df99a1
Packit df99a1
template <class TYPE> inline int
Packit df99a1
GP<TYPE>::operator! () const
Packit df99a1
{
Packit df99a1
  return !ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
/* GPBUFFER */
Packit df99a1
Packit df99a1
/* What is this LT innovation ? 
Packit df99a1
   What does it do that a GArray does not do ? 
Packit df99a1
   What about the objects construction and destruction ? */
Packit df99a1
Packit df99a1
class DJVUAPI GPBufferBase
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  GPBufferBase(void *&,const size_t n,const size_t t);
Packit df99a1
  void swap(GPBufferBase &p);
Packit df99a1
  void resize(const size_t n,const size_t t);
Packit df99a1
  void replace(void *nptr,const size_t n);
Packit df99a1
  void set(const size_t t,const char c);
Packit df99a1
  ~GPBufferBase();
Packit df99a1
  operator int(void) const { return ptr ? num : 0; }
Packit df99a1
private:
Packit df99a1
  void *&pt;;
Packit df99a1
  size_t num;
Packit df99a1
};
Packit df99a1
Packit df99a1
template<class TYPE>
Packit df99a1
class GPBuffer : public GPBufferBase
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  GPBuffer(TYPE *&xptr,const size_t n=0) 
Packit df99a1
    : GPBufferBase((void *&)xptr,n,sizeof(TYPE)) {}
Packit df99a1
  inline void resize(const size_t n) {GPBufferBase::resize(n,sizeof(TYPE));}
Packit df99a1
  inline void clear(void) {GPBufferBase::set(sizeof(TYPE),0);}
Packit df99a1
  inline void set(const char c) {GPBufferBase::set(sizeof(TYPE),c);}
Packit df99a1
  inline operator int(void) const {return GPBufferBase::operator int();}
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