smallvec_type.hpp

Go to the documentation of this file.
00001 /* $Id: smallvec_type.hpp 20731 2010-09-03 23:04:02Z yexo $ */
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 #include "math_func.hpp"
00018 
00029 template <typename T, uint S>
00030 class SmallVector {
00031 protected:
00032   T *data;       
00033   uint items;    
00034   uint capacity; 
00035 
00036 public:
00037   SmallVector() : data(NULL), items(0), capacity(0) { }
00038 
00039   template <uint X>
00040   SmallVector(const SmallVector<T, X> &other) : data(NULL), items(0), capacity(0)
00041   {
00042     MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
00043   }
00044 
00045   template <uint X>
00046   SmallVector &operator=(const SmallVector<T, X> &other)
00047   {
00048     this->Reset();
00049     MemCpyT<T>(this->Append(other.Length()), other.Begin(), other.Length());
00050     return *this;
00051   }
00052 
00053   ~SmallVector()
00054   {
00055     free(this->data);
00056   }
00057 
00061   FORCEINLINE void Clear()
00062   {
00063     /* In fact we just reset the item counter avoiding the need to
00064      * probably reallocate the same amount of memory the list was
00065      * previously using. */
00066     this->items = 0;
00067   }
00068 
00072   FORCEINLINE void Reset()
00073   {
00074     this->items = 0;
00075     this->capacity = 0;
00076     free(data);
00077     data = NULL;
00078   }
00079 
00083   FORCEINLINE void Compact()
00084   {
00085     uint capacity = Align(this->items, S);
00086     if (capacity >= this->capacity) return;
00087 
00088     this->capacity = capacity;
00089     this->data = ReallocT(this->data, this->capacity);
00090   }
00091 
00097   FORCEINLINE T *Append(uint to_add = 1)
00098   {
00099     uint begin = this->items;
00100     this->items += to_add;
00101 
00102     if (this->items > this->capacity) {
00103       this->capacity = Align(this->items, S);
00104       this->data = ReallocT(this->data, this->capacity);
00105     }
00106 
00107     return &this->data[begin];
00108   }
00109 
00116   FORCEINLINE const T *Find(const T &item) const
00117   {
00118     const T *pos = this->Begin();
00119     const T *end = this->End();
00120     while (pos != end && *pos != item) pos++;
00121     return pos;
00122   }
00123 
00130   FORCEINLINE T *Find(const T &item)
00131   {
00132     T *pos = this->Begin();
00133     const T *end = this->End();
00134     while (pos != end && *pos != item) pos++;
00135     return pos;
00136   }
00137 
00144   FORCEINLINE int FindIndex(const T &item)
00145   {
00146     int index = 0;
00147     T *pos = this->Begin();
00148     const T *end = this->End();
00149     while (pos != end && *pos != item) {
00150       pos++;
00151       index++;
00152     }
00153     return pos == end ? -1 : index;
00154   }
00155 
00162   FORCEINLINE bool Contains(const T &item) const
00163   {
00164     return this->Find(item) != this->End();
00165   }
00166 
00172   FORCEINLINE void Erase(T *item)
00173   {
00174     assert(item >= this->Begin() && item < this->End());
00175     *item = this->data[--this->items];
00176   }
00177 
00184   FORCEINLINE bool Include(const T &item)
00185   {
00186     bool is_member = this->Contains(item);
00187     if (!is_member) *this->Append() = item;
00188     return is_member;
00189   }
00190 
00194   FORCEINLINE uint Length() const
00195   {
00196     return this->items;
00197   }
00198 
00204   FORCEINLINE const T *Begin() const
00205   {
00206     return this->data;
00207   }
00208 
00214   FORCEINLINE T *Begin()
00215   {
00216     return this->data;
00217   }
00218 
00224   FORCEINLINE const T *End() const
00225   {
00226     return &this->data[this->items];
00227   }
00228 
00234   FORCEINLINE T *End()
00235   {
00236     return &this->data[this->items];
00237   }
00238 
00245   FORCEINLINE const T *Get(uint index) const
00246   {
00247     /* Allow access to the 'first invalid' item */
00248     assert(index <= this->items);
00249     return &this->data[index];
00250   }
00251 
00258   FORCEINLINE T *Get(uint index)
00259   {
00260     /* Allow access to the 'first invalid' item */
00261     assert(index <= this->items);
00262     return &this->data[index];
00263   }
00264 
00271   FORCEINLINE const T &operator[](uint index) const
00272   {
00273     assert(index < this->items);
00274     return this->data[index];
00275   }
00276 
00283   FORCEINLINE T &operator[](uint index)
00284   {
00285     assert(index < this->items);
00286     return this->data[index];
00287   }
00288 };
00289 
00290 
00301 template <typename T, uint S>
00302 class AutoFreeSmallVector : public SmallVector<T, S> {
00303 public:
00304   ~AutoFreeSmallVector()
00305   {
00306     this->Clear();
00307   }
00308 
00312   FORCEINLINE void Clear()
00313   {
00314     for (uint i = 0; i < this->items; i++) {
00315       free(this->data[i]);
00316     }
00317 
00318     this->items = 0;
00319   }
00320 };
00321 
00322 typedef AutoFreeSmallVector<char*, 4> StringList;
00323 
00324 #endif /* SMALLVEC_TYPE_HPP */

Generated on Fri Dec 31 17:15:30 2010 for OpenTTD by  doxygen 1.6.1