00001 /* _______ __ 00002 / ___/ / ___ __ _ / / ___ 00003 / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00004 \___/_//_/\___/_/_/_/_.__/\___/ 00005 */ 00006 // CHOMBO Copyright (c) 2000-2004, The Regents of the University of 00007 // California, through Lawrence Berkeley National Laboratory (subject to 00008 // receipt of any required approvals from U.S. Dept. of Energy). All 00009 // rights reserved. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are met: 00013 // 00014 // (1) Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // (2) Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the distribution. 00019 // (3) Neither the name of Lawrence Berkeley National Laboratory, U.S. 00020 // Dept. of Energy nor the names of its contributors may be used to endorse 00021 // or promote products derived from this software without specific prior 00022 // written permission. 00023 // 00024 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00025 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00026 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00027 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00028 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00029 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00030 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00031 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00032 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00033 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00034 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 // 00036 // You are under no obligation whatsoever to provide any bug fixes, 00037 // patches, or upgrades to the features, functionality or performance of 00038 // the source code ("Enhancements") to anyone; however, if you choose to 00039 // make your Enhancements available either publicly, or directly to 00040 // Lawrence Berkeley National Laboratory, without imposing a separate 00041 // written license agreement for such Enhancements, then you hereby grant 00042 // the following license: a non-exclusive, royalty-free perpetual license 00043 // to install, use, modify, prepare derivative works, incorporate into 00044 // other computer software, distribute, and sublicense such Enhancements or 00045 // derivative works thereof, in binary and source code form. 00046 // 00047 // TRADEMARKS. Product and company names mentioned herein may be the 00048 // trademarks of their respective owners. Any rights not expressly granted 00049 // herein are reserved. 00050 // 00051 00052 #ifndef _REFCOUNTEDPTR_H_ 00053 #define _REFCOUNTEDPTR_H_ 00054 00055 #include "MayDay.H" 00056 00058 00101 template <class T> 00102 class RefCountedPtr { 00103 public: 00104 // 00105 inline RefCountedPtr(T* ptr = 0); 00106 // 00107 inline RefCountedPtr(const RefCountedPtr<T>& other); 00108 // 00109 inline ~RefCountedPtr(); 00111 00113 inline const RefCountedPtr<T>& operator =(const RefCountedPtr<T>& rhs); 00115 inline T* operator ->(); 00116 inline const T* operator ->() const; 00117 // 00118 inline bool isNull() const; 00119 // 00121 inline T& operator *(); 00122 inline const T& operator *() const; 00123 // 00125 inline operator const T* () const; 00126 00128 inline bool isNonUnique() const; 00129 00130 inline int refCount() const; 00131 00132 inline void swap(RefCountedPtr<T>& b); 00133 00134 protected: 00135 T* ptr_; 00136 int* refCount_; 00137 private: 00138 }; 00139 00140 template <class T> inline 00141 RefCountedPtr<T>::RefCountedPtr(T* ptr) 00142 : ptr_(ptr), 00143 refCount_(0) 00144 { 00145 if (ptr_) 00146 { 00147 refCount_ = new int; 00148 if (refCount_ == 0) 00149 MayDay::Error("RefCountedPtr::RefCountedPtr(T* ptr) out of memory"); 00150 *refCount_ = 1; 00151 } 00152 } 00153 00154 template <class T> inline 00155 RefCountedPtr<T>::RefCountedPtr(const RefCountedPtr<T>& other) 00156 : ptr_(other.ptr_), 00157 refCount_(other.refCount_) 00158 { 00159 if (refCount_ != 0) 00160 ++(*refCount_); 00161 } 00162 00163 template <class T> inline 00164 RefCountedPtr<T>::~RefCountedPtr() { 00165 if (refCount_ != 0 && --(*refCount_) == 0) 00166 { 00167 delete ptr_; 00168 ptr_ = 0; 00169 delete refCount_; 00170 refCount_ = 0; 00171 } 00172 } 00173 00174 template <class T> inline 00175 const RefCountedPtr<T>& RefCountedPtr<T>::operator =(const RefCountedPtr<T>& rhs) { 00176 if (ptr_ != rhs.ptr_) 00177 { 00178 if (refCount_ != 0 && --(*refCount_) == 0) 00179 { 00180 delete ptr_; 00181 delete refCount_; 00182 } 00183 ptr_ = rhs.ptr_; 00184 refCount_ = rhs.refCount_; 00185 if (refCount_ != 0) 00186 ++(*refCount_); 00187 } 00188 return *this; 00189 } 00190 00191 template <class T> inline 00192 bool RefCountedPtr<T>::isNull() const { 00193 return (ptr_ == 0); 00194 } 00195 00196 template <class T> inline 00197 T* RefCountedPtr<T>::operator ->() { 00198 if (ptr_ == 0) 00199 MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer"); 00200 return ptr_; 00201 } 00202 00203 template <class T> inline 00204 const T* RefCountedPtr<T>::operator ->() const { 00205 if (ptr_ == 0) 00206 MayDay::Error("RefCountedPtr<T>::operator ->() on null pointer"); 00207 return ptr_; 00208 } 00209 00210 template <class T> inline 00211 T& RefCountedPtr<T>::operator *() { 00212 if (ptr_ == 0) 00213 MayDay::Error("RefCountedPtr<T>::operator *() on null pointer"); 00214 return *ptr_; 00215 } 00216 00217 template <class T> inline 00218 const T& RefCountedPtr<T>::operator *() const { 00219 if (ptr_ == 0) 00220 MayDay::Error("RefCountedPtr<T>::operator *() on null pointer"); 00221 return *ptr_; 00222 } 00223 00224 template <class T> inline 00225 RefCountedPtr<T>::operator const T* () const { 00226 return ptr_; 00227 } 00228 00229 template <class T> inline 00230 bool RefCountedPtr<T>::isNonUnique() const { 00231 return refCount_ == 0 ? false : *refCount_ != 1; 00232 } 00233 00234 template <class T> inline 00235 int RefCountedPtr<T>::refCount() const { 00236 return refCount_ == 0 ? 0 : *refCount_; 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 #endif