Change interface to categorise bibles by language, and adapt SWORD bible manager...
[kworship.git] / include / CountedReference.h
blob72b1a87ca01fe6588e84109bf1fec271876ee488
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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_
23 /**
24 * @file CountedReference.h
25 * @brief Counted reference templates.
26 * @author James Hogan <james@albanarts.com>
29 #include <algorithm>
31 /// Interface to reference counting.
32 template <typename T>
33 struct Referencer
35 /// Unique key type.
36 typedef T* Key;
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() )
49 delete object;
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)
62 return object;
66 /// Base class for reference counting
67 class ReferenceCounted
69 public:
72 Constructors + destructor
75 /// Default constructor
76 ReferenceCounted()
77 : referenceCount(0u)
81 /// Destructor.
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;
108 private:
111 Variables
114 /// Number of references
115 unsigned int referenceCount;
118 /// Extending class for reference counting
119 template <typename T>
120 class ReferenceCountedExtension : public T
122 public:
125 * Types
128 /// Default referencing class.
129 typedef Referencer<ReferenceCountedExtension> DefaultReferencer;
132 Constructors + destructor
135 /// Default constructor
136 ReferenceCountedExtension()
137 : T()
138 , referenceCount(0u)
142 /// Destructor.
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;
169 private:
172 Variables
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
187 public:
190 Constructors + destructor
193 /// 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
221 public:
224 * Reference counting functions from ReferenceCountedAbstract
227 /// Increment the reference count.
228 virtual void incRefCount()
230 ++_referenceCount;
233 /// Decrement the reference count.
234 virtual void decRefCount()
236 --_referenceCount;
237 if ( autoDelete && _referenceCount == 0 )
239 delete this;
243 /// Get the number of references.
244 virtual unsigned int getRefCount() const
246 return _referenceCount;
249 private:
252 * Variables
255 /// Reference count
256 unsigned int _referenceCount;
259 /// Interface to reference counting.
260 template <typename T>
261 struct ReferencerSimple
263 /// Unique key type.
264 typedef T* Key;
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)
287 return 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) \
303 template <> \
304 struct DefaultReferencer< T > \
306 typedef R Type; \
308 // Inherit the default referencer of another class
309 #define INHERIT_DEFAULT_REFERENCER(T,P) \
310 template <> \
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) >
318 class Reference
320 public:
323 Types
326 /// Object type.
327 typedef T Object;
329 /// Referencer structure.
330 typedef REF Referencer;
333 Constructors + destructor
336 /// Default/Primary constructor.
337 Reference(Object* newObject = 0)
338 : object(newObject)
340 if ( newObject )
342 REF::incRefCount(newObject);
346 /// Copy constructor.
347 Reference(const Reference& ref)
348 : object((Object*)ref)
350 if ( object )
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))
361 if ( object )
363 Referencer::incRefCount(object);
367 /// Destructor.
368 ~Reference()
370 if ( 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
393 if ( object )
395 return Referencer::getRefCount(object);
397 else
399 return 0;
405 Modification operators
408 /// Assignment to object.
409 Reference & operator = (Object* newObject)
411 if ( object != newObject )
413 if ( object )
415 Referencer::decRefCount(object);
417 object = newObject;
418 if ( newObject )
420 Referencer::incRefCount(newObject);
423 return *this;
426 /// Assignment to reference.
427 template <typename REF2>
428 Reference & operator = (Reference<T,REF2>& newObject)
430 if ( object != (Object*)newObject )
432 if ( object )
434 Referencer::decRefCount(object);
436 object = (Object*)newObject;
437 if ( object )
439 Referencer::incRefCount(object);
442 return *this;
446 Access operators
449 /// Cast to Object*.
450 operator Object* () const
452 return object;
455 /// Dereference.
456 Object* operator -> () const
458 return object;
462 * Casting
465 /// Dynamic cast.
466 template <typename U>
467 friend U dynamicCast(const Reference& ref)
469 return dynamic_cast<U>(ref.object);
472 protected:
475 Variables
478 /// Pointer to the object.
479 Object* object;
482 namespace std
485 std::swap specialisations
487 template <typename T, typename REF>
488 void swap(Reference<T,REF>& a, Reference<T,REF>& b)
490 a.swap(b);
494 #endif // _countedReference_h_