1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec 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 *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 #ifndef _COUNTED_REFERENCE_H_
21 #define _COUNTED_REFERENCE_H_
24 * @file util/CountedReference.h
25 * @brief Counted reference templates.
26 * @author James Hogan <james@albanarts.com>
31 /// Base class for reference counting
32 class ReferenceCounted
37 Constructors + destructor
40 /// Default constructor
47 virtual ~ReferenceCounted()
52 Reference counting functions
55 /// Increment the reference count.
56 unsigned int incRefCount()
58 return ++referenceCount
;
61 /// Decrement the reference count.
62 unsigned int decRefCount()
64 return --referenceCount
;
67 /// Get the number of references.
68 unsigned int getRefCount() const
70 return referenceCount
;
79 /// Number of references
80 unsigned int referenceCount
;
83 /// Base class for virtual reference counting.
85 * Use this as a virtual base class during multiple inheritance.
86 * Its quite simply an interface allowing the derived class to implement its
87 * own reference counting.
89 class ReferenceCountedAbstract
94 Constructors + destructor
98 virtual ~ReferenceCountedAbstract()
103 Reference counting functions
106 /// Increment the reference count.
107 virtual void incRefCount() = 0;
109 /// Decrement the reference count.
110 virtual void decRefCount() = 0;
112 /// Get the number of references.
113 virtual unsigned int getRefCount() const = 0;
116 /// Base class for virtual reference counting.
118 * Use this as a virtual base class during multiple inheritance.
119 * It implements a basic reference counter.
120 * @param autoDelete Whether to delete when reference reaches zero.
122 template <bool autoDelete
>
123 class ReferenceCountedVirtual
: public virtual ReferenceCountedAbstract
128 * Reference counting functions from ReferenceCountedAbstract
131 /// Increment the reference count.
132 virtual void incRefCount()
137 /// Decrement the reference count.
138 virtual void decRefCount()
141 if ( autoDelete
&& _referenceCount
== 0 )
147 /// Get the number of references.
148 virtual unsigned int getRefCount() const
150 return _referenceCount
;
160 unsigned int _referenceCount
;
163 /// Interface to reference counting.
164 template <typename T
>
170 /// Increment the reference count for @p object.
171 static void incRefCount(T
* object
)
173 object
->incRefCount();
176 /// Decrement the reference count for @p object and delete if zero.
177 static void decRefCount(T
* object
)
179 if ( 0u == object
->decRefCount() )
185 /// Get the number of references to @p object.
186 static unsigned int getRefCount(const T
* object
)
188 return object
->getRefCount();
191 /// Get the unique key for @p object.
192 static const Key
& getKey(const T
* object
)
198 /// Interface to reference counting.
199 template <typename T
>
200 struct ReferencerSimple
205 /// Increment the reference count for @p object.
206 static void incRefCount(T
* object
)
208 object
->incRefCount();
211 /// Decrement the reference count for @p object.
212 static void decRefCount(T
* object
)
214 object
->decRefCount();
217 /// Get the number of references to @p object.
218 static unsigned int getRefCount(const T
* object
)
220 return object
->getRefCount();
223 /// Get the unique key for @p object.
224 static const Key
& getKey(const T
* object
)
230 // By default use T::DefaultReferencer
231 template <typename T
>
232 struct DefaultReferencer
234 typedef typename
T::DefaultReferencer Type
;
236 // Expands to the default referencer for type T
237 #define DEFAULT_REFERENCER_TYPE(T) \
238 ::DefaultReferencer< T >::Type
240 // Override default referencer
241 #define DEFAULT_REFERENCER(T,R) \
243 struct DefaultReferencer< T > \
247 // Inherit the default referencer of another class
248 #define INHERIT_DEFAULT_REFERENCER(T,P) \
250 struct DefaultReferencer< T > \
252 typedef DEFAULT_REFERENCER_TYPE(P) Type; \
255 /// A reference to a counted object.
256 template <typename T
, typename REF
= typename
DEFAULT_REFERENCER_TYPE(T
) >
268 /// Referencer structure.
269 typedef REF Referencer
;
272 Constructors + destructor
275 /// Default/Primary constructor.
276 Reference(Object
* newObject
= 0)
281 REF::incRefCount(newObject
);
285 /// Copy constructor.
286 Reference(const Reference
& ref
)
287 : object((Object
*)ref
)
291 Referencer::incRefCount(object
);
295 /// Conversion constructor.
296 template <typename U
, typename REF2
>
297 Reference(const Reference
<U
,REF2
>& ref
)
302 Referencer::incRefCount(object
);
311 Referencer::decRefCount(object
);
317 Object management / efficiency
320 /// Swap with another object references.
321 void swap(Reference
& other
)
323 std::swap(object
, other
.object
);
326 /// Get the number of references to this object.
328 * @return 0 if nothing is referenced
330 unsigned int getRefCount() const
334 return Referencer::getRefCount(object
);
344 Modification operators
347 /// Assignment to object.
348 Reference
& operator = (Object
* newObject
)
350 if ( object
!= newObject
)
354 Referencer::decRefCount(object
);
359 Referencer::incRefCount(newObject
);
365 /// Assignment to reference.
366 Reference
& operator = (const Reference
<T
,REF
>& newObject
)
368 if ( object
!= (Object
*)newObject
)
372 Referencer::decRefCount(object
);
374 object
= (Object
*)newObject
;
377 Referencer::incRefCount(object
);
383 /// Assignment to reference.
384 template <typename REF2
>
385 Reference
& operator = (const Reference
<T
,REF2
>& newObject
)
387 if ( object
!= (Object
*)newObject
)
391 Referencer::decRefCount(object
);
393 object
= (Object
*)newObject
;
396 Referencer::incRefCount(object
);
407 operator Object
* () const
413 Object
* operator -> () const
423 template <typename U
>
424 friend U
dynamicCast(const Reference
& ref
)
426 return dynamic_cast<U
>(ref
.object
);
435 /// Pointer to the object.
442 std::swap specialisations
444 template <typename T
, typename REF
>
445 void swap(Reference
<T
,REF
>& a
, Reference
<T
,REF
>& b
)
451 #endif // _COUNTED_REFERENCE_H_