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   FORCEINLINE 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   FORCEINLINE void Reset()
00080   {
00081     this->items = 0;
00082     this->capacity = 0;
00083     free(data);
00084     data = NULL;
00085   }
00086 
00090   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE bool Contains(const T &item) const
00170   {
00171     return this->Find(item) != this->End();
00172   }
00173 
00179   FORCEINLINE void Erase(T *item)
00180   {
00181     assert(item >= this->Begin() && item < this->End());
00182     *item = this->data[--this->items];
00183   }
00184 
00191   FORCEINLINE 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   FORCEINLINE uint Length() const
00202   {
00203     return this->items;
00204   }
00205 
00211   FORCEINLINE const T *Begin() const
00212   {
00213     return this->data;
00214   }
00215 
00221   FORCEINLINE T *Begin()
00222   {
00223     return this->data;
00224   }
00225 
00231   FORCEINLINE const T *End() const
00232   {
00233     return &this->data[this->items];
00234   }
00235 
00241   FORCEINLINE T *End()
00242   {
00243     return &this->data[this->items];
00244   }
00245 
00252   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE const T &operator[](uint index) const
00279   {
00280     assert(index < this->items);
00281     return this->data[index];
00282   }
00283 
00290   FORCEINLINE 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   FORCEINLINE 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 
00329 typedef AutoFreeSmallVector<char*, 4> StringList; 
00330 
00331 #endif /* SMALLVEC_TYPE_HPP */

Generated on Fri May 27 04:19:41 2011 for OpenTTD by  doxygen 1.6.1