casa
$Rev:20696$
|
00001 //# CountedPtr.h: Referenced counted pointer classes 00002 //# Copyright (C) 1993,1994,1995,1996,1999,2001 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: CountedPtr.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00027 00028 #ifndef CASA_COUNTEDPTR_H 00029 #define CASA_COUNTEDPTR_H 00030 00031 #include <casa/aips.h> 00032 00033 // Uncommenting out the following two lines will define USE_SHARED_PTR and 00034 // cause the implementtion of CountedPtr to use a thread-safe smart 00035 // pointer implementation class inside (at this writing this will be 00036 // boost::shared_ptr but will eventually be std::shared_ptr). 00037 // Another effect is that portions of the measures framework will use 00038 // boost::recursive_mutex to make those classes friendly to multithreading. 00039 // 00040 // N.B.: I would not recommend mixing defined/undefined for the two symbols. 00041 // 00042 // Changing the setting will causes a major rebuild of both the casacore 00043 // and code projects since CountedPtr underlies most data structures and 00044 // because of the template nature of CountedPtr. (jjacobs 7/19/12) 00045 // 00048 00049 #if ! defined (USE_SHARED_PTR) 00050 00051 //==================================================================== 00052 //==================================================================== 00053 // 00054 // This is the original, thread-hostile implementatlow ion. 00055 // For nonthreaded applications it's fine, though and as a bonus 00056 // it does not incur and dependencies on boost. 00057 // 00058 //==================================================================== 00059 //==================================================================== 00060 00061 #include <casa/aips.h> 00062 00063 namespace casa { //#Begin casa namespace 00064 00065 //# Forward Declarations 00066 template<class t> class SimpleCountedPtr; 00067 template<class t> class SimpleCountedConstPtr; 00068 template<class t> class CountedPtr; 00069 template<class t> class CountedConstPtr; 00070 00071 // <summary> act on dereference error </summary> 00072 // <synopsis> 00073 // Global function that throws an exception. It is called by the 00074 // member functions of the counted pointer classes when an 00075 // un-initialized (null) pointer is followed. 00076 // </synopsis> 00077 // <group name=dereference_error> 00078 void throw_Null_CountedPtr_dereference_error(); 00079 // </group> 00080 00081 // <summary>Internal representation for <src>CountedPtr</src></summary> 00082 // <use visibility=local> 00083 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00084 00085 // <prerequisite> 00086 // <li> class <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto> 00087 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto> 00088 // </prerequisite> 00089 00090 // <synopsis> 00091 // This class is a utility class for 00092 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto> 00093 // and <linkto class="CountedPtr:description">CountedPtr</linkto>. 00094 // It stores the reference count and the pointer to the real data. 00095 // 00096 // <note role=tip> It is currently a template and is used such that 00097 // <src>t</src> is the <em>true</em> type of the stored pointer. This 00098 // means, however, that when it is used, a template instantiation must be 00099 // done for each type which <src>t</src> assumes. This makes debugging 00100 // easier, but in the future all of these pointers could be declared with 00101 // <src>void</src> type to avoid template instantiations. 00102 // </note> 00103 // </synopsis> 00104 00105 // <motivation> 00106 // This class isolates all of the low level management of the reference. 00107 // </motivation> 00108 00109 template<class t> class PtrRep 00110 { 00111 00112 public: 00113 00114 friend class SimpleCountedPtr<t>; 00115 friend class SimpleCountedConstPtr<t>; 00116 friend class CountedPtr<t>; 00117 friend class CountedConstPtr<t>; 00118 00119 protected: 00120 00121 // This constructor sets up the reference count to one and 00122 // initializes the pointer to the real data. The 00123 // <src>delit</src> flag can be passed in to indicate whether 00124 // the real data should be freed or not when the 00125 // reference count reaches zero. 00126 // <group> 00127 PtrRep(t *v) : val(v), count(1), deletable(True) {} 00128 PtrRep(t *v, Bool delit) : val(v), count(1), deletable(delit) {} 00129 // </group> 00130 00131 // This deletes the real data if indeed it can be deleted. 00132 void freeVal(); 00133 00134 // This destructor uses the <src>deletable</src> flag to indicate if the 00135 // real data should be freed or not. 00136 // 00137 ~PtrRep() { 00138 freeVal(); 00139 } 00140 00141 private: 00142 00143 t *val; 00144 unsigned int count; 00145 Bool deletable; 00146 00147 }; 00148 00149 // <summary>Simple referenced counted pointer for constant data</summary> 00150 // <use visibility=export> 00151 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00152 00153 // <etymology> 00154 // This class is <em>Simple</em> because it does not have the 00155 // <src>operator->()</src> operator. This means that it puts less demands 00156 // on the underlying type. It is <em>Counted</em> because it is reference 00157 // counted, and it is <em>Const</em> because the underlying value is 00158 // non-modifiable. 00159 // </etymology> 00160 00161 // <synopsis> 00162 // This class implements a simple reference counting mechanism. It 00163 // allows <src>SimpleCountedConstPtr</src>s to be passed around freely, 00164 // incrementing or decrementing the reference count as needed when one 00165 // <src>SimpleCountedConstPtr</src> is assigned to another. When the 00166 // reference count reaches zero the internal storage is deleted by 00167 // default, but this behavior can be overridden. 00168 // 00169 // This class is used as a pointer to constant data. As such, it only 00170 // has the subset of the 00171 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto> 00172 // functions which are relevant for constant data. 00173 // </synopsis> 00174 00175 // <motivation> 00176 // Reference counting 00177 // </motivation> 00178 00179 template<class t> class SimpleCountedConstPtr 00180 { 00181 public: 00182 00183 // This constructor allows for the creation of a null 00184 // <src>SimpleCountedConstPtr</src>. The assignment operator can be used 00185 // to assign a null <src>SimpleCountedConstPtr</src> from another 00186 // pointer. 00187 // 00188 SimpleCountedConstPtr() : ref(0) {} 00189 00190 // This constructor sets up a reference count for the <src>val</src> 00191 // pointer. By default, the data pointed to by <src>val</src> 00192 // will be deleted when it is no longer referenced. Passing in 00193 // <src>False</src> for <src>delit</src> will prevent the data 00194 // from being deleted when the reference count reaches zero. 00195 // 00196 // <note role=warning> After the counted pointer is initialized 00197 // the value should no longer be manipulated by the raw pointer of 00198 // type <src>t*</src>. 00199 // </note> 00200 // 00201 SimpleCountedConstPtr(t *val, Bool delit = True) { 00202 ref = new PtrRep<t>(val,delit); 00203 } 00204 00205 // This constructor sets up a reference count for the 00206 // <src>val</src> pointer. Since <src>val</src> is a pointer to 00207 // constant data, the data will not be deleted when the reference 00208 // count reaches zero. 00209 // 00210 // <note role=tip> Since the constant data will NOT be cleaned up 00211 // when the reference count reaches zero, the use of this class for 00212 // pointers to constant data may not be desirable. 00213 // </note> 00214 // 00215 SimpleCountedConstPtr(const t *val) { 00216 ref = new PtrRep<t>((t *) val,False); 00217 } 00218 00219 // This copy constructor allows <src>SimpleCountedConstPtr</src>s to be 00220 // initialized from other <src>SimpleCountedConstPtr</src>s. 00221 // 00222 SimpleCountedConstPtr(const SimpleCountedConstPtr<t> &val) : ref(val.ref) { 00223 if (ref) 00224 (*ref).count++; 00225 } 00226 00227 // This destructor only deletes the really stored data when it was 00228 // initialized as deletable and the reference count is zero. 00229 // 00230 virtual ~SimpleCountedConstPtr(); 00231 00232 // The <src>SimpleCountedConstPtr</src> indirection operator simply 00233 // returns a reference to the value being protected. If the pointer 00234 // is un-initialized (null), an exception will be thrown. The member 00235 // function 00236 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 00237 // can be used to catch such a condition in time. 00238 // 00239 // <thrown> 00240 // <li> ExcpError 00241 // </thrown> 00242 // 00243 // <note role=tip> The address of the reference returned should 00244 // not be stored for later use. 00245 // </note> 00246 // 00247 const t &operator*() const { 00248 if (!ref) throw_Null_CountedPtr_dereference_error(); 00249 return(*(*ref).val); 00250 } 00251 00252 // Equality operator which checks to see if two 00253 // <src>SimpleCountedConstPtr</src>s are pointing at the same thing. 00254 // 00255 Bool operator==(const SimpleCountedConstPtr<t> &other) const { 00256 return (ref == other.ref ? True : False); 00257 } 00258 00259 // Non-equality operator which checks to see if two 00260 // <src>SimpleCountedConstPtr</src>s are not pointing at the same thing. 00261 // 00262 Bool operator!=(const SimpleCountedConstPtr<t> &other) const { 00263 return (ref != other.ref ? True : False); 00264 } 00265 00266 // This assignment operator allows <src>SimpleCountedConstPtr</src>s 00267 // to be freely assigned to each other. 00268 // 00269 SimpleCountedConstPtr<t> &operator=(const SimpleCountedConstPtr<t> &val) { 00270 if (ref && --(*ref).count == 0){ 00271 delete ref; 00272 ref = 0; 00273 } 00274 if ((ref = val.ref) != 0) 00275 (*ref).count++; 00276 return *this; 00277 } 00278 00279 // This assignment operator allows the object to which the current 00280 // <src>SimpleCountedConstPtr</src> points to be changed. 00281 // 00282 SimpleCountedConstPtr<t> &operator=(t *v); 00283 00284 // Sometimes it is useful to know if there is more than one 00285 // reference made. This is a way of getting that. Of course the point 00286 // of these classes is that this information is normally not required. 00287 // 00288 uInt nrefs() const {return ref->count;} 00289 00290 // This function changes the value for this 00291 // <src>SimpleCountedConstPtr</src> and all of the other 00292 // <src>SimpleCountedConstPtr</src>s which point to this same value. 00293 // 00294 // <note role=warning> This is dangerous, and generally should not 00295 // be done. 00296 // </note> 00297 // 00298 // 00299 // ==> This method violates the expected semantics for a smart pointer 00300 // (both boost and C++0x) and should not be used. The existing CASA 00301 // use of this method has been rewritten to accomplish it's needs without 00302 // polluting this class. 00303 00304 void replace(t *v, Bool delit = True) __attribute__ ((deprecated)) { 00305 if (ref) { 00306 (*ref).freeVal(); 00307 (*ref).val = v; 00308 (*ref).deletable = delit; 00309 } 00310 } 00311 00312 // Check to see if this <src>SimpleCountedConstPtr</src> is 00313 // un-initialized, null. 00314 // 00315 Bool null() const { return (ref==0 || (ref->val == 0));} 00316 00317 protected: 00318 00319 PtrRep<t> *ref; 00320 00321 }; 00322 00323 // <summary>Regular referenced counted pointer for constant data</summary> 00324 // <use visibility=export> 00325 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00326 00327 // <prerequisite> 00328 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto> 00329 // </prerequisite> 00330 00331 // <synopsis> 00332 // This class has the same objective as 00333 // <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto> 00334 // but it adds the <src>operator->()</src>. It still only contains a 00335 // pointer whose underlying data cannot be changed. The destructor 00336 // deletes the underlying data when the reference count reaches zero. 00337 // </synopsis> 00338 00339 // <motivation> 00340 // <src>operator->()</src> is useful, but not always available for 00341 // every type. 00342 // </motivation> 00343 00344 template<class t> class CountedConstPtr : virtual public SimpleCountedConstPtr<t> { 00345 public: 00346 00347 // This constructor allows for the creation of a null 00348 // <src>CountedConstPtr</src>. The assignment operator can be 00349 // used to assign a null <src>CountedConstPtr</src> from 00350 // another pointer. 00351 // 00352 CountedConstPtr() : SimpleCountedConstPtr<t>() {} 00353 00354 // This constructor sets up a reference count for the <src>val</src> 00355 // pointer. By default, the data pointed to by <src>val</src> will 00356 // be deleted when it is no longer referenced. Passing in 00357 // <src>False</src> for <src>delit</src> will prevent the data 00358 // from being deleted when the reference count reaches zero. 00359 // 00360 // <note role=warning> After the counted pointer is initialized 00361 // the value should no longer be manipulated by the raw pointer 00362 // of type <src>t*</src>. 00363 // </note> 00364 // 00365 CountedConstPtr(t *val, Bool delit = True) : SimpleCountedConstPtr<t>(val,delit) {} 00366 00367 // This copy constructor allows <src>CountedConstPtr</src>s to be 00368 // initialized from other <src>CountedConstPtr</src>s. 00369 // 00370 CountedConstPtr(const CountedConstPtr<t> &val) : SimpleCountedConstPtr<t>(val) {} 00371 00372 // This assignment operator allows <src>CountedConstPtr</src>s to be 00373 // freely assigned to each other. 00374 // 00375 CountedConstPtr<t> &operator=(const CountedConstPtr<t> &val) { 00376 SimpleCountedConstPtr<t>::operator=(val); 00377 return *this; 00378 } 00379 00380 // This assignment operator allows the object to which the current 00381 // <src>CountedConstPtr</src> points to be changed. 00382 // 00383 CountedConstPtr<t> &operator=(t *v) { 00384 SimpleCountedConstPtr<t>::operator=(v); 00385 return *this; 00386 } 00387 00388 // This dereferencing operator behaves as expected; it returns the 00389 // pointer to the value being protected, and then its dereferencing 00390 // operator will be invoked as appropriate. If the pointer is 00391 // un-initialized (null), an exception will be thrown. The member 00392 // function 00393 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 00394 // can be used to catch such a condition in time. 00395 // 00396 // <thrown> 00397 // <li> ExcpError 00398 // </thrown> 00399 // 00400 const t *operator->() const { 00401 if (!this->ref) throw_Null_CountedPtr_dereference_error(); 00402 return ((*this->ref).val); 00403 } 00404 }; 00405 00406 // <summary> Simple referenced counted pointer to non-constant data</summary> 00407 // <use visibility=export> 00408 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00409 00410 // <prerequisite> 00411 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto> 00412 // </prerequisite> 00413 00414 // <synopsis> 00415 // This class, like 00416 // <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto>, 00417 // does not define the <src>operator->()</src>. Thus it can point to 00418 // simple data which does not have this operator defined. In contrast to 00419 // <src>SimpleCountedConstPtr</src>, this class points at non-constant 00420 // underlying data. The deletion properties are the same for both 00421 // classes. 00422 // </synopsis> 00423 00424 template<class t> class SimpleCountedPtr : virtual public SimpleCountedConstPtr<t> { 00425 public: 00426 00427 // This constructor allows for the creation of a null 00428 // <src>SimpleCountedPtr</src>. The assignment operator can be used 00429 // to assign a null <src>SimpleCountedPtr</src> from another pointer. 00430 // 00431 SimpleCountedPtr() : SimpleCountedConstPtr<t>() {} 00432 00433 // This constructor sets up a reference count for the <src>val</src> 00434 // pointer. By default, the data pointed to by <src>val</src> 00435 // will be deleted when it is no longer referenced. Passing in 00436 // <src>False</src> for <src>delit</src> will prevent the data 00437 // from being deleted when the reference count reaches zero. 00438 // 00439 // <note role=warning> After the counted pointer is initialized 00440 // the value should no longer be manipulated by the raw pointer 00441 // of type <src>t*</src>. 00442 // </note> 00443 // 00444 SimpleCountedPtr(t *val, Bool delit = True) : SimpleCountedConstPtr<t>(val,delit) {} 00445 00446 // This copy constructor allows <src>SimpleCountedPtr</src>s to be 00447 // initialized from other <src>SimpleCountedPtr</src>s. 00448 // 00449 SimpleCountedPtr(const SimpleCountedPtr<t> &val) : SimpleCountedConstPtr<t>(val) {} 00450 00451 // This assignment operator allows <src>SimpleCountedPtr</src>s to be 00452 // freely assigned to each other. 00453 // 00454 SimpleCountedPtr<t> &operator=(const SimpleCountedPtr<t> &val) { 00455 SimpleCountedConstPtr<t>::operator=(val); 00456 return *this; 00457 } 00458 00459 // This assignment operator allows the object to which the current 00460 // <src>SimpleCountedPtr</src> points to be changed. 00461 // 00462 SimpleCountedPtr<t> &operator=(t *v) { 00463 SimpleCountedConstPtr<t>::operator=(v); 00464 return *this; 00465 } 00466 00467 // The <src>SimpleCountedPtr</src> indirection operator simply 00468 // returns a reference to the value being protected. If the pointer 00469 // is un-initialized (null), an exception will be thrown. The member 00470 // function 00471 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 00472 // can be used to catch such a condition in time. 00473 // 00474 // <thrown> 00475 // <li> ExcpError 00476 // </thrown> 00477 // 00478 // <note role=tip> The address of the reference returned should 00479 // not be stored for later use. 00480 // </note> 00481 // 00482 // <group> 00483 const t &operator*() const { 00484 if (!this->ref) throw_Null_CountedPtr_dereference_error(); 00485 return(*(*this->ref).val); 00486 } 00487 t &operator*() { 00488 if (!this->ref) throw_Null_CountedPtr_dereference_error(); 00489 return(*(*this->ref).val); 00490 } 00491 // </group> 00492 00493 }; 00494 00495 // <summary>Regular referenced counted pointer for non-constant data</summary> 00496 // <use visibility=export> 00497 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00498 00499 // <prerequisite> 00500 // <li> class <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto> 00501 // <li> class <linkto class="CountedConstPtr:description">CountedConstPtr</linkto> 00502 // </prerequisite> 00503 00504 // <synopsis> 00505 // This class completes the lattice. It inherits much of the members 00506 // which deal with non-constant data from 00507 // <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto>, 00508 // and it inherits the const <src>operator->()</src> from 00509 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto>. 00510 // What this class adds is the <src>operator->()</src> which returns a 00511 // modifiable pointer. 00512 // </synopsis> 00513 // 00514 template<class t> class CountedPtr : public SimpleCountedPtr<t>, 00515 public CountedConstPtr<t> { 00516 public: 00517 00518 // This constructor allows for the creation of a null 00519 // <src>CountedPtr</src>. The assignment operator can be used 00520 // to assign a null <src>CountedPtr</src> from another 00521 // pointer. 00522 // 00523 CountedPtr(); 00524 00525 // This constructor sets up a reference count for the 00526 // <src>val</src> pointer. By default, the data pointed to by 00527 // <src>val</src> will be deleted when it is no longer 00528 // referenced. Passing in <src>False</src> for <src>delit</src> will 00529 // prevent the data from being deleted when the reference count 00530 // reaches zero. 00531 // 00532 // <note role=warning> After the counted pointer is initialized 00533 // the value should no longer be manipulated by the raw pointer of 00534 // type <src>t*</src>. 00535 // </note> 00536 // 00537 CountedPtr(t *val, Bool delit = True); 00538 00539 // This copy constructor allows <src>CountedPtr</src>s to be 00540 // initialized from other <src>CountedPtr</src>s. 00541 // 00542 CountedPtr(const CountedPtr<t> &val); 00543 00544 // This assignment operator allows <src>CountedPtr</src>s to be 00545 // freely assigned to each other. 00546 // 00547 CountedPtr<t> &operator=(const CountedPtr<t> &val) { 00548 SimpleCountedPtr<t>::operator=(val); 00549 return *this; 00550 } 00551 00552 // This assignment operator allows the object to which the current 00553 // <src>CountedPtr</src> points to be changed. 00554 // 00555 CountedPtr<t> &operator=(t *v) { 00556 SimpleCountedPtr<t>::operator=(v); 00557 return *this; 00558 } 00559 00560 // This dereferencing operator behaves as expected; it returns the 00561 // pointer to the value being protected, and then its dereferencing 00562 // operator will be invoked as appropriate. If the pointer is 00563 // un-initialized (null), an exception will be thrown. The member 00564 // function 00565 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 00566 // can be used to catch such a condition in time. 00567 // 00568 // <thrown> 00569 // <li> ExcpError 00570 // </thrown> 00571 // 00572 // <group> 00573 t *operator->() const { 00574 if (!this->ref) throw_Null_CountedPtr_dereference_error(); 00575 return ((*this->ref).val); 00576 } 00577 t *operator->() { 00578 if (!this->ref) throw_Null_CountedPtr_dereference_error(); 00579 return ((*this->ref).val); 00580 } 00581 // </group> 00582 }; 00583 00584 } //#End casa namespace 00585 00586 // Keep this definition local 00587 00588 #else // when defined (USE_SHARED_PTR) is true 00589 00590 00591 #include <boost/shared_ptr.hpp> 00592 00593 namespace casa { //#Begin casa namespace 00594 00595 //# Forward Declarations 00596 template<class t> class SimpleCountedPtr; 00597 template<class t> class SimpleCountedConstPtr; 00598 template<class t> class CountedPtr; 00599 template<class t> class CountedConstPtr; 00600 00601 // <summary> act on dereference error </summary> 00602 // <synopsis> 00603 // Global function that throws an exception. It is called by the 00604 // member functions of the counted pointer classes when an 00605 // un-initialized (null) pointer is followed. 00606 // </synopsis> 00607 // <group name=dereference_error> 00608 void throw_Null_CountedPtr_dereference_error(); 00609 // </group> 00610 00611 00612 // <summary>Simple referenced counted pointer for constant data</summary> 00613 // <use visibility=export> 00614 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00615 00616 // <etymology> 00617 // This class is <em>Simple</em> because it does not have the 00618 // <src>operator->()</src> operator. This means that it puts less demands 00619 // on the underlying type. It is <em>Counted</em> because it is reference 00620 // counted, and it is <em>Const</em> because the underlying value is 00621 // non-modifiable. 00622 // </etymology> 00623 00624 // <synopsis> 00625 // This class implements a simple reference counting mechanism. It 00626 // allows <src>SimpleCountedConstPtr</src>s to be passed around freely, 00627 // incrementing or decrementing the reference count as needed when one 00628 // <src>SimpleCountedConstPtr</src> is assigned to another. When the 00629 // reference count reaches zero the internal storage is deleted by 00630 // default, but this behavior can be overridden. 00631 // 00632 // This class is used as a pointer to constant data. As such, it only 00633 // has the subset of the 00634 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto> 00635 // functions which are relevant for constant data. 00636 // </synopsis> 00637 00638 // <motivation> 00639 // Reference counting 00640 // </motivation> 00641 00642 template<class t> 00643 class SimpleCountedConstPtr 00644 { 00645 00646 protected: 00647 00648 template <typename T> 00649 class Deleter { 00650 public: 00651 Deleter (Bool deleteIt) : reallyDeleteIt_p (deleteIt) {} 00652 void operator() (T * data) const { if (reallyDeleteIt_p) delete data;} 00653 private: 00654 Bool reallyDeleteIt_p; 00655 }; 00656 00657 public: 00658 00659 00660 // This constructor allows for the creation of a null 00661 // <src>SimpleCountedConstPtr</src>. The assignment operator can be used 00662 // to assign a null <src>SimpleCountedConstPtr</src> from another 00663 // pointer. 00664 // 00665 SimpleCountedConstPtr() : pointerRep_p () {} 00666 00667 // This constructor sets up a reference count for the <src>val</src> 00668 // pointer. By default, the data pointed to by <src>val</src> 00669 // will be deleted when it is no longer referenced. Passing in 00670 // <src>False</src> for <src>delit</src> will prevent the data 00671 // from being deleted when the reference count reaches zero. 00672 // 00673 // <note role=warning> After the counted pointer is initialized 00674 // the value should no longer be manipulated by the raw pointer of 00675 // type <src>t*</src>. 00676 // </note> 00677 // 00678 SimpleCountedConstPtr(t *val, Bool delit = True) 00679 : pointerRep_p (val, Deleter<t> (delit)) 00680 {} 00681 00682 // This constructor sets up a reference count for the 00683 // <src>val</src> pointer. Since <src>val</src> is a pointer to 00684 // constant data, the data will not be deleted when the reference 00685 // count reaches zero. 00686 // 00687 // <note role=tip> Since the constant data will NOT be cleaned up 00688 // when the reference count reaches zero, the use of this class for 00689 // pointers to constant data may not be desirable. 00690 // </note> 00691 // 00692 SimpleCountedConstPtr(const t *val) 00693 : pointerRep_p (val, Deleter<t> (False)) 00694 {} 00695 00696 // This copy constructor allows <src>SimpleCountedConstPtr</src>s to be 00697 // initialized from other <src>SimpleCountedConstPtr</src>s. 00698 // 00699 // SimpleCountedConstPtr(const SimpleCountedConstPtr<t> &val) : ref(val.ref) { 00700 // if (ref) 00701 // (*ref).count++; 00702 // } 00703 00704 // This destructor only deletes the really stored data when it was 00705 // initialized as deletable and the reference count is zero. 00706 // 00707 virtual ~SimpleCountedConstPtr() {} 00708 00709 // The <src>SimpleCountedConstPtr</src> indirection operator simply 00710 // returns a reference to the value being protected. If the pointer 00711 // is un-initialized (null), an exception will be thrown. The member 00712 // function 00713 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 00714 // can be used to catch such a condition in time. 00715 // 00716 // <thrown> 00717 // <li> ExcpError 00718 // </thrown> 00719 // 00720 // <note role=tip> The address of the reference returned should 00721 // not be stored for later use. 00722 // </note> 00723 // 00724 const t &operator*() const { 00725 if (null()){ 00726 throw_Null_CountedPtr_dereference_error(); 00727 } 00728 return pointerRep_p.operator* (); 00729 } 00730 00731 // Equality operator which checks to see if two 00732 // <src>SimpleCountedConstPtr</src>s are pointing at the same thing. 00733 // 00734 Bool operator==(const SimpleCountedConstPtr<t> &other) const { 00735 return (this->get() == other.get() ? True : False); 00736 } 00737 00738 // Non-equality operator which checks to see if two 00739 // <src>SimpleCountedConstPtr</src>s are not pointing at the same thing. 00740 // 00741 Bool operator!=(const SimpleCountedConstPtr<t> &other) const { 00742 return (this->get() != other.get() ? True : False); 00743 } 00744 00745 // This assignment operator allows <src>SimpleCountedConstPtr</src>s 00746 // to be freely assigned to each other. 00747 // 00748 // SimpleCountedConstPtr<t> & 00749 // operator=(const SimpleCountedConstPtr<t> &val) { 00750 // if (ref && --(*ref).count == 0){ 00751 // delete ref; 00752 // ref = 0; 00753 // } 00754 // if ((ref = val.ref) != 0) 00755 // (*ref).count++; 00756 // return *this; 00757 // } 00758 00759 // This assignment operator allows the object to which the current 00760 // <src>SimpleCountedConstPtr</src> points to be changed. 00761 // 00762 SimpleCountedConstPtr<t> & 00763 operator=(t *v) 00764 { 00765 pointerRep_p = PointerRep (v); 00766 00767 return * this; 00768 } 00769 00770 // Sometimes it is useful to know if there is more than one 00771 // reference made. This is a way of getting that. Of course the point 00772 // of these classes is that this information is normally not required. 00773 // 00774 uInt nrefs() const {return pointerRep_p.use_count();} 00775 00776 // This function changes the value for this 00777 // <src>SimpleCountedConstPtr</src> and all of the other 00778 // <src>SimpleCountedConstPtr</src>s which point to this same value. 00779 // 00780 // <note role=warning> This is dangerous, and generally should not 00781 // be done. 00782 // </note> 00783 // 00784 // void replace(t *v, Bool delit = True) { 00785 // if (ref) { 00786 // (*ref).freeVal(); 00787 // (*ref).val = v; 00788 // (*ref).deletable = delit; 00789 // } 00790 // } 00791 00792 // Check to see if this <src>SimpleCountedConstPtr</src> is 00793 // un-initialized, null. 00794 // 00795 Bool null() const { return get() == 0;} 00796 00797 protected: 00798 00799 typedef boost::shared_ptr<t> PointerRep; 00800 00801 PointerRep pointerRep_p; 00802 00803 t * 00804 get () const 00805 { 00806 return pointerRep_p.get(); 00807 } 00808 00809 // t * 00810 // get () 00811 // { 00812 // return pointerRep_p.get(); 00813 // } 00814 00815 }; 00816 00817 // <summary>Regular referenced counted pointer for constant data</summary> 00818 // <use visibility=export> 00819 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00820 00821 // <prerequisite> 00822 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto> 00823 // </prerequisite> 00824 00825 // <synopsis> 00826 // This class has the same objective as 00827 // <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto> 00828 // but it adds the <src>operator->()</src>. It still only contains a 00829 // pointer whose underlying data cannot be changed. The destructor 00830 // deletes the underlying data when the reference count reaches zero. 00831 // </synopsis> 00832 00833 // <motivation> 00834 // <src>operator->()</src> is useful, but not always available for 00835 // every type. 00836 // </motivation> 00837 00838 template<class t> class CountedConstPtr : virtual public SimpleCountedConstPtr<t> { 00839 public: 00840 00841 // This constructor allows for the creation of a null 00842 // <src>CountedConstPtr</src>. The assignment operator can be 00843 // used to assign a null <src>CountedConstPtr</src> from 00844 // another pointer. 00845 // 00846 CountedConstPtr() : SimpleCountedConstPtr<t>() {} 00847 00848 // This constructor sets up a reference count for the <src>val</src> 00849 // pointer. By default, the data pointed to by <src>val</src> will 00850 // be deleted when it is no longer referenced. Passing in 00851 // <src>False</src> for <src>delit</src> will prevent the data 00852 // from being deleted when the reference count reaches zero. 00853 // 00854 // <note role=warning> After the counted pointer is initialized 00855 // the value should no longer be manipulated by the raw pointer 00856 // of type <src>t*</src>. 00857 // </note> 00858 // 00859 CountedConstPtr(t *val, Bool delit = True) : SimpleCountedConstPtr<t>(val,delit) {} 00860 00861 // This copy constructor allows <src>CountedConstPtr</src>s to be 00862 // initialized from other <src>CountedConstPtr</src>s. 00863 // 00864 CountedConstPtr(const CountedConstPtr<t> &val) : SimpleCountedConstPtr<t>(val) {} 00865 00866 // This assignment operator allows <src>CountedConstPtr</src>s to be 00867 // freely assigned to each other. 00868 // 00869 CountedConstPtr<t> &operator=(const CountedConstPtr<t> &val) { 00870 SimpleCountedConstPtr<t>::operator=(val); 00871 return *this; 00872 } 00873 00874 // This assignment operator allows the object to which the current 00875 // <src>CountedConstPtr</src> points to be changed. 00876 // 00877 CountedConstPtr<t> &operator=(t *v) { 00878 SimpleCountedConstPtr<t>::operator=(v); 00879 return *this; 00880 } 00881 00882 // This dereferencing operator behaves as expected; it returns the 00883 // pointer to the value being protected, and then its dereferencing 00884 // operator will be invoked as appropriate. If the pointer is 00885 // un-initialized (null), an exception will be thrown. The member 00886 // function 00887 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 00888 // can be used to catch such a condition in time. 00889 // 00890 // <thrown> 00891 // <li> ExcpError 00892 // </thrown> 00893 // 00894 const t 00895 *operator->() const { 00896 00897 if (this->null()){ 00898 throw_Null_CountedPtr_dereference_error(); 00899 } 00900 00901 return this->get (); 00902 } 00903 }; 00904 00905 // <summary> Simple referenced counted pointer to non-constant data</summary> 00906 // <use visibility=export> 00907 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 00908 00909 // <prerequisite> 00910 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto> 00911 // </prerequisite> 00912 00913 // <synopsis> 00914 // This class, like 00915 // <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto>, 00916 // does not define the <src>operator->()</src>. Thus it can point to 00917 // simple data which does not have this operator defined. In contrast to 00918 // <src>SimpleCountedConstPtr</src>, this class points at non-constant 00919 // underlying data. The deletion properties are the same for both 00920 // classes. 00921 // </synopsis> 00922 00923 template<class t> class SimpleCountedPtr : virtual public SimpleCountedConstPtr<t> { 00924 public: 00925 00926 // This constructor allows for the creation of a null 00927 // <src>SimpleCountedPtr</src>. The assignment operator can be used 00928 // to assign a null <src>SimpleCountedPtr</src> from another pointer. 00929 // 00930 SimpleCountedPtr() : SimpleCountedConstPtr<t>() {} 00931 00932 // This constructor sets up a reference count for the <src>val</src> 00933 // pointer. By default, the data pointed to by <src>val</src> 00934 // will be deleted when it is no longer referenced. Passing in 00935 // <src>False</src> for <src>delit</src> will prevent the data 00936 // from being deleted when the reference count reaches zero. 00937 // 00938 // <note role=warning> After the counted pointer is initialized 00939 // the value should no longer be manipulated by the raw pointer 00940 // of type <src>t*</src>. 00941 // </note> 00942 // 00943 SimpleCountedPtr(t *val, Bool delit = True) : SimpleCountedConstPtr<t>(val,delit) {} 00944 00945 // This copy constructor allows <src>SimpleCountedPtr</src>s to be 00946 // initialized from other <src>SimpleCountedPtr</src>s. 00947 // 00948 SimpleCountedPtr(const SimpleCountedPtr<t> &val) : SimpleCountedConstPtr<t>(val) {} 00949 00950 // This assignment operator allows <src>SimpleCountedPtr</src>s to be 00951 // freely assigned to each other. 00952 // 00953 SimpleCountedPtr<t> &operator=(const SimpleCountedPtr<t> &val) { 00954 SimpleCountedConstPtr<t>::operator=(val); 00955 return *this; 00956 } 00957 00958 // This assignment operator allows the object to which the current 00959 // <src>SimpleCountedPtr</src> points to be changed. 00960 // 00961 SimpleCountedPtr<t> &operator=(t *v) { 00962 SimpleCountedConstPtr<t>::operator=(v); 00963 return *this; 00964 } 00965 00966 // The <src>SimpleCountedPtr</src> indirection operator simply 00967 // returns a reference to the value being protected. If the pointer 00968 // is un-initialized (null), an exception will be thrown. The member 00969 // function 00970 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 00971 // can be used to catch such a condition in time. 00972 // 00973 // <thrown> 00974 // <li> ExcpError 00975 // </thrown> 00976 // 00977 // <note role=tip> The address of the reference returned should 00978 // not be stored for later use. 00979 // </note> 00980 // 00981 // <group> 00982 const t &operator*() const { 00983 if (this->null()){ 00984 throw_Null_CountedPtr_dereference_error(); 00985 } 00986 return * this->get(); 00987 } 00988 t &operator*() { 00989 if (this->null()){ 00990 throw_Null_CountedPtr_dereference_error(); 00991 } 00992 return * this->get(); 00993 } 00994 // </group> 00995 00996 }; 00997 00998 // <summary>Regular referenced counted pointer for non-constant data</summary> 00999 // <use visibility=export> 01000 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos=""> 01001 01002 // <prerequisite> 01003 // <li> class <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto> 01004 // <li> class <linkto class="CountedConstPtr:description">CountedConstPtr</linkto> 01005 // </prerequisite> 01006 01007 // <synopsis> 01008 // This class completes the lattice. It inherits much of the members 01009 // which deal with non-constant data from 01010 // <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto>, 01011 // and it inherits the const <src>operator->()</src> from 01012 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto>. 01013 // What this class adds is the <src>operator->()</src> which returns a 01014 // modifiable pointer. 01015 // </synopsis> 01016 // 01017 template<class t> class CountedPtr : public SimpleCountedPtr<t>, 01018 public CountedConstPtr<t> { 01019 public: 01020 01021 // This constructor allows for the creation of a null 01022 // <src>CountedPtr</src>. The assignment operator can be used 01023 // to assign a null <src>CountedPtr</src> from another 01024 // pointer. 01025 // 01026 CountedPtr(); 01027 01028 // This constructor sets up a reference count for the 01029 // <src>val</src> pointer. By default, the data pointed to by 01030 // <src>val</src> will be deleted when it is no longer 01031 // referenced. Passing in <src>False</src> for <src>delit</src> will 01032 // prevent the data from being deleted when the reference count 01033 // reaches zero. 01034 // 01035 // <note role=warning> After the counted pointer is initialized 01036 // the value should no longer be manipulated by the raw pointer of 01037 // type <src>t*</src>. 01038 // </note> 01039 // 01040 CountedPtr(t *val, Bool delit = True); 01041 01042 // This copy constructor allows <src>CountedPtr</src>s to be 01043 // initialized from other <src>CountedPtr</src>s. 01044 // 01045 CountedPtr(const CountedPtr<t> &val); 01046 01047 // This assignment operator allows <src>CountedPtr</src>s to be 01048 // freely assigned to each other. 01049 // 01050 CountedPtr<t> &operator=(const CountedPtr<t> &val) { 01051 SimpleCountedPtr<t>::operator=(val); 01052 return *this; 01053 } 01054 01055 // This assignment operator allows the object to which the current 01056 // <src>CountedPtr</src> points to be changed. 01057 // 01058 CountedPtr<t> &operator=(t *v) { 01059 SimpleCountedPtr<t>::operator=(v); 01060 return *this; 01061 } 01062 01063 // This dereferencing operator behaves as expected; it returns the 01064 // pointer to the value being protected, and then its dereferencing 01065 // operator will be invoked as appropriate. If the pointer is 01066 // un-initialized (null), an exception will be thrown. The member 01067 // function 01068 // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>() 01069 // can be used to catch such a condition in time. 01070 // 01071 // <thrown> 01072 // <li> ExcpError 01073 // </thrown> 01074 // 01075 // <group> 01076 t * 01077 operator->() const { 01078 if (this->null()){ 01079 throw_Null_CountedPtr_dereference_error(); 01080 } 01081 return this->get(); 01082 } 01083 t * 01084 operator->() { 01085 if (this->null()){ 01086 throw_Null_CountedPtr_dereference_error(); 01087 } 01088 01089 return this->get(); 01090 } 01091 // </group> 01092 }; 01093 01094 } //#End casa namespace 01095 01096 01097 #endif // defined (USE_BOOST_SHARED_PTR) 01098 01099 01100 #ifndef CASACORE_NO_AUTO_TEMPLATES 01101 #include <casa/Utilities/CountedPtr.tcc> 01102 #endif //# CASACORE_NO_AUTO_TEMPLATES 01103 01104 01105 #endif