![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference cAutoPtr.hGo to the documentation of this file.00001 /************************************************************************ 00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library 00003 Copyright (C) 2003 Aaron Cameron 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 A copy of the GNU Lesser General Public License has been provided with 00020 this library in the file 'COPYING'. 00021 00022 Contact information for the author of this library has been provided 00023 with this library in the file 'AUTHOR'. 00024 ************************************************************************/ 00025 #ifndef _n2l4_cAutoPtr_h 00026 #define _n2l4_cAutoPtr_h 00027 00028 #include "types.h" 00029 #include "cBadCastException.h" 00030 #include "assert.h" 00031 00032 /******************************************************************************/ 00033 namespace n2l 00034 { 00050 template <class TPtr> 00051 class cAutoPtr 00052 { 00053 private: 00054 typedef tUint tRefCount; 00055 typedef TPtr tValue; 00056 00057 tRefCount * mRefCount; 00058 tValue * mPtr; 00061 void incRefCount() const { assert(mRefCount); (*mRefCount)++; } 00062 00064 void decRefCount() const { 00065 assert(mRefCount); assert(*mRefCount); (*mRefCount)--; 00066 } 00067 00071 void set( tValue * const i_ioPtr ) { mPtr = i_ioPtr; } 00072 00076 tValue * const get() const { return mPtr; } 00077 00078 00079 protected: 00080 public: 00084 cAutoPtr() : 00085 mRefCount(0), 00086 mPtr(0) 00087 { 00088 } 00089 00094 cAutoPtr( const cAutoPtr & i_autoPtr ) : 00095 mRefCount(0), mPtr(0) 00096 { 00097 assign( i_autoPtr ); 00098 } 00099 00104 cAutoPtr( tValue * io_ptr ) : 00105 mRefCount(0), mPtr(0) 00106 { 00107 assign( io_ptr ); 00108 } 00109 00113 ~cAutoPtr() 00114 { 00115 release(); 00116 } 00117 00121 const tRefCount count() const { 00122 assert(mRefCount); 00123 return (*mRefCount); 00124 } 00125 00132 void assign( const cAutoPtr & i_autoPtr ) 00133 { 00134 // Check for self assignment 00135 if (i_autoPtr.mPtr==mPtr) return; 00136 00137 // Clean the slate 00138 release(); 00139 00140 // If we're assigning to a null (acting) autopointer, stop 00141 // after releasing 00142 if ( (0==i_autoPtr.mPtr) || (0==i_autoPtr.mRefCount) ) return; 00143 00144 mRefCount = i_autoPtr.mRefCount; 00145 mPtr = i_autoPtr.mPtr; 00146 incRefCount(); 00147 } 00148 00159 void assign( tValue * i_ptr ) 00160 { 00161 // Check for self assignment 00162 if (i_ptr==mPtr) return; 00163 00164 // Clean the slate 00165 release(); 00166 00167 // If we're assigning null, leave this instance acting as null 00168 if (0==i_ptr) return; 00169 00170 mRefCount = new tRefCount(1); 00171 mPtr = i_ptr; 00172 } 00173 00175 void operator =( tValue * i_ptr ) { assign(i_ptr); } 00176 00178 void operator =( const cAutoPtr & i_autoPtr ) { assign(i_autoPtr); } 00179 00180 const tBool operator >(const cAutoPtr &iAutoPtr) const { 00181 return get()>iAutoPtr.get(); 00182 } 00183 00184 const tBool operator <(const cAutoPtr &iAutoPtr) const { 00185 return get()<iAutoPtr.get(); 00186 } 00187 00188 const tBool operator >=(const cAutoPtr &iAutoPtr) const { 00189 return get()>=iAutoPtr.get(); 00190 } 00191 00192 const tBool operator <=(const cAutoPtr &iAutoPtr) const { 00193 return get()<=iAutoPtr.get(); 00194 } 00195 00200 void release() { 00201 if (!mPtr) return; 00202 decRefCount(); 00203 if (!count()) { 00204 delete mPtr; 00205 delete mRefCount; 00206 } 00207 mPtr = 0; 00208 mRefCount=0; 00209 } 00210 00216 const tBool equals( const cAutoPtr & i_autoPtr ) const { 00217 return (get()==i_autoPtr.get()); 00218 } 00219 00230 const tBool equals( const tValue * const i_ptr ) const { 00231 return (get()==i_ptr); 00232 } 00233 00235 const tBool operator ==( const tValue * const i_ptr ) const { 00236 return equals(i_ptr); 00237 } 00238 00239 const tBool operator !=( const tValue * const i_ptr ) const { 00240 return !equals(i_ptr); 00241 } 00242 00244 const tBool operator ==( const cAutoPtr & i_autoPtr ) const { 00245 return equals(i_autoPtr); 00246 } 00247 00248 const tBool operator !=( const cAutoPtr & i_autoPtr ) const { 00249 return !equals(i_autoPtr); 00250 } 00251 00255 tValue & operator *() const { return *mPtr; } 00256 00260 tValue * operator ->() const { return mPtr; } 00261 00267 operator tBool() const { return tBool(mPtr); } 00268 00284 void _setRealRefCountPtr( tRefCount * i_newRefCountPtr ) { 00285 assert(0==mRefCount); mRefCount = i_newRefCountPtr; 00286 } 00287 00303 void _setRealPtr( tValue * i_newPtr ) { 00304 assert(0==mPtr); mPtr = i_newPtr; 00305 } 00306 00312 template <class TOtherPtr> 00313 cAutoPtr<TOtherPtr> as() const 00314 { 00315 if (mPtr==0) return 0; 00316 TOtherPtr * newPtr; 00317 cAutoPtr<TOtherPtr> newAutoPtr; 00318 newPtr = dynamic_cast<TOtherPtr *>(mPtr); 00319 if (0==newPtr) return 0; 00320 newAutoPtr._setRealPtr(newPtr); 00321 newAutoPtr._setRealRefCountPtr(mRefCount); 00322 incRefCount(); 00323 return newAutoPtr; 00324 } 00325 00339 template <class TOtherPtr> 00340 operator cAutoPtr<TOtherPtr>() const 00341 { 00342 if (mPtr==0) return 0; 00343 TOtherPtr * newPtr; 00344 cAutoPtr<TOtherPtr> newAutoPtr; 00345 00346 newPtr = dynamic_cast<TOtherPtr *>(mPtr); 00347 if (0==newPtr) 00348 throw cBadCastException( "cAutoPtr::Typecast::dynamic_cast", 00349 "Bad Cast"); 00350 newAutoPtr._setRealPtr(newPtr); 00351 newAutoPtr._setRealRefCountPtr(mRefCount); 00352 incRefCount(); 00353 return newAutoPtr; 00354 } 00355 00356 template <class TOtherPtr> 00357 operator cAutoPtr<const TOtherPtr>() const 00358 { 00359 if (mPtr==0) return 0; 00360 const TOtherPtr * const newPtr( 00361 dynamic_cast<const TOtherPtr * const>(mPtr) ); 00362 if (0==newPtr) 00363 throw cBadCastException( "cAutoPtr::Typecast::dynamic_cast", 00364 "Bad Cast (const)"); 00365 cAutoPtr<const TOtherPtr> newAutoPtr; 00366 newAutoPtr._setRealPtr(newPtr); 00367 newAutoPtr._setRealRefCountPtr(mRefCount); 00368 incRefCount(); 00369 return newAutoPtr; 00370 } 00371 00372 00373 /*******************************************************************/ 00374 // Auto pointer extensions 00375 00381 const tBool isSet() const { return mPtr!=0; } 00382 00383 tValue * const dumbPtr() const { return mPtr; } 00384 00385 00386 }; 00387 00388 } // namespace n2l 00389 00390 #endif |