Home | nevrax.com |
|
smart_ptr.hGo to the documentation of this file.00001 00007 /* Copyright, 2000 Nevrax Ltd. 00008 * 00009 * This file is part of NEVRAX NEL. 00010 * NEVRAX NEL is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2, or (at your option) 00013 * any later version. 00014 00015 * NEVRAX NEL 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 * General Public License for more details. 00019 00020 * You should have received a copy of the GNU General Public License 00021 * along with NEVRAX NEL; see the file COPYING. If not, write to the 00022 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 00023 * MA 02111-1307, USA. 00024 */ 00025 00026 #ifndef NL_SMART_PTR_H 00027 #define NL_SMART_PTR_H 00028 00029 00030 #include "nel/misc/types_nl.h" 00031 00032 #include <stdio.h> 00033 00034 00035 namespace NLMISC 00036 { 00037 00038 00039 // *************************************************************************** 00047 class CRefCount 00048 { 00049 public: 00050 // The instance handle. 00051 // Can't put those to private since must be used by CRefPtr (and friend doesn't work with template). 00052 struct CPtrInfo 00053 { 00054 void *Ptr; // to know if the instance is valid. 00055 sint RefCount; // RefCount of ptrinfo (!= instance) 00056 // For fu... dll problems, must use a flag to mark NullPtrInfo. 00057 bool IsNullPtrInfo; 00058 00059 CPtrInfo(void *p) {Ptr=p; RefCount=0; IsNullPtrInfo=false;} 00060 // Just for internal use, to mark our Null pointer. 00061 CPtrInfo(char ) {Ptr=NULL; RefCount=0x7FFFFFFF; IsNullPtrInfo=true;} 00062 }; 00063 00064 // OWN null for ref ptr. (Optimisations!!!) 00065 static CPtrInfo NullPtrInfo; 00066 friend struct CPtrInfo; 00067 00068 public: 00069 // Can't put this to private since must be used by CSmartPtr (and friend doesn't work with template). 00070 // Provide incref()/decref() function doen't work since decref() can't do a delete this on a non virtual dtor. 00071 // So Ptr gestion can only be used via CSmartPtr. 00072 mutable sint crefs; // The ref counter for SmartPtr use. 00073 mutable CPtrInfo *pinfo; // The ref ptr for RefPtr use. 00074 00076 ~CRefCount(); 00078 CRefCount() { crefs = 0; pinfo=&NullPtrInfo; } 00080 CRefCount &operator=(const CRefCount &) {return *this;} 00082 CRefCount(const CRefCount &) {crefs = 0; pinfo=&NullPtrInfo;} 00083 }; 00084 00085 00086 00087 // *************************************************************************** 00088 // For debug only. 00089 #define SMART_TRACE(_s) ((void)0) 00090 #define REF_TRACE(_s) ((void)0) 00091 //#define SMART_TRACE(_s) printf("%s: %d \n", _s, Ptr?Ptr->crefs:0) 00092 //#define REF_TRACE(_s) printf("%s: %d \n", _s, pinfo!=&CRefCount::NullPtrInfo?pinfo->RefCount:0) 00093 00094 00177 template <class T> 00178 class CSmartPtr 00179 { 00180 T* Ptr; 00181 public: 00182 00184 CSmartPtr() { Ptr=NULL; SMART_TRACE("ctor()"); } 00186 CSmartPtr(T* p) { Ptr=p; if(Ptr) Ptr->crefs++; SMART_TRACE("ctor(T*)"); } 00188 CSmartPtr(const CSmartPtr ©) { Ptr=copy.Ptr; if(Ptr) Ptr->crefs++; SMART_TRACE("ctor(Copy)"); } 00190 ~CSmartPtr(); 00191 00192 00194 operator T*(void) const { SMART_TRACE("castT*()"); return Ptr; } 00196 T& operator*(void) const { SMART_TRACE("ope*()"); return *Ptr; } 00198 T* operator->(void) const { SMART_TRACE("ope->()"); return Ptr; } 00199 00201 CSmartPtr& operator=(T* p); 00203 CSmartPtr& operator=(const CSmartPtr &p); 00205 bool operator<(const CSmartPtr &p) const; 00206 00207 sint getNbRef() { if(Ptr) return Ptr->crefs; else return 0; } 00208 // No need to do any operator==. Leave the work to cast operator T*(void). 00209 }; 00210 00211 00212 00213 // *************************************************************************** 00243 template <class T> 00244 class CRefPtr 00245 { 00246 private: 00247 CRefCount::CPtrInfo *pinfo; // A ptr to the handle of the object. 00248 mutable T *Ptr; // A cache for pinfo->Ptr. UseFull to speed up ope->() and ope*() 00249 00250 void unRef() const; // Just release the handle pinfo, but do not update pinfo/Ptr, if deleted. 00251 00252 public: 00253 00255 CRefPtr(); 00257 CRefPtr(T *v); 00259 CRefPtr(const CRefPtr ©); 00261 ~CRefPtr(void); 00262 00263 00265 operator T*() const; 00267 T& operator*(void) const; 00269 T* operator->(void) const; 00270 00271 00273 CRefPtr& operator=(T *v); 00275 CRefPtr& operator=(const CRefPtr ©); 00276 00277 00285 void kill(); 00286 00287 00288 // No need to do any operator==. Leave the work to cast operator T*(void). 00289 }; 00290 00291 00292 00293 } 00294 00295 00296 // *************************************************************************** 00297 // *************************************************************************** 00298 // Implementation. 00299 // *************************************************************************** 00300 // *************************************************************************** 00301 00302 00303 #include "smart_ptr_inline.h" 00304 #undef SMART_TRACE 00305 #undef REF_TRACE 00306 00307 00308 00309 #endif // NL_SMART_PTR_H 00310 00311 /* End of smart_ptr.h */ |