casacore
PtrHolder.h
Go to the documentation of this file.
1 //# PtrHolder.h: Hold and delete pointers not deleted by object destructors
2 //# Copyright (C) 1994,1995,1999,2000
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef CASA_PTRHOLDER_H
29 #define CASA_PTRHOLDER_H
30 
31 //# Includes
32 #include <casacore/casa/aips.h>
33 
34 
35 namespace casacore { //# NAMESPACE CASACORE - BEGIN
36 
37 // <summary>
38 // Hold and delete pointers not deleted by object destructors
39 // </summary>
40 
41 // <use visibility=export>
42 // <reviewed reviewer="troberts" date="1995/07/29" tests="tPtrHolder">
43 // </reviewed>
44 
45 // <prerequisite>
46 // <li> module <linkto module=Exceptions>Exceptions</linkto>
47 // </prerequisite>
48 
49 // <synopsis>
50 // <src>PtrHolder</src>s hold allocated pointers which should be
51 // deleted when an exception is thrown. Exceptions only call destructors
52 // of objects. Thus, for example, storage allocated in a global function
53 // (outside of an object)is not deleted. A <src>PtrHolder</src> solves
54 // this problem: it merely holds the pointer and deletes it when it is
55 // destroyed itself, e.g. when an exception is thrown or when the
56 // function exits normally.
57 // </synopsis>
58 
59 // <example>
60 // <srcblock>
61 // void func(Int *ptr); // some other function that takes a pointer
62 // // ...
63 // // True below means it's an array, False (the default) would mean
64 // // a singleton object.
65 // PtrHolder<Int> iholder(new Int[10000], True);
66 // func(iholder); // converts automatically to ptr
67 // (iholder.ptr() + 5) = 11; // use pointer explicitly
68 // some_function_that_throws_exception(); // pointer is deleted
69 // </srcblock>
70 // </example>
71 
72 // <motivation>
73 // Avoid leaks when throwing/catching exceptions.
74 // </motivation>
75 
76 // <todo asof="2000/04/11">
77 // <li> Use the autoptr class from the Standard Library
78 // </todo>
79 
80 
81 template<class T> class PtrHolder
82 {
83 public:
84  // The default constructor uses a null pointer.
86 
87  // Construct a <src>PtrHolder</src> from a pointer which MUST have
88  // been allocated from <src>new</src>, since the destructor will
89  // call <src>delete</src> on it. If the pointer is to an array,
90  // i.e. allocated with operator <src>new[]</src>, then
91  // <src>isCarray</src> should be set to True. (This parameter is
92  // required because C-arrays need to be deleted with
93  // <src>delete[]</src>.)
94  //
95  // After the pointer is placed into the holder, the user should
96  // not manually delete the pointer; the <src>PtrHolder</src>
97  // object will do that, unless <src>set()</src> or
98  // <src>clear()</src> is called with <src>deleteCurrentPtr</src>
99  // set to False. The pointer must also only be put into
100  // <em>one</em> holder to avoid double deletion.
101  PtrHolder(T *pointer, Bool isCArray = False);
102 
104 
105  // Set the pointer to a new value. If <src>deleteCurrentPtr </src>is
106  // True (the default), then delete the existing pointer first. If
107  // <src>isCarray</src> is True, then the new pointer is assumed to
108  // have been allocated with <src>new[]</src>.
109  void set(T *pointer, Bool isCarray = False, Bool deleteCurrentPtr = True);
110 
111  // Set the current pointer to null; if <src>deletePtr</src> is True
112  // (the default), then the current pointer is deleted first.
113  void clear(Bool deleteCurrentPtr = True);
114 
115  // Release the pointer for use.
116  // <group>
117  T *ptr() { return ptr_p; }
118  const T *ptr() const { return ptr_p; }
119  // </group>
120 
121  // Attempt to automatically release a pointer when required. If the
122  // compiler can't figure it out, you can use the <src>ptr()</src>
123  // member function directly.
124  operator T *() { return ptr_p; }
125  operator T *() const { return ptr_p; }
126  // </group>
127 
128  // Make it possible to use -> on the pointer object.
129  T* operator->() const
130  { return ptr_p; }
131 
132  // See if the pointer points to a C-array.
133  Bool isCArray() const {return isCarray_p;}
134 
135 private:
136  //# Undefined and inaccessible
137  PtrHolder(const PtrHolder<T> &other);
139 
140  //# We'd also like the following to be undefined and inaccessible,
141  //# unfortunately CFront doesn't seem to let you do that.
142  //# void *operator new(size_t s);
143 
144  //# Put functionality in one place
146 
147  T *ptr_p;
148  //# If space were critical, we could make isCarray_p a char
150 };
151 
152 
153 
154 // <summary>
155 // Hold and delete pointers not deleted by object destructors
156 // </summary>
157 
158 // <use visibility=export>
159 // <reviewed reviewer="" date="" tests="tPtrHolder">
160 // </reviewed>
161 
162 // <prerequisite>
163 // <li> module <linkto module=Exceptions>Exceptions</linkto>
164 // </prerequisite>
165 
166 // <synopsis>
167 // <src>SPtrHolder</src>s hold allocated pointers to non-array objects
168 // which should be deleted when an exception is thrown.
169 // SPtrHolder is similar to PtrHolder, but easier to use and only valid
170 // for pointer to a single object, thus not to a C-array of objects.
171 // </synopsis>
172 
173 // <example>
174 // <srcblock>
175 // void func(Table *ptr); // some other function that takes a pointer
176 // // ...
177 // // True below means it's an array, False (the default) would mean
178 // // a singleton object.
179 // SPtrHolder<Int> iholder(new Table(...));
180 // func(iholder); // converts automatically to ptr
181 // Table* tab = iholder.transfer(); // transfer ownership
182 // </srcblock>
183 // If an exception is thrown in function <src>func</src>, the Table will be
184 // deleted automatically. After the function call, the ownership is tranfered
185 // back to the 'user'
186 // </example>
187 
188 // <motivation>
189 // <src>std::auto_ptr</src> is harder to use and its future is unclear.
190 // <br>
191 // <src>PtrHolder</src> is not fully inlined and has C-array overhead.
192 // Furthermore the automatic conversion to a T* is dangerous, because the
193 // programmer may not be aware that the pointer is maybe taken over.
194 // </motivation>
195 
196 
197 template<class T> class SPtrHolder
198 {
199 public:
200  // Construct an <src>SPtrHolder</src> from a pointer which MUST have
201  // been allocated from <src>new</src>, since the destructor will
202  // After the pointer is placed into the holder, the user should
203  // not manually delete the pointer unless the transfer function is called.
204  // The pointer must also only be put into
205  // <em>one</em> holder to avoid double deletion.
206  explicit SPtrHolder (T* ptr = 0)
207  : itsPtr(ptr) {}
208 
210  { delete itsPtr; }
211 
212  // Reset the pointer.
213  void reset (T* ptr)
214  { if (ptr != itsPtr) { delete itsPtr; itsPtr = ptr; }}
215 
216  // Transfer ownership of the pointer.
217  // I.e. return the pointer and set it to 0 in the object.
218  T* transfer()
219  { T* ptr = itsPtr; itsPtr = 0; return ptr; }
220 
221  // Release the pointer.
222  void release()
223  { itsPtr = 0; }
224 
225  // Make it possible to dereference the pointer object.
226  // <group>
228  { return *itsPtr; }
229  const T& operator*() const
230  { return *itsPtr; }
231  // </group>
232 
233  // Make it possible to use -> on the pointer object.
234  T* operator->() const
235  { return itsPtr; }
236 
237  // Get the pointer for use.
238  // <group>
239  T* ptr()
240  { return itsPtr; }
241  const T* ptr() const
242  { return itsPtr; }
243  // </group>
244 
245 private:
246  // SPrtHolder cannot be copied.
247  // <group>
248  SPtrHolder(const SPtrHolder<T> &other);
250  // </group>
251 
252  //# The pointer itself.
253  T* itsPtr;
254 };
255 
256 
257 
258 } //# NAMESPACE CASACORE - END
259 
260 #ifndef CASACORE_NO_AUTO_TEMPLATES
261 #include <casacore/casa/Utilities/PtrHolder.tcc>
262 #endif //# CASACORE_NO_AUTO_TEMPLATES
263 #endif
Hold and delete pointers not deleted by object destructors.
Definition: PtrHolder.h:198
T * itsPtr
Definition: PtrHolder.h:253
T * operator->() const
Make it possible to use -> on the pointer object.
Definition: PtrHolder.h:234
void release()
Release the pointer.
Definition: PtrHolder.h:222
SPtrHolder(const SPtrHolder< T > &other)
SPrtHolder cannot be copied.
void reset(T *ptr)
Reset the pointer.
Definition: PtrHolder.h:213
const T & operator*() const
Definition: PtrHolder.h:229
T * transfer()
Transfer ownership of the pointer.
Definition: PtrHolder.h:218
const T * ptr() const
Definition: PtrHolder.h:241
T * ptr()
Get the pointer for use.
Definition: PtrHolder.h:239
SPtrHolder(T *ptr=0)
Construct an SPtrHolder from a pointer which MUST have been allocated from new, since the destructor ...
Definition: PtrHolder.h:206
SPtrHolder< T > & operator=(const SPtrHolder< T > &other)
T & operator*()
Make it possible to dereference the pointer object.
Definition: PtrHolder.h:227
const T * ptr() const
Definition: PtrHolder.h:118
PtrHolder()
The default constructor uses a null pointer.
PtrHolder(T *pointer, Bool isCArray=False)
Construct a PtrHolder from a pointer which MUST have been allocated from new, since the destructor wi...
T * ptr()
Release the pointer for use.
Definition: PtrHolder.h:117
void set(T *pointer, Bool isCarray=False, Bool deleteCurrentPtr=True)
Set the pointer to a new value.
void clear(Bool deleteCurrentPtr=True)
Set the current pointer to null; if deletePtr is True (the default), then the current pointer is dele...
this file contains all the compiler specific defines
Definition: mainpage.dox:28
const Bool False
Definition: aipstype.h:44
T * operator->() const
Make it possible to use -> on the pointer object.
Definition: PtrHolder.h:129
Bool isCarray_p
Definition: PtrHolder.h:149
PtrHolder< T > & operator=(const PtrHolder< T > &other)
void delete_pointer_if_necessary()
Bool isCArray() const
See if the pointer points to a C-array.
Definition: PtrHolder.h:133
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
const Bool True
Definition: aipstype.h:43
T * ptr_p
Definition: PtrHolder.h:147