00001 #ifdef CH_LANG_CC 00002 /* 00003 * _______ __ 00004 * / ___/ / ___ __ _ / / ___ 00005 * / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00006 * \___/_//_/\___/_/_/_/_.__/\___/ 00007 * Please refer to Copyright.txt, in Chombo's root directory. 00008 */ 00009 #endif 00010 00011 #ifndef _REFCOUNTEDPTR_H_ 00012 #define _REFCOUNTEDPTR_H_ 00013 00014 #include "MayDay.H" 00015 #include "BaseNamespaceHeader.H" 00016 00018 00061 template <class T> 00062 class RefCountedPtr { 00063 public: 00064 // 00065 explicit inline RefCountedPtr(T* ptr = 0); 00066 // 00067 inline RefCountedPtr(const RefCountedPtr<T>& other); 00068 // 00069 inline ~RefCountedPtr(); 00071 00073 inline const RefCountedPtr<T>& operator =(const RefCountedPtr<T>& rhs); 00075 inline T* operator ->(); 00076 inline const T* operator ->() const; 00077 // 00078 inline bool isNull() const; 00079 // 00081 inline T& operator *(); 00082 #ifdef CH_TEMPEST 00083 inline T& operator *() const; // As in Boost::shared_ptr. 00084 #else 00085 inline const T& operator *() const; 00086 #endif 00087 // 00089 inline operator const T* () const; 00090 00092 inline bool isNonUnique() const; 00093 00094 inline int refCount() const; 00095 00096 inline void swap(RefCountedPtr<T>& b); 00097 00099 00103 template<class T2> inline operator RefCountedPtr<T2>(); 00104 00105 // Will never delete ptr_. Useful in functions that need to return a 00106 // pointer which, under some circumstances, we want to own, and under others 00107 // we don't. 00108 inline void neverDelete(); 00109 00110 template<class T2> friend class RefCountedPtr; 00111 00112 protected: 00113 T* ptr_; 00114 int* refCount_; 00115 private: 00116 00117 }; 00118 00119 00120 00121 00122 template <class T> inline 00123 RefCountedPtr<T>::RefCountedPtr(T* ptr) 00124 : ptr_(ptr), 00125 refCount_(0) 00126 { 00127 if (ptr_) 00128 { 00129 refCount_ = new int; 00130 if (refCount_ == 0) 00131 MayDay::Error("RefCountedPtr::RefCountedPtr(T* ptr) out of memory"); 00132 *refCount_ = 1; 00133 } 00134 } 00135 00136 template <class T> inline 00137 RefCountedPtr<T>::RefCountedPtr(const RefCountedPtr<T>& other) 00138 : ptr_(other.ptr_), 00139 refCount_(other.refCount_) 00140 { 00141 if (refCount_ != 0) 00142 ++(*refCount_); 00143 } 00144 00145 template <class T> inline 00146 RefCountedPtr<T>::~RefCountedPtr() { 00147 if (refCount_ != 0 && --(*refCount_) == 0) 00148 { 00149 delete ptr_; 00150 ptr_ = 0; 00151 delete refCount_; 00152 refCount_ = 0; 00153 } 00154 } 00155 00156 template <class T> inline 00157 const RefCountedPtr<T>& RefCountedPtr<T>::operator =(const RefCountedPtr<T>& rhs) { 00158 if (ptr_ != rhs.ptr_) 00159 { 00160 if (refCount_ != 0 && --(*refCount_) == 0) 00161 { 00162 delete ptr_; 00163 delete refCount_; 00164 } 00165 ptr_ = rhs.ptr_; 00166 refCount_ = rhs.refCount_; 00167 if (refCount_ != 0) 00168 ++(*refCount_); 00169 } 00170 return *this; 00171 } 00172 00173 template <class T> inline 00174 bool RefCountedPtr<T>::isNull() const { 00175 return (ptr_ == 0); 00176 } 00177 00178 template <class T> inline 00179 T* RefCountedPtr<T>::operator ->() { 00180 if (ptr_ == 0) 00181 MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer"); 00182 return ptr_; 00183 } 00184 00185 template <class T> inline 00186 const T* RefCountedPtr<T>::operator ->() const { 00187 if (ptr_ == 0) 00188 MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer"); 00189 return ptr_; 00190 } 00191 00192 template <class T> inline 00193 T& RefCountedPtr<T>::operator *() { 00194 if (ptr_ == 0) 00195 MayDay::Error("RefCountedPtr<T>::operator *() on null pointer"); 00196 return *ptr_; 00197 } 00198 00199 template <class T> inline 00200 #ifndef CH_TEMPEST 00201 const 00202 #endif 00203 T& RefCountedPtr<T>::operator *() const { 00204 if (ptr_ == 0) 00205 MayDay::Error("RefCountedPtr<T>::operator *() on null pointer"); 00206 return *ptr_; 00207 } 00208 00209 template <class T> inline 00210 RefCountedPtr<T>::operator const T* () const { 00211 return ptr_; 00212 } 00213 00214 template <class T> inline 00215 bool RefCountedPtr<T>::isNonUnique() const { 00216 return refCount_ == 0 ? false : *refCount_ != 1; 00217 } 00218 00219 template <class T> inline 00220 int RefCountedPtr<T>::refCount() const { 00221 return refCount_ == 0 ? 0 : *refCount_; 00222 } 00223 00224 00225 00226 00227 template <class T> 00228 template <class T2> 00229 inline RefCountedPtr<T>::operator RefCountedPtr<T2> () 00230 { 00231 RefCountedPtr<T2> rtn(ptr_); // if you have a compiler error that points here, then T2 is probably not a T 00232 ++ *refCount_; 00233 delete rtn.refCount_; 00234 rtn.refCount_ = refCount_; 00235 return rtn; 00236 } 00237 00238 00239 template <class T> inline 00240 void RefCountedPtr<T>::swap(RefCountedPtr<T>& b) 00241 { 00242 T* s = ptr_; 00243 ptr_ = b.ptr_; 00244 b.ptr_ = s; 00245 00246 int* r = refCount_; 00247 refCount_ = b.refCount_; 00248 b.refCount_ = r; 00249 } 00250 00251 template <class T> inline 00252 void RefCountedPtr<T>::neverDelete() 00253 { 00254 ++ *refCount_; 00255 } 00256 00257 #include "BaseNamespaceFooter.H" 00258 #endif