Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef SMALLVEC_TYPE_HPP
00013 #define SMALLVEC_TYPE_HPP
00014
00015 #include "alloc_func.hpp"
00016 #include "mem_func.hpp"
00017
00028 template <typename T, uint S>
00029 class SmallVector {
00030 protected:
00031 T *data;
00032 uint items;
00033 uint capacity;
00034
00035 public:
00036 SmallVector() : data(NULL), items(0), capacity(0) { }
00037
00042 SmallVector(const SmallVector &other) : data(NULL), items(0), capacity(0)
00043 {
00044 this->Assign(other);
00045 }
00046
00051 template <uint X>
00052 SmallVector(const SmallVector<T, X> &other) : data(NULL), items(0), capacity(0)
00053 {
00054 this->Assign(other);
00055 }
00056
00061 SmallVector &operator=(const SmallVector &other)
00062 {
00063 this->Assign(other);
00064 return *this;
00065 }
00066
00071 template <uint X>
00072 SmallVector &operator=(const SmallVector<T, X> &other)
00073 {
00074 this->Assign(other);
00075 return *this;
00076 }
00077
00078 ~SmallVector()
00079 {
00080 free(this->data);
00081 }
00082
00086 template <uint X>
00087 inline void Assign(const SmallVector<T, X> &other)
00088 {
00089 if ((const void *)&other == (void *)this) return;
00090
00091 this->Clear();
00092 if (other.Length() > 0) MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
00093 }
00094
00098 inline void Clear()
00099 {
00100
00101
00102
00103 this->items = 0;
00104 }
00105
00109 inline void Reset()
00110 {
00111 this->items = 0;
00112 this->capacity = 0;
00113 free(data);
00114 data = NULL;
00115 }
00116
00120 inline void Compact()
00121 {
00122 uint capacity = Align(this->items, S);
00123 if (capacity >= this->capacity) return;
00124
00125 this->capacity = capacity;
00126 this->data = ReallocT(this->data, this->capacity);
00127 }
00128
00134 inline T *Append(uint to_add = 1)
00135 {
00136 uint begin = this->items;
00137 this->items += to_add;
00138
00139 if (this->items > this->capacity) {
00140 this->capacity = Align(this->items, S);
00141 this->data = ReallocT(this->data, this->capacity);
00142 }
00143
00144 return &this->data[begin];
00145 }
00146
00151 inline void Resize(uint num_items)
00152 {
00153 this->items = num_items;
00154
00155 if (this->items > this->capacity) {
00156 this->capacity = Align(this->items, S);
00157 this->data = ReallocT(this->data, this->capacity);
00158 }
00159 }
00160
00167 inline const T *Find(const T &item) const
00168 {
00169 const T *pos = this->Begin();
00170 const T *end = this->End();
00171 while (pos != end && *pos != item) pos++;
00172 return pos;
00173 }
00174
00181 inline T *Find(const T &item)
00182 {
00183 T *pos = this->Begin();
00184 const T *end = this->End();
00185 while (pos != end && *pos != item) pos++;
00186 return pos;
00187 }
00188
00195 inline int FindIndex(const T &item) const
00196 {
00197 int index = 0;
00198 const T *pos = this->Begin();
00199 const T *end = this->End();
00200 while (pos != end && *pos != item) {
00201 pos++;
00202 index++;
00203 }
00204 return pos == end ? -1 : index;
00205 }
00206
00213 inline bool Contains(const T &item) const
00214 {
00215 return this->Find(item) != this->End();
00216 }
00217
00223 inline void Erase(T *item)
00224 {
00225 assert(item >= this->Begin() && item < this->End());
00226 *item = this->data[--this->items];
00227 }
00228
00234 void ErasePreservingOrder(uint pos, uint count = 1)
00235 {
00236 if (count == 0) return;
00237 assert(pos < this->items);
00238 assert(pos + count <= this->items);
00239 this->items -= count;
00240 uint to_move = this->items - pos;
00241 if (to_move > 0) MemMoveT(this->data + pos, this->data + pos + count, to_move);
00242 }
00243
00250 inline bool Include(const T &item)
00251 {
00252 bool is_member = this->Contains(item);
00253 if (!is_member) *this->Append() = item;
00254 return is_member;
00255 }
00256
00260 inline uint Length() const
00261 {
00262 return this->items;
00263 }
00264
00270 inline const T *Begin() const
00271 {
00272 return this->data;
00273 }
00274
00280 inline T *Begin()
00281 {
00282 return this->data;
00283 }
00284
00290 inline const T *End() const
00291 {
00292 return &this->data[this->items];
00293 }
00294
00300 inline T *End()
00301 {
00302 return &this->data[this->items];
00303 }
00304
00311 inline const T *Get(uint index) const
00312 {
00313
00314 assert(index <= this->items);
00315 return &this->data[index];
00316 }
00317
00324 inline T *Get(uint index)
00325 {
00326
00327 assert(index <= this->items);
00328 return &this->data[index];
00329 }
00330
00337 inline const T &operator[](uint index) const
00338 {
00339 assert(index < this->items);
00340 return this->data[index];
00341 }
00342
00349 inline T &operator[](uint index)
00350 {
00351 assert(index < this->items);
00352 return this->data[index];
00353 }
00354 };
00355
00356
00367 template <typename T, uint S>
00368 class AutoFreeSmallVector : public SmallVector<T, S> {
00369 public:
00370 ~AutoFreeSmallVector()
00371 {
00372 this->Clear();
00373 }
00374
00378 inline void Clear()
00379 {
00380 for (uint i = 0; i < this->items; i++) {
00381 free(this->data[i]);
00382 }
00383
00384 this->items = 0;
00385 }
00386 };
00387
00398 template <typename T, uint S>
00399 class AutoDeleteSmallVector : public SmallVector<T, S> {
00400 public:
00401 ~AutoDeleteSmallVector()
00402 {
00403 this->Clear();
00404 }
00405
00409 inline void Clear()
00410 {
00411 for (uint i = 0; i < this->items; i++) {
00412 delete this->data[i];
00413 }
00414
00415 this->items = 0;
00416 }
00417 };
00418
00419 typedef AutoFreeSmallVector<char*, 4> StringList;
00420
00421 #endif