# smallvec_type.hpp

Go to the documentation of this file.

    00001 /* $Id: smallvec_type.hpp 17541 2009-09-14 20:59:46Z 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 "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   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
    00080   FORCEINLINE T *Append()
    00081   {
    00082     if (this->items == this->capacity) {
    00083       this->capacity += S;
    00084       this->data = ReallocT(this->data, this->capacity);
    00085     }
    00086
    00087     return &this->data[this->items++];
    00088   }
    00089
    00096   FORCEINLINE const T *Find(const T &item) const
    00097   {
    00098     const T *pos = this->Begin();
    00099     const T *end = this->End();
    00100     while (pos != end && *pos != item) pos++;
    00101     return pos;
    00102   }
    00103
    00110   FORCEINLINE T *Find(const T &item)
    00111   {
    00112     T *pos = this->Begin();
    00113     const T *end = this->End();
    00114     while (pos != end && *pos != item) pos++;
    00115     return pos;
    00116   }
    00117
    00124   FORCEINLINE int FindIndex(const T &item)
    00125   {
    00126     int index = 0;
    00127     T *pos = this->Begin();
    00128     const T *end = this->End();
    00129     while (pos != end && *pos != item) {
    00130       pos++;
    00131       index++;
    00132     }
    00133     return pos == end ? -1 : index;
    00134   }
    00135
    00142   FORCEINLINE bool Contains(const T &item) const
    00143   {
    00144     return this->Find(item) != this->End();
    00145   }
    00146
    00151   FORCEINLINE void Erase(T *item)
    00152   {
    00153     assert(item >= this->Begin() && item < this->End());
    00154     *item = this->data[--this->items];
    00155   }
    00156
    00163   FORCEINLINE bool Include(const T &item)
    00164   {
    00165     bool is_member = this->Contains(item);
    00166     if (!is_member) *this->Append() = item;
    00167     return is_member;
    00168   }
    00169
    00173   FORCEINLINE uint Length() const
    00174   {
    00175     return this->items;
    00176   }
    00177
    00183   FORCEINLINE const T *Begin() const
    00184   {
    00185     return this->data;
    00186   }
    00187
    00193   FORCEINLINE T *Begin()
    00194   {
    00195     return this->data;
    00196   }
    00197
    00203   FORCEINLINE const T *End() const
    00204   {
    00205     return &this->data[this->items];
    00206   }
    00207
    00213   FORCEINLINE T *End()
    00214   {
    00215     return &this->data[this->items];
    00216   }
    00217
    00224   FORCEINLINE const T *Get(uint index) const
    00225   {
    00226     return &this->data[index];
    00227   }
    00228
    00235   FORCEINLINE T *Get(uint index)
    00236   {
    00237     return &this->data[index];
    00238   }
    00239
    00246   FORCEINLINE const T &operator[](uint index) const
    00247   {
    00248     return this->data[index];
    00249   }
    00250
    00257   FORCEINLINE T &operator[](uint index)
    00258   {
    00259     return this->data[index];
    00260   }
    00261 };
    00262
    00263
    00274 template <typename T, uint S>
    00275 class AutoFreeSmallVector : public SmallVector<T, S> {
    00276 public:
    00277   ~AutoFreeSmallVector()
    00278   {
    00279     this->Clear();
    00280   }
    00281
    00285   FORCEINLINE void Clear()
    00286   {
    00287     for (uint i = 0; i < this->items; i++) {
    00288       free(this->data[i]);
    00289     }
    00290
    00291     this->items = 0;
    00292   }
    00293 };
    00294
    00295 typedef AutoFreeSmallVector<char*, 4> StringList;
    00296
    00297 #endif /* SMALLVEC_TYPE_HPP */