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$
00027 
00028 #ifndef CASA_COUNTEDPTR_H
00029 #define CASA_COUNTEDPTR_H
00030 
00031 #include <casa/aips.h>
00032 
00033 namespace casa { //#Begin casa namespace
00034 
00035 //# Forward Declarations 
00036 template<class t> class SimpleCountedPtr;
00037 template<class t> class SimpleCountedConstPtr;
00038 template<class t> class CountedPtr;
00039 template<class t> class CountedConstPtr;
00040 
00041 // <summary> act on dereference error </summary>
00042 // <synopsis>
00043 // Global function that throws an exception. It is called by the 
00044 // member functions of the counted pointer classes when an
00045 // un-initialized (null) pointer is followed.
00046 // </synopsis>
00047 // <group name=dereference_error>
00048 void throw_Null_CountedPtr_dereference_error();
00049 // </group>
00050 
00051 // <summary>Internal representation for <src>CountedPtr</src></summary> 
00052 // <use visibility=local>
00053 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos="">
00054 
00055 // <prerequisite>
00056 // <li> class <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto>
00057 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto>
00058 // </prerequisite>
00059 
00060 // <synopsis> 
00061 // This class is a utility class for
00062 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto>
00063 // and <linkto class="CountedPtr:description">CountedPtr</linkto>.
00064 // It stores the reference count and the pointer to the real data.
00065 //
00066 // <note role=tip> It is currently a template and is used such that
00067 // <src>t</src> is the <em>true</em> type of the stored pointer. This
00068 // means, however, that when it is used, a template instantiation must be
00069 // done for each type which <src>t</src> assumes. This makes debugging
00070 // easier, but in the future all of these pointers could be declared with
00071 // <src>void</src> type to avoid template instantiations.
00072 // </note>
00073 // </synopsis> 
00074 
00075 // <motivation>
00076 // This class isolates all of the low level management of the reference.
00077 // </motivation>
00078 
00079 template<class t> class PtrRep
00080 {
00081 
00082 public: 
00083 
00084     friend class SimpleCountedPtr<t>;
00085     friend class SimpleCountedConstPtr<t>;
00086     friend class CountedPtr<t>;
00087     friend class CountedConstPtr<t>;
00088     
00089 protected:
00090 
00091     // This constructor sets up the reference count to one and
00092     // initializes the pointer to the real data. The
00093     // <src>delit</src> flag can be passed in to indicate whether
00094     // the real data should be freed or not when the
00095     // reference count reaches zero.
00096     // <group>
00097     PtrRep(t *v) : val(v), count(1), deletable(True) {}
00098     PtrRep(t *v, Bool delit) : val(v), count(1), deletable(delit) {}
00099     // </group>
00100 
00101     // This deletes the real data if indeed it can be deleted.
00102     void freeVal();
00103 
00104     // This destructor uses the <src>deletable</src> flag to indicate if the
00105     // real data should be freed or not.
00106     //
00107     ~PtrRep() {
00108         freeVal();
00109     }
00110 
00111 private:
00112 
00113     t *val;
00114     unsigned int count;
00115     Bool deletable;
00116 
00117 };
00118 
00119 // <summary>Simple referenced counted pointer for constant data</summary> 
00120 // <use visibility=export>
00121 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos="">
00122 
00123 // <etymology>
00124 // This class is <em>Simple</em> because it does not have the
00125 // <src>operator->()</src> operator. This means that it puts less demands
00126 // on the underlying type. It is <em>Counted</em> because it is reference
00127 // counted, and it is <em>Const</em> because the underlying value is
00128 // non-modifiable.
00129 // </etymology>
00130 
00131 // <synopsis> 
00132 // This class implements a simple reference counting mechanism. It
00133 // allows <src>SimpleCountedConstPtr</src>s to be passed around freely,
00134 // incrementing or decrementing the reference count as needed when one
00135 // <src>SimpleCountedConstPtr</src> is assigned to another. When the
00136 // reference count reaches zero the internal storage is deleted by
00137 // default, but this behavior can be overridden.
00138 //
00139 // This class is used as a pointer to constant data. As such, it only
00140 // has the subset of the
00141 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto>
00142 // functions which are relevant for constant data.  
00143 // </synopsis>
00144 
00145 // <motivation>
00146 // Reference counting
00147 // </motivation>
00148 
00149 template<class t> class SimpleCountedConstPtr
00150 {
00151 public:
00152 
00153     // This constructor allows for the creation of a null
00154     // <src>SimpleCountedConstPtr</src>. The assignment operator can be used
00155     // to assign a null <src>SimpleCountedConstPtr</src> from another
00156     // pointer.
00157     //
00158     SimpleCountedConstPtr() : ref(0) {}
00159 
00160     // This constructor sets up a reference count for the <src>val</src>
00161     // pointer.  By default, the data pointed to by <src>val</src>
00162     // will be deleted when it is no longer referenced. Passing in
00163     // <src>False</src> for <src>delit</src> will prevent the data
00164     // from being deleted when the reference count reaches zero.
00165     //
00166     // <note role=warning> After the counted pointer is initialized
00167     // the value should no longer be manipulated by the raw pointer of
00168     // type <src>t*</src>.
00169     // </note>
00170     //
00171     SimpleCountedConstPtr(t *val, Bool delit = True) {
00172         ref = new PtrRep<t>(val,delit);
00173     }
00174 
00175     // This constructor sets up a reference count for the
00176     // <src>val</src> pointer.  Since <src>val</src> is a pointer to
00177     // constant data, the data will not be deleted when the reference
00178     // count reaches zero.
00179     //
00180     // <note role=tip> Since the constant data will NOT be cleaned up
00181     // when the reference count reaches zero, the use of this class for
00182     // pointers to constant data may not be desirable.
00183     // </note>
00184     //
00185     SimpleCountedConstPtr(const t *val) {
00186         ref = new PtrRep<t>((t *) val,False);
00187     }
00188 
00189     // This copy constructor allows <src>SimpleCountedConstPtr</src>s to be
00190     // initialized from other <src>SimpleCountedConstPtr</src>s.
00191     //
00192     SimpleCountedConstPtr(const SimpleCountedConstPtr<t> &val) : ref(val.ref) {
00193         if (ref)
00194             (*ref).count++;
00195     }
00196 
00197     // This destructor only deletes the really stored data when it was
00198     // initialized as deletable and the reference count is zero.
00199     //
00200     virtual ~SimpleCountedConstPtr();
00201 
00202     // The <src>SimpleCountedConstPtr</src> indirection operator simply
00203     // returns a reference to the value being protected. If the pointer
00204     // is un-initialized (null), an exception will be thrown. The member
00205     // function
00206     // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>()
00207     // can be used to catch such a condition in time.
00208     //
00209     // <thrown>
00210     // <li> ExcpError
00211     // </thrown>
00212     //
00213     // <note role=tip> The address of the reference returned should
00214     // not be stored for later use.
00215     // </note>
00216     //
00217     const t &operator*() const {
00218         if (!ref) throw_Null_CountedPtr_dereference_error();
00219         return(*(*ref).val);
00220     }
00221 
00222     // Equality operator which checks to see if two
00223     // <src>SimpleCountedConstPtr</src>s are pointing at the same thing.
00224     //
00225     Bool operator==(const SimpleCountedConstPtr<t> &other) const {
00226         return (ref == other.ref ? True : False);
00227     }
00228 
00229     // Non-equality operator which checks to see if two
00230     // <src>SimpleCountedConstPtr</src>s are not pointing at the same thing.
00231     //
00232     Bool operator!=(const SimpleCountedConstPtr<t> &other) const {
00233         return (ref != other.ref ? True : False);
00234     }
00235 
00236     // This assignment operator allows <src>SimpleCountedConstPtr</src>s
00237     // to be freely assigned to each other.
00238     //
00239     SimpleCountedConstPtr<t> &operator=(const SimpleCountedConstPtr<t> &val) {
00240         if (ref && --(*ref).count == 0){
00241             delete ref;
00242             ref = 0;
00243         }
00244         if ((ref = val.ref) != 0)
00245             (*ref).count++;
00246         return *this;
00247     }
00248 
00249     // This assignment operator allows the object to which the current
00250     // <src>SimpleCountedConstPtr</src> points to be changed.
00251     //
00252     SimpleCountedConstPtr<t> &operator=(t *v);
00253 
00254     // Sometimes it is useful to know if there is more than one
00255     // reference made. This is a way of getting that. Of course the point
00256     // of these classes is that this information is normally not required.
00257     //
00258     uInt nrefs() const {return ref->count;}
00259 
00260     // This function changes the value for this
00261     // <src>SimpleCountedConstPtr</src> and all of the other
00262     // <src>SimpleCountedConstPtr</src>s which point to this same value.
00263     //
00264     // <note role=warning> This is dangerous, and generally should not
00265     // be done.
00266     // </note>
00267     //
00268     void replace(t *v, Bool delit = True) {
00269         if (ref && (v != (*ref).val)) { // Guarding against replacing ourselves
00270             (*ref).freeVal();
00271             (*ref).val = v;
00272             (*ref).deletable = delit;
00273         }
00274     }
00275 
00276     // Check to see if this <src>SimpleCountedConstPtr</src> is
00277     // un-initialized, null.
00278     //
00279     Bool null() const { return (ref==0 || (ref->val == 0));}
00280 
00281 protected:
00282 
00283     PtrRep<t> *ref;
00284 
00285 };
00286 
00287 // <summary>Regular referenced counted pointer for constant data</summary> 
00288 // <use visibility=export>
00289 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos="">
00290 
00291 // <prerequisite>
00292 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto>
00293 // </prerequisite>
00294 
00295 // <synopsis> 
00296 // This class has the same objective as 
00297 // <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto>
00298 // but it adds the <src>operator->()</src>. It still only contains a
00299 // pointer whose underlying data cannot be changed. The destructor
00300 // deletes the underlying data when the reference count reaches zero.
00301 // </synopsis> 
00302 
00303 // <motivation>
00304 // <src>operator->()</src> is useful, but not always available for 
00305 // every type.
00306 // </motivation>
00307 
00308 template<class t> class CountedConstPtr : virtual public SimpleCountedConstPtr<t> {
00309 public:
00310 
00311     // This constructor allows for the creation of a null
00312     // <src>CountedConstPtr</src>. The assignment operator can be
00313     // used to assign a null <src>CountedConstPtr</src> from
00314     // another pointer.
00315     //
00316     CountedConstPtr() : SimpleCountedConstPtr<t>() {}
00317 
00318     // This constructor sets up a reference count for the <src>val</src>
00319     // pointer. By default, the data pointed to by <src>val</src> will
00320     // be deleted when it is no longer referenced. Passing in
00321     // <src>False</src> for <src>delit</src> will prevent the data
00322     // from being deleted when the reference count reaches zero.
00323     //
00324     // <note role=warning> After the counted pointer is initialized
00325     // the value should no longer be manipulated by the raw pointer
00326     // of type <src>t*</src>.
00327     // </note>
00328     //
00329     CountedConstPtr(t *val, Bool delit = True) : SimpleCountedConstPtr<t>(val,delit) {}
00330 
00331     // This copy constructor allows <src>CountedConstPtr</src>s to be
00332     // initialized from other <src>CountedConstPtr</src>s.
00333     //
00334     CountedConstPtr(const CountedConstPtr<t> &val) : SimpleCountedConstPtr<t>(val) {}
00335 
00336     // This assignment operator allows <src>CountedConstPtr</src>s to be
00337     // freely assigned to each other.
00338     //
00339     CountedConstPtr<t> &operator=(const CountedConstPtr<t> &val) {
00340         SimpleCountedConstPtr<t>::operator=(val);
00341         return *this;
00342     }
00343 
00344     // This assignment operator allows the object to which the current
00345     // <src>CountedConstPtr</src> points to be changed.
00346     //
00347     CountedConstPtr<t> &operator=(t *v) {
00348         SimpleCountedConstPtr<t>::operator=(v);
00349         return *this;
00350     }
00351 
00352     // This dereferencing operator behaves as expected; it returns the
00353     // pointer to the value being protected, and then its dereferencing
00354     // operator will be invoked as appropriate. If the pointer is
00355     // un-initialized (null), an exception will be thrown. The member
00356     // function
00357     // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>()
00358     // can be used to catch such a condition in time.
00359     //
00360     // <thrown>
00361     // <li> ExcpError
00362     // </thrown>
00363     //
00364     const t *operator->() const {
00365         if (!this->ref) throw_Null_CountedPtr_dereference_error();
00366         return ((*this->ref).val);
00367     }
00368 };
00369 
00370 // <summary> Simple referenced counted pointer to non-constant data</summary> 
00371 // <use visibility=export>
00372 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos="">
00373 
00374 // <prerequisite>
00375 // <li> class <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto>
00376 // </prerequisite>
00377 
00378 // <synopsis> 
00379 // This class, like
00380 // <linkto class="SimpleCountedConstPtr:description">SimpleCountedConstPtr</linkto>,
00381 // does not define the <src>operator->()</src>. Thus it can point to
00382 // simple data which does not have this operator defined. In contrast to
00383 // <src>SimpleCountedConstPtr</src>, this class points at non-constant
00384 // underlying data. The deletion properties are the same for both
00385 // classes.
00386 // </synopsis> 
00387 
00388 template<class t> class SimpleCountedPtr : virtual public SimpleCountedConstPtr<t> {
00389 public:
00390 
00391     // This constructor allows for the creation of a null
00392     // <src>SimpleCountedPtr</src>. The assignment operator can be used
00393     // to assign a null <src>SimpleCountedPtr</src> from another pointer.
00394     //
00395     SimpleCountedPtr() : SimpleCountedConstPtr<t>() {}
00396 
00397     // This constructor sets up a reference count for the <src>val</src>
00398     // pointer.  By default, the data pointed to by <src>val</src>
00399     // will be deleted when it is no longer referenced. Passing in
00400     // <src>False</src> for <src>delit</src> will prevent the data
00401     // from being deleted when the reference count reaches zero.
00402     //
00403     // <note role=warning> After the counted pointer is initialized
00404     // the value should no longer be manipulated by the raw pointer
00405     // of type <src>t*</src>.
00406     // </note>
00407     //
00408     SimpleCountedPtr(t *val, Bool delit = True) : SimpleCountedConstPtr<t>(val,delit) {}
00409 
00410     // This copy constructor allows <src>SimpleCountedPtr</src>s to be
00411     // initialized from other <src>SimpleCountedPtr</src>s.
00412     //
00413     SimpleCountedPtr(const SimpleCountedPtr<t> &val) : SimpleCountedConstPtr<t>(val) {}
00414 
00415     // This assignment operator allows <src>SimpleCountedPtr</src>s to be
00416     // freely assigned to each other.
00417     //
00418     SimpleCountedPtr<t> &operator=(const SimpleCountedPtr<t> &val) {
00419         SimpleCountedConstPtr<t>::operator=(val);
00420         return *this;
00421     }
00422 
00423     // This assignment operator allows the object to which the current
00424     // <src>SimpleCountedPtr</src> points to be changed.
00425     //
00426     SimpleCountedPtr<t> &operator=(t *v) {
00427         SimpleCountedConstPtr<t>::operator=(v);
00428         return *this;
00429     }
00430 
00431     // The <src>SimpleCountedPtr</src> indirection operator simply
00432     // returns a reference to the value being protected. If the pointer
00433     // is un-initialized (null), an exception will be thrown. The member
00434     // function
00435     // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>()
00436     // can be used to catch such a condition in time.
00437     //
00438     // <thrown>
00439     // <li> ExcpError
00440     // </thrown>
00441     //
00442     // <note role=tip> The address of the reference returned should
00443     // not be stored for later use.
00444     // </note>
00445     //
00446     // <group>
00447     const t &operator*() const {
00448         if (!this->ref) throw_Null_CountedPtr_dereference_error();
00449         return(*(*this->ref).val);
00450     }
00451     t &operator*() {
00452         if (!this->ref) throw_Null_CountedPtr_dereference_error();
00453         return(*(*this->ref).val);
00454     }
00455     // </group>
00456 
00457 };
00458 
00459 // <summary>Regular referenced counted pointer for non-constant data</summary> 
00460 // <use visibility=export>
00461 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos="">
00462 
00463 // <prerequisite>
00464 // <li> class <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto>
00465 // <li> class <linkto class="CountedConstPtr:description">CountedConstPtr</linkto>
00466 // </prerequisite>
00467 
00468 // <synopsis> 
00469 // This class completes the lattice. It inherits much of the members
00470 // which deal with non-constant data from
00471 // <linkto class="SimpleCountedPtr:description">SimpleCountedPtr</linkto>,
00472 // and it inherits the const <src>operator->()</src> from
00473 // <linkto class="CountedConstPtr:description">CountedConstPtr</linkto>.
00474 // What this class adds is the <src>operator->()</src> which returns a
00475 // modifiable pointer.
00476 // </synopsis> 
00477 //
00478 template<class t> class CountedPtr : public SimpleCountedPtr<t>, 
00479                                      public CountedConstPtr<t> {
00480 public:
00481 
00482     // This constructor allows for the creation of a null
00483     // <src>CountedPtr</src>. The assignment operator can be used
00484     // to assign a null <src>CountedPtr</src> from another
00485     // pointer.
00486     //
00487     CountedPtr();
00488 
00489     // This constructor sets up a reference count for the
00490     // <src>val</src> pointer.  By default, the data pointed to by
00491     // <src>val</src> will be deleted when it is no longer
00492     // referenced. Passing in <src>False</src> for <src>delit</src> will
00493     // prevent the data from being deleted when the reference count
00494     // reaches zero.
00495     //
00496     // <note role=warning> After the counted pointer is initialized
00497     // the value should no longer be manipulated by the raw pointer of
00498     // type <src>t*</src>.
00499     // </note>
00500     //
00501     CountedPtr(t *val, Bool delit = True);
00502 
00503     // This copy constructor allows <src>CountedPtr</src>s to be
00504     // initialized from other <src>CountedPtr</src>s.
00505     //
00506     CountedPtr(const CountedPtr<t> &val);
00507 
00508     // This assignment operator allows <src>CountedPtr</src>s to be
00509     // freely assigned to each other.
00510     //
00511     CountedPtr<t> &operator=(const CountedPtr<t> &val) {
00512         SimpleCountedPtr<t>::operator=(val);
00513         return *this;
00514     }
00515 
00516     // This assignment operator allows the object to which the current
00517     // <src>CountedPtr</src> points to be changed.
00518     //
00519     CountedPtr<t> &operator=(t *v) {
00520         SimpleCountedPtr<t>::operator=(v);
00521         return *this;
00522     }
00523 
00524     // This dereferencing operator behaves as expected; it returns the
00525     // pointer to the value being protected, and then its dereferencing
00526     // operator will be invoked as appropriate. If the pointer is
00527     // un-initialized (null), an exception will be thrown. The member
00528     // function
00529     // <linkto class="SimpleCountedConstPtr:null()const">null</linkto>()
00530     // can be used to catch such a condition in time.
00531     //
00532     // <thrown>
00533     // <li> ExcpError
00534     // </thrown>
00535     //
00536     // <group>
00537     t *operator->() const {
00538         if (!this->ref) throw_Null_CountedPtr_dereference_error();
00539         return ((*this->ref).val);
00540     }
00541     t *operator->() {
00542         if (!this->ref) throw_Null_CountedPtr_dereference_error();
00543         return ((*this->ref).val);
00544     }
00545     // </group>
00546 };
00547 
00548  } //#End casa namespace
00549 #ifndef AIPS_NO_TEMPLATE_SRC
00550 #include <casa/Utilities/CountedPtr.cc>
00551 #include <casa/Utilities/CountedPtr2.cc>
00552 #endif //# AIPS_NO_TEMPLATE_SRC
00553 #endif

Generated on Mon Sep 1 22:33:59 2008 for NRAOCASA by  doxygen 1.5.1