• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

RakNetSmartPtr.h

Go to the documentation of this file.
00001 #ifndef __RAKNET_SMART_PTR_H
00002 #define __RAKNET_SMART_PTR_H
00003 
00004 // From http://www.codeproject.com/KB/cpp/SmartPointers.aspx
00005 // with bugs fixed
00006 
00007 #include "RakMemoryOverride.h"
00008 #include "Export.h"
00009 
00010 //static int allocCount=0;
00011 //static int deallocCount=0;
00012 
00013 class RAK_DLL_EXPORT ReferenceCounter
00014 {
00015 private:
00016         int refCount;
00017 
00018 public:
00019         ReferenceCounter() {refCount=0;}
00020         ~ReferenceCounter() {}
00021         void AddRef() {refCount++;}
00022         int Release() {return --refCount;}
00023         int GetRefCount(void) const {return refCount;}
00024 };
00025 
00026 template < typename T > class RAK_DLL_EXPORT RakNetSmartPtr
00027 {
00028 private:
00029         T*    ptr;       // pointer
00030         ReferenceCounter* reference; // Reference refCount
00031 
00032 public:
00033         RakNetSmartPtr() : ptr(0), reference(0)
00034         {
00035                 // Do not allocate by default, wasteful if we just have a list of preallocated and unassigend smart pointers
00036         }
00037 
00038         RakNetSmartPtr(T* pValue) : ptr(pValue)
00039         {
00040                 reference = RakNet::OP_NEW<ReferenceCounter>(__FILE__,__LINE__);
00041                 reference->AddRef();
00042 
00043 //              allocCount+=2;
00044 //              printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00045         }
00046 
00047         RakNetSmartPtr(const RakNetSmartPtr<T>& sp) : ptr(sp.ptr), reference(sp.reference)
00048         {
00049                 if (reference)
00050                         reference->AddRef();
00051         }
00052 
00053         ~RakNetSmartPtr()
00054         {
00055                 if(reference && reference->Release() == 0)
00056                 {
00057                         RakNet::OP_DELETE(ptr, __FILE__, __LINE__);
00058                         RakNet::OP_DELETE(reference, __FILE__, __LINE__);
00059 
00060 //                      deallocCount+=2;
00061 //                      printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00062                 }
00063         }
00064 
00065         bool IsNull(void) const
00066         {
00067                 return ptr==0;
00068         }
00069 
00070         void SetNull(void)
00071         {
00072                 if(reference && reference->Release() == 0)
00073                 {
00074                         RakNet::OP_DELETE(ptr, __FILE__, __LINE__);
00075                         RakNet::OP_DELETE(reference, __FILE__, __LINE__);
00076 
00077 //                      deallocCount+=2;
00078 //                      printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00079                 }
00080                 ptr=0;
00081                 reference=0;
00082         }
00083 
00084         bool IsUnique(void) const
00085         {
00086                 return reference->GetRefCount()==1;
00087         }
00088 
00089         // Allow you to change the values of the internal contents of the pointer, without changing what is pointed to by other instances of the smart pointer
00090         void Clone(bool copyContents)
00091         {
00092                 if (IsUnique()==false)
00093                 {
00094                         reference->Release();
00095 
00096                         reference = RakNet::OP_NEW<ReferenceCounter>(__FILE__,__LINE__);
00097                         reference->AddRef();
00098                         T* oldPtr=ptr;
00099                         ptr=RakNet::OP_NEW<T>(__FILE__,__LINE__);
00100                         if (copyContents)
00101                                 *ptr=*oldPtr;
00102                 }
00103         }
00104 
00105         int GetRefCount(void) const
00106         {
00107                 return reference->GetRefCount();
00108         }
00109 
00110         T& operator* ()
00111         {
00112                 return *ptr;
00113         }
00114 
00115         const T& operator* () const
00116         {
00117                 return *ptr;
00118         }
00119 
00120         T* operator-> ()
00121         {
00122                 return ptr;
00123         }
00124 
00125         const T* operator-> () const
00126         {
00127                 return ptr;
00128         }
00129 
00130         bool operator == (const RakNetSmartPtr<T>& sp)
00131         {
00132                 return ptr == sp.ptr;
00133         }
00134         bool operator<( const RakNetSmartPtr<T> &right ) {return ptr < right.ptr;}
00135         bool operator>( const RakNetSmartPtr<T> &right ) {return ptr > right.ptr;}
00136 
00137         bool operator != (const RakNetSmartPtr<T>& sp)
00138         {
00139                 return ptr != sp.ptr;
00140         }
00141 
00142         RakNetSmartPtr<T>& operator = (const RakNetSmartPtr<T>& sp)
00143         {
00144                 // Assignment operator
00145 
00146                 if (this != &sp) // Avoid self assignment
00147                 {
00148                         if(reference && reference->Release() == 0)
00149                         {
00150                                 RakNet::OP_DELETE(ptr, __FILE__, __LINE__);
00151                                 RakNet::OP_DELETE(reference, __FILE__, __LINE__);
00152 
00153 //                              deallocCount+=2;
00154 //                              printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00155                         }
00156 
00157                         ptr = sp.ptr;
00158                         reference = sp.reference;
00159                         if (reference)
00160                                 reference->AddRef();
00161                 }
00162                 return *this;
00163         }
00164 
00165 
00166 };
00167 
00168 #endif

Generated on Thu Sep 30 2010 01:27:26 for RakNet by  doxygen 1.7.1