# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

smart_ptr.h

Go 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 &copy) { 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 &copy);
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 &copy);
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 */