Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

LightVector.hpp

Go to the documentation of this file.
00001 /*
00002  * LightVector.hpp
00003  *   -- a lightweight vector whichs memory model is accessible from outside and thus allows 
00004  *      for efficient operations.
00005  * 
00006  * Time-stamp: <05/05/18 16:09:14 lars>
00007  */
00008 
00009 #ifndef __LIGHT_VECTOR__
00010 #define __LIGHT_VECTOR__
00011 
00012 #include <iostream>
00013 using namespace std;
00014 
00015 #include "common/debug.hpp"
00016 
00049 template <class TYPE>
00050 class LightVector {
00051 public:
00052 #if DEBUG_LEVEL > 0
00053 
00056   LightVector(TYPE* const values, int& size) : m_values(values), m_size(size), m_capacity(size) {}
00057   LightVector(TYPE* const values, int& size, int capacity) : m_values(values), m_size(size), m_capacity(capacity) {}
00058 #else
00059   LightVector(TYPE* const values, int& size) : m_values(values), m_size(size) {}
00060 #endif
00061 
00067   int size() const { return m_size; }
00068 
00069   bool empty() const { return size == 0; }
00070 
00076   void resize(int size) { 
00077     assert(size <= m_capacity);
00078     m_size = size;
00079   }
00080 
00081   void clear() { m_size = 0; }
00082 
00088   TYPE operator[] (int index) const { 
00089     assert(index >= 0);
00090     assert(index < m_size);
00091     return m_values[index]; 
00092   }
00093 
00094   TYPE back() const { 
00095     assert(m_size > 0);
00096     return m_values[m_size-1];
00097   }
00098 
00102   void setEntry(int index, TYPE value) { 
00103     assert(index >= 0);
00104     assert(index < m_capacity);
00105     m_values[index] = value; 
00106   }
00107 
00108   void push_back(TYPE value) {
00109     assert(m_size < m_capacity);
00110     m_values[m_size++] = value;
00111   }
00112 
00113   void pop_back() { 
00114     assert(m_size > 0);
00115     m_size--; 
00116   }
00117 
00118   /*
00119    * There are three types of iterators:
00120    * (i)   iterator -- a read/write iterator for the elements 0..(size-1).
00121    * (ii)  const_iterator -- a read-only iterator for the elements 0..(size-1).
00122    * (iii) unbounded iterator -- a read/write iterator for the elements 0..(capacity-1). 
00123    * 
00124    * Methods begin/end of const objects automatically create const_iterators.
00125    *
00126    * unbounded iterators can be created by the methods beginUnbounded / endUnbounded.
00127    * 
00128    * unbounded iterators can be used for writing to a LightVector; when writing / filling the vector 
00129    * is finished, resizeToEndOf(iter) has to be called. 
00130    *
00131    * In debugging mode iterators check bounds, in production mode not. 
00132    */
00133 #if DEBUG_LEVEL > 0
00134   // Define bounds checking iterators:
00135   class iterator : public std::iterator<std::random_access_iterator_tag, TYPE> {
00136   public:
00137     iterator(TYPE* const values, int const & size, int index) : m_values(values), m_size(size), m_index(index) {}
00138     iterator(const iterator& iter) : m_values(iter.m_values), m_size(iter.m_size), m_index(iter.m_index) {}
00139     TYPE& operator* () const { 
00140       assert(m_index >= 0);
00141       assert(m_index < m_size);
00142       return m_values[m_index]; 
00143     }
00144     iterator& operator++ () { 
00145       assert(m_index < m_size);
00146       m_index++;
00147       return *this;
00148     }
00149     iterator operator++ (int) { 
00150       assert(m_index < m_size);
00151       iterator iter = *this;
00152       m_index++;
00153       return iter;
00154     }
00155     iterator& operator-- () { 
00156       assert(m_index > 0);
00157       m_index--;
00158       return *this;
00159     }
00160     iterator operator-- (int) { 
00161       assert(m_index > 0);
00162       iterator iter = *this;
00163       m_index--;
00164       return iter;
00165     }
00166     void operator+= (int index) {
00167       assert(m_index + index <= m_size);
00168       m_index += index;
00169     } 
00170     void operator-= (int index) {
00171       assert(m_index >= index);
00172       m_index -= index;
00173     } 
00174     bool operator!= (iterator const & iter) const {
00175       assert(m_values == iter.m_values);
00176       assert(m_size == iter.m_size);
00177       return m_index != iter.m_index;
00178     }
00179     bool operator== (iterator const & iter) const {
00180       assert(m_values == iter.m_values);
00181       assert(m_size == iter.m_size);
00182       return m_index == iter.m_index;
00183     }
00184     bool operator< (iterator const & iter) const {
00185       assert(m_values == iter.m_values);
00186       assert(m_size == iter.m_size);
00187       return m_index < iter.m_index;
00188     }
00189     bool operator<= (iterator const & iter) const {
00190       assert(m_values == iter.m_values);
00191       assert(m_size == iter.m_size);
00192       return m_index <= iter.m_index;
00193     }
00194     bool operator> (iterator const & iter) const {
00195       assert(m_values == iter.m_values);
00196       assert(m_size == iter.m_size);
00197       return m_index > iter.m_index;
00198     }
00199     bool operator>= (iterator const & iter) const {
00200       assert(m_values == iter.m_values);
00201       assert(m_size == iter.m_size);
00202       return m_index >= iter.m_index;
00203     }
00204     int operator- (iterator const & iter) const { 
00205       assert(m_values == iter.m_values);
00206       assert(m_size == iter.m_size);
00207       return m_index - iter.m_index;
00208     }
00209     iterator operator- (const int size) const { 
00210       assert(m_index - size >= 0);
00211       assert(m_index - size <= m_size);
00212       return iterator(m_values, m_size, m_index - size);
00213     }
00214     iterator operator+ (const int size) const { 
00215       assert(m_index + size >= 0);
00216       assert(m_index + size <= m_size);
00217       return iterator(m_values, m_size, m_index + size);
00218     }
00219     iterator& operator= (const iterator& iter) {
00220       assert(m_values == iter.m_values);
00221       assert(m_size == iter.m_size);
00222       m_index = iter.m_index;
00223       return *this;
00224     }
00225     int index() const { return m_index; }
00226   private:
00227     TYPE * const m_values;
00228     int const & m_size;
00229     int m_index;
00230   };
00231 
00232   class const_iterator : public std::iterator<std::random_access_iterator_tag, TYPE> {
00233   public:
00234     const_iterator(TYPE const * const values, int& size, int index) : m_values(values), m_size(size), m_index(index) {}
00235     const_iterator(const const_iterator& iter) : m_values(iter.m_values), m_size(iter.m_size), m_index(iter.m_index) {}
00236     TYPE operator* () const { 
00237       assert(m_index >= 0);
00238       assert(m_index < m_size);
00239       return m_values[m_index]; 
00240     }
00241     const_iterator& operator++ () { 
00242       assert(m_index < m_size);
00243       m_index++;
00244       return *this;
00245     }
00246     const_iterator operator++ (int) { 
00247       assert(m_index < m_size);
00248       const_iterator iter = *this;
00249       m_index++;
00250       return iter;
00251     }
00252     const_iterator& operator-- () { 
00253       assert(m_index > 0);
00254       m_index--;
00255       return *this;
00256     }
00257     const_iterator operator-- (int) { 
00258       assert(m_index > 0);
00259       const_iterator iter = *this;
00260       m_index--;
00261       return iter;
00262     }
00263     void operator-= (int index) {
00264       assert(m_index >= index);
00265       m_index -= index;
00266     } 
00267     void operator+= (int index) {
00268       assert(m_index + index <= m_size);
00269       m_index += index;
00270     } 
00271     bool operator!= (const_iterator const & iter) const {
00272       assert(m_values == iter.m_values);
00273       assert(m_size == iter.m_size);
00274       return m_index != iter.m_index;
00275     }
00276     bool operator== (const_iterator const & iter) const {
00277       assert(m_values == iter.m_values);
00278       assert(m_size == iter.m_size);
00279       return m_index == iter.m_index;
00280     }
00281     bool operator< (const_iterator const & iter) const {
00282       assert(m_values == iter.m_values);
00283       assert(m_size == iter.m_size);
00284       return m_index < iter.m_index;
00285     }
00286     bool operator<= (const_iterator const & iter) const {
00287       assert(m_values == iter.m_values);
00288       assert(m_size == iter.m_size);
00289       return m_index <= iter.m_index;
00290     }
00291     bool operator> (const_iterator const & iter) const {
00292       assert(m_values == iter.m_values);
00293       assert(m_size == iter.m_size);
00294       return m_index > iter.m_index;
00295     }
00296     bool operator>= (const_iterator const & iter) const {
00297       assert(m_values == iter.m_values);
00298       assert(m_size == iter.m_size);
00299       return m_index >= iter.m_index;
00300     }
00301     int operator- (const_iterator const & iter) const { 
00302       assert(m_values == iter.m_values);
00303       assert(m_size == iter.m_size);
00304       return m_index - iter.m_index;
00305     }
00306     const_iterator operator- (const int size) const { 
00307       assert(m_index - size >= 0);
00308       assert(m_index - size <= m_size);
00309       return const_iterator(m_values, m_size, m_index - size);
00310     }
00311     const_iterator operator+ (const int size) const { 
00312       assert(m_index + size >= 0);
00313       assert(m_index + size <= m_size);
00314       return const_iterator(m_values, m_size, m_index + size);
00315     }
00316     int index() const { return m_index; }
00317   private:
00318     TYPE const * const m_values;
00319     int& m_size;
00320     int m_index;
00321   };
00322 
00323   iterator begin() { return iterator(m_values, m_capacity, 0); }
00324   iterator end() { return iterator(m_values, m_capacity, m_size); }
00325   // iterator begin() { return iterator(m_values, m_size, 0); }
00326   // iterator end() { return iterator(m_values, m_size, m_size); }
00327   const_iterator begin() const { return const_iterator(m_values, m_size, 0); }
00328   const_iterator end() const { return const_iterator(m_values, m_size, m_size); }
00329   // iterator beginUnbounded() { return iterator(m_values, m_capacity, 0); }
00330   // iterator endUnbounded() { return iterator(m_values, m_capacity, m_size); }
00331 
00332 #else
00333   // Define non-bounds checkings, lightweight iterators: (stolen from Balazs)
00334   typedef int* iterator;
00335   typedef int const * const_iterator;
00336 
00337   iterator begin() { return m_values; }
00338   iterator end() { return m_values + m_size; }
00339   const_iterator begin() const { return m_values; }
00340   const_iterator end() const { return m_values + m_size; }
00341   // iterator beginUnbounded() { return m_values; }
00342   // iterator endUnbounded() { return m_values + m_size; }
00343 
00344 #endif
00345 
00349   TYPE* values() const { return m_values; }
00350   
00351 #if DEBUG_LEVEL > 0
00352   int capacity() const { return m_capacity; }
00353 #endif
00354 
00360   static LightVector<TYPE>* create(int capacity, TYPE initValue = TYPE()) {
00361     TYPE* values = new int[capacity];
00362     for (int i = 0; i < capacity; i++)
00363       values[i] = initValue;
00364 #if DEBUG_LEVEL > 0
00365     return new LightVector(values, *(new int[1]), capacity);
00366 #else
00367     return new LightVector(values, *(new int[1]));
00368 #endif
00369   }
00370 
00375   void destroy() {
00376     delete[] m_values;
00377     delete[] (&m_size);
00378     delete this;
00379   }
00380 
00381 
00382 private:
00383   TYPE* const m_values;
00384   int& m_size;
00385 #if DEBUG_LEVEL > 0
00386   int const m_capacity;
00387 #endif
00388 };
00389 
00390 template <class TYPE> ostream& operator<< (ostream& out, LightVector<TYPE> const & vector) {
00391   if (vector.size() == 0)
00392     out << "[empty]";
00393   else {
00394     out << vector[0];
00395     for (int i = 1; i < vector.size(); i++)
00396       out << " " << vector[i];
00397   }
00398   return out;
00399 }
00400 
00401 
00402 #endif

Generated on Sun Sep 17 17:50:39 2006 for FIM environment by  doxygen 1.4.4