svn merge -r 13452:14721 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / intern / memutil / MEM_SmartPtr.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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_SmartPtr.h
30  * Declaration of MEM_RefCounted and MEM_RefCountable classes.
31  * @author Laurence
32  */
33
34 #ifndef NAN_INCLUDED_MEM_SmartPtr_h
35 #define NAN_INCLUDED_MEM_SmartPtr_h
36
37
38 #include <stdlib.h> // for NULL !
39
40
41 /**
42  * @section MEM_SmartPtr 
43  * This class defines a smart pointer similar to that defined in 
44  * the Standard Template Library but without the painful get()
45  * semantics to access the internal c style pointer.
46  *
47  * It is often useful to explicitely decalre ownership of memory
48  * allocated on the heap within class or function scope. This
49  * class helps you to encapsulate this ownership within a value
50  * type. When an instance of this class goes out of scope it
51  * makes sure that any memory associated with it's internal pointer
52  * is deleted. It can help to inform users of an aggregate class
53  * that it owns instances of it's members and these instances 
54  * should not be shared. This is not reliably enforcable in C++
55  * but this class attempts to make the 1-1 relationship clear.
56  * 
57  * @section Example usage
58  *
59  * class foo {
60  *              ...constructors accessors etc.
61  *              int x[1000];
62  * }
63  * 
64  * class bar {
65  *  public :
66  *              static
67  *                      bar *
68  *              New(
69  *              ) {
70  *                      MEM_SmartPtr<foo> afoo = new foo();
71  *                      MEM_SmartPtr<bar> that = new bar();
72  *
73  *                      if (foo == NULL || that == NULL) return NULL;
74  *
75  *                      that->m_foo = afoo.Release();
76  *                      return that.Release();
77  *              }
78  *
79  *              ~bar() {
80  *                      // smart ptr takes care of deletion
81  *              }
82  *      private :
83  *              MEM_SmartPtr<foo> m_foo;
84  *      }
85  *                      
86  * You may also safely construct vectors of MEM_SmartPtrs and 
87  * have the vector own stuff you put into it. 
88  *
89  * e.g.
90  * { 
91  * std::vector<MEM_SmartPtr<foo> > foo_vector;
92  * foo_vector.push_back( new foo());
93  * foo_vector.push_back( new foo());
94  *
95  * foo_vector[0]->bla();
96  * } // foo_vector out of scope => heap memory freed for both foos
97  *
98  * @warning this class should only be used for objects created
99  * on the heap via the new function. It will not behave correctly
100  * if you pass ptrs to objects created with new[] nor with 
101  * objects declared on the stack. Doing this is likely to crash
102  * the program or lead to memory leaks.
103  */
104
105 template 
106         < class T >
107 class MEM_SmartPtr {
108
109 public :
110
111         /**
112          * Construction from reference - this class
113          * always assumes ownership from the rhs.
114          */
115
116         MEM_SmartPtr(
117                 const MEM_SmartPtr &rhs
118         ){
119                 m_val = rhs.Release();
120         }
121
122         /**
123          * Construction from ptr - this class always
124          * assumes that it now owns the memory associated with the
125          * ptr.
126          */
127
128         MEM_SmartPtr(
129                 T* val
130         ) :
131                 m_val (val)
132         {
133         }
134         
135         /**
136          * Defalut constructor
137          */
138
139         MEM_SmartPtr(
140         ) :
141                 m_val (NULL)
142         {
143         }
144
145         /**
146          * Type conversion from this class to the type
147          * of a pointer to the template parameter. 
148          * This means you can pass an instance of this class
149          * to a function expecting a ptr of type T.
150          */
151
152         operator T * () const {
153                 return m_val;
154         }
155
156         /**
157          * Return a reference to the internal ptr class.
158          * Use with care when you now that the internal ptr
159          * is not NULL!
160          */
161
162                 T &
163         Ref(
164         ) const {
165                 return *m_val;
166         }       
167
168         /** 
169          * Assignment operator - ownership is transfered from rhs to lhs. 
170          * There is an intenional side-effect of function of transferring
171          * ownership from the const parameter rhs. This is to insure 
172          * the 1-1 relationship.
173          * The object associated with this instance is deleted if it 
174          * is not the same as that contained in the rhs.
175          */
176
177         MEM_SmartPtr & operator=(
178                 const MEM_SmartPtr &rhs
179         ) {
180                 if (this->m_val != rhs.m_val) {
181                         delete this->m_val;
182                 }
183
184                 this->m_val = rhs.Release();
185                 return *this;
186         }
187         
188         /** 
189          * Overload the operator -> so that it's possible to access
190          * all the normal methods of the internal ptr. 
191          */
192         
193         T * operator->() const {
194                 return m_val;
195         }
196
197         /**
198          * Caller takes ownership of the object - the object will not 
199          * be deleted when the ptr goes out of scope.
200          */
201
202                 T *
203         Release(
204         ) const {
205                 T* temp = m_val;
206                 (const_cast<MEM_SmartPtr *>(this))->m_val = NULL;       
207                 return temp;
208         }
209
210         /**
211          * Force destruction of the internal object.
212          */
213         
214                 void
215         Delete(
216         ) {
217                 delete (m_val);
218                 m_val = NULL;
219         }
220
221         /** 
222          * Destructor - deletes object if it exists
223          */
224
225         ~MEM_SmartPtr(
226         ) {
227                 delete (m_val);
228         }
229
230 private :
231         
232         /// The ptr owned by this class.
233         T * m_val;
234 };
235
236 #endif
237