tvalarray.h

00001 #ifndef _tvalarray_h
00002 #define _tvalarray_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 
00013 
00014 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00015 inline bool resize_warning()
00016 {
00017     std::cerr<<"General information: do not use tvalarray< tvalarray<T> >::resize(unsigned, tvalarray<T>),\n"
00018              <<"because does not work!\n"
00019              <<"In case of hyper-arrays use resize(tvalarray< tvalarray<T> >&, unsigned, tvalarray<T>) instead!\n";
00020     return true;
00021 }
00022 
00023 inline bool display_resize_warning()
00024 {
00025     static const bool resize_warning_buffer=resize_warning();
00026     return resize_warning_buffer;
00027 }
00028 #endif
00029 
00030 
00038 template <class T>
00039 class tvalarray
00040 {
00041 private:
00042     T* x;
00043     unsigned n;
00044     const bool ownsData;
00045 
00046 protected:
00048     tvalarray(T* array, unsigned _n, bool realloc);
00049 
00050 public:
00052     tvalarray() : ownsData(true) {
00053         x = 0;
00054         n = 0;
00055     }
00056 
00058     tvalarray(unsigned _n) : ownsData(true) {
00059         if(_n > 0) {
00060             n=_n;
00061             x = new T[n];
00062             *this = T(); // initialize elements
00063         } else {
00064             n = 0;
00065             x = 0;
00066         }
00067     }
00068 
00070     tvalarray(const T& value, unsigned _n);
00071 
00073     tvalarray(const T* values, unsigned _n);
00074 
00076     tvalarray(const tvalarray& a) : ownsData(true) {
00077         n = a.n;
00078         if(n > 0) {
00079             x = new T[n];
00080             const T* y = a.x;
00081             for(unsigned i = 0; i < n; ++i) {
00082                 x[i] = y[i];
00083             }
00084         } else {
00085             n = 0;
00086             x = 0;
00087         }
00088     }
00089 
00090     ~tvalarray() {
00091         if(x != 0 && ownsData) {
00092             delete[] x;
00093         }
00094     }
00095 
00097     unsigned size() const {
00098         return n;
00099     }
00100 
00102     operator T*() {
00103         return x;
00104     }
00105 
00107     operator const T*() const {
00108         return x;
00109     }
00110 
00112     tvalarray& operator =(const tvalarray& a) {
00113 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00114         if(n != a.n) {
00115             std::cerr << "Fatal error: tvalarray a = b with different sizes ("
00116                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00117             ::abort();
00118         }
00119 #endif
00120         const T* y = a.x;
00121         for(unsigned i = 0; i < n; ++i) {
00122             x[i] = y[i];
00123         }
00124         return *this;
00125     }
00126 
00130     template <class Tp>
00131     friend void copy(const tvalarray<Tp>& source, tvalarray<Tp>& dest);
00132 
00136     template <class Tp>
00137     friend void copy(const tvalarray< tvalarray<Tp> >& source, tvalarray< tvalarray<Tp> >& dest);
00138 
00140     tvalarray& operator +=(const tvalarray& a) {
00141 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00142         if(n != a.n) {
00143             std::cerr << "Fatal error: tvalarray a += b with different sizes ("
00144                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00145             ::abort();
00146         }
00147 #endif
00148         const T* y = a.x;
00149         for(unsigned i = 0; i < n; ++i) {
00150             x[i] += y[i];
00151         }
00152         return *this;
00153     }
00154 
00156     tvalarray& operator +=(const T& c) {
00157         for(unsigned i = 0; i < n; ++i) {
00158             x[i] += c;
00159         }
00160         return *this;
00161     }
00162 
00164     tvalarray& operator ^=(const tvalarray& a) {
00165 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00166         if(n != a.n) {
00167             std::cerr << "Fatal error: tvalarray a ^= b with different sizes ("
00168                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00169             ::abort();
00170         }
00171 #endif
00172         const T* y = a.x;
00173         for(unsigned i = 0; i < n; ++i) {
00174             x[i] ^= y[i];
00175         }
00176         return *this;
00177     }
00178 
00180     tvalarray& operator ^=(const T& c) {
00181         for(unsigned i = 0; i < n; ++i) {
00182             x[i] ^= c;
00183         }
00184         return *this;
00185     }
00186 
00188     tvalarray& operator &=(const tvalarray& a) {
00189 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00190         if(n != a.n) {
00191             std::cerr << "Fatal error: tvalarray a &= b with different sizes ("
00192                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00193             ::abort();
00194         }
00195 #endif
00196         const T* y = a.x;
00197         for(unsigned i = 0; i < n; ++i) {
00198             x[i] &= y[i];
00199         }
00200         return *this;
00201     }
00202 
00204     tvalarray& operator &=(const T& c) {
00205         for(unsigned i = 0; i < n; ++i) {
00206             x[i] &= c;
00207         }
00208         return *this;
00209     }
00210 
00212     tvalarray& operator |=(const tvalarray& a) {
00213 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00214         if(n != a.n) {
00215             std::cerr << "Fatal error: tvalarray a |= b with different sizes ("
00216                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00217             ::abort();
00218         }
00219 #endif
00220         const T* y = a.x;
00221         for(unsigned i = 0; i < n; ++i) {
00222             x[i] |= y[i];
00223         }
00224         return *this;
00225     }
00226 
00228     tvalarray& operator |=(const T& c) {
00229         for(unsigned i = 0; i < n; ++i) {
00230             x[i] |= c;
00231         }
00232         return *this;
00233     }
00234 
00236     tvalarray& operator <<=(const tvalarray& a) {
00237 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00238         if(n != a.n) {
00239             std::cerr << "Fatal error: tvalarray a <<= b with different sizes ("
00240                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00241             ::abort();
00242         }
00243 #endif
00244         const T* y = a.x;
00245         for(unsigned i = 0; i < n; ++i) {
00246             x[i] <<= y[i];
00247         }
00248         return *this;
00249     }
00250 
00252     tvalarray& operator <<=(const T& c) {
00253         for(unsigned i = 0; i < n; ++i) {
00254             x[i] <<= c;
00255         }
00256         return *this;
00257     }
00258 
00260     tvalarray& operator >>=(const tvalarray& a) {
00261 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00262         if(n != a.n) {
00263             std::cerr << "Fatal error: tvalarray a >>= b with different sizes ("
00264                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00265             ::abort();
00266         }
00267 #endif
00268         const T* y = a.x;
00269         for(unsigned i = 0; i < n; ++i) {
00270             x[i] >>= y[i];
00271         }
00272         return *this;
00273     }
00274 
00276     tvalarray& operator >>=(const T& c) {
00277         for(unsigned i = 0; i < n; ++i) {
00278             x[i] >>= c;
00279         }
00280         return *this;
00281     }
00282 
00284     tvalarray& operator *=(const tvalarray& a) {
00285 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00286         if(n != a.n) {
00287             std::cerr << "Fatal error: tvalarray a *= b with different sizes ("
00288                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00289             ::abort();
00290         }
00291 #endif
00292         const T* y = a.x;
00293         for(unsigned i = 0; i < n; ++i) {
00294             x[i] *= y[i];
00295         }
00296         return *this;
00297     }
00298 
00300     tvalarray& operator *=(const T& c) {
00301         for(unsigned i = 0; i < n; ++i) {
00302             x[i] *= c;
00303         }
00304         return *this;
00305     }
00306 
00308     tvalarray& operator /=(const tvalarray& a) {
00309 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00310         if(n != a.n) {
00311             std::cerr << "Fatal error: tvalarray a /= b with different sizes ("
00312                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00313             ::abort();
00314         }
00315 #endif
00316         const T* y = a.x;
00317         for(unsigned i = 0; i < n; ++i) {
00318             x[i] /= y[i];
00319         }
00320         return *this;
00321     }
00322 
00324     tvalarray& operator /=(const T& c) {
00325         for(unsigned i = 0; i < n; ++i) {
00326             x[i] /= c;
00327         }
00328         return *this;
00329     }
00330 
00332     tvalarray& operator %=(const tvalarray& a) {
00333 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00334         if(n != a.n) {
00335             std::cerr << "Fatal error: tvalarray a %= b with different sizes ("
00336                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00337             ::abort();
00338         }
00339 #endif
00340         const T* y = a.x;
00341         for(unsigned i = 0; i < n; ++i) {
00342             x[i] %= y[i];
00343         }
00344         return *this;
00345     }
00346 
00348     tvalarray& operator %=(const T& c) {
00349         for(unsigned i = 0; i < n; ++i) {
00350             x[i] %= c;
00351         }
00352         return *this;
00353     }
00354 
00356     tvalarray& operator =(const T& c) {
00357         for(unsigned i = 0; i < n; ++i) {
00358             x[i] = c;
00359         }
00360         return *this;
00361     }
00362 
00364     tvalarray& operator -=(const T& c) {
00365         for(unsigned i = 0; i < n; ++i) {
00366             x[i] -= c;
00367         }
00368         return *this;
00369     }
00370 
00372     tvalarray& operator -=(const tvalarray& a) {
00373 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00374         if(n != a.n) {
00375             std::cerr << "Fatal error: tvalarray a -= b with different sizes ("
00376                  << n << " != " << a.n << ")\n" _COREDEBUG_STR << std::endl;
00377             ::abort();
00378         }
00379 #endif
00380         const T* y = a.x;
00381         for(unsigned i = 0; i < n; ++i) {
00382             x[i] -= y[i];
00383         }
00384         return *this;
00385     }
00386 
00388     void resize(unsigned _n, T value = T()) {
00389 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00390         display_resize_warning();
00391 #endif
00392         if(_n > n) {
00393             realloc(_n);
00394         }
00395         if((n = _n) > 0) {
00396             *this = value; // initialize elements (does not work for T==tvalarray<>)
00397         }
00398     }
00399 
00401     template <class Tp>
00402     friend void resize(tvalarray<Tp>& arr, unsigned _n, Tp value = Tp());
00403 
00405     template <class Tp>
00406     friend void resize(tvalarray< tvalarray<Tp> >& arr, unsigned _n, tvalarray<Tp> value = tvalarray<Tp>());
00407 
00409     T operator [](int k) const {
00410 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00411         if(k < 0 || k >= (int)n) {
00412             std::cerr << "Fatal error: tvalarray index " << k
00413                  << " out of range [0, " << n << "[\n" _COREDEBUG_STR << std::endl;
00414             ::abort();
00415         }
00416 #endif
00417         return x[k];
00418     }
00419 
00421     T& operator [](int k) {
00422 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00423         if(k < 0 || k >= (int)n) {
00424             std::cerr << "Fatal error: tvalarray index " << k
00425                  << " out of range [0, " << n << "[\n" _COREDEBUG_STR << std::endl;
00426             ::abort();
00427         }
00428 #endif
00429         return x[k];
00430     }
00431 
00433     tvalarray shift(int k) const;
00434 
00436     tvalarray cshift(int k) const;
00437 
00438 public:
00440     void realloc(int _n) {
00441         if(ownsData) {
00442             if ( x!=0 ) delete [] x;
00443             if(_n > 0) { n = _n; x = new T[n]; }
00444             else { n=0; x=0; }
00445         } else {
00446 #if defined(DEBUG) || defined(ARRAY_BOUNDS_CHECK)
00447             std::cerr << "Fatal error: reallocating tvalarray not owning data\n" 
00448                          << _COREDEBUG_STR << std::endl;
00449             ::abort();
00450 #endif
00451             x = 0;
00452             n = 0;
00453         }
00454     }
00455 };
00456 
00464 template <class T>
00465 class tvalarray_wrapper: public tvalarray<T>
00466 {
00467 public:
00469     tvalarray_wrapper(T* array, unsigned n): tvalarray<T>(array, n, false) {
00470     }
00471 };
00472 
00473 template <class T> tvalarray<T> tvalarray<T>::shift(int k) const
00474 {
00475     tvalarray<T> result(n);
00476     T* q = result.x;
00477     if((k > 0 && (unsigned)k >= n) || (k < 0 && (unsigned)(-k) >= n)) {
00478         T* end = result.x + n;
00479         while(q != end) {
00480             *(q++) = 0;
00481         }
00482     } else if(k >= 0) {
00483         T* q = result.x;
00484         T* end = x + n;
00485         for(T* p = x + k; p != end; ++p) {
00486             *(q++) = *p;
00487         }
00488         for(int i = 0; i < k; ++i) {
00489             *(q++) = 0;
00490         }
00491     } else {
00492         k = -k;
00493         for(int i = 0; i < k; ++i) {
00494             *(q++) = 0;
00495         }
00496         T* end = x + n - k;
00497         for(T* p = x; p != end; ++p) {
00498             *(q++) = *p;
00499         }
00500     }
00501     return result;
00502 }
00503 
00504 template <class T> tvalarray<T> tvalarray<T>::cshift(int k) const
00505 {
00506     if(k < 0) {
00507         k = n - (-k) % n;
00508     } else if((unsigned)k >= n) {
00509         k = k % n;
00510     }
00511     tvalarray<T> result(n);
00512     T* end = x + n;
00513     T* q = result.x;
00514     for(T* p = x + k; p != end; ++p) {
00515         *(q++) = *p;
00516     }
00517     end = x + k;
00518     for(T* p = x; p != end; ++p) {
00519         *(q++) = *p;
00520     }
00521     return result;
00522 }
00523 
00524 template <class T> tvalarray<T>::tvalarray(const T& value, unsigned _n)
00525  : ownsData(true)
00526 {
00527     if(_n > 0) {
00528         n = _n;
00529         x = new T[n];
00530         *this = value; // initialize elements
00531     } else {
00532         n=0;
00533         x = 0;
00534     }
00535 }
00536 
00537 template <class T> tvalarray<T>::tvalarray(T* array, unsigned _n, bool realloc)
00538  : ownsData(realloc)
00539 {
00540     if(_n > 0) {
00541         n=_n;
00542         if(realloc) {
00543             x = new T[n];
00544             for(unsigned i = 0; i < n; ++i) {
00545                 x[i] = array[i]; // initialize elements
00546             }
00547         } else {
00548             x = array;
00549         }
00550     } else {
00551         n=0;
00552         x = 0;
00553     }
00554 }
00555 
00556 template <class T> tvalarray<T>::tvalarray(const T* values, unsigned _n)
00557  : ownsData(true)
00558 {
00559     if(_n > 0) {
00560         n=_n;
00561         x = new T[n];
00562         for(unsigned i = 0; i < n; ++i) {
00563             x[i] = values[i]; // initialize elements
00564         }
00565     } else {
00566         n=0;
00567         x = 0;
00568     }
00569 }
00570 
00574 template <class T>
00575 void copy(const tvalarray<T>& source, tvalarray<T>& dest)
00576 {
00577     if ( dest.n!=source.n )
00578     {
00579         dest.realloc(source.n);
00580     }
00581     const T* y = source.x;
00582     for(unsigned i = 0; i < dest.n; ++i)
00583     {
00584         dest.x[i] = y[i]; // <- Here T==tvalarray<something> would not work.
00585     }
00586 }
00587 
00591 template <class T>
00592 void copy(const tvalarray< tvalarray<T> >& source, tvalarray< tvalarray<T> >& dest)
00593 {
00594     if ( dest.n!=source.n )
00595     {
00596         dest.realloc(source.n);
00597     }
00598     const tvalarray<T>* y = source.x;
00599     for(unsigned i = 0; i < dest.n; ++i) {
00600         copy(y[i], dest.x[i]); // <- Here T==tvalarray<something> would not work.
00601     }
00602 }
00603 
00605 template <class T>
00606 void resize(tvalarray< T >& arr, unsigned _n, T value=T())
00607 {
00608     if(_n > arr.n) {
00609         arr.realloc(_n);
00610     }
00611     if(arr.n > 0) {
00612         arr=value;
00613     }
00614 }
00615 
00617 template <class T>
00618 void resize(tvalarray< tvalarray<T> >& arr, unsigned _n, tvalarray<T> value=tvalarray<T>())
00619 {
00620     if(_n > arr.n) {
00621         arr.realloc(_n);
00622     }
00623     if(arr.n > 0) {
00624         for ( unsigned int i=0 ; i<arr.n ; ++i ) copy(value, arr[i]);
00625     }
00626 }
00627 
00628 #ifdef DEBUG
00629 template <class T>
00630 inline std::ostream& operator <<(std::ostream& out, const tvalarray<T>& x)
00631 {
00632     for(unsigned i = 0; i < x.size(); ++i) {
00633         out << x[i];
00634         if(i+1 < x.size()) {
00635             out << ", ";
00636         }
00637     }
00638     return out;
00639 }
00640 #endif /* DEBUG */
00641 
00642 #endif /* _tvalarray_h */

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