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 <casacore/casa/aips.h>
00032 
00033 #if (defined(AIPS_CXX11) || (defined(__APPLE_CC__) && __APPLE_CC__ > 5621))
00034 #include <memory>
00035 #define SHARED_PTR std::shared_ptr
00036 #define DYNAMIC_POINTER_CAST std::dynamic_pointer_cast
00037 #define CONST_POINTER_CAST std::const_pointer_cast
00038 #define STATIC_POINTER_CAST std::static_pointer_cast
00039 #else
00040 #include <tr1/memory>
00041 #define SHARED_PTR std::tr1::shared_ptr
00042 #define DYNAMIC_POINTER_CAST std::tr1::dynamic_pointer_cast
00043 #define CONST_POINTER_CAST std::tr1::const_pointer_cast
00044 #define STATIC_POINTER_CAST std::tr1::static_pointer_cast
00045 #endif
00046 
00047 namespace casacore { //#Begin casa namespace
00048 
00049 
00050 // <summary> act on dereference error </summary>
00051 // <synopsis>
00052 // Global function that throws an exception. It is called by the
00053 // member functions of the counted pointer classes when an
00054 // un-initialized (null) pointer is followed.
00055 // </synopsis>
00056 // <group name=dereference_error>
00057 void throw_Null_CountedPtr_dereference_error();
00058 // </group>
00059 
00060 
00061 // <summary>Referenced counted pointer for constant data</summary>
00062 // <use visibility=export>
00063 // <reviewed reviewer="Friso Olnon" date="1995/03/15" tests="tCountedPtr" demos="">
00064 
00065 // <etymology>
00066 // This class is <em>Counted</em> because it is reference counted.
00067 // </etymology>
00068 
00069 // <synopsis>
00070 // This class implements a reference counting mechanism. It
00071 // allows <src>CountedPtr</src>s to be passed around freely,
00072 // incrementing or decrementing the reference count as needed when one
00073 // <src>CountedPtr</src> is assigned to another. When the
00074 // reference count reaches zero the internal storage is deleted by
00075 // default, but this behavior can be overridden.
00076 //
00077 // Internally the class uses std::shared_ptr to be thread-safe. Note that
00078 // tr1 is used if the compiler does not support C++11 yet.
00079 // </synopsis>
00080 
00081 // <motivation>
00082 // Reference counting
00083 // </motivation>
00084 
00085 template<class t>
00086 class CountedPtr
00087 {
00088 
00089 protected:
00090     // Helper class to make deletion of object optional.
00091     template <typename T>
00092     class Deleter {
00093     public:
00094         Deleter (Bool deleteIt) : reallyDeleteIt_p (deleteIt) {}
00095         void operator() (T * data) const { if (reallyDeleteIt_p) delete data;}
00096     private:
00097         Bool reallyDeleteIt_p;
00098     };
00099 
00100 
00101 public:
00102 
00103 
00104 
00105     // This constructor allows for the creation of a null
00106     // <src>CountedPtr</src>. The assignment operator can be used
00107     // to assign a null <src>CountedPtr</src> from another
00108     // pointer.
00109     //
00110     CountedPtr() : pointerRep_p () {}
00111 
00112     // This constructor sets up a reference count for the <src>val</src>
00113     // pointer.  By default, the data pointed to by <src>val</src>
00114     // will be deleted when it is no longer referenced. Passing in
00115     // <src>False</src> for <src>delit</src> will prevent the data
00116     // from being deleted when the reference count reaches zero.
00117     //
00118     // <note role=warning> After the counted pointer is initialized
00119     // the value should no longer be manipulated by the raw pointer of
00120     // type <src>t*</src>.
00121     // </note>
00122     CountedPtr(t *val, Bool delit = True)
00123     : pointerRep_p (val, Deleter<t> (delit))
00124     {}
00125     
00126     // This copy constructor allows <src>CountedPtr</src>s to be
00127     // initialized from other <src>CountedPtr</src>s for which the pointer TP*
00128     // is convertible to T*.
00129     template<typename TP>
00130     CountedPtr(const CountedPtr<TP>& that)
00131       : pointerRep_p(that.pointerRep_p)
00132     {}
00133 
00134     // Create from a shared_ptr.
00135     CountedPtr (const SHARED_PTR<t>& rep)
00136       : pointerRep_p (rep)
00137     {}
00138 
00139     // This destructor only deletes the really stored data when it was
00140     // initialized as deletable and the reference count is zero.
00141     ~CountedPtr() {}
00142 
00143     // This assignment operator allows <src>CountedPtr</src>s to be
00144     // copied from other <src>CountedPtr</src>s for which the pointer TP*
00145     // is convertible to t*.
00146     template<typename TP>
00147     CountedPtr<t>& operator=(const CountedPtr<TP>& that)
00148     {
00149       pointerRep_p = that.pointerRep_p;
00150       return *this;
00151     }
00152 
00153     // Reset the pointer.
00154     // <group>
00155     void reset (t *val, Bool delit=True)
00156       { pointerRep_p = PointerRep (val, Deleter<t>(delit)); }
00157     void reset()
00158       { pointerRep_p.reset(); }
00159     // </group>
00160 
00161     // The <src>CountedPtr</src> indirection operator simply
00162     // returns a reference to the value being protected. If the pointer
00163     // is un-initialized (null), an exception will be thrown. The member
00164     // function
00165     // <linkto class="CountedPtr:null()const">null</linkto>()
00166     // can be used to catch such a condition in time.
00167     // <note role=tip> The address of the reference returned should
00168     // not be stored for later use.
00169     // </note>
00170     t &operator*() const {
00171         if (null()){
00172             throw_Null_CountedPtr_dereference_error();
00173         }
00174         return pointerRep_p.operator* ();
00175     }
00176 
00177     // This dereferencing operator behaves as expected; it returns the
00178     // pointer to the value being protected, and then its dereferencing
00179     // operator will be invoked as appropriate. If the pointer is
00180     // un-initialized (null), an exception will be thrown. The member
00181     // function
00182     // <linkto class="CountedPtr:null()const">null</linkto>()
00183     // can be used to catch such a condition in time.
00184     t *operator->() const {
00185         return get ();
00186     }
00187 
00188     // Get the underlying pointer.
00189     t* get () const {
00190         return pointerRep_p.get();
00191     }
00192 
00193     // Equality operator which checks to see if two
00194     // <src>CountedPtr</src>s are pointing at the same thing.
00195     Bool operator==(const CountedPtr<t> &other) const {
00196         return (get() == other.get());
00197     }
00198     //# Note: use of const void* gives ambiguius overload error.
00199     Bool operator==(int ptr) const {
00200         return (ptr == 0  &&  get() == 0);
00201     }
00202 
00203     // Non-equality operator which checks to see if two
00204     // <src>CountedPtr</src>s are not pointing at the same thing.
00205     Bool operator!=(const CountedPtr<t> &other) const {
00206         return (get() != other.get()  ? True : False);
00207     }
00208     //# Note: use of const void* gives ambiguius overload error.
00209     Bool operator!=(int ptr) const {
00210         return (ptr != 0  ||  get() != 0);
00211     }
00212 
00213     // This assignment operator allows the object to which the current
00214     // <src>CountedPtr</src> points to be changed.
00215     CountedPtr<t> &
00216     operator=(t *v)
00217     {
00218         pointerRep_p = PointerRep (v);
00219         return * this;
00220     }
00221 
00222     // Cast functions.
00223     // <group>
00224     template<typename U>
00225     CountedPtr<U> static_ptr_cast() const
00226       { return CountedPtr<U> (STATIC_POINTER_CAST<U> (pointerRep_p)); }
00227     template<typename U>
00228     CountedPtr<U> const_ptr_cast() const
00229       { return CountedPtr<U> (CONST_POINTER_CAST<U> (pointerRep_p)); }
00230     template<typename U>
00231     CountedPtr<U> dynamic_ptr_cast() const
00232       { return CountedPtr<U> (DYNAMIC_POINTER_CAST<U> (pointerRep_p)); }
00233     // </group>
00234 
00235     // Sometimes it is useful to know if there is more than one
00236     // reference made. This is a way of getting that. Of course the point
00237     // of these classes is that this information is normally not required.
00238     uInt nrefs() const
00239       { return pointerRep_p.use_count(); }
00240 
00241     // Check to see if this <src>CountedPtr</src> is
00242     // un-initialized, null.
00243     Bool null() const
00244       { return get() == 0; }
00245 
00246     // Test if it contains a valid pointer.
00247     operator bool() const
00248       { return get() != 0; }
00249 
00250 private:
00251     // Make all types of CountedPtr a friend for the templated operator=.
00252     template<typename TP> friend class CountedPtr;
00253 
00254     typedef SHARED_PTR<t> PointerRep;
00255 
00256     PointerRep pointerRep_p;
00257 };
00258 
00259 // A shared_ptr is used as implementation.
00260 inline Bool countedPtrShared()
00261   { return True; }
00262 
00263 // Cast the CountedPtr from one pointer type to another.
00264 template<typename T, typename U>
00265 CountedPtr<T> static_pointer_cast (const CountedPtr<U>& that)
00266   { return that.template static_ptr_cast<T>(); }
00267 template<typename T, typename U>
00268 CountedPtr<T> const_pointer_cast (const CountedPtr<U>& that)
00269   { return that.template const_ptr_cast<T>(); }
00270 template<typename T, typename U>
00271 CountedPtr<T> dynamic_pointer_cast (const CountedPtr<U>& that)
00272   { return that.template dynamic_ptr_cast<T>(); }
00273 
00274 
00275 } //#End casa namespace
00276 
00277 
00278 #ifndef CASACORE_NO_AUTO_TEMPLATES
00279 #include <casacore/casa/Utilities/CountedPtr.tcc>
00280 #endif //# CASACORE_NO_AUTO_TEMPLATES
00281 
00282 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1