Basic elevation optimisation channel
[tecorrec.git] / geo / CountedReference.h
blob3b99d0b9c7c497af7ff1ee5fc1014490f49124c1
1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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_
23 /**
24 * @file util/CountedReference.h
25 * @brief Counted reference templates.
26 * @author James Hogan <james@albanarts.com>
29 #include <algorithm>
31 /// Base class for reference counting
32 class ReferenceCounted
34 public:
37 Constructors + destructor
40 /// Default constructor
41 ReferenceCounted()
42 : referenceCount(0u)
46 /// Destructor.
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;
73 private:
76 Variables
79 /// Number of references
80 unsigned int referenceCount;
83 /// Base class for virtual reference counting.
84 /**
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
91 public:
94 Constructors + destructor
97 /// 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
125 public:
128 * Reference counting functions from ReferenceCountedAbstract
131 /// Increment the reference count.
132 virtual void incRefCount()
134 ++_referenceCount;
137 /// Decrement the reference count.
138 virtual void decRefCount()
140 --_referenceCount;
141 if ( autoDelete && _referenceCount == 0 )
143 delete this;
147 /// Get the number of references.
148 virtual unsigned int getRefCount() const
150 return _referenceCount;
153 private:
156 * Variables
159 /// Reference count
160 unsigned int _referenceCount;
163 /// Interface to reference counting.
164 template <typename T>
165 struct Referencer
167 /// Unique key type.
168 typedef T* Key;
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() )
181 delete object;
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)
194 return object;
198 /// Interface to reference counting.
199 template <typename T>
200 struct ReferencerSimple
202 /// Unique key type.
203 typedef T* Key;
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)
226 return 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) \
242 template <> \
243 struct DefaultReferencer< T > \
245 typedef R Type; \
247 // Inherit the default referencer of another class
248 #define INHERIT_DEFAULT_REFERENCER(T,P) \
249 template <> \
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) >
257 class Reference
259 public:
262 Types
265 /// Object type.
266 typedef T Object;
268 /// Referencer structure.
269 typedef REF Referencer;
272 Constructors + destructor
275 /// Default/Primary constructor.
276 Reference(Object* newObject = 0)
277 : object(newObject)
279 if ( newObject )
281 REF::incRefCount(newObject);
285 /// Copy constructor.
286 Reference(const Reference& ref)
287 : object((Object*)ref)
289 if ( object )
291 Referencer::incRefCount(object);
295 /// Conversion constructor.
296 template <typename U, typename REF2>
297 Reference(const Reference<U,REF2>& ref)
298 : object((T*)ref)
300 if ( object )
302 Referencer::incRefCount(object);
306 /// Destructor.
307 ~Reference()
309 if ( 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
332 if ( object )
334 return Referencer::getRefCount(object);
336 else
338 return 0;
344 Modification operators
347 /// Assignment to object.
348 Reference & operator = (Object* newObject)
350 if ( object != newObject )
352 if ( object )
354 Referencer::decRefCount(object);
356 object = newObject;
357 if ( newObject )
359 Referencer::incRefCount(newObject);
362 return *this;
365 /// Assignment to reference.
366 Reference & operator = (const Reference<T,REF>& newObject)
368 if ( object != (Object*)newObject )
370 if ( object )
372 Referencer::decRefCount(object);
374 object = (Object*)newObject;
375 if ( object )
377 Referencer::incRefCount(object);
380 return *this;
383 /// Assignment to reference.
384 template <typename REF2>
385 Reference & operator = (const Reference<T,REF2>& newObject)
387 if ( object != (Object*)newObject )
389 if ( object )
391 Referencer::decRefCount(object);
393 object = (Object*)newObject;
394 if ( object )
396 Referencer::incRefCount(object);
399 return *this;
403 Access operators
406 /// Cast to Object*.
407 operator Object* () const
409 return object;
412 /// Dereference.
413 Object* operator -> () const
415 return object;
419 * Casting
422 /// Dynamic cast.
423 template <typename U>
424 friend U dynamicCast(const Reference& ref)
426 return dynamic_cast<U>(ref.object);
429 protected:
432 Variables
435 /// Pointer to the object.
436 Object* object;
439 namespace std
442 std::swap specialisations
444 template <typename T, typename REF>
445 void swap(Reference<T,REF>& a, Reference<T,REF>& b)
447 a.swap(b);
451 #endif // _COUNTED_REFERENCE_H_