2
* cxxtools - general purpose C++-toolbox
3
* Copyright (C) 2005 Tommi Maekitalo
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef CXXTOOLS_SMARTPTR_H
21
#define CXXTOOLS_SMARTPTR_H
23
#include <cxxtools/atomicity.h>
27
template <typename objectType>
30
mutable const RefLinked* prev;
31
mutable const RefLinked* next;
34
bool unlink(objectType* object)
53
void link(const RefLinked& ptr, objectType* object)
62
template <typename objectType>
63
class InternalRefCounted
66
bool unlink(objectType* object)
73
void link(const InternalRefCounted& ptr, objectType* object)
81
template <typename objectType>
82
class ExternalRefCounted
90
bool unlink(objectType* object)
92
if (object && atomicDecrement(*refs) <= 0)
95
// no need to set refs to 0 since the pointer is either
96
// destroyed or another object is linked in
103
void link(const ExternalRefCounted& ptr, objectType* object)
108
refs = new atomic_t(1);
112
atomicIncrement(*refs);
120
atomic_t getRefs() const
121
{ return refs ? *refs : 0; }
124
template <typename objectType>
125
class DefaultDestroyPolicy
128
void destroy(objectType* ptr)
132
template <typename objectType>
133
class ArrayDestroyPolicy
136
void destroy(objectType* ptr)
141
* Policy-based smart-pointer-class.
143
* This class works like a pointer, but the destructor deletes the held
144
* object if this is the last reference. The policy specifies, how the class
145
* counts the references. There are 3 policies:
147
* ExternalRefCounted: allocates a reference-count
149
* InternalRefCounted: the pointed object needs to have a reference-counter
150
* with methods addRef() and release(). The release-method deletes the
151
* object, when the reference-count drops to 0.
153
* RefLinked: all pointers to a object are linked
155
* The default policy is InternalRefCounted. Another class
156
* cxxtools::RefCounted implements proper methods for the pointer, which
157
* makes it straight-forward to use.
160
template <typename objectType,
161
template <class> class ownershipPolicy = InternalRefCounted,
162
template <class> class destroyPolicy = DefaultDestroyPolicy>
163
class SmartPtr : public ownershipPolicy<objectType>,
164
public destroyPolicy<objectType>
167
typedef ownershipPolicy<objectType> ownershipPolicyType;
168
typedef destroyPolicy<objectType> destroyPolicyType;
174
SmartPtr(objectType* ptr)
176
{ ownershipPolicyType::link(*this, ptr); }
177
SmartPtr(const SmartPtr& ptr)
179
{ ownershipPolicyType::link(ptr, ptr.object); }
181
{ if (ownershipPolicyType::unlink(object))
184
SmartPtr& operator= (const SmartPtr& ptr)
186
if (object != ptr.object)
188
if (ownershipPolicyType::unlink(object))
193
ownershipPolicyType::link(ptr, object);
198
/// The object can be dereferenced like the held object
199
objectType* operator->() const { return object; }
200
/// The object can be dereferenced like the held object
201
objectType& operator*() const { return *object; }
203
bool operator== (const objectType* p) const { return object == p; }
204
bool operator!= (const objectType* p) const { return object != p; }
205
bool operator< (const objectType* p) const { return object < p; }
206
bool operator! () const { return object == 0; }
207
operator bool () const { return object != 0; }
209
objectType* getPointer() { return object; }
210
const objectType* getPointer() const { return object; }
211
operator objectType* () { return object; }
212
operator const objectType* () const { return object; }
217
#endif // CXXTOOLS_SMARTPTR_H