Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_CSUTIL_COWWRAPPER_H__
00020 #define __CS_CSUTIL_COWWRAPPER_H__
00021
00022 #include "csutil/custom_new_disable.h"
00023
00024 #include "csutil/allocator.h"
00025
00030 namespace CS
00031 {
00032
00061 template<typename T, class MemoryAllocator = Memory::AllocatorMalloc>
00062 class CowWrapper
00063 {
00065 struct WrappedData
00066 {
00067 int refcount;
00068
00069 void IncRef () { refcount++; }
00070 void DecRef ()
00071 {
00072 refcount--;
00073 if (refcount == 0)
00074 {
00075 this->~WrappedData();
00076 MemoryAllocator::Free (this);
00077 }
00078 }
00079 int GetRefCount () const { return refcount; }
00080
00081 T data;
00082 public:
00083 WrappedData (const T& other) : refcount (1), data (other) {}
00084 WrappedData (const WrappedData& other) : refcount (1), data (other.data) {}
00085 };
00086 public:
00092 static const size_t allocSize = sizeof (WrappedData);
00093 private:
00094 csRef<WrappedData> data;
00095 inline WrappedData* NewData (const T& other)
00096 {
00097 WrappedData* p = (WrappedData*)MemoryAllocator::Alloc (allocSize);
00098 new (p) WrappedData (other);
00099 return p;
00100 }
00101 public:
00103 CowWrapper (const CowWrapper& other) : data (other.data) {}
00105 CowWrapper (const T& other)
00106 {
00107 data.AttachNew (NewData (other));
00108 }
00109
00111 const T& operator* () const
00112 {
00113 return data->data;
00114 }
00120 T& operator* ()
00121 {
00122 if (data->GetRefCount() > 1)
00123 {
00124 WrappedData* newData = NewData (data->data);
00125 data.AttachNew (newData);
00126 }
00127 return data->data;
00128 }
00130 const T* operator -> () const
00131 { return &(operator*()); }
00137 T* operator -> ()
00138 { return &(operator*()); }
00139 };
00140
00141 }
00142
00143 #include "csutil/custom_new_enable.h"
00144
00145 #endif // __CS_CSUTIL_COWWRAPPER_H__