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 #ifndef REFCOUNTEDPTR_H 00034 #define REFCOUNTEDPTR_H 00035 00036 #include "MayDay.H" 00037 00039 00084 template <class T> 00085 class RefCountedPtr { 00086 public: 00087 // 00088 inline RefCountedPtr(T* ptr = 0); 00089 // 00090 inline RefCountedPtr(const RefCountedPtr<T>& other); 00091 // 00092 inline ~RefCountedPtr(); 00094 00096 inline const RefCountedPtr<T>& operator =(const RefCountedPtr<T>& rhs); 00098 inline T* operator ->(); 00099 inline const T* operator ->() const; 00100 // 00101 inline bool isNull() const; 00102 // 00104 inline T& operator *(); 00105 inline const T& operator *() const; 00106 // 00108 inline operator const T* () const; 00109 00111 inline bool isNonUnique() const; 00112 00113 inline int refCount() const; 00114 00115 protected: 00116 T* ptr_; 00117 int* refCount_; 00118 private: 00119 }; 00120 00121 template <class T> inline 00122 RefCountedPtr<T>::RefCountedPtr(T* ptr) 00123 : ptr_(ptr), 00124 refCount_(0) 00125 { 00126 if (ptr_) 00127 { 00128 refCount_ = new int; 00129 if (refCount_ == 0) 00130 MayDay::Error("RefCountedPtr::RefCountedPtr(T* ptr) out of memory"); 00131 *refCount_ = 1; 00132 } 00133 } 00134 00135 template <class T> inline 00136 RefCountedPtr<T>::RefCountedPtr(const RefCountedPtr<T>& other) 00137 : ptr_(other.ptr_), 00138 refCount_(other.refCount_) 00139 { 00140 if (refCount_ != 0) 00141 ++(*refCount_); 00142 } 00143 00144 template <class T> inline 00145 RefCountedPtr<T>::~RefCountedPtr() { 00146 if (refCount_ != 0 && --(*refCount_) == 0) 00147 { 00148 delete ptr_; 00149 ptr_ = 0; 00150 delete refCount_; 00151 refCount_ = 0; 00152 } 00153 } 00154 00155 template <class T> inline 00156 const RefCountedPtr<T>& RefCountedPtr<T>::operator =(const RefCountedPtr<T>& rhs) { 00157 if (ptr_ != rhs.ptr_) 00158 { 00159 if (refCount_ != 0 && --(*refCount_) == 0) 00160 { 00161 delete ptr_; 00162 delete refCount_; 00163 } 00164 ptr_ = rhs.ptr_; 00165 refCount_ = rhs.refCount_; 00166 if (refCount_ != 0) 00167 ++(*refCount_); 00168 } 00169 return *this; 00170 } 00171 00172 template <class T> inline 00173 bool RefCountedPtr<T>::isNull() const { 00174 return (ptr_ == 0); 00175 } 00176 00177 template <class T> inline 00178 T* RefCountedPtr<T>::operator ->() { 00179 if (ptr_ == 0) 00180 MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer"); 00181 return ptr_; 00182 } 00183 00184 template <class T> inline 00185 const T* RefCountedPtr<T>::operator ->() const { 00186 if (ptr_ == 0) 00187 MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer"); 00188 return ptr_; 00189 } 00190 00191 template <class T> inline 00192 T& RefCountedPtr<T>::operator *() { 00193 if (ptr_ == 0) 00194 MayDay::Error("RefCountedPtr<T>::operator *() on null pointer"); 00195 return *ptr_; 00196 } 00197 00198 template <class T> inline 00199 const T& RefCountedPtr<T>::operator *() const { 00200 if (ptr_ == 0) 00201 MayDay::Error("RefCountedPtr<T>::operator *() on null pointer"); 00202 return *ptr_; 00203 } 00204 00205 template <class T> inline 00206 RefCountedPtr<T>::operator const T* () const { 00207 return ptr_; 00208 } 00209 00210 template <class T> inline 00211 bool RefCountedPtr<T>::isNonUnique() const { 00212 return refCount_ == 0 ? false : *refCount_ != 1; 00213 } 00214 00215 template <class T> inline 00216 int RefCountedPtr<T>::refCount() const { 00217 return refCount_ == 0 ? 0 : *refCount_; 00218 } 00219 00220 #endif