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>
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();
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;
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;
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];
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];
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];
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]);
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
00641
00642 #endif