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