casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
CountedPtr.h
Go to the documentation of this file.
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