1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * KWorship 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 * KWorship 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 KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 #ifndef _countedReference_h_
21 #define _countedReference_h_
24 * @file CountedReference.h
25 * @brief Counted reference templates.
26 * @author James Hogan <james@albanarts.com>
31 /// Interface to reference counting.
38 /// Increment the reference count for @p object.
39 static void incRefCount(T
* object
)
41 object
->incRefCount();
44 /// Decrement the reference count for @p object and delete if zero.
45 static void decRefCount(T
* object
)
47 if ( 0u == object
->decRefCount() )
53 /// Get the number of references to @p object.
54 static unsigned int getRefCount(const T
* object
)
56 return object
->getRefCount();
59 /// Get the unique key for @p object.
60 static const Key
& getKey(const T
* object
)
66 /// Base class for reference counting
67 class ReferenceCounted
72 Constructors + destructor
75 /// Default constructor
82 virtual ~ReferenceCounted()
87 Reference counting functions
90 /// Increment the reference count.
91 unsigned int incRefCount()
93 return ++referenceCount
;
96 /// Decrement the reference count.
97 unsigned int decRefCount()
99 return --referenceCount
;
102 /// Get the number of references.
103 unsigned int getRefCount() const
105 return referenceCount
;
114 /// Number of references
115 unsigned int referenceCount
;
118 /// Extending class for reference counting
119 template <typename T
>
120 class ReferenceCountedExtension
: public T
128 /// Default referencing class.
129 typedef Referencer
<ReferenceCountedExtension
> DefaultReferencer
;
132 Constructors + destructor
135 /// Default constructor
136 ReferenceCountedExtension()
143 virtual ~ReferenceCountedExtension()
148 Reference counting functions
151 /// Increment the reference count.
152 unsigned int incRefCount()
154 return ++referenceCount
;
157 /// Decrement the reference count.
158 unsigned int decRefCount()
160 return --referenceCount
;
163 /// Get the number of references.
164 unsigned int getRefCount() const
166 return referenceCount
;
175 /// Number of references
176 unsigned int referenceCount
;
179 /// Base class for virtual reference counting.
181 * Use this as a virtual base class during multiple inheritance.
182 * Its quite simply an interface allowing the derived class to implement its
183 * own reference counting.
185 class ReferenceCountedAbstract
190 Constructors + destructor
194 virtual ~ReferenceCountedAbstract()
199 Reference counting functions
202 /// Increment the reference count.
203 virtual void incRefCount() = 0;
205 /// Decrement the reference count.
206 virtual void decRefCount() = 0;
208 /// Get the number of references.
209 virtual unsigned int getRefCount() const = 0;
212 /// Base class for virtual reference counting.
214 * Use this as a virtual base class during multiple inheritance.
215 * It implements a basic reference counter.
216 * @param autoDelete Whether to delete when reference reaches zero.
218 template <bool autoDelete
>
219 class ReferenceCountedVirtual
: public virtual ReferenceCountedAbstract
224 * Reference counting functions from ReferenceCountedAbstract
227 /// Increment the reference count.
228 virtual void incRefCount()
233 /// Decrement the reference count.
234 virtual void decRefCount()
237 if ( autoDelete
&& _referenceCount
== 0 )
243 /// Get the number of references.
244 virtual unsigned int getRefCount() const
246 return _referenceCount
;
256 unsigned int _referenceCount
;
259 /// Interface to reference counting.
260 template <typename T
>
261 struct ReferencerSimple
266 /// Increment the reference count for @p object.
267 static void incRefCount(T
* object
)
269 object
->incRefCount();
272 /// Decrement the reference count for @p object.
273 static void decRefCount(T
* object
)
275 object
->decRefCount();
278 /// Get the number of references to @p object.
279 static unsigned int getRefCount(const T
* object
)
281 return object
->getRefCount();
284 /// Get the unique key for @p object.
285 static const Key
& getKey(const T
* object
)
291 // By default use T::DefaultReferencer
292 template <typename T
>
293 struct DefaultReferencer
295 typedef typename
T::DefaultReferencer Type
;
297 // Expands to the default referencer for type T
298 #define DEFAULT_REFERENCER_TYPE(T) \
299 ::DefaultReferencer< T >::Type
301 // Override default referencer
302 #define DEFAULT_REFERENCER(T,R) \
304 struct DefaultReferencer< T > \
308 // Inherit the default referencer of another class
309 #define INHERIT_DEFAULT_REFERENCER(T,P) \
311 struct DefaultReferencer< T > \
313 typedef DEFAULT_REFERENCER_TYPE(P) Type; \
316 /// A reference to a counted object.
317 template <typename T
, typename REF
= typename
DEFAULT_REFERENCER_TYPE(T
) >
329 /// Referencer structure.
330 typedef REF Referencer
;
333 Constructors + destructor
336 /// Default/Primary constructor.
337 Reference(Object
* newObject
= 0)
342 REF::incRefCount(newObject
);
346 /// Copy constructor.
347 Reference(const Reference
& ref
)
348 : object((Object
*)ref
)
352 Referencer::incRefCount(object
);
356 /// Conversion constructor.
357 template <typename U
, typename REF2
>
358 Reference(const Reference
<U
,REF2
>& ref
)
359 : object(static_cast<T
*>(ref
))
363 Referencer::incRefCount(object
);
372 Referencer::decRefCount(object
);
378 Object management / efficiency
381 /// Swap with another object references.
382 void swap(Reference
& other
)
384 std::swap(object
, other
.object
);
387 /// Get the number of references to this object.
389 * @return 0 if nothing is referenced
391 unsigned int getRefCount() const
395 return Referencer::getRefCount(object
);
405 Modification operators
408 /// Assignment to object.
409 Reference
& operator = (Object
* newObject
)
411 if ( object
!= newObject
)
415 Referencer::decRefCount(object
);
420 Referencer::incRefCount(newObject
);
426 /// Assignment to reference.
427 template <typename REF2
>
428 Reference
& operator = (Reference
<T
,REF2
>& newObject
)
430 if ( object
!= (Object
*)newObject
)
434 Referencer::decRefCount(object
);
436 object
= (Object
*)newObject
;
439 Referencer::incRefCount(object
);
450 operator Object
* () const
456 Object
* operator -> () const
466 template <typename U
>
467 friend U
dynamicCast(const Reference
& ref
)
469 return dynamic_cast<U
>(ref
.object
);
478 /// Pointer to the object.
485 std::swap specialisations
487 template <typename T
, typename REF
>
488 void swap(Reference
<T
,REF
>& a
, Reference
<T
,REF
>& b
)
494 #endif // _countedReference_h_