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