These files are needed for booleans (which I had disabled)
[blender-staging.git] / intern / memutil / MEM_RefCountPtr.h
1 /**
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
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.
9  *
10  * This program 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 this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28 /**
29  * @file        MEM_RefCountPtr.h
30  * Declaration of MEM_RefCounted and MEM_RefCountable classes.
31  * @author Laurence
32  */
33
34 #ifndef NAN_INCLUDED_MEM_RefCountPtr_h
35 #define NAN_INCLUDED_MEM_RefCountPtr_h
36
37 #include <stdlib.h> // for NULL !
38
39 /**
40  * @section MEM_RefCountable
41  * This is a base class for reference countable objects.
42  * If you want an object to be shared using a reference 
43  * counted system derrivce from this class. All subclasses
44  * should insist that they are created on the heap, this
45  * can be done by makeing all constructors private and 
46  * defining a static New() method that returns a ref counted
47  * ptr to a new()ly allocated instance. 
48  *
49  * @section Example subclass
50  *
51  *
52  * class MySharedObject : public MEM_RefCountable {
53  *
54  * private :
55  *      MySharedObject() : MEM_RefCountable() { //class specific initialization};
56  *  MySharedObject(const MySharedObject &other) // not implemented
57  * public :
58  *              static  
59  *                      MEM_RefCountPtr<MySharedObject> 
60  *              New(
61  *              ) {
62  *                      return MEM_RefCountPtr<MySharedObject>( new MySharedObject());
63  *              }
64  *              
65  *              // other member functions
66  * };
67  *
68  * Alternitively you may first wish to define a fully functional
69  * class and then define a reference counting wrapper for this class.
70  * This is useful when the base type can be used without reference
71  * counting.
72  *
73  * E.g.
74  * class UsefullClass {
75  * private :
76  *  ...
77  * public :
78  *
79  *      UsefullClass()
80  *      UsefullMethod(...)
81  *      AnotherUsefullMethod(...)
82  * };
83  *
84  * class RcUsefullClass : public UsefullClass, public MEM_RefCountable
85  * {
86  * private :
87  *      // Override base class public constructor --- forces
88  *      // use of New(...)
89  *      RcUsefullClass(...)
90  * public :
91  *
92  *  // Override each public constructor of UsefullClass with
93  *  // an equivalent static New method returning a MEM_RefCountPtr
94  *
95  *  static
96  *      MEM_RefCountPtr<RcUsefullClass>
97  *  New(...){
98  *       return MEM_RefCountPtr<RcUsefullClass> output(
99  *           new UsefullClass(...)
100  *       );
101  *   }
102  *
103  *  // warning never call destructor directly allow ref counting
104  *  // mechanism to handle object lifetime.
105  *  ~RcUsefullClass();
106  * };
107  *
108  *
109  */
110
111 class MEM_RefCountable {
112 private :
113
114         /**
115          * The reference count!
116          * We use mutable here because we would like to
117          * share references of const objects!
118          * Maybe should think about having decRef()
119          * another value because we should not be deleting
120          * non-const objects
121          */
122
123         mutable int m_count;
124
125 protected :
126
127         /**
128          * Protected constructors
129          * This class is not for direct instanciation. Sub classes
130          * should only be allocated on the heap.
131          */
132
133         MEM_RefCountable (
134         ) :
135                 m_count (0)
136         {
137         };
138
139         MEM_RefCountable (
140                 const MEM_RefCountable &
141         ) :
142                 m_count (0)
143         {
144         }
145
146 public :
147
148                 void
149         IncRef(
150         ) const {
151                 m_count++;
152         }
153
154                 int
155         DecRef(
156         ) {
157                 return (--m_count);
158         }
159
160         ~MEM_RefCountable(
161         ) {
162                 //nothing to do
163         }
164 };
165
166 /**
167  * @section MEM_RefCountPtr
168  */
169
170 template
171         < class T >
172 class MEM_RefCountPtr {
173
174 public :
175
176         /**
177          * Construction from reference - share ownership with
178          * the right hand side.
179          */
180
181         MEM_RefCountPtr(
182                 const MEM_RefCountPtr &rhs
183         ) : m_val (NULL) {
184                 ShareOwnership(rhs.m_val);
185         }
186
187         /**
188          * Construction from ptr - this class shares
189          * ownership of object val.
190          */
191
192         MEM_RefCountPtr(
193                 const T* val
194         ) :
195                 m_val (NULL)
196         {
197                 ShareOwnership(val);
198         }
199
200         /**
201          * Default constructor
202          */
203
204         MEM_RefCountPtr(
205         ) :
206                 m_val (NULL)
207         {
208         }
209
210         /**
211          * Type conversion from this class to the type
212          * of a pointer to the template parameter.
213          * This means you can pass an instance of this class
214          * to a function expecting a ptr of type T.
215          */
216
217         operator T * () const {
218                 return m_val;
219         }
220
221
222         MEM_RefCountPtr & operator=(
223                 const MEM_RefCountPtr &rhs
224         ) {
225                 if (this->m_val != rhs.m_val) {
226                         ReleaseOwnership();
227                         ShareOwnership(rhs.m_val);
228                 }
229                 return *this;
230         }
231
232         /**
233          * Overload the operator -> so that it's possible to access
234          * all the normal methods of the internal ptr.
235          */
236
237         T * operator->() const {
238                 return m_val;
239         }
240
241         /**
242          * Returrn a reference to the shared object.
243          */
244
245                 T&
246         Ref(
247         ) {
248                 return *m_val;
249         }
250
251
252         /**
253          * Destructor - deletes object if it's ref count is zero.
254          */
255
256         ~MEM_RefCountPtr(
257         ) {
258                 ReleaseOwnership();
259         }
260
261 private :
262         
263         /// The ptr owned by this class.
264         T * m_val;
265
266                 void
267         ShareOwnership(
268                 const T * val
269         ) {
270                 if (val != NULL) {
271                         val->IncRef();
272                 }
273                 m_val = const_cast<T *>(val);
274         }
275                 
276                 void
277         ReleaseOwnership(
278         ) {
279                 if (m_val) {
280                         if (m_val->DecRef() == 0) {
281                                 delete(m_val);
282                                 m_val = NULL;
283                         }
284                 }
285         }
286
287 };
288
289 #endif
290