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