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