source: trunk/libdjvu/GSmartPointer.h @ 15

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

needed libs update

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