casacore
Loading...
Searching...
No Matches
COWPtr.h
Go to the documentation of this file.
1//# COWPtr.h: this defines the Copy-On-Write-Pointer class.
2//# Copyright (C) 1996,1997,1999
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//#
27//# $Id$
28
29#ifndef CASA_COWPTR_H
30#define CASA_COWPTR_H
31
32#include <casacore/casa/aips.h>
33#include <casacore/casa/Utilities/CountedPtr.h>
34
35namespace casacore { //# NAMESPACE CASACORE - BEGIN
36
37// <summary>
38// Copy-On-Write-Pointer class - allows control of copy based on constness.
39// </summary>
40
41// <use visibility=export>
42
43// <reviewed reviewer="Ger van Diepen" date="1996/02/21" tests="tCOWPtr.cc" demos="">
44// </reviewed>
45
46// <prerequisite>
47// <li> none
48// </prerequisite>
49//
50// <etymology>
51// The COWPtr class name is a contraction of Copy-On-Write-Pointer
52// and is a reflection of its role as a carrier of objects which need to
53// minimize their copying and control their destruction. Such objects only
54// need to copy if written to.
55// </etymology>
56//
57// <synopsis>
58// COWPtr can be used by other classes to implement copy-on-write
59// semantics. Copy-on-write means that a copy of an object is not
60// made until necessary. A well-known example is a String class
61// with internally a pointer to a StringRep containing the true string.
62// When a copy of a String is made, the StringRep is not copied yet.
63// Only when the String gets changed and when more than one String
64// points to the same StringRep, a copy of the StringRep is made.
65// This technique can prevent a lot of copying when arguments are
66// passed by value.
67//<br>
68// Implementing a String in this way is straightforward when
69// String defines the pointer to its StringRep as <src>COWPtr<StringRep></src>
70// and uses the appropriate functions (ref() and rwRef()) to execute
71// const and non-const StringRep functions.
72//<br>
73// An example of this (straightforward) usage is class
74// <linkto class=RecordDesc>RecordDesc</linkto>.
75//<p>
76// COWPtr offers possibilities for more advanced usage:
77// <ul>
78// <li> Normally a copy (on write) is made when more than one String points to
79// the same StringRep. By constructing the COWPtr object with
80// readOnly=True, it is possible to already do that when only one
81// String points to a StringRep. This can be used when a function
82// returns an object referencing a constant object. For instance,
83// a function can return an Array object referencing another Array
84// which should not be altered.
85// By returning a <src>COWPtr<Array></src> with readOnly=True,
86// it is assured that a copy is made as soon as somebody wants
87// to change the returned Array object. No (expensive) copy is
88// made when only const access is being done.
89// <li> Normally the COWPtr object takes over the pointer and deletes
90// the underlying object when it is not used anymore. With the
91// deleteIt flag it is possible to change this behavior.
92//</ul>
93//<p>
94// Apart from the fact that COWPtr handles the copying, it has
95// the big advantage that it forces that its access functions (ref and
96// rwRef) are used in the correct way (ie. ref() for a const
97// function and rwRef() for a non-const function). This ensures that
98// copies are made when needed and not made when not needed.
99//<p>
100// Note that COWPtr uses the default constructor and the assignment
101// operator to make a copy (thus not the copy constructor). The
102// reason for this is that the copy constructor of some classes
103// (e.g. Array) has reference semantics iso. copy semantics.
104// </synopsis>
105//
106// <example>
107// <h4>Example 1:</h4>
108// <srcblock>
109// class String {
110// public:
111// // The constructor allocates a StringRep and hands to pointer
112// // to COWPtr.
113// String()
114// : itsRep (new StringRep;) {}
115// // This non-const function needs rwRef to make a copy when needed.
116// void set (const char* str) {itsRep.rwRef().set (str);}
117// // This const function can use ref (making a copy is not needed).
118// const char* get const {return itsRep.ref();}
119// private:
120// COWPtr<StringRep> itsRep;
121// };
122// class StringRep {
123// friend class String;
124// private:
125// void set (const char*);
126// const char* get() const;
127// char* itsData;
128// };
129//</srcblock>
130// <h4>Example 2:</h4>
131// This function requires a const Array be passed out from the local scope.
132// The Array is created with non-const functions out of necessity (i.e. no
133// const versions of the Array::getSlice() function exist.) Preventing
134// copies of the Array from being made forces us to use a COWPtr. The COWPtr
135// has arguments which allow us to declare the Array as const and not make
136// any copies until a write operation is performed.
137// <srcblock>
138// void myFunc(COWPtr<Array<Float> > &obj){
139// // make a nonconst from some static const Array that exists "out there"
140// Array<Float> &nonConstArray = (Array<Float> &)staticConstArray;
141// // "fill" the COWPtr and bring back constness without copying. The first
142// // "True" argument indicates the caller of this function may take
143// // control of the dynamic pointer's destruction. The second "True"
144// // argument indicates the array is read only and should make a copy of
145// // itself if writing is needed.
146// obj.set(new Array<Float>(nonConstArray.getSlice(...), True, True));
147// }
148// </srcblock>
149// The caller of the function will get their piece of a const array without
150// making a copy until the last possible moment (maybe never.)
151// <srcblock>
152// #include <casacore/casa/Utilities/COWPtr.h>
153// main(){
154// // create a null filled COWPtr
155// COWPtr<Array<Float> > COW;
156// // fill it inside myfunc
157// myFunc(COW);
158// // use a single element - still no copies have been made!
159// Float someVal = COW->operator()(IPosition(2,3,3))
160// // write to the array - now we get a copy!
161// COW.rwRef().set(42.0f);
162// // etc...
163// };
164// </srcblock>
165// </example>
166//
167// <motivation>
168// Three words; efficiency, efficiency, efficiency. Not everything may be
169// passed as a reference. With COWPtrs we may fake it.
170// </motivation>
171//
172// <templating arg=T>
173// <li> default constructor
174// <li> assignment operator
175// </templating>
176//
177// <thrown>
178// <li> AipsError
179// </thrown>
180//
181// <todo asof="1996/01/16">
182// <li> none
183// </todo>
184
185template <class T> class COWPtr
186{
187public:
188
189 // The default constructor: used to create a null pointer which is
190 // delete-able by the destructor. It is not "readOnly" so that it may be
191 // changed by the COWPtr<T>::set() function.
192 inline COWPtr();
193
194 // The dynamic "pointer to object" constructor: default behavior is to
195 // delete the allocated memory when this instance's of COWPtr is destructed.
196 // Or the Boolean argument of "deleteIt = False" implies the pointer is
197 // being maintained by an object other than this instance of COWPtr and
198 // will not delete the allocated memory upon this instance's destruction.
199 // Control of copying is provided by the Boolean "readOnly" argument. The
200 // default value of "readOnly = False" forces a copy if the number of
201 // references to the dynamic memory is greater than one. Copying is always
202 // done if the constructor is given an argument of "readOnly = True".
203 // <note> The only copying done (if ever) is upon a call to
204 // COWPtr<T>::rwRef().</note>
205 explicit COWPtr(T *obj, Bool deleteIt = True, Bool readOnly = False);
206
207 // copy ctor with reference semantics
208 inline COWPtr(const COWPtr<T> &other);
209
210 // assignment operator with reference semantics
211 inline COWPtr &operator=(const COWPtr<T> &other);
212
213 // return a pointer to a const object. This prevents "write" operations.
214 inline const T *operator->() const;
215
216 // return a reference to a const object. This prevents "write" operations.
217 inline const T &operator*() const;
218
219 // Function used to change this instance of COWPtr. The pointer must be
220 // dynamically allocated. Default behavior is to
221 // delete the allocated memory when this instance's of COWPtr is destructed.
222 // Or the Boolean argument of "deleteIt = False" implies the pointer is
223 // being maintained by an object other than this instance of COWPtr and
224 // will not delete the allocated memory upon this instance's destruction.
225 // Control of copying is provided by the Boolean "readOnly" argument. The
226 // default value of "readOnly = False" forces a copy if the number of
227 // references to the dynamic memory is greater than one. Copying is always
228 // done if the constructor is given an argument of "readOnly = True".
229 // <note> The only copying done (if ever) is upon a call to
230 // COWPtr<T>::rwRef().
231 // </note>
232 // The <src>setReadOnly</src> function is the same as <src>set</src>, but
233 // forces <src>deleteIt=False</src> and <src>ReadOnly=True</src>. In
234 // that way a const object can also be safely referenced by COWPtr.
235 // <group>
236 void set(T *obj, Bool deleteIt = True, Bool readOnly = False);
237 void setReadOnly (const T *obj);
238 void setReadOnly ();
239 // </group>
240
241 // return a const reference to the object.
242 inline const T &ref() const;
243
244 // return a readable and writable reference to this instance. Instances of
245 // COWPtr constructed with argument "readOnly = True" will be made a copy.
246 // Additionally, all instances of COWPtr with more than one reference to
247 // the allocated memory stored within will be copied.
248 inline T &rwRef();
249
250 // returns False if this contains a non-null ptr, otherwise, return True.
251 inline Bool isNull() const;
252
253 // returns True if the object is const, otherwise, return False.
254 inline Bool isReadOnly() const;
255
256 // returns True if the object is the only instance, otherwise, return False.
257 inline Bool isUnique() const;
258
259 // Return True if copied, otherwise, False. This function will make this
260 // instance's object a copy if it is constructed with
261 // "readOnly = True." Additionally, all instances of COWPtr with more
262 // than one reference to the allocated memory stored within will be
263 // copied.
265
266protected:
269};
270
271
272
273// Make our own default pointer - deleteIt==True by default, const_p==False
274template <class T> inline COWPtr<T>::COWPtr()
275:obj_p(static_cast<T *>(0), True), const_p(False)
276{
277 // does nothing
278}
279
280// copy ctor with reference semantics
281template <class T> inline COWPtr<T>::COWPtr(const COWPtr<T> &other)
282: obj_p(other.obj_p), const_p(other.const_p)
283{
284 // does nothing
285}
286
287//assignment operator with reference semantics
288template <class T>
290{
291 if (this != &other){
292 obj_p = other.obj_p;
293 const_p = other.const_p;
294 }
295 return *this;
296}
297
298template <class T> inline void COWPtr<T>::setReadOnly (const T *obj)
299{
300 set ((T*)obj, False, True);
301}
302
303template <class T> inline void COWPtr<T>::setReadOnly ()
304{
305 const_p = True;
306}
307
308template <class T> inline const T *COWPtr<T>::operator->() const
309{
310 return obj_p.operator->();
311}
312
313template <class T> inline const T &COWPtr<T>::operator*() const
314{
315 return obj_p.operator*();
316}
317
318template <class T> inline const T &COWPtr<T>::ref() const
319{
320 return *obj_p;
321}
322
323template <class T> inline T &COWPtr<T>::rwRef()
324{
325 makeUnique();
326 return *obj_p;
327}
328
329template <class T> inline Bool COWPtr<T>::isNull() const
330{
331 return obj_p.null();
332}
333
334template <class T> inline Bool COWPtr<T>::isReadOnly() const
335{
336 return const_p;
337}
338
339template <class T> inline Bool COWPtr<T>::isUnique() const
340{
341 return (const_p || obj_p.nrefs()>1) ? False : True;
342}
343
344
345
346} //# NAMESPACE CASACORE - END
347
348#ifndef CASACORE_NO_AUTO_TEMPLATES
349#include <casacore/casa/Utilities/COWPtr.tcc>
350#endif //# CASACORE_NO_AUTO_TEMPLATES
351#endif
const T * operator->() const
return a pointer to a const object.
Definition COWPtr.h:308
Bool isReadOnly() const
returns True if the object is const, otherwise, return False.
Definition COWPtr.h:334
Bool isNull() const
returns False if this contains a non-null ptr, otherwise, return True.
Definition COWPtr.h:329
COWPtr()
The default constructor: used to create a null pointer which is delete-able by the destructor.
Definition COWPtr.h:274
Bool makeUnique()
Return True if copied, otherwise, False.
Bool isUnique() const
returns True if the object is the only instance, otherwise, return False.
Definition COWPtr.h:339
COWPtr & operator=(const COWPtr< T > &other)
assignment operator with reference semantics
Definition COWPtr.h:289
COWPtr(T *obj, Bool deleteIt=True, Bool readOnly=False)
The dynamic "pointer to object" constructor: default behavior is to delete the allocated memory when ...
CountedPtr< T > obj_p
Definition COWPtr.h:267
void setReadOnly(const T *obj)
Definition COWPtr.h:298
COWPtr(const COWPtr< T > &other)
copy ctor with reference semantics
Definition COWPtr.h:281
const T & operator*() const
return a reference to a const object.
Definition COWPtr.h:313
void set(T *obj, Bool deleteIt=True, Bool readOnly=False)
Function used to change this instance of COWPtr.
T & rwRef()
return a readable and writable reference to this instance.
Definition COWPtr.h:323
void setReadOnly()
Definition COWPtr.h:303
const T & ref() const
return a const reference to the object.
Definition COWPtr.h:318
Referenced counted pointer for constant data.
Definition CountedPtr.h:81
this file contains all the compiler specific defines
Definition mainpage.dox:28
const Bool False
Definition aipstype.h:44
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:42
const Bool True
Definition aipstype.h:43