Added nice css styling instead of simple class based. now uses scopes and object...
[kworship.git] / include / CountedReference.h
blob8957c63b2cefda809ba4f2e1edf885565686efcd
1 #ifndef _COUNTED_REFERENCE_H_
2 #define _COUNTED_REFERENCE_H_
4 /**
5 * @file CountedReference.h
6 * @brief Counted reference templates.
7 * @author James Hogan <james@albanarts.com>
8 */
10 #include <algorithm>
12 /// Interface to reference counting.
13 template <typename T>
14 struct Referencer
16 /// Unique key type.
17 typedef T* Key;
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() )
30 delete object;
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)
43 return object;
47 /// Base class for reference counting
48 class ReferenceCounted
50 public:
53 Constructors + destructor
56 /// Default constructor
57 ReferenceCounted()
58 : referenceCount(0u)
62 /// Destructor.
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;
89 private:
92 Variables
95 /// Number of references
96 unsigned int referenceCount;
99 /// Extending class for reference counting
100 template <typename T>
101 class ReferenceCountedExtension : public T
103 public:
106 * Types
109 /// Default referencing class.
110 typedef Referencer<ReferenceCountedExtension> DefaultReferencer;
113 Constructors + destructor
116 /// Default constructor
117 ReferenceCountedExtension()
118 : T()
119 , referenceCount(0u)
123 /// Destructor.
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;
150 private:
153 Variables
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
168 public:
171 Constructors + destructor
174 /// 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
202 public:
205 * Reference counting functions from ReferenceCountedAbstract
208 /// Increment the reference count.
209 virtual void incRefCount()
211 ++_referenceCount;
214 /// Decrement the reference count.
215 virtual void decRefCount()
217 --_referenceCount;
218 if ( autoDelete && _referenceCount == 0 )
220 delete this;
224 /// Get the number of references.
225 virtual unsigned int getRefCount() const
227 return _referenceCount;
230 private:
233 * Variables
236 /// Reference count
237 unsigned int _referenceCount;
240 /// Interface to reference counting.
241 template <typename T>
242 struct ReferencerSimple
244 /// Unique key type.
245 typedef T* Key;
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)
268 return 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) \
284 template <> \
285 struct DefaultReferencer< T > \
287 typedef R Type; \
289 // Inherit the default referencer of another class
290 #define INHERIT_DEFAULT_REFERENCER(T,P) \
291 template <> \
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) >
299 class Reference
301 public:
304 Types
307 /// Object type.
308 typedef T Object;
310 /// Referencer structure.
311 typedef REF Referencer;
314 Constructors + destructor
317 /// Default/Primary constructor.
318 Reference(Object* newObject = 0)
319 : object(newObject)
321 if ( newObject )
323 REF::incRefCount(newObject);
327 /// Copy constructor.
328 Reference(const Reference& ref)
329 : object((Object*)ref)
331 if ( object )
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))
342 if ( object )
344 Referencer::incRefCount(object);
348 /// Destructor.
349 ~Reference()
351 if ( 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
374 if ( object )
376 return Referencer::getRefCount(object);
378 else
380 return 0;
386 Modification operators
389 /// Assignment to object.
390 Reference & operator = (Object* newObject)
392 if ( object != newObject )
394 if ( object )
396 Referencer::decRefCount(object);
398 object = newObject;
399 if ( newObject )
401 Referencer::incRefCount(newObject);
404 return *this;
407 /// Assignment to reference.
408 template <typename REF2>
409 Reference & operator = (Reference<T,REF2>& newObject)
411 if ( object != (Object*)newObject )
413 if ( object )
415 Referencer::decRefCount(object);
417 object = (Object*)newObject;
418 if ( object )
420 Referencer::incRefCount(object);
423 return *this;
427 Access operators
430 /// Cast to Object*.
431 operator Object* () const
433 return object;
436 /// Dereference.
437 Object* operator -> () const
439 return object;
443 * Casting
446 /// Dynamic cast.
447 template <typename U>
448 friend U dynamicCast(const Reference& ref)
450 return dynamic_cast<U>(ref.object);
453 protected:
456 Variables
459 /// Pointer to the object.
460 Object* object;
463 namespace std
466 std::swap specialisations
468 template <typename T, typename REF>
469 void swap(Reference<T,REF>& a, Reference<T,REF>& b)
471 a.swap(b);
475 #endif // _COUNTED_REFERENCE_H_