remove $Id: tags after discussion on the mailign list: http://markmail.org/message...
[blender.git] / intern / memutil / MEM_SmartPtr.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file memutil/MEM_SmartPtr.h
29  *  \ingroup memutil
30  */
31
32 /**
33  * @file        MEM_SmartPtr.h
34  * Declaration of MEM_RefCounted and MEM_RefCountable classes.
35  * @author Laurence
36  */
37
38 #ifndef NAN_INCLUDED_MEM_SmartPtr_h
39 #define NAN_INCLUDED_MEM_SmartPtr_h
40
41
42 #include <stdlib.h> // for NULL !
43
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 explicitly declare 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 enforceable 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 may 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
241