# smallvec_type.hpp

Go to the documentation of this file.

    00001 /* $Id: smallvec_type.hpp 18640 2009-12-26 13:49:14Z smatz $ */
    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 "math_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
    00038   ~SmallVector()
    00039   {
    00040     free(this->data);
    00041   }
    00042
    00046   FORCEINLINE void Clear()
    00047   {
    00048     /* In fact we just reset the item counter avoiding the need to
    00049      * probably reallocate the same amount of memory the list was
    00050      * previously using. */
    00051     this->items = 0;
    00052   }
    00053
    00057   FORCEINLINE void Reset()
    00058   {
    00059     this->items = 0;
    00060     this->capacity = 0;
    00061     free(data);
    00062     data = NULL;
    00063   }
    00064
    00068   FORCEINLINE void Compact()
    00069   {
    00070     uint capacity = Align(this->items, S);
    00071     if (capacity >= this->capacity) return;
    00072
    00073     this->capacity = capacity;
    00074     this->data = ReallocT(this->data, this->capacity);
    00075   }
    00076
    00081   FORCEINLINE T *Append()
    00082   {
    00083     if (this->items == this->capacity) {
    00084       this->capacity += S;
    00085       this->data = ReallocT(this->data, this->capacity);
    00086     }
    00087
    00088     return &this->data[this->items++];
    00089   }
    00090
    00097   FORCEINLINE const T *Find(const T &item) const
    00098   {
    00099     const T *pos = this->Begin();
    00100     const T *end = this->End();
    00101     while (pos != end && *pos != item) pos++;
    00102     return pos;
    00103   }
    00104
    00111   FORCEINLINE T *Find(const T &item)
    00112   {
    00113     T *pos = this->Begin();
    00114     const T *end = this->End();
    00115     while (pos != end && *pos != item) pos++;
    00116     return pos;
    00117   }
    00118
    00125   FORCEINLINE int FindIndex(const T &item)
    00126   {
    00127     int index = 0;
    00128     T *pos = this->Begin();
    00129     const T *end = this->End();
    00130     while (pos != end && *pos != item) {
    00131       pos++;
    00132       index++;
    00133     }
    00134     return pos == end ? -1 : index;
    00135   }
    00136
    00143   FORCEINLINE bool Contains(const T &item) const
    00144   {
    00145     return this->Find(item) != this->End();
    00146   }
    00147
    00153   FORCEINLINE void Erase(T *item)
    00154   {
    00155     assert(item >= this->Begin() && item < this->End());
    00156     *item = this->data[--this->items];
    00157   }
    00158
    00165   FORCEINLINE bool Include(const T &item)
    00166   {
    00167     bool is_member = this->Contains(item);
    00168     if (!is_member) *this->Append() = item;
    00169     return is_member;
    00170   }
    00171
    00175   FORCEINLINE uint Length() const
    00176   {
    00177     return this->items;
    00178   }
    00179
    00185   FORCEINLINE const T *Begin() const
    00186   {
    00187     return this->data;
    00188   }
    00189
    00195   FORCEINLINE T *Begin()
    00196   {
    00197     return this->data;
    00198   }
    00199
    00205   FORCEINLINE const T *End() const
    00206   {
    00207     return &this->data[this->items];
    00208   }
    00209
    00215   FORCEINLINE T *End()
    00216   {
    00217     return &this->data[this->items];
    00218   }
    00219
    00226   FORCEINLINE const T *Get(uint index) const
    00227   {
    00228     /* Allow access to the 'first invalid' item */
    00229     assert(index <= this->items);
    00230     return &this->data[index];
    00231   }
    00232
    00239   FORCEINLINE T *Get(uint index)
    00240   {
    00241     /* Allow access to the 'first invalid' item */
    00242     assert(index <= this->items);
    00243     return &this->data[index];
    00244   }
    00245
    00252   FORCEINLINE const T &operator[](uint index) const
    00253   {
    00254     assert(index < this->items);
    00255     return this->data[index];
    00256   }
    00257
    00264   FORCEINLINE T &operator[](uint index)
    00265   {
    00266     assert(index < this->items);
    00267     return this->data[index];
    00268   }
    00269 };
    00270
    00271
    00282 template <typename T, uint S>
    00283 class AutoFreeSmallVector : public SmallVector<T, S> {
    00284 public:
    00285   ~AutoFreeSmallVector()
    00286   {
    00287     this->Clear();
    00288   }
    00289
    00293   FORCEINLINE void Clear()
    00294   {
    00295     for (uint i = 0; i < this->items; i++) {
    00296       free(this->data[i]);
    00297     }
    00298
    00299     this->items = 0;
    00300   }
    00301 };
    00302
    00303 typedef AutoFreeSmallVector<char*, 4> StringList;
    00304
    00305 #endif /* SMALLVEC_TYPE_HPP */