smallvec_type.hpp

Go to the documentation of this file.
00001 /* $Id: smallvec_type.hpp 21890 2011-01-22 14:52:20Z rubidium $ */
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 
00038   template <uint X>
00039   SmallVector(const SmallVector<T, X> &other) : data(NULL), items(0), capacity(0)
00040   {
00041     MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
00042   }
00043 
00044   template <uint X>
00045   SmallVector &operator=(const SmallVector<T, X> &other)
00046   {
00047     this->Reset();
00048     MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
00049     return *this;
00050   }
00051 
00052   ~SmallVector()
00053   {
00054     free(this->data);
00055   }
00056 
00060   FORCEINLINE void Clear()
00061   {
00062     /* In fact we just reset the item counter avoiding the need to
00063      * probably reallocate the same amount of memory the list was
00064      * previously using. */
00065     this->items = 0;
00066   }
00067 
00071   FORCEINLINE void Reset()
00072   {
00073     this->items = 0;
00074     this->capacity = 0;
00075     free(data);
00076     data = NULL;
00077   }
00078 
00082   FORCEINLINE void Compact()
00083   {
00084     uint capacity = Align(this->items, S);
00085     if (capacity >= this->capacity) return;
00086 
00087     this->capacity = capacity;
00088     this->data = ReallocT(this->data, this->capacity);
00089   }
00090 
00096   FORCEINLINE T *Append(uint to_add = 1)
00097   {
00098     uint begin = this->items;
00099     this->items += to_add;
00100 
00101     if (this->items > this->capacity) {
00102       this->capacity = Align(this->items, S);
00103       this->data = ReallocT(this->data, this->capacity);
00104     }
00105 
00106     return &this->data[begin];
00107   }
00108 
00115   FORCEINLINE const T *Find(const T &item) const
00116   {
00117     const T *pos = this->Begin();
00118     const T *end = this->End();
00119     while (pos != end && *pos != item) pos++;
00120     return pos;
00121   }
00122 
00129   FORCEINLINE T *Find(const T &item)
00130   {
00131     T *pos = this->Begin();
00132     const T *end = this->End();
00133     while (pos != end && *pos != item) pos++;
00134     return pos;
00135   }
00136 
00143   FORCEINLINE int FindIndex(const T &item)
00144   {
00145     int index = 0;
00146     T *pos = this->Begin();
00147     const T *end = this->End();
00148     while (pos != end && *pos != item) {
00149       pos++;
00150       index++;
00151     }
00152     return pos == end ? -1 : index;
00153   }
00154 
00161   FORCEINLINE bool Contains(const T &item) const
00162   {
00163     return this->Find(item) != this->End();
00164   }
00165 
00171   FORCEINLINE void Erase(T *item)
00172   {
00173     assert(item >= this->Begin() && item < this->End());
00174     *item = this->data[--this->items];
00175   }
00176 
00183   FORCEINLINE bool Include(const T &item)
00184   {
00185     bool is_member = this->Contains(item);
00186     if (!is_member) *this->Append() = item;
00187     return is_member;
00188   }
00189 
00193   FORCEINLINE uint Length() const
00194   {
00195     return this->items;
00196   }
00197 
00203   FORCEINLINE const T *Begin() const
00204   {
00205     return this->data;
00206   }
00207 
00213   FORCEINLINE T *Begin()
00214   {
00215     return this->data;
00216   }
00217 
00223   FORCEINLINE const T *End() const
00224   {
00225     return &this->data[this->items];
00226   }
00227 
00233   FORCEINLINE T *End()
00234   {
00235     return &this->data[this->items];
00236   }
00237 
00244   FORCEINLINE const T *Get(uint index) const
00245   {
00246     /* Allow access to the 'first invalid' item */
00247     assert(index <= this->items);
00248     return &this->data[index];
00249   }
00250 
00257   FORCEINLINE T *Get(uint index)
00258   {
00259     /* Allow access to the 'first invalid' item */
00260     assert(index <= this->items);
00261     return &this->data[index];
00262   }
00263 
00270   FORCEINLINE const T &operator[](uint index) const
00271   {
00272     assert(index < this->items);
00273     return this->data[index];
00274   }
00275 
00282   FORCEINLINE T &operator[](uint index)
00283   {
00284     assert(index < this->items);
00285     return this->data[index];
00286   }
00287 };
00288 
00289 
00300 template <typename T, uint S>
00301 class AutoFreeSmallVector : public SmallVector<T, S> {
00302 public:
00303   ~AutoFreeSmallVector()
00304   {
00305     this->Clear();
00306   }
00307 
00311   FORCEINLINE void Clear()
00312   {
00313     for (uint i = 0; i < this->items; i++) {
00314       free(this->data[i]);
00315     }
00316 
00317     this->items = 0;
00318   }
00319 };
00320 
00321 typedef AutoFreeSmallVector<char*, 4> StringList;
00322 
00323 #endif /* SMALLVEC_TYPE_HPP */

Generated on Fri Mar 18 23:17:34 2011 for OpenTTD by  doxygen 1.6.1