smallvec_type.hpp

Go to the documentation of this file.
00001 /* $Id: smallvec_type.hpp 18996 2010-02-03 21:45:48Z 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 "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 
00082   FORCEINLINE T *Append(uint to_add = 1)
00083   {
00084     uint begin = this->items;
00085     this->items += to_add;
00086 
00087     if (this->items > this->capacity) {
00088       this->capacity = Align(this->items, S);
00089       this->data = ReallocT(this->data, this->capacity);
00090     }
00091 
00092     return &this->data[begin];
00093   }
00094 
00101   FORCEINLINE const T *Find(const T &item) const
00102   {
00103     const T *pos = this->Begin();
00104     const T *end = this->End();
00105     while (pos != end && *pos != item) pos++;
00106     return pos;
00107   }
00108 
00115   FORCEINLINE T *Find(const T &item)
00116   {
00117     T *pos = this->Begin();
00118     const T *end = this->End();
00119     while (pos != end && *pos != item) pos++;
00120     return pos;
00121   }
00122 
00129   FORCEINLINE int FindIndex(const T &item)
00130   {
00131     int index = 0;
00132     T *pos = this->Begin();
00133     const T *end = this->End();
00134     while (pos != end && *pos != item) {
00135       pos++;
00136       index++;
00137     }
00138     return pos == end ? -1 : index;
00139   }
00140 
00147   FORCEINLINE bool Contains(const T &item) const
00148   {
00149     return this->Find(item) != this->End();
00150   }
00151 
00157   FORCEINLINE void Erase(T *item)
00158   {
00159     assert(item >= this->Begin() && item < this->End());
00160     *item = this->data[--this->items];
00161   }
00162 
00169   FORCEINLINE bool Include(const T &item)
00170   {
00171     bool is_member = this->Contains(item);
00172     if (!is_member) *this->Append() = item;
00173     return is_member;
00174   }
00175 
00179   FORCEINLINE uint Length() const
00180   {
00181     return this->items;
00182   }
00183 
00189   FORCEINLINE const T *Begin() const
00190   {
00191     return this->data;
00192   }
00193 
00199   FORCEINLINE T *Begin()
00200   {
00201     return this->data;
00202   }
00203 
00209   FORCEINLINE const T *End() const
00210   {
00211     return &this->data[this->items];
00212   }
00213 
00219   FORCEINLINE T *End()
00220   {
00221     return &this->data[this->items];
00222   }
00223 
00230   FORCEINLINE const T *Get(uint index) const
00231   {
00232     /* Allow access to the 'first invalid' item */
00233     assert(index <= this->items);
00234     return &this->data[index];
00235   }
00236 
00243   FORCEINLINE T *Get(uint index)
00244   {
00245     /* Allow access to the 'first invalid' item */
00246     assert(index <= this->items);
00247     return &this->data[index];
00248   }
00249 
00256   FORCEINLINE const T &operator[](uint index) const
00257   {
00258     assert(index < this->items);
00259     return this->data[index];
00260   }
00261 
00268   FORCEINLINE T &operator[](uint index)
00269   {
00270     assert(index < this->items);
00271     return this->data[index];
00272   }
00273 };
00274 
00275 
00286 template <typename T, uint S>
00287 class AutoFreeSmallVector : public SmallVector<T, S> {
00288 public:
00289   ~AutoFreeSmallVector()
00290   {
00291     this->Clear();
00292   }
00293 
00297   FORCEINLINE void Clear()
00298   {
00299     for (uint i = 0; i < this->items; i++) {
00300       free(this->data[i]);
00301     }
00302 
00303     this->items = 0;
00304   }
00305 };
00306 
00307 typedef AutoFreeSmallVector<char*, 4> StringList;
00308 
00309 #endif /* SMALLVEC_TYPE_HPP */

Generated on Sun Nov 14 14:41:50 2010 for OpenTTD by  doxygen 1.6.1