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