casacore
casa
Utilities
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
35
namespace
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
185
template
<
class
T>
class
COWPtr
186
{
187
public
:
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