# smallvec_type.hpp

Go to the documentation of this file.

    00001 /* $Id: smallvec_type.hpp 24448 2012-07-29 20:02:25Z frosch $ */
    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   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     /* In fact we just reset the item counter avoiding the need to
    00101      * probably reallocate the same amount of memory the list was
    00102      * previously using. */
    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
    00153   inline const T *Find(const T &item) const
    00154   {
    00155     const T *pos = this->Begin();
    00156     const T *end = this->End();
    00157     while (pos != end && *pos != item) pos++;
    00158     return pos;
    00159   }
    00160
    00167   inline T *Find(const T &item)
    00168   {
    00169     T *pos = this->Begin();
    00170     const T *end = this->End();
    00171     while (pos != end && *pos != item) pos++;
    00172     return pos;
    00173   }
    00174
    00181   inline int FindIndex(const T &item) const
    00182   {
    00183     int index = 0;
    00184     const T *pos = this->Begin();
    00185     const T *end = this->End();
    00186     while (pos != end && *pos != item) {
    00187       pos++;
    00188       index++;
    00189     }
    00190     return pos == end ? -1 : index;
    00191   }
    00192
    00199   inline bool Contains(const T &item) const
    00200   {
    00201     return this->Find(item) != this->End();
    00202   }
    00203
    00209   inline void Erase(T *item)
    00210   {
    00211     assert(item >= this->Begin() && item < this->End());
    00212     *item = this->data[--this->items];
    00213   }
    00214
    00221   inline bool Include(const T &item)
    00222   {
    00223     bool is_member = this->Contains(item);
    00224     if (!is_member) *this->Append() = item;
    00225     return is_member;
    00226   }
    00227
    00231   inline uint Length() const
    00232   {
    00233     return this->items;
    00234   }
    00235
    00241   inline const T *Begin() const
    00242   {
    00243     return this->data;
    00244   }
    00245
    00251   inline T *Begin()
    00252   {
    00253     return this->data;
    00254   }
    00255
    00261   inline const T *End() const
    00262   {
    00263     return &this->data[this->items];
    00264   }
    00265
    00271   inline T *End()
    00272   {
    00273     return &this->data[this->items];
    00274   }
    00275
    00282   inline const T *Get(uint index) const
    00283   {
    00284     /* Allow access to the 'first invalid' item */
    00285     assert(index <= this->items);
    00286     return &this->data[index];
    00287   }
    00288
    00295   inline T *Get(uint index)
    00296   {
    00297     /* Allow access to the 'first invalid' item */
    00298     assert(index <= this->items);
    00299     return &this->data[index];
    00300   }
    00301
    00308   inline const T &operator[](uint index) const
    00309   {
    00310     assert(index < this->items);
    00311     return this->data[index];
    00312   }
    00313
    00320   inline T &operator[](uint index)
    00321   {
    00322     assert(index < this->items);
    00323     return this->data[index];
    00324   }
    00325 };
    00326
    00327
    00338 template <typename T, uint S>
    00339 class AutoFreeSmallVector : public SmallVector<T, S> {
    00340 public:
    00341   ~AutoFreeSmallVector()
    00342   {
    00343     this->Clear();
    00344   }
    00345
    00349   inline void Clear()
    00350   {
    00351     for (uint i = 0; i < this->items; i++) {
    00352       free(this->data[i]);
    00353     }
    00354
    00355     this->items = 0;
    00356   }
    00357 };
    00358
    00369 template <typename T, uint S>
    00370 class AutoDeleteSmallVector : public SmallVector<T, S> {
    00371 public:
    00372   ~AutoDeleteSmallVector()
    00373   {
    00374     this->Clear();
    00375   }
    00376
    00380   inline void Clear()
    00381   {
    00382     for (uint i = 0; i < this->items; i++) {
    00383       delete this->data[i];
    00384     }
    00385
    00386     this->items = 0;
    00387   }
    00388 };
    00389
    00390 typedef AutoFreeSmallVector<char*, 4> StringList;
    00391
    00392 #endif /* SMALLVEC_TYPE_HPP */