source: trunk/libdjvu/GSmartPointer.h @ 206

Last change on this file since 206 was 206, checked in by Eugene Romanenko, 14 years ago

DJVU plugin: djvulibre updated to version 3.5.19

File size: 16.4 KB
RevLine 
[206]1//C-  -*- C++ -*-
2//C- -------------------------------------------------------------------
3//C- DjVuLibre-3.5
4//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5//C- Copyright (c) 2001  AT&T
6//C-
7//C- This software is subject to, and may be distributed under, the
8//C- GNU General Public License, either Version 2 of the license,
9//C- or (at your option) any later version. The license should have
10//C- accompanied the software or you may obtain a copy of the license
11//C- from the Free Software Foundation at http://www.fsf.org .
12//C-
13//C- This program is distributed in the hope that it will be useful,
14//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
15//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16//C- GNU General Public License for more details.
17//C-
18//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
19//C- Lizardtech Software.  Lizardtech Software has authorized us to
20//C- replace the original DjVu(r) Reference Library notice by the following
21//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
22//C-
23//C-  ------------------------------------------------------------------
24//C- | DjVu (r) Reference Library (v. 3.5)
25//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
26//C- | The DjVu Reference Library is protected by U.S. Pat. No.
27//C- | 6,058,214 and patents pending.
28//C- |
29//C- | This software is subject to, and may be distributed under, the
30//C- | GNU General Public License, either Version 2 of the license,
31//C- | or (at your option) any later version. The license should have
32//C- | accompanied the software or you may obtain a copy of the license
33//C- | from the Free Software Foundation at http://www.fsf.org .
34//C- |
35//C- | The computer code originally released by LizardTech under this
36//C- | license and unmodified by other parties is deemed "the LIZARDTECH
37//C- | ORIGINAL CODE."  Subject to any third party intellectual property
38//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
39//C- | non-exclusive license to make, use, sell, or otherwise dispose of
40//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
41//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
42//C- | General Public License.   This grant only confers the right to
43//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
44//C- | the extent such infringement is reasonably necessary to enable
45//C- | recipient to make, have made, practice, sell, or otherwise dispose
46//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
47//C- | any greater extent that may be necessary to utilize further
48//C- | modifications or combinations.
49//C- |
50//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
51//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
52//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
53//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
54//C- +------------------------------------------------------------------
55//
56// $Id: GSmartPointer.h,v 1.13 2007/03/25 20:48:32 leonb Exp $
57// $Name: release_3_5_19 $
58
59#ifndef _GSMARTPOINTER_H_
60#define _GSMARTPOINTER_H_
61#ifdef HAVE_CONFIG_H
62#include "config.h"
63#endif
64#if NEED_GNUG_PRAGMAS
65# pragma interface
66#endif
67
68/** @name GSmartPointer.h
69
70    Files #"GSmartPointer.h"# and #"GSmartPointer.cpp"# define a smart-pointer
71    class which automatically performs thread-safe reference counting.  Class
72    \Ref{GP} implements smart-pointers by overloading the usual pointer
73    assignment and dereferencing operators. The overloaded operators maintain
74    the reference counters and destroy the pointed objects as soon as their
75    reference counter reaches zero.  Transparent type conversions are provided
76    between smart-pointers and regular pointers.  Objects referenced by
77    smart-pointers must be derived from class \Ref{GPEnabled}.
78
79    @memo
80    Thread-Safe reference counting smart-pointers.
81    @author
82    L\'eon Bottou <leonb@research.att.com> -- initial implementation\\
83    Andrei Erofeev <eaf@geocities.com> -- bug fix.
84
85// From: Leon Bottou, 1/31/2002
86// Class GPBuffer has been added (but not documented) by Lizardtech.
87// Our original implementation consisted of multiple classes.
88// <http://prdownloads.sourceforge.net/djvu/DjVu2_2b-src.tgz>.
89
90    @version
91    #$Id: GSmartPointer.h,v 1.13 2007/03/25 20:48:32 leonb Exp $#
92    @args
93*/
94//@{
95
96#if defined(_MSC_VER)
97// Language lawyer say MSVC6 is wrong on that one.
98// Cf section 5.4.7 in november 1997 draft.
99#pragma warning( disable : 4243 )
100#endif
101
102#include "DjVuGlobal.h"
103
104#ifdef HAVE_NAMESPACES
105namespace DJVU {
106# ifdef NOT_DEFINED // Just to fool emacs c++ mode
107}
108#endif
109#endif
110
111
112
113/** Base class for reference counted objects. 
114    This is the base class for all reference counted objects.
115    Any instance of a subclass of #GPEnabled# can be used with
116    smart-pointers (see \Ref{GP}). 
117 */
118class GPEnabled
119{
120public:
121  /// Null constructor.
122  GPEnabled();
123  /// Copy construcotr
124  GPEnabled(const GPEnabled & obj);
125  /// Virtual destructor.
126  virtual ~GPEnabled();
127  /// Copy operator
128  GPEnabled & operator=(const GPEnabled & obj);
129  /** Returns the number of references to this object.  This should be only
130      used for debugging purposes. Other uses are not thread-safe. */
131  int get_count(void) const;
132protected:
133  /// The reference counter
134  volatile int count;
135private:
136  friend class GPBase;
137  void unref();
138  void ref();
139  void destroy();
140};
141
142
143
144/** Base class for all smart-pointers.
145    This class implements common mechanisms for all
146    smart-pointers (see \Ref{GP}). There should be no need
147    to use this class directly.  Its sole purpose consists
148    in reducing the template expansion overhead.
149*/
150
151class GPBase
152{
153public:
154  /** Null Constructor. */
155  GPBase();
156  /** Copy Constructor.
157      Increments the reference count.
158      @param sptr reference to a #GPBase# object. */
159  GPBase(const GPBase &sptr);
160  /** Construct a GPBase from a pointer.
161      Increments the reference count.
162      @param nptr pointer to a #GPEnabled# object. */
163  GPBase(GPEnabled *nptr);
164  /** Destructor. Decrements the reference count. */
165  ~GPBase();
166  /** Accesses the actual pointer. */
167  GPEnabled* get() const;
168  /** Assignment from smartpointer.
169      Increments the counter of the new value of the pointer.
170      Decrements the counter of the previous value of the pointer. */
171  GPBase& assign(const GPBase &sptr);
172  /** Assignment from pointer.
173      Checks that the object is not being destroyed.
174      Increments the counter of the new value of the pointer.
175      Decrements the counter of the previous value of the pointer. */
176  GPBase& assign(GPEnabled *nptr);
177  /** Assignment operator. */
178  GPBase & operator=(const GPBase & obj);
179  /** Comparison operator. */
180  int operator==(const GPBase & g2) const;
181protected:
182  /** Actual pointer */
183  GPEnabled *ptr;
184};
185
186
187/** Reference counting pointer.
188    Class #GP<TYPE># represents a smart-pointer to an object of type #TYPE#.
189    Type #TYPE# must be a subclass of #GPEnabled#.  This class overloads the
190    usual pointer assignment and dereferencing operators. The overloaded
191    operators maintain the reference counters and destroy the pointed object
192    as soon as their reference counter reaches zero.  Transparent type
193    conversions are provided between smart-pointers and regular pointers.
194
195    Using a smart-pointer is a convenience and not an obligation.  There is no
196    need to use a smart-pointer to access a #GPEnabled# object.  As long as
197    you never use a smart-pointer to access a #GPEnabled# object, its
198    reference counter remains zero.  Since the reference counter is never
199    decremented from one to zero, the object is never destroyed by the
200    reference counting code.  You can therefore choose to only use regular
201    pointers to access objects allocated on the stack (automatic variables) or
202    objects allocated dynamically.  In the latter case you must explicitly
203    destroy the dynamically allocated object with operator #delete#.
204
205    The first time you use a smart-pointer to access #GPEnabled# object, the
206    reference counter is incremented to one. Object destruction will then
207    happen automatically when the reference counter is decremented back to
208    zero (i.e. when the last smart-pointer referencing this object stops doing so).
209    This will happen regardless of how many regular pointers reference this object.
210    In other words, if you start using smart-pointers with a #GPEnabled#
211    object, you engage automatic mode for this object.  You should only do
212    this with objects dynamically allocated with operator #new#.  You should
213    never destroy the object yourself, but let the smart-pointers control the
214    life of the object.
215   
216    {\bf Performance considerations} --- Thread safe reference counting incurs
217    a significant overhead. Smart-pointer are best used with sizeable objects
218    for which the cost of maintaining the counters represent a small fraction
219    of the processing time.  It is always possible to cache a smart-pointer
220    into a regular pointer.  The cached pointer will remain valid until the
221    smart-pointer object is destroyed or the smart-pointer value is changed.
222
223    {\bf Safety considerations} --- As explained above, a #GPEnabled# object
224    switches to automatic mode as soon as it becomes referenced by a
225    smart-pointer.  There is no way to switch the object back to manual mode.
226    Suppose that you have decided to only use regular pointers with a
227    particular #GPEnabled# object.  You therefore plan to destroy the object
228    explicitly when you no longer need it.  When you pass a regular pointer to
229    this object as argument to a function, you really need to be certain that
230    the function implementation will not assign this pointer to a
231    smart-pointer.  Doing so would indeed destroy the object as soon as the
232    function returns.  The bad news is that the fact that a function assigns a
233    pointer argument to a smart-pointer does not necessarily appear in the
234    function prototype.  Such a behavior must be {\em documented} with the
235    function public interface.  As a convention, we usually write such
236    functions with smart-pointer arguments instead of a regular pointer
237    arguments.  This is not enough to catch the error at compile time, but
238    this is a simple way to document such a behavior.  We still believe that
239    this is a small problem in regard to the benefits of the smart-pointer.
240    But one has to be aware of its existence.  */
241
242template <class TYPE>
243class GP : protected GPBase
244{
245public:
246  /** Constructs a null smart-pointer. */
247  GP();
248  /** Constructs a copy of a smart-pointer.
249      @param sptr smart-pointer to copy. */
250  GP(const GP<TYPE> &sptr);
251  /** Constructs a smart-pointer from a regular pointer.
252      The pointed object must be dynamically allocated (with operator #new#).
253      You should no longer explicitly destroy the object referenced by #sptr#
254      since the object life is now controlled by smart-pointers. 
255      @param nptr regular pointer to a {\em dynamically allocated object}. */
256  GP(TYPE *nptr);
257  /** Converts a smart-pointer into a regular pointer. 
258      This is useful for caching the value of a smart-pointer for performances
259      purposes.  The cached pointer will remain valid until the smart-pointer
260      is destroyed or until the smart-pointer value is changed. */
261  operator TYPE* () const;
262  /** Assigns a regular pointer to a smart-pointer lvalue.
263      The pointed object must be dynamically allocated (with operator #new#).
264      You should no longer explicitly destroy the object referenced by #sptr#
265      since the object life is now controlled by smart-pointers. 
266      @param nptr regular pointer to a {\em dynamically allocated object}. */
267  GP<TYPE>& operator= (TYPE *nptr);
268  /** Assigns a smart-pointer to a smart-pointer lvalue.
269      @param sptr smart-pointer copied into this smart-pointer. */
270  GP<TYPE>& operator= (const GP<TYPE> &sptr);
271  /** Indirection operator.
272      This operator provides a convenient access to the members
273      of a smart-pointed object. Operator #-># works with smart-pointers
274      exactly as with regular pointers. */
275  TYPE* operator->() const;
276  /** Dereferencement operator.
277      This operator provides a convenient access to the smart-pointed object.
278      Operator #*# works with smart-pointers exactly as with regular pointers. */
279  TYPE& operator*() const;
280  /** Comparison operator.
281      Returns true if both this smart-pointer and pointer #nptr# point to the
282      same object.  The automatic conversion from smart-pointers to regular
283      pointers allows you to compare two smart-pointers as well. 
284      @param nptr pointer to compare with. */
285  int operator== (TYPE *nptr) const;
286  /** Comparison operator. 
287      Returns true if this smart-pointer and pointer #nptr# point to different
288      objects. The automatic conversion from smart-pointers to regular
289      pointers allows you to compare two smart-pointers as well. 
290      @param nptr pointer to compare with. */
291  int operator!= (TYPE *nptr) const;
292  /** Test operator.
293      Returns true if the smart-pointer is null.  The automatic conversion
294      from smart-pointers to regular pointers allows you to test whether
295      a smart-pointer is non-null.  You can use both following constructs:
296      \begin{verbatim}
297      if (gp) { ... }
298      while (! gp) { ... }
299      \end{verbatim} */
300  int operator! () const;
301};
302
303//@}
304
305// INLINE FOR GPENABLED
306
307inline
308GPEnabled::GPEnabled()
309  : count(0)
310{
311}
312
313inline
314GPEnabled::GPEnabled(const GPEnabled & obj) 
315  : count(0) 
316{
317
318}
319
320inline int
321GPEnabled::get_count(void) const
322{
323   return count;
324}
325
326inline GPEnabled & 
327GPEnabled::operator=(const GPEnabled & obj)
328{ 
329  /* The copy operator should do nothing because the count should not be
330     changed.  Subclasses of GPEnabled will call this version of the copy
331     operator as part of the default 'memberwise copy' strategy. */
332  return *this; 
333}
334
335// INLINE FOR GPBASE
336
337inline
338GPBase::GPBase()
339  : ptr(0)
340{
341}
342
343inline
344GPBase::GPBase(GPEnabled *nptr)
345  : ptr(0)
346{
347  assign(nptr);
348}
349
350inline
351GPBase::GPBase(const GPBase &sptr)
352{
353  if (sptr.ptr)
354    sptr.ptr->ref();
355  ptr = sptr.ptr;
356}
357
358inline
359GPBase::~GPBase()
360{
361  GPEnabled *old = ptr;
362  ptr = 0;
363  if (old)
364    old->unref();
365}
366
367inline GPEnabled* 
368GPBase::get() const
369{
370  return ptr;
371}
372
373inline GPBase &
374GPBase::operator=(const GPBase & obj)
375{
376  return assign(obj);
377}
378
379inline int 
380GPBase::operator==(const GPBase & g2) const
381{
382  return ptr == g2.ptr;
383}
384
385
386
387
388// INLINE FOR GP<TYPE>
389
390template <class TYPE> inline
391GP<TYPE>::GP()
392{
393}
394
395template <class TYPE> inline
396GP<TYPE>::GP(TYPE *nptr)
397: GPBase((GPEnabled*)nptr)
398{
399}
400
401template <class TYPE> inline
402GP<TYPE>::GP(const GP<TYPE> &sptr)
403: GPBase((const GPBase&) sptr)
404{
405}
406
407template <class TYPE> inline
408GP<TYPE>::operator TYPE* () const
409{
410  return (TYPE*) ptr;
411}
412
413template <class TYPE> inline TYPE*
414GP<TYPE>::operator->() const
415{
416  return (TYPE*) ptr;
417}
418
419template <class TYPE> inline TYPE&
420GP<TYPE>::operator*() const
421{
422  return *(TYPE*) ptr;
423}
424
425template <class TYPE> inline GP<TYPE>& 
426GP<TYPE>::operator= (TYPE *nptr)
427{
428  return (GP<TYPE>&)( assign(nptr) );
429}
430
431template <class TYPE> inline GP<TYPE>& 
432GP<TYPE>::operator= (const GP<TYPE> &sptr)
433{
434  return (GP<TYPE>&)( assign((const GPBase&)sptr) );
435}
436
437template <class TYPE> inline int
438GP<TYPE>::operator== (TYPE *nptr) const
439{
440  return ( (TYPE*)ptr == nptr );
441}
442
443template <class TYPE> inline int
444GP<TYPE>::operator!= (TYPE *nptr) const
445{
446  return ( (TYPE*)ptr != nptr );
447}
448
449template <class TYPE> inline int
450GP<TYPE>::operator! () const
451{
452  return !ptr;
453}
454
455/* GPBUFFER */
456
457/* What is this LT innovation ?
458   What does it do that a GArray does not do ?
459   What about the objects construction and destruction ? */
460
461class GPBufferBase
462{
463public:
464  GPBufferBase(void *&,const size_t n,const size_t t);
465  void swap(GPBufferBase &p);
466  void resize(const size_t n,const size_t t);
467  void replace(void *nptr,const size_t n);
468  void set(const size_t t,const char c);
469  ~GPBufferBase();
470  operator int(void) const { return ptr ? num : 0; }
471private:
472  void *&ptr;
473  size_t num;
474};
475
476template<class TYPE>
477class GPBuffer : public GPBufferBase
478{
479public:
480  GPBuffer(TYPE *&xptr,const size_t n=0) : GPBufferBase((void *&)xptr,n,sizeof(TYPE)) {}
481  inline void resize(const size_t n) {GPBufferBase::resize(n,sizeof(TYPE));}
482  inline void clear(void) {GPBufferBase::set(sizeof(TYPE),0);}
483  inline void set(const char c) {GPBufferBase::set(sizeof(TYPE),c);}
484  inline operator int(void) const {return GPBufferBase::operator int();}
485};
486
487
488
489#ifdef HAVE_NAMESPACES
490}
491# ifndef NOT_USING_DJVU_NAMESPACE
492using namespace DJVU;
493# endif
494#endif
495#endif
Note: See TracBrowser for help on using the repository browser.