Go to the documentation of this file.00001 #ifndef __RAKNET_SMART_PTR_H
00002 #define __RAKNET_SMART_PTR_H
00003
00004
00005
00006
00007 #include "RakMemoryOverride.h"
00008 #include "Export.h"
00009
00010
00011
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;
00030 ReferenceCounter* reference;
00031
00032 public:
00033 RakNetSmartPtr() : ptr(0), reference(0)
00034 {
00035
00036 }
00037
00038 RakNetSmartPtr(T* pValue) : ptr(pValue)
00039 {
00040 reference = RakNet::OP_NEW<ReferenceCounter>(__FILE__,__LINE__);
00041 reference->AddRef();
00042
00043
00044
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
00061
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
00078
00079 }
00080 ptr=0;
00081 reference=0;
00082 }
00083
00084 bool IsUnique(void) const
00085 {
00086 return reference->GetRefCount()==1;
00087 }
00088
00089
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
00145
00146 if (this != &sp)
00147 {
00148 if(reference && reference->Release() == 0)
00149 {
00150 RakNet::OP_DELETE(ptr, __FILE__, __LINE__);
00151 RakNet::OP_DELETE(reference, __FILE__, __LINE__);
00152
00153
00154
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