Shadowrun: Awakened 29 September 2011 - Build 871
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 namespace RakNet
00014 {
00015 
00016 class RAK_DLL_EXPORT ReferenceCounter
00017 {
00018 private:
00019     int refCount;
00020 
00021 public:
00022     ReferenceCounter() {refCount=0;}
00023     ~ReferenceCounter() {}
00024     void AddRef() {refCount++;}
00025     int Release() {return --refCount;}
00026     int GetRefCount(void) const {return refCount;}
00027 };
00028 
00029 template < typename T > class RAK_DLL_EXPORT RakNetSmartPtr
00030 {
00031 private:
00032     T*    ptr;       // pointer
00033     ReferenceCounter* reference; // Reference refCount
00034 
00035 public:
00036     RakNetSmartPtr() : ptr(0), reference(0)
00037     {
00038         // Do not allocate by default, wasteful if we just have a list of preallocated and unassigend smart pointers
00039     }
00040 
00041     RakNetSmartPtr(T* pValue) : ptr(pValue)
00042     {
00043         reference = RakNet::OP_NEW<ReferenceCounter>(_FILE_AND_LINE_);
00044         reference->AddRef();
00045 
00046 //      allocCount+=2;
00047 //      printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00048     }
00049 
00050     RakNetSmartPtr(const RakNetSmartPtr<T>& sp) : ptr(sp.ptr), reference(sp.reference)
00051     {
00052         if (reference)
00053             reference->AddRef();
00054     }
00055 
00056     ~RakNetSmartPtr()
00057     {
00058         if(reference && reference->Release() == 0)
00059         {
00060             RakNet::OP_DELETE(ptr, _FILE_AND_LINE_);
00061             RakNet::OP_DELETE(reference, _FILE_AND_LINE_);
00062 
00063 //          deallocCount+=2;
00064 //          printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00065         }
00066     }
00067 
00068     bool IsNull(void) const
00069     {
00070         return ptr==0;
00071     }
00072 
00073     void SetNull(void)
00074     {
00075         if(reference && reference->Release() == 0)
00076         {
00077             RakNet::OP_DELETE(ptr, _FILE_AND_LINE_);
00078             RakNet::OP_DELETE(reference, _FILE_AND_LINE_);
00079 
00080 //          deallocCount+=2;
00081 //          printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00082         }
00083         ptr=0;
00084         reference=0;
00085     }
00086 
00087     bool IsUnique(void) const
00088     {
00089         return reference->GetRefCount()==1;
00090     }
00091 
00092     // 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
00093     void Clone(bool copyContents)
00094     {
00095         if (IsUnique()==false)
00096         {
00097             reference->Release();
00098 
00099             reference = RakNet::OP_NEW<ReferenceCounter>(_FILE_AND_LINE_);
00100             reference->AddRef();
00101             T* oldPtr=ptr;
00102             ptr=RakNet::OP_NEW<T>(_FILE_AND_LINE_);
00103             if (copyContents)
00104                 *ptr=*oldPtr;
00105         }
00106     }
00107 
00108     int GetRefCount(void) const
00109     {
00110         return reference->GetRefCount();
00111     }
00112 
00113     T& operator* ()
00114     {
00115         return *ptr;
00116     }
00117 
00118     const T& operator* () const
00119     {
00120         return *ptr;
00121     }
00122 
00123     T* operator-> ()
00124     {
00125         return ptr;
00126     }
00127 
00128     const T* operator-> () const
00129     {
00130         return ptr;
00131     }
00132 
00133     bool operator == (const RakNetSmartPtr<T>& sp)
00134     {
00135         return ptr == sp.ptr;
00136     }
00137     bool operator<( const RakNetSmartPtr<T> &right ) {return ptr < right.ptr;}
00138     bool operator>( const RakNetSmartPtr<T> &right ) {return ptr > right.ptr;}
00139 
00140     bool operator != (const RakNetSmartPtr<T>& sp)
00141     {
00142         return ptr != sp.ptr;
00143     }
00144 
00145     RakNetSmartPtr<T>& operator = (const RakNetSmartPtr<T>& sp)
00146     {
00147         // Assignment operator
00148 
00149         if (this != &sp) // Avoid self assignment
00150         {
00151             if(reference && reference->Release() == 0)
00152             {
00153                 RakNet::OP_DELETE(ptr, _FILE_AND_LINE_);
00154                 RakNet::OP_DELETE(reference, _FILE_AND_LINE_);
00155 
00156 //              deallocCount+=2;
00157 //              printf("allocCount=%i deallocCount=%i Line=%i\n",allocCount, deallocCount, __LINE__);
00158             }
00159 
00160             ptr = sp.ptr;
00161             reference = sp.reference;
00162             if (reference)
00163                 reference->AddRef();
00164         }
00165         return *this;
00166     }
00167 
00168 
00169 };
00170 
00171 } // namespace RakNet
00172 
00173 #endif

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net