1 #ifndef _COUNTED_REFERENCE_H_
2 #define _COUNTED_REFERENCE_H_
5 * @file CountedReference.h
6 * @brief Counted reference templates.
7 * @author James Hogan <james@albanarts.com>
12 /// Interface to reference counting.
19 /// Increment the reference count for @p object.
20 static void incRefCount(T
* object
)
22 object
->incRefCount();
25 /// Decrement the reference count for @p object and delete if zero.
26 static void decRefCount(T
* object
)
28 if ( 0u == object
->decRefCount() )
34 /// Get the number of references to @p object.
35 static unsigned int getRefCount(const T
* object
)
37 return object
->getRefCount();
40 /// Get the unique key for @p object.
41 static const Key
& getKey(const T
* object
)
47 /// Base class for reference counting
48 class ReferenceCounted
53 Constructors + destructor
56 /// Default constructor
63 virtual ~ReferenceCounted()
68 Reference counting functions
71 /// Increment the reference count.
72 unsigned int incRefCount()
74 return ++referenceCount
;
77 /// Decrement the reference count.
78 unsigned int decRefCount()
80 return --referenceCount
;
83 /// Get the number of references.
84 unsigned int getRefCount() const
86 return referenceCount
;
95 /// Number of references
96 unsigned int referenceCount
;
99 /// Extending class for reference counting
100 template <typename T
>
101 class ReferenceCountedExtension
: public T
109 /// Default referencing class.
110 typedef Referencer
<ReferenceCountedExtension
> DefaultReferencer
;
113 Constructors + destructor
116 /// Default constructor
117 ReferenceCountedExtension()
124 virtual ~ReferenceCountedExtension()
129 Reference counting functions
132 /// Increment the reference count.
133 unsigned int incRefCount()
135 return ++referenceCount
;
138 /// Decrement the reference count.
139 unsigned int decRefCount()
141 return --referenceCount
;
144 /// Get the number of references.
145 unsigned int getRefCount() const
147 return referenceCount
;
156 /// Number of references
157 unsigned int referenceCount
;
160 /// Base class for virtual reference counting.
162 * Use this as a virtual base class during multiple inheritance.
163 * Its quite simply an interface allowing the derived class to implement its
164 * own reference counting.
166 class ReferenceCountedAbstract
171 Constructors + destructor
175 virtual ~ReferenceCountedAbstract()
180 Reference counting functions
183 /// Increment the reference count.
184 virtual void incRefCount() = 0;
186 /// Decrement the reference count.
187 virtual void decRefCount() = 0;
189 /// Get the number of references.
190 virtual unsigned int getRefCount() const = 0;
193 /// Base class for virtual reference counting.
195 * Use this as a virtual base class during multiple inheritance.
196 * It implements a basic reference counter.
197 * @param autoDelete Whether to delete when reference reaches zero.
199 template <bool autoDelete
>
200 class ReferenceCountedVirtual
: public virtual ReferenceCountedAbstract
205 * Reference counting functions from ReferenceCountedAbstract
208 /// Increment the reference count.
209 virtual void incRefCount()
214 /// Decrement the reference count.
215 virtual void decRefCount()
218 if ( autoDelete
&& _referenceCount
== 0 )
224 /// Get the number of references.
225 virtual unsigned int getRefCount() const
227 return _referenceCount
;
237 unsigned int _referenceCount
;
240 /// Interface to reference counting.
241 template <typename T
>
242 struct ReferencerSimple
247 /// Increment the reference count for @p object.
248 static void incRefCount(T
* object
)
250 object
->incRefCount();
253 /// Decrement the reference count for @p object.
254 static void decRefCount(T
* object
)
256 object
->decRefCount();
259 /// Get the number of references to @p object.
260 static unsigned int getRefCount(const T
* object
)
262 return object
->getRefCount();
265 /// Get the unique key for @p object.
266 static const Key
& getKey(const T
* object
)
272 // By default use T::DefaultReferencer
273 template <typename T
>
274 struct DefaultReferencer
276 typedef typename
T::DefaultReferencer Type
;
278 // Expands to the default referencer for type T
279 #define DEFAULT_REFERENCER_TYPE(T) \
280 ::DefaultReferencer< T >::Type
282 // Override default referencer
283 #define DEFAULT_REFERENCER(T,R) \
285 struct DefaultReferencer< T > \
289 // Inherit the default referencer of another class
290 #define INHERIT_DEFAULT_REFERENCER(T,P) \
292 struct DefaultReferencer< T > \
294 typedef DEFAULT_REFERENCER_TYPE(P) Type; \
297 /// A reference to a counted object.
298 template <typename T
, typename REF
= typename
DEFAULT_REFERENCER_TYPE(T
) >
310 /// Referencer structure.
311 typedef REF Referencer
;
314 Constructors + destructor
317 /// Default/Primary constructor.
318 Reference(Object
* newObject
= 0)
323 REF::incRefCount(newObject
);
327 /// Copy constructor.
328 Reference(const Reference
& ref
)
329 : object((Object
*)ref
)
333 Referencer::incRefCount(object
);
337 /// Conversion constructor.
338 template <typename U
, typename REF2
>
339 Reference(const Reference
<U
,REF2
>& ref
)
340 : object(static_cast<T
*>(ref
))
344 Referencer::incRefCount(object
);
353 Referencer::decRefCount(object
);
359 Object management / efficiency
362 /// Swap with another object references.
363 void swap(Reference
& other
)
365 std::swap(object
, other
.object
);
368 /// Get the number of references to this object.
370 * @return 0 if nothing is referenced
372 unsigned int getRefCount() const
376 return Referencer::getRefCount(object
);
386 Modification operators
389 /// Assignment to object.
390 Reference
& operator = (Object
* newObject
)
392 if ( object
!= newObject
)
396 Referencer::decRefCount(object
);
401 Referencer::incRefCount(newObject
);
407 /// Assignment to reference.
408 template <typename REF2
>
409 Reference
& operator = (Reference
<T
,REF2
>& newObject
)
411 if ( object
!= (Object
*)newObject
)
415 Referencer::decRefCount(object
);
417 object
= (Object
*)newObject
;
420 Referencer::incRefCount(object
);
431 operator Object
* () const
437 Object
* operator -> () const
447 template <typename U
>
448 friend U
dynamicCast(const Reference
& ref
)
450 return dynamic_cast<U
>(ref
.object
);
459 /// Pointer to the object.
466 std::swap specialisations
468 template <typename T
, typename REF
>
469 void swap(Reference
<T
,REF
>& a
, Reference
<T
,REF
>& b
)
475 #endif // _COUNTED_REFERENCE_H_