![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
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.