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 */

Generated on Wed Jan 20 23:38:34 2010 for OpenTTD by  doxygen 1.5.6