# smallvec_type.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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   template <uint X>
    00043   SmallVector(const SmallVector<T, X> &other) : data(NULL), items(0), capacity(0)
    00044   {
    00045     MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
    00046   }
    00047
    00052   template <uint X>
    00053   SmallVector &operator=(const SmallVector<T, X> &other)
    00054   {
    00055     this->Reset();
    00056     MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
    00057     return *this;
    00058   }
    00059
    00060   ~SmallVector()
    00061   {
    00062     free(this->data);
    00063   }
    00064
    00068   inline void Clear()
    00069   {
    00070     /* In fact we just reset the item counter avoiding the need to
    00071      * probably reallocate the same amount of memory the list was
    00072      * previously using. */
    00073     this->items = 0;
    00074   }
    00075
    00079   inline void Reset()
    00080   {
    00081     this->items = 0;
    00082     this->capacity = 0;
    00083     free(data);
    00084     data = NULL;
    00085   }
    00086
    00090   inline void Compact()
    00091   {
    00092     uint capacity = Align(this->items, S);
    00093     if (capacity >= this->capacity) return;
    00094
    00095     this->capacity = capacity;
    00096     this->data = ReallocT(this->data, this->capacity);
    00097   }
    00098
    00104   inline T *Append(uint to_add = 1)
    00105   {
    00106     uint begin = this->items;
    00107     this->items += to_add;
    00108
    00109     if (this->items > this->capacity) {
    00110       this->capacity = Align(this->items, S);
    00111       this->data = ReallocT(this->data, this->capacity);
    00112     }
    00113
    00114     return &this->data[begin];
    00115   }
    00116
    00123   inline const T *Find(const T &item) const
    00124   {
    00125     const T *pos = this->Begin();
    00126     const T *end = this->End();
    00127     while (pos != end && *pos != item) pos++;
    00128     return pos;
    00129   }
    00130
    00137   inline T *Find(const T &item)
    00138   {
    00139     T *pos = this->Begin();
    00140     const T *end = this->End();
    00141     while (pos != end && *pos != item) pos++;
    00142     return pos;
    00143   }
    00144
    00151   inline int FindIndex(const T &item)
    00152   {
    00153     int index = 0;
    00154     T *pos = this->Begin();
    00155     const T *end = this->End();
    00156     while (pos != end && *pos != item) {
    00157       pos++;
    00158       index++;
    00159     }
    00160     return pos == end ? -1 : index;
    00161   }
    00162
    00169   inline bool Contains(const T &item) const
    00170   {
    00171     return this->Find(item) != this->End();
    00172   }
    00173
    00179   inline void Erase(T *item)
    00180   {
    00181     assert(item >= this->Begin() && item < this->End());
    00182     *item = this->data[--this->items];
    00183   }
    00184
    00191   inline bool Include(const T &item)
    00192   {
    00193     bool is_member = this->Contains(item);
    00194     if (!is_member) *this->Append() = item;
    00195     return is_member;
    00196   }
    00197
    00201   inline uint Length() const
    00202   {
    00203     return this->items;
    00204   }
    00205
    00211   inline const T *Begin() const
    00212   {
    00213     return this->data;
    00214   }
    00215
    00221   inline T *Begin()
    00222   {
    00223     return this->data;
    00224   }
    00225
    00231   inline const T *End() const
    00232   {
    00233     return &this->data[this->items];
    00234   }
    00235
    00241   inline T *End()
    00242   {
    00243     return &this->data[this->items];
    00244   }
    00245
    00252   inline const T *Get(uint index) const
    00253   {
    00254     /* Allow access to the 'first invalid' item */
    00255     assert(index <= this->items);
    00256     return &this->data[index];
    00257   }
    00258
    00265   inline T *Get(uint index)
    00266   {
    00267     /* Allow access to the 'first invalid' item */
    00268     assert(index <= this->items);
    00269     return &this->data[index];
    00270   }
    00271
    00278   inline const T &operator[](uint index) const
    00279   {
    00280     assert(index < this->items);
    00281     return this->data[index];
    00282   }
    00283
    00290   inline T &operator[](uint index)
    00291   {
    00292     assert(index < this->items);
    00293     return this->data[index];
    00294   }
    00295 };
    00296
    00297
    00308 template <typename T, uint S>
    00309 class AutoFreeSmallVector : public SmallVector<T, S> {
    00310 public:
    00311   ~AutoFreeSmallVector()
    00312   {
    00313     this->Clear();
    00314   }
    00315
    00319   inline void Clear()
    00320   {
    00321     for (uint i = 0; i < this->items; i++) {
    00322       free(this->data[i]);
    00323     }
    00324
    00325     this->items = 0;
    00326   }
    00327 };
    00328
    00339 template <typename T, uint S>
    00340 class AutoDeleteSmallVector : public SmallVector<T, S> {
    00341 public:
    00342   ~AutoDeleteSmallVector()
    00343   {
    00344     this->Clear();
    00345   }
    00346
    00350   inline void Clear()
    00351   {
    00352     for (uint i = 0; i < this->items; i++) {
    00353       delete this->data[i];
    00354     }
    00355
    00356     this->items = 0;
    00357   }
    00358 };
    00359
    00360 typedef AutoFreeSmallVector<char*, 4> StringList;
    00361
    00362 #endif /* SMALLVEC_TYPE_HPP */