00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _IAIAUTOBUFFER_H_
00022 #define _IAIAUTOBUFFER_H_
00023
00024
00025 #include <string>
00026
00029 namespace ai {
00030
00033 class SPAlloc {
00034 public:
00039 static void* AllocateBlock(size_t byteCount);
00043 static void DeleteBlock(void* block);
00044 };
00045
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template<class elem, typename size_type=size_t, class A=SPAlloc> class AutoBuffer {
00063 public:
00067 explicit AutoBuffer (size_type count = 0)
00068 : fCapacity(count),
00069 fBuffer(0)
00070 {
00071 if ( fCapacity > 0 )
00072 {
00073 fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(fCapacity)));
00074 Init();
00075 }
00076 }
00080 AutoBuffer (const AutoBuffer& b)
00081 : fCapacity(b.fCapacity),
00082 fBuffer(0)
00083 {
00084 if ( fCapacity > 0 )
00085 {
00086 fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(fCapacity)));
00087 Copy(b.fBuffer);
00088 }
00089 }
00092 ~AutoBuffer ()
00093 {
00094 if ( fBuffer )
00095 {
00096 Destroy(fBuffer);
00097 A::DeleteBlock(fBuffer);
00098 }
00099 }
00100
00104 bool IsValid () const
00105 {
00106 return fBuffer != 0;
00107 }
00108
00113 elem* GetBuffer () const
00114 {
00115 return fBuffer;
00116 }
00117 operator elem* () const
00118 {
00119 return GetBuffer();
00120 }
00121
00128 elem& operator[] (size_type n)
00129 {
00130 return fBuffer[n];
00131 }
00135 size_type GetCount () const
00136 {
00137 return fCapacity;
00138 }
00145 void Resize (size_type newSize)
00146 {
00147 if ( newSize != fCapacity )
00148 {
00149 elem *newBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(newSize)));
00150 if ( fBuffer )
00151 {
00152 elem* oldBuffer = fBuffer;
00153 fBuffer = newBuffer;
00154 Copy(oldBuffer, 0, fCapacity < newSize ? fCapacity : newSize );
00155
00156
00157 Init(fCapacity, newSize);
00158
00159 Destroy(oldBuffer, 0, fCapacity);
00160 A::DeleteBlock(oldBuffer);
00161 }
00162 else
00163 {
00164 fBuffer = newBuffer;
00165 Init();
00166 }
00167 fCapacity = newSize;
00168 }
00169 }
00170
00171 AutoBuffer& operator= (const AutoBuffer& rhs)
00172 {
00173 if ( this != &rhs )
00174 {
00175 if ( fCapacity != rhs.fCapacity )
00176 {
00177 Destroy(fBuffer);
00178 A::DeleteBlock(fBuffer);
00179 fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(rhs.fCapacity)));
00180 fCapacity = rhs.fCapacity;
00181 }
00182 Copy(rhs.fBuffer);
00183 }
00184 return *this;
00185 }
00186
00187 static size_type lastIndex ()
00188 { return size_type(-1); }
00189 private:
00190 void Init (size_type start = 0, size_type end = lastIndex())
00191 {
00192 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00193 for (size_type i = start; i < elemCount; ++i)
00194 {
00195
00196 new (&fBuffer[i])elem;
00197 }
00198 }
00199 void Destroy (elem* e, size_type start = 0, size_type end = lastIndex())
00200 {
00201 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00202 for (size_type i = start; i < elemCount; ++i)
00203 {
00204 e[i].~elem();
00205 }
00206 }
00207 void Copy (const elem* e, size_type start = 0, size_type end = lastIndex())
00208 {
00209 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00210 for (size_type i = start; i < elemCount; ++i)
00211 {
00212 fBuffer[i] = e[i];
00213 }
00214 }
00215 size_type ByteCount (size_type elemCount)
00216 {
00217 return elemCount * sizeof(elem);
00218 }
00219 private:
00220 size_type fCapacity;
00221 elem* fBuffer;
00222 };
00223
00224 }
00225
00226 #endif // _IAIAUTOBUFFER_H_