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