Merge branch 'db/rev'
[plumiferos.git] / intern / memutil / MEM_RefCountPtr.h
blob4707b2d6cc05b6c1ab6c001638b79fc74e747e6b
1 /**
2 * $Id: MEM_RefCountPtr.h 6960 2006-03-04 16:23:15Z blendix $
3 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version. The Blender
9 * Foundation also sells licenses for use in proprietary software under
10 * the Blender License. See http://www.blender.org/BL/ for information
11 * about this.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23 * All rights reserved.
25 * The Original Code is: all of this file.
27 * Contributor(s): none yet.
29 * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 /**
32 * @file MEM_RefCountPtr.h
33 * Declaration of MEM_RefCounted and MEM_RefCountable classes.
34 * @author Laurence
37 #ifndef NAN_INCLUDED_MEM_RefCountPtr_h
38 #define NAN_INCLUDED_MEM_RefCountPtr_h
40 #include <stdlib.h> // for NULL !
42 /**
43 * @section MEM_RefCountable
44 * This is a base class for reference countable objects.
45 * If you want an object to be shared using a reference
46 * counted system derrivce from this class. All subclasses
47 * should insist that they are created on the heap, this
48 * can be done by makeing all constructors private and
49 * defining a static New() method that returns a ref counted
50 * ptr to a new()ly allocated instance.
52 * @section Example subclass
55 * class MySharedObject : public MEM_RefCountable {
57 * private :
58 * MySharedObject() : MEM_RefCountable() { //class specific initialization};
59 * MySharedObject(const MySharedObject &other) // not implemented
60 * public :
61 * static
62 * MEM_RefCountPtr<MySharedObject>
63 * New(
64 * ) {
65 * return MEM_RefCountPtr<MySharedObject>( new MySharedObject());
66 * }
68 * // other member functions
69 * };
71 * Alternitively you may first wish to define a fully functional
72 * class and then define a reference counting wrapper for this class.
73 * This is useful when the base type can be used without reference
74 * counting.
76 * E.g.
77 * class UsefullClass {
78 * private :
79 * ...
80 * public :
82 * UsefullClass()
83 * UsefullMethod(...)
84 * AnotherUsefullMethod(...)
85 * };
87 * class RcUsefullClass : public UsefullClass, public MEM_RefCountable
88 * {
89 * private :
90 * // Override base class public constructor --- forces
91 * // use of New(...)
92 * RcUsefullClass(...)
93 * public :
95 * // Override each public constructor of UsefullClass with
96 * // an equivalent static New method returning a MEM_RefCountPtr
98 * static
99 * MEM_RefCountPtr<RcUsefullClass>
100 * New(...){
101 * return MEM_RefCountPtr<RcUsefullClass> output(
102 * new UsefullClass(...)
103 * );
106 * // warning never call destructor directly allow ref counting
107 * // mechanism to handle object lifetime.
108 * ~RcUsefullClass();
109 * };
114 class MEM_RefCountable {
115 private :
118 * The reference count!
119 * We use mutable here because we would like to
120 * share references of const objects!
121 * Maybe should think about having decRef()
122 * another value because we should not be deleting
123 * non-const objects
126 mutable int m_count;
128 protected :
131 * Protected constructors
132 * This class is not for direct instanciation. Sub classes
133 * should only be allocated on the heap.
136 MEM_RefCountable (
138 m_count (0)
142 MEM_RefCountable (
143 const MEM_RefCountable &
145 m_count (0)
149 public :
151 void
152 IncRef(
153 ) const {
154 m_count++;
158 DecRef(
160 return (--m_count);
163 ~MEM_RefCountable(
165 //nothing to do
170 * @section MEM_RefCountPtr
173 template
174 < class T >
175 class MEM_RefCountPtr {
177 public :
180 * Construction from reference - share ownership with
181 * the right hand side.
184 MEM_RefCountPtr(
185 const MEM_RefCountPtr &rhs
186 ) : m_val (NULL) {
187 ShareOwnership(rhs.m_val);
191 * Construction from ptr - this class shares
192 * ownership of object val.
195 MEM_RefCountPtr(
196 const T* val
198 m_val (NULL)
200 ShareOwnership(val);
204 * Default constructor
207 MEM_RefCountPtr(
209 m_val (NULL)
214 * Type conversion from this class to the type
215 * of a pointer to the template parameter.
216 * This means you can pass an instance of this class
217 * to a function expecting a ptr of type T.
220 operator T * () const {
221 return m_val;
225 MEM_RefCountPtr & operator=(
226 const MEM_RefCountPtr &rhs
228 if (this->m_val != rhs.m_val) {
229 ReleaseOwnership();
230 ShareOwnership(rhs.m_val);
232 return *this;
236 * Overload the operator -> so that it's possible to access
237 * all the normal methods of the internal ptr.
240 T * operator->() const {
241 return m_val;
245 * Returrn a reference to the shared object.
249 Ref(
251 return *m_val;
256 * Destructor - deletes object if it's ref count is zero.
259 ~MEM_RefCountPtr(
261 ReleaseOwnership();
264 private :
266 /// The ptr owned by this class.
267 T * m_val;
269 void
270 ShareOwnership(
271 const T * val
273 if (val != NULL) {
274 val->IncRef();
276 m_val = const_cast<T *>(val);
279 void
280 ReleaseOwnership(
282 if (m_val) {
283 if (m_val->DecRef() == 0) {
284 delete(m_val);
285 m_val = NULL;
292 #endif