tvector.h

00001 #ifndef _tvector_h
00002 #define _tvector_h
00003 
00004 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00005 #include <iostream>
00006 #include <cstdlib> /* abort() */
00007 #ifndef _COREDEBUG_STR
00008 #define _COREDEBUG_STR "To debug the core, use this command:\n"\
00009 "    gdb -c core /path/to/executable             (gdb) bt"
00010 #endif
00011 #endif
00012 
00021 template <class T>
00022 class tvector
00023 {
00024 public:
00026     typedef T* iterator;
00027 
00029     typedef const T* const_iterator;
00030 
00031 private:
00032     T* x;
00033     unsigned max;
00034     unsigned n;
00035 
00036 public:
00038     tvector() {
00039         x = 0;
00040         max = 0;
00041         n = 0;
00042     }
00043 
00045     tvector(unsigned n) {
00046 //      if(n < 0)
00047 //          n = 0;
00048         this->n = max = n;
00049         if(n > 0) {
00050             x = new T[n];
00051             fill(begin(), begin() + n, T());
00052         } else {
00053             x = 0;
00054         }
00055     }
00056 
00058     tvector(unsigned n, const T& value);
00059 
00061     tvector(const tvector& a) {
00062         n = max = a.n;
00063         if(n > 0) {
00064             x = new T[n];
00065             a.copyInto(x);
00066         } else {
00067             x = 0;
00068         }
00069     }
00070 
00071     ~tvector() {
00072        if(x != 0) {
00073             delete [] x;
00074        }
00075     }
00076 
00078     unsigned size() const {
00079         return n;
00080     }
00081 
00083     unsigned capacity() const {
00084         return max;
00085     }
00086 
00088     operator T*() {
00089         return x;
00090     }
00091 
00093     operator const T*() const {
00094         return x;
00095     }
00096 
00098     tvector& operator =(const tvector& a) {
00099         if(n != a.n) {
00100             resize_nofill(a.n);
00101         }
00102         a.copyInto(x);
00103         return *this;
00104     }
00105 
00107     void clear() {
00108         delete[] x;
00109         x = 0;
00110         n = max = 0;
00111     }
00112 
00114     void erase(iterator first) {
00115         erase(first, first + 1);
00116     }
00117 
00119     void erase(iterator first, iterator last);
00120 
00122     void erase(const T& x);
00123 
00125     void resize(unsigned n) {
00126         resize(n, T());
00127     }
00128 
00130     void resize(unsigned n, const T& value) {
00131         unsigned prev = this->n;
00132         resize_nofill(n);
00133         if(this->n > prev) {
00134             fill(begin() + prev, begin() + this->n, value);
00135         }
00136     }
00137 
00139     void insert(iterator p, const T& value);
00140 
00142     void insert(iterator p, const T* first, const T* last);
00143 
00145     void push_back(const T& value) {
00146         if(n < max) {
00147             x[n++] = value;
00148         } else {
00149             resize_nofill(n + 1);
00150             x[n - 1] = value;
00151         }
00152     }
00153 
00155     void pop_back() {
00156 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00157         if(n == 0) {
00158             std::cerr << "Fatal error: pop_back() called for empty tvector\n"
00159                  _COREDEBUG_STR << std::endl;
00160             ::abort();
00161         }
00162 #endif
00163         --n;
00164     }
00165 
00167     T& operator [](int k) {
00168 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00169         if(k < 0 || k >= (int)n) {
00170             std::cerr << "Fatal error: tvector index " << k
00171                  << " out of range [0, "
00172                  << n << "[\n" _COREDEBUG_STR << std::endl;
00173             ::abort();
00174         }
00175 #endif
00176         return x[k];
00177     }
00178 
00179 // method commented out because of gcc 3.3.3 compilation error:
00180 // In member function `virtual gromit::TwoBodyInter*
00181 // gromit_interactions_impl::CollisionTableImp::getInteraction(int, int) const':
00182 // error: ISO C++ says that `const T& tvector<T>::operator[](int) const [with
00183 // T = gromit::TwoBodyInter*]' and `operator[]' are ambiguous even though the
00184 // worst conversion for the former is better than the worst conversion for the
00185 // latter (06/22/2004 cspeter)
00186 //    /** Gets the kth element. */
00187 //    const T& operator [](int k) const {
00188 //#if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00189 //      if(k < 0 || k >= (int)n) {
00190 //          std::cerr << "Fatal error: tvector index " << k
00191 //               << " out of range [0, "
00192 //               << n << "[\n" << _COREDEBUG_STR << std::endl;
00193 //          ::abort();
00194 //      }
00195 //#endif
00196 //      return x[k];
00197 //    }
00198 
00200     T& front() {
00201         return *begin();
00202     }
00203 
00205     const T& front() const {
00206         return *begin();
00207     }
00208 
00210     T& back() {
00211         return *(end() - 1);
00212     }
00213 
00215     const T& back() const {
00216         return *(end() - 1);
00217     }
00218 
00220     iterator begin() {
00221         return x;
00222     }
00223 
00225     const_iterator begin() const {
00226         return x;
00227     }
00228 
00230     iterator end() {
00231         return x+n;
00232     }
00233 
00235     const_iterator end() const {
00236         return x+n;
00237     }
00238 
00240     void sort();
00241 
00242 private:
00244     void resize_nofill(unsigned _n);
00245 
00247     void copyInto(T* y) const {
00248         for(unsigned i = 0; i < n; ++i) {
00249             y[i] = x[i];
00250         }
00251     }
00252 
00254     void fill(iterator begin, iterator end, const T& value);
00255 
00257     void sort(int lo, int hi);
00258 };
00259 
00260 template <class T> tvector<T>::tvector(unsigned _n, const T& value)
00261 {
00262 //    if(_n < 0)
00263 //      _n = 0;
00264     n = max = _n;
00265     if(n > 0) {
00266         x = new T[n];
00267         fill(begin(), begin() + n, value);
00268     } else {
00269         x = 0;
00270     }
00271 }
00272 
00273 template <class T> void tvector<T>::erase(iterator first, iterator last)
00274 {
00275     int d = last - first;
00276     if(d <= 0) {
00277         return;
00278     }
00279     for(unsigned i = last - x; i < n; ++i) {
00280         x[i - d] = x[i];
00281     }
00282     n -= d;
00283 }
00284 
00285 template <class T> void tvector<T>::erase(const T& v)
00286 {
00287     for(int i = n - 1; i >= 0; --i) {
00288         if(x[i] == v) {
00289             erase(begin() + i);
00290         }
00291     }
00292 }
00293  
00294 template <class T> void tvector<T>::insert(iterator p, const T& value)
00295 {
00296     unsigned k = p - x;
00297     if(n < max) {
00298         for(unsigned i = n; i > k; --i) {
00299             x[i] = x[i - 1];
00300         }
00301         x[k] = value;
00302     } else {
00303         max = 2*(n + 1);
00304         T* y = new T[max];
00305         for(unsigned i = 0; i < k; ++i) {
00306             y[i] = x[i];
00307         }
00308         for(unsigned i = k; i < n; ++i) {
00309             y[i + 1] = x[i];
00310         }
00311         y[k] = value;
00312         delete [] x;
00313         x = y;
00314     }
00315     ++n;
00316 }
00317  
00318 template <class T> void tvector<T>::insert(iterator p,
00319                                            const T* first, const T* last)
00320 {
00321     int delta = last - first + 1;
00322 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00323         if(delta < 1) {
00324             std::cerr << "Fatal error: cannot insert zero or less elements "
00325                     "into tvector\n"
00326                  _COREDEBUG_STR << std::endl;
00327             ::abort();
00328         }
00329 #endif
00330     int k = p - x;
00331     int k_plus_delta = k + delta;
00332     if(n + delta <= max) {
00333         for(int i = n - 1; i >= k; --i) {
00334             x[i + delta] = x[i];
00335         }
00336         for(int i = k; i < k_plus_delta; ++i) {
00337             x[i] = *(first++);
00338         }
00339     } else {
00340         max = 2*(n + delta);
00341         T* y = new T[max];
00342         for(int i = 0; i < k; ++i) {
00343             y[i] = x[i];
00344         }
00345         for(int i = n - 1; i >= k; --i) {
00346             y[i + delta] = x[i];
00347         }
00348         for(int i = k; i < k_plus_delta; ++i) {
00349             y[i] = *(first++);
00350         }
00351         delete [] x;
00352         x = y;
00353     }
00354     n += delta;
00355 }
00356 
00357 template <class T> void tvector<T>::resize_nofill(unsigned _n)
00358 {
00359 //    if(_n < 0) {
00360 //      n = 0;
00361 //    } else
00362     if(_n <= max) {
00363         n = _n;
00364     } else {
00365         for(max = 1; max < _n; max <<= 1);
00366         T* y = new T[max];
00367         copyInto(y);
00368         delete [] x;
00369         x = y;
00370         n = _n;
00371     }
00372 }
00373 
00374 template <class T> void tvector<T>::fill(iterator p, iterator end, const T& val)
00375 {
00376     while(p != end) {
00377         *(p++) = val;
00378     }
00379 }
00380 
00381 // quicksort the contend of the vector, T must define operator <
00382 template <class T> void tvector<T>::sort()
00383 {
00384     sort(0, n-1);
00385 }
00386 
00387 // quicksort the contend of the vector, T must define operator <
00388 template <class T> void tvector<T>::sort(int lo, int hi)
00389 {
00390     if(lo>=hi) return;
00391     T ref= x[(lo+hi)/2];
00392     int left= lo, right= hi;
00393     while(left <= right) {
00394         while(left < hi && x[left] < ref) left++;
00395         while(right > lo && ref < x[right]) right--;
00396         if(left < right) {
00397             T tmp= x[left];
00398             x[left]= x[right];
00399             x[right]= tmp;
00400             left++; right--;
00401         } else if(left== right) {
00402             left++; right--;
00403         }
00404     }
00405     sort(lo, right);
00406     sort(left, hi);
00407 }
00408 
00409 #ifdef DEBUG
00410 template <class T>
00411 inline std::ostream& operator <<(std::ostream& out, const tvector<T>& x)
00412 {
00413     for(unsigned i = 0; i < x.size(); ++i) {
00414         out << x[i];
00415         if(i+1 < x.size() ) {
00416             out << ", ";
00417         }
00418     }
00419     return out;
00420 }
00421 #endif /* DEBUG */
00422 
00423 #endif /* _tvector_h */

Generated on Wed Jun 17 18:46:47 2009 for GridRipper by  doxygen 1.5.6