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