Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

RefCountedPtr.H

Go to the documentation of this file.
00001 /* _______              __
00002   / ___/ /  ___  __ _  / /  ___
00003  / /__/ _ \/ _ \/  ' \/ _ \/ _ \
00004  \___/_//_/\___/_/_/_/_.__/\___/ 
00005 */
00006 //
00007 // This software is copyright (C) by the Lawrence Berkeley
00008 // National Laboratory.  Permission is granted to reproduce
00009 // this software for non-commercial purposes provided that
00010 // this notice is left intact.
00011 // 
00012 // It is acknowledged that the U.S. Government has rights to
00013 // this software under Contract DE-AC03-765F00098 between
00014 // the U.S.  Department of Energy and the University of
00015 // California.
00016 //
00017 // This software is provided as a professional and academic
00018 // contribution for joint exchange. Thus it is experimental,
00019 // is provided ``as is'', with no warranties of any kind
00020 // whatsoever, no support, no promise of updates, or printed
00021 // documentation. By using this software, you acknowledge
00022 // that the Lawrence Berkeley National Laboratory and
00023 // Regents of the University of California shall have no
00024 // liability with respect to the infringement of other
00025 // copyrights by any part of this software.
00026 //
00027 
00028 // RefCountedPtr.h
00029 // ==================
00030 
00031 
00032 /*
00033         A reference counting handle class.
00034 
00035         This is to be used as a pointer to class T.  
00036         This will feel and smell just like a built-in pointer except:
00037         1.  There is no need to call delete on the pointer.
00038         2.  The default copy constructor and assignment implement ref-counting.
00039         3.  The user may call isNonUnique to determine if this pointer is
00040             the only pointer to the data.  This can be used to hide the
00041             ref-counting behavior of a class.
00042         4.  Checks for dereference of a null pointer.
00043 */
00044 
00045 #ifndef REFCOUNTEDPTR_H
00046 #define REFCOUNTEDPTR_H
00047 
00048 #include "MayDay.H"
00049 
00050 //
00051 template <class T>
00052 class RefCountedPtr {
00053 public:
00054   //
00055   inline RefCountedPtr(T* ptr = 0);
00056   //
00057   inline RefCountedPtr(const RefCountedPtr<T>& other);
00058   //
00059   inline ~RefCountedPtr();
00060   //
00061   inline const RefCountedPtr<T>& operator =(const RefCountedPtr<T>& rhs);
00062   //
00063   inline T* operator ->();
00064   //
00065   inline bool isNull() const;
00066   //
00067   inline const T* operator ->() const;
00068   //
00069   inline T& operator *();
00070   //
00071   inline const T& operator *() const;
00072   //
00073   // auto conversion to regular const pointer where required.
00074   inline operator const T* () const;
00075   //
00076   inline bool isNonUnique() const;
00077 
00078   inline int refCount() const;
00079 
00080 protected:
00081   T* ptr_;
00082   int* refCount_;
00083 private:
00084 };
00085 
00086 template <class T> inline
00087 RefCountedPtr<T>::RefCountedPtr(T* ptr)
00088   : ptr_(ptr),
00089     refCount_(0)
00090 {
00091   if (ptr_)
00092     {
00093       refCount_ = new int;
00094       if (refCount_ == 0)
00095         MayDay::Error("RefCountedPtr::RefCountedPtr(T* ptr) out of memory");
00096       *refCount_ = 1;
00097     }
00098 }
00099 
00100 template <class T> inline
00101 RefCountedPtr<T>::RefCountedPtr(const RefCountedPtr<T>& other)
00102   : ptr_(other.ptr_),
00103     refCount_(other.refCount_)
00104 {
00105   if (refCount_ != 0)
00106     ++(*refCount_);
00107 }
00108 
00109 template <class T> inline
00110 RefCountedPtr<T>::~RefCountedPtr() {
00111   if (refCount_ != 0 && --(*refCount_) == 0)
00112     {
00113       delete ptr_;
00114       ptr_ = 0;
00115       delete refCount_;
00116       refCount_ = 0;
00117     }
00118 }
00119 
00120 template <class T> inline
00121 const RefCountedPtr<T>& RefCountedPtr<T>::operator =(const RefCountedPtr<T>& rhs) {
00122   if (ptr_ != rhs.ptr_)
00123     {
00124       if (refCount_ != 0 && --(*refCount_) == 0)
00125         {
00126           delete ptr_;
00127           delete refCount_;
00128         }
00129       ptr_ = rhs.ptr_;
00130       refCount_ = rhs.refCount_;
00131       if (refCount_ != 0)
00132         ++(*refCount_);
00133     }
00134   return *this;
00135 }
00136 
00137 template <class T> inline
00138 bool RefCountedPtr<T>::isNull() const {
00139   return (ptr_ == 0);
00140 }
00141 
00142 template <class T> inline
00143 T* RefCountedPtr<T>::operator ->() {
00144   if (ptr_ == 0)
00145     MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer");
00146   return ptr_;
00147 }
00148 
00149 template <class T> inline
00150 const T* RefCountedPtr<T>::operator ->() const {
00151   if (ptr_ == 0)
00152     MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer");
00153   return ptr_;
00154 }
00155 
00156 template <class T> inline
00157 T& RefCountedPtr<T>::operator *() {
00158   if (ptr_ == 0)
00159     MayDay::Error("RefCountedPtr<T>::operator *() on null pointer");
00160   return *ptr_;
00161 }
00162 
00163 template <class T> inline
00164 const T& RefCountedPtr<T>::operator *() const {
00165   if (ptr_ == 0)
00166     MayDay::Error("RefCountedPtr<T>::operator *() on null pointer");
00167   return *ptr_;
00168 }
00169 
00170 template <class T> inline
00171 RefCountedPtr<T>::operator const T* () const {
00172   return ptr_;
00173 }
00174 
00175 template <class T> inline
00176 bool RefCountedPtr<T>::isNonUnique() const {
00177   return refCount_ == 0 ? false : *refCount_ != 1;
00178 }
00179 
00180 template <class T> inline
00181 int RefCountedPtr<T>::refCount() const {
00182   return refCount_ == 0 ? 0 : *refCount_;
00183 }
00184 
00185 #endif

Generated on Wed Apr 16 14:26:49 2003 for Chombo by doxygen1.2.16