00001 #ifndef _LCORE_RefCountPtr_H_ // -*-c++-*- 00002 00003 #ifdef __GNUG__ 00004 # pragma interface 00005 #endif 00006 00007 /* 00008 * Copyright 1991-2002 Eric M. Hopper <hopper@omnifarious.org> 00009 * 00010 * This program is free software; you can redistribute it and/or modify it 00011 * under the terms of the GNU Lesser General Public License as published 00012 * by the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, but 00016 * WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this program; if not, write to the Free Software 00022 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00023 */ 00024 00025 /* $Header: /home/hopper/src/cvs/C++/LCore/LCore/RefCountPtr.h,v 1.14 2002/11/25 05:40:05 hopper Exp $ */ 00026 00027 // For log see ../ChangeLog 00028 // 00029 // Revision 1.3 1998/05/01 11:59:32 hopper 00030 // Changed bool to bool_val or bool_cst as appropriate so it will be easier to 00031 // port to platforms that don't support bool. 00032 // 00033 // Revision 1.2 1997/05/12 16:28:33 hopper 00034 // Fixed operator = to only check type of non-NULL pointers. 00035 // 00036 // Revision 1.1 1997/05/12 14:32:55 hopper 00037 // Added new RefCountPtr class, and RefCountPtrT class to aid in using 00038 // the ReferenceCounting mixin class. 00039 // 00040 00041 #ifndef _LCORE_Protocol_H_ 00042 # include <LCore/Protocol.h> 00043 #endif 00044 #include <cassert> 00045 00046 #define _LCORE_RefCountPtr_H_ 00047 00048 namespace strmod { 00049 namespace lcore { 00050 00051 class ReferenceCounting; 00052 00053 /** \class RefCountPtr RefCountPtr.h LCore/RefCountPtr.h 00054 * A smart pointer class that points to objects of type ReferenceCounting and 00055 * maintains their reference counts. 00056 * 00057 * There's not much more to this than the brief description says. 00058 */ 00059 class RefCountPtr : virtual public Protocol 00060 { 00061 public: 00062 typedef ReferenceCounting RC; 00063 static const LCore_ClassIdent identifier; 00064 00065 //! Contruct a null pointer 00066 inline RefCountPtr(); 00067 //! Construct a pointer pointing at rfptr and increment its reference count 00068 inline RefCountPtr(RC *rfptr); 00069 //! Copy a RefCountPtr and incremement the reference count of the thing pointed to 00070 inline RefCountPtr(const RefCountPtr &b); 00071 /** Destroy the pointer and decrement the reference count of the thing pointed to. 00072 * 00073 * If the reference count of the thing pointed to goes to 0, its destructor 00074 * will be called. 00075 */ 00076 inline virtual ~RefCountPtr(); 00077 00078 inline virtual int AreYouA(const lcore::ClassIdent &cid) const; 00079 00080 //! Smart pointer operator, if _LCORE_RefCountPtr_H_DEBUG is set, asserts non-null 00081 inline RC &operator *() const; 00082 //! Smart pointer operator, if _LCORE_RefCountPtr_H_DEBUG is set, asserts non-null 00083 inline RC *operator ->() const; 00084 00085 //! What am I pointing at? 00086 inline RC *GetPtr() const { return(ptr_); } 00087 /** Set me to point at null, decrement the reference count of previous pointer destination 00088 * 00089 * If the reference count of the thing previously pointed to goes to 0, its 00090 * destructor will be called. 00091 */ 00092 inline void ReleasePtr(bool deleteref = true); 00093 00094 //! Am I non-null? 00095 inline operator bool() const; 00096 //! Am I null? 00097 inline bool operator !() const; 00098 00099 /** Copy a reference counted pointer, handling reference counts appropriately 00100 * 00101 * This handles *this = *this, and *this = ReferenceCounting(*this) properly. 00102 * It decrements the reference count of, and possibly destroys what's 00103 * currently being pointed at, and increments the reference count of what 00104 * will be pointed to. 00105 * 00106 * This also uses the i_CheckType() function to do some type checking of the 00107 * pointer being pointed to. This is so new pointer classes with type 00108 * constraints can be derived from this class. 00109 */ 00110 inline const RefCountPtr &operator =(const RefCountPtr &b); 00111 /** Copy from a regular pointer, handling reference counts appropriately 00112 * 00113 * This handles *this = this->GetPtr() properly. It decrements the reference 00114 * count of, and possibly destroys what's currently being pointed at, and 00115 * increments the reference count of what will be pointed to. 00116 * 00117 * This also uses the i_CheckType() function to do some type checking of the 00118 * pointer being pointed to. This is so new pointer classes with type 00119 * constraints can be derived from this class. 00120 */ 00121 inline const RefCountPtr &operator =(RC *b); 00122 00123 protected: 00124 virtual const ClassIdent *i_GetIdent() const { return(&identifier); } 00125 00126 /** Do some type checking of a ReferenceCounting pointer to make sure it points at the right type. 00127 * 00128 * @param p The pointer who's type needs to be checked. 00129 * @return null if the pointer is the wrong type, the value of p if it is of the right type. 00130 */ 00131 virtual RC *i_CheckType(RC *p) const { return(p); } 00132 /** Change what this RefCountPtr points to, maybe modifying reference counts 00133 * 00134 * This will properly handle i_SetPtr(GetPtr()). Normally, it will increment 00135 * the reference count of the new value of the pointer, then decrement the 00136 * reference count of the old value, possibly deleting the pointed to object 00137 * if the reference count goes to 0. If deleteref is false, the decrement 00138 * won't happen. 00139 * 00140 * @param p The new value of the pointer. 00141 * @param deleteref Should the old value's reference count be decremented? 00142 */ 00143 void i_SetPtr(ReferenceCounting *p, bool deleteref = true); 00144 00145 private: 00146 RC *ptr_; 00147 }; 00148 00149 //-----------------------------inline functions-------------------------------- 00150 00151 inline RefCountPtr::RefCountPtr() : ptr_(0) 00152 { 00153 } 00154 00155 inline RefCountPtr::RefCountPtr(RC *rfptr) : ptr_(0) 00156 { 00157 if (rfptr) { 00158 i_SetPtr(rfptr); 00159 } 00160 } 00161 00162 inline RefCountPtr::RefCountPtr(const RefCountPtr &b) : ptr_(0) 00163 { 00164 if (b) { 00165 i_SetPtr(b.GetPtr()); 00166 } 00167 } 00168 00169 inline RefCountPtr::~RefCountPtr() 00170 { 00171 ReleasePtr(true); 00172 } 00173 00174 inline int RefCountPtr::AreYouA(const ClassIdent &cid) const 00175 { 00176 return((identifier == cid) || Protocol::AreYouA(cid)); 00177 } 00178 00179 #if !defined(_LCORE_RefCountPtr_H_DEBUG) || defined(_LCORE_RefCountPtr_H_CC) 00180 inline ReferenceCounting &RefCountPtr::operator *() const 00181 { 00182 #ifdef _LCORE_RefCountPtr_H_CC 00183 assert(GetPtr() != 0); 00184 #endif 00185 00186 return *GetPtr(); 00187 } 00188 00189 inline ReferenceCounting *RefCountPtr::operator ->() const 00190 { 00191 #ifdef _LCORE_RefCountPtr_H_CC 00192 assert(GetPtr() != 0); 00193 #endif 00194 00195 return GetPtr(); 00196 } 00197 #endif 00198 00199 inline void RefCountPtr::ReleasePtr(bool deleteref) 00200 { 00201 i_SetPtr(0, deleteref); 00202 } 00203 00204 inline RefCountPtr::operator bool() const 00205 { 00206 return((GetPtr() != 0) ? true : false); 00207 } 00208 00209 inline bool RefCountPtr::operator !() const 00210 { 00211 return(GetPtr() == 0); 00212 } 00213 00214 inline const RefCountPtr &RefCountPtr::operator =(const RefCountPtr &b) 00215 { 00216 if (this != &b) { 00217 RC *p = b.GetPtr(); 00218 00219 operator =(p); 00220 } 00221 return(*this); 00222 } 00223 00224 inline const RefCountPtr &RefCountPtr::operator =(RC *b) 00225 { 00226 if (GetPtr() != b) { 00227 if (b) { 00228 b = i_CheckType(b); 00229 } 00230 i_SetPtr(b); 00231 } 00232 return(*this); 00233 } 00234 00235 } // namespace lcore 00236 } // namespace strmod 00237 00238 #endif
1.3-rc1