2
//C- -------------------------------------------------------------------
4
//C- Copyright (c) 2002 Leon Bottou and Yann Le Cun.
5
//C- Copyright (c) 2001 AT&T
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 .
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.
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):
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.
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 .
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.
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- +------------------------------------------------------------------
56
#ifndef _GSMARTPOINTER_H_
57
#define _GSMARTPOINTER_H_
65
/** @name GSmartPointer.h
67
Files #"GSmartPointer.h"# and #"GSmartPointer.cpp"# define a smart-pointer
68
class which automatically performs thread-safe reference counting. Class
69
\Ref{GP} implements smart-pointers by overloading the usual pointer
70
assignment and dereferencing operators. The overloaded operators maintain
71
the reference counters and destroy the pointed objects as soon as their
72
reference counter reaches zero. Transparent type conversions are provided
73
between smart-pointers and regular pointers. Objects referenced by
74
smart-pointers must be derived from class \Ref{GPEnabled}.
77
Thread-Safe reference counting smart-pointers.
79
L\'eon Bottou <leonb@research.att.com> -- initial implementation\\
80
Andrei Erofeev <eaf@geocities.com> -- bug fix.
82
// From: Leon Bottou, 1/31/2002
83
// Class GPBuffer has been added (but not documented) by Lizardtech.
84
// Our original implementation consisted of multiple classes.
85
// <http://prdownloads.sourceforge.net/djvu/DjVu2_2b-src.tgz>.
92
// Language lawyer say MSVC6 is wrong on that one.
93
// Cf section 5.4.7 in november 1997 draft.
94
#pragma warning( disable : 4243 )
97
#include "DjVuGlobal.h"
100
#ifdef HAVE_NAMESPACES
102
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
109
/** Base class for reference counted objects.
110
This is the base class for all reference counted objects.
111
Any instance of a subclass of #GPEnabled# can be used with
112
smart-pointers (see \Ref{GP}).
114
class DJVUAPI GPEnabled
121
/// Null constructor.
124
GPEnabled(const GPEnabled & obj);
125
/// Virtual destructor.
126
virtual ~GPEnabled();
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;
133
/// The reference counter
139
/** Base class for all smart-pointers.
140
This class implements common mechanisms for all
141
smart-pointers (see \Ref{GP}). There should be no need
142
to use this class directly. Its sole purpose consists
143
in reducing the template expansion overhead.
149
/** Null Constructor. */
151
/** Copy Constructor.
152
Increments the reference count.
153
@param sptr reference to a #GPBase# object. */
154
GPBase(const GPBase &sptr);
155
/** Construct a GPBase from a pointer.
156
Increments the reference count.
157
@param nptr pointer to a #GPEnabled# object. */
158
GPBase(GPEnabled *nptr);
159
/** Destructor. Decrements the reference count. */
161
/** Accesses the actual pointer. */
162
GPEnabled* get() const;
163
/** Assignment from smartpointer.
164
Increments the counter of the new value of the pointer.
165
Decrements the counter of the previous value of the pointer. */
166
GPBase& assign(const GPBase &sptr);
167
/** Assignment from pointer.
168
Checks that the object is not being destroyed.
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(GPEnabled *nptr);
172
/** Assignment operator. */
173
GPBase & operator=(const GPBase & obj);
174
/** Comparison operator. */
175
int operator==(const GPBase & g2) const;
177
/** Actual pointer */
182
/** Reference counting pointer.
183
Class #GP<TYPE># represents a smart-pointer to an object of type #TYPE#.
184
Type #TYPE# must be a subclass of #GPEnabled#. This class overloads the
185
usual pointer assignment and dereferencing operators. The overloaded
186
operators maintain the reference counters and destroy the pointed object
187
as soon as their reference counter reaches zero. Transparent type
188
conversions are provided between smart-pointers and regular pointers.
190
Using a smart-pointer is a convenience and not an obligation. There is no
191
need to use a smart-pointer to access a #GPEnabled# object. As long as
192
you never use a smart-pointer to access a #GPEnabled# object, its
193
reference counter remains zero. Since the reference counter is never
194
decremented from one to zero, the object is never destroyed by the
195
reference counting code. You can therefore choose to only use regular
196
pointers to access objects allocated on the stack (automatic variables) or
197
objects allocated dynamically. In the latter case you must explicitly
198
destroy the dynamically allocated object with operator #delete#.
200
The first time you use a smart-pointer to access #GPEnabled# object, the
201
reference counter is incremented to one. Object destruction will then
202
happen automatically when the reference counter is decremented back to
203
zero (i.e. when the last smart-pointer referencing
204
this object stops doing so).
205
This will happen regardless of how many regular pointers
206
reference this object.
207
In other words, if you start using smart-pointers with a #GPEnabled#
208
object, you engage automatic mode for this object. You should only do
209
this with objects dynamically allocated with operator #new#. You should
210
never destroy the object yourself, but let the smart-pointers control the
213
{\bf Performance considerations} --- Thread safe reference counting incurs
214
a significant overhead. Smart-pointer are best used with sizeable objects
215
for which the cost of maintaining the counters represent a small fraction
216
of the processing time. It is always possible to cache a smart-pointer
217
into a regular pointer. The cached pointer will remain valid until the
218
smart-pointer object is destroyed or the smart-pointer value is changed.
220
{\bf Safety considerations} --- As explained above, a #GPEnabled# object
221
switches to automatic mode as soon as it becomes referenced by a
222
smart-pointer. There is no way to switch the object back to manual mode.
223
Suppose that you have decided to only use regular pointers with a
224
particular #GPEnabled# object. You therefore plan to destroy the object
225
explicitly when you no longer need it. When you pass a regular pointer to
226
this object as argument to a function, you really need to be certain that
227
the function implementation will not assign this pointer to a
228
smart-pointer. Doing so would indeed destroy the object as soon as the
229
function returns. The bad news is that the fact that a function assigns a
230
pointer argument to a smart-pointer does not necessarily appear in the
231
function prototype. Such a behavior must be {\em documented} with the
232
function public interface. As a convention, we usually write such
233
functions with smart-pointer arguments instead of a regular pointer
234
arguments. This is not enough to catch the error at compile time, but
235
this is a simple way to document such a behavior. We still believe that
236
this is a small problem in regard to the benefits of the smart-pointer.
237
But one has to be aware of its existence. */
239
template <class TYPE>
240
class GP : protected GPBase
243
/** Constructs a null smart-pointer. */
245
/** Constructs a copy of a smart-pointer.
246
@param sptr smart-pointer to copy. */
247
GP(const GP<TYPE> &sptr);
248
/** Constructs a smart-pointer from a regular pointer.
249
The pointed object must be dynamically allocated (with operator #new#).
250
You should no longer explicitly destroy the object referenced by #sptr#
251
since the object life is now controlled by smart-pointers.
252
@param nptr regular pointer to a {\em dynamically allocated object}. */
254
/** Converts a smart-pointer into a regular pointer.
255
This is useful for caching the value of a smart-pointer for performances
256
purposes. The cached pointer will remain valid until the smart-pointer
257
is destroyed or until the smart-pointer value is changed. */
258
operator TYPE* () const;
259
/** Assigns a regular pointer to a smart-pointer lvalue.
260
The pointed object must be dynamically allocated (with operator #new#).
261
You should no longer explicitly destroy the object referenced by #sptr#
262
since the object life is now controlled by smart-pointers.
263
@param nptr regular pointer to a {\em dynamically allocated object}. */
264
GP<TYPE>& operator= (TYPE *nptr);
265
/** Assigns a smart-pointer to a smart-pointer lvalue.
266
@param sptr smart-pointer copied into this smart-pointer. */
267
GP<TYPE>& operator= (const GP<TYPE> &sptr);
268
/** Indirection operator.
269
This operator provides a convenient access to the members
270
of a smart-pointed object. Operator #-># works with smart-pointers
271
exactly as with regular pointers. */
272
TYPE* operator->() const;
273
/** Dereferencement operator.
274
This operator provides a convenient access to the smart-pointed object.
275
Operator #*# works with smart-pointers exactly as with regular pointers. */
276
TYPE& operator*() const;
277
/** Comparison operator.
278
Returns true if both this smart-pointer and pointer #nptr# point to the
279
same object. The automatic conversion from smart-pointers to regular
280
pointers allows you to compare two smart-pointers as well.
281
@param nptr pointer to compare with. */
282
int operator== (TYPE *nptr) const;
283
/** Comparison operator.
284
Returns true if this smart-pointer and pointer #nptr# point to different
285
objects. The automatic conversion from smart-pointers to regular
286
pointers allows you to compare two smart-pointers as well.
287
@param nptr pointer to compare with. */
288
int operator!= (TYPE *nptr) const;
290
Returns true if the smart-pointer is null. The automatic conversion
291
from smart-pointers to regular pointers allows you to test whether
292
a smart-pointer is non-null. You can use both following constructs:
297
int operator! () const;
302
// INLINE FOR GPENABLED
305
GPEnabled::GPEnabled()
311
GPEnabled::GPEnabled(const GPEnabled & obj)
318
GPEnabled::get_count(void) const
324
GPEnabled::operator=(const GPEnabled & obj)
326
/* The copy operator should do nothing because the count should not be
327
changed. Subclasses of GPEnabled will call this version of the copy
328
operator as part of the default 'memberwise copy' strategy. */
338
atomicIncrement(&count);
347
if (! atomicDecrement(&count))
360
GPBase::GPBase(GPEnabled *nptr)
367
GPBase::GPBase(const GPBase &sptr)
377
GPEnabled *old = ptr;
387
if (ptr && ptr->get_count() <= 0)
394
GPBase::operator=(const GPBase & obj)
400
GPBase::operator==(const GPBase & g2) const
402
return ptr == g2.ptr;
408
// INLINE FOR GP<TYPE>
410
template <class TYPE> inline
415
template <class TYPE> inline
416
GP<TYPE>::GP(TYPE *nptr)
417
: GPBase((GPEnabled*)nptr)
421
template <class TYPE> inline
422
GP<TYPE>::GP(const GP<TYPE> &sptr)
423
: GPBase((const GPBase&) sptr)
427
template <class TYPE> inline
428
GP<TYPE>::operator TYPE* () const
433
template <class TYPE> inline TYPE*
434
GP<TYPE>::operator->() const
437
if (ptr && ptr->get_count() <= 0)
443
template <class TYPE> inline TYPE&
444
GP<TYPE>::operator*() const
447
if (ptr && ptr->get_count() <= 0)
453
template <class TYPE> inline GP<TYPE>&
454
GP<TYPE>::operator= (TYPE *nptr)
456
return (GP<TYPE>&)( assign(nptr) );
459
template <class TYPE> inline GP<TYPE>&
460
GP<TYPE>::operator= (const GP<TYPE> &sptr)
462
return (GP<TYPE>&)( assign((const GPBase&)sptr) );
465
template <class TYPE> inline int
466
GP<TYPE>::operator== (TYPE *nptr) const
468
return ( (TYPE*)ptr == nptr );
471
template <class TYPE> inline int
472
GP<TYPE>::operator!= (TYPE *nptr) const
474
return ( (TYPE*)ptr != nptr );
477
template <class TYPE> inline int
478
GP<TYPE>::operator! () const
485
/* What is this LT innovation ?
486
What does it do that a GArray does not do ?
487
What about the objects construction and destruction ? */
489
class DJVUAPI GPBufferBase
492
GPBufferBase(void *&,const size_t n,const size_t t);
493
void swap(GPBufferBase &p);
494
void resize(const size_t n,const size_t t);
495
void replace(void *nptr,const size_t n);
496
void set(const size_t t,const char c);
498
operator int(void) const { return ptr ? num : 0; }
505
class GPBuffer : public GPBufferBase
508
GPBuffer(TYPE *&xptr,const size_t n=0) : GPBufferBase((void *&)xptr,n,sizeof(TYPE)) {}
509
inline void resize(const size_t n) {GPBufferBase::resize(n,sizeof(TYPE));}
510
inline void clear(void) {GPBufferBase::set(sizeof(TYPE),0);}
511
inline void set(const char c) {GPBufferBase::set(sizeof(TYPE),c);}
512
inline operator int(void) const {return GPBufferBase::operator int();}
517
#ifdef HAVE_NAMESPACES
519
# ifndef NOT_USING_DJVU_NAMESPACE
520
using namespace DJVU;