00001 #ifndef include_MultiDimArrayAccess_h
00002 #define include_MultiDimArrayAccess_h
00003
00004 #include <sys/types.h>
00005 #include <iostream.h>
00006
00007
00014 template< int DIM >
00015 class MultiDimArrayIndexRange {
00016
00018 protected: int d_start[DIM];
00020 protected: size_t d_size[DIM];
00021
00037 public: MultiDimArrayIndexRange
00038 ( const size_t *sz=((size_t*)0)
00039 , const int *st=((int*)0)
00040 , bool reverse=false
00041 ) {
00042 int i;
00043 if ( st ) { for ( i=0; i<DIM; i++ ) d_start[i] = st[i]; }
00044 else { for ( i=0; i<DIM; i++ ) d_start[i] = 0; }
00045 if ( sz ) { for ( i=0; i<DIM; i++ ) d_size[i] = sz[i]; }
00046 else { for ( i=0; i<DIM; i++ ) d_size[i] = 0; }
00047 if ( reverse ) reverseDim();
00048 }
00049
00068 public: MultiDimArrayIndexRange ( const int *si
00070 , const int *sf
00071 , bool reverse=false
00072 ) {
00073 int i;
00074 if ( si ) { for ( i=0; i<DIM; i++ ) d_start[i] = si[i]; }
00075 else { for ( i=0; i<DIM; i++ ) d_start[i] = 0; }
00076 if ( sf ) { for ( i=0; i<DIM; i++ ) d_size[i] = 1 + sf[i] - d_start[i]; }
00077 else { for ( i=0; i<DIM; i++ ) d_size[i] = 0; }
00078 if ( reverse ) reverseDim();
00079 }
00080
00082
00086 public: void setSizeAndStart ( const size_t *sz=((size_t*)0)
00088 , const int *st=((int*)0)
00089 , bool reverse=false
00090 ) {
00091 if ( reverse ) reverseDim();
00092 if (sz) for ( int i=0; i<DIM; i++ ) d_size[i] = sz[i];
00093 if (st) for ( int i=0; i<DIM; i++ ) d_start[i] = st[i];
00094 if ( reverse ) reverseDim();
00095 }
00096
00100 public: void setInclusiveRange ( const int first[DIM]
00102 , const int final[DIM]
00103 , bool reverse=false
00104 ) {
00105 if ( reverse ) reverseDim();
00106 if (first) for ( int i=0; i<DIM; i++ ) d_start[i] = first[i];
00107 if (final) for ( int i=0; i<DIM; i++ ) d_size[i] = final[i] - first[i] + 1;
00108 if ( reverse ) reverseDim();
00109 }
00110
00131 public: void reverseDim() {
00132 for ( int i=0; i<DIM/2; i++ ) {
00133 int itmp; size_t stmp;
00134 itmp = d_start[i]; d_start[i] = d_start[DIM-1-i]; d_start[DIM-1-i] = itmp;
00135 stmp = d_size[i]; d_size[i] = d_size[DIM-1-i]; d_size[DIM-1-i] = stmp;
00136 }
00137 }
00138
00152 public: const MultiDimArrayIndexRange &adjustDim
00153 ( int d
00154 , int first
00155 , int final
00156 ) {
00157 if ( d < 0 || d >= DIM ) {
00158 int i;
00159 for ( i=0; i<DIM; i++ ) {
00160 d_start[i] += first;
00161 d_size[i] += final - first;
00162 }
00163 }
00164 else {
00165 d_start[d] += first;
00166 d_size[d] += final - first;
00167 }
00168 return *this;
00169 }
00170
00172
00173
00174
00176
00179 friend ostream &operator<<( ostream &os, const MultiDimArrayIndexRange<DIM> &r ) {
00180 os << DIM;
00181 for ( int i=0; i<DIM; i++ )
00182 os << ' ' << r.d_start[i] << ' ' << r.d_size[i];
00183 return os;
00184 }
00188 friend istream &operator<<( istream &is, MultiDimArrayIndexRange<DIM> &r ) {
00189 int dim;
00190 is >> dim;
00191 assert(dim == DIM);
00192 for ( int i=0; i<DIM; i++ )
00193 is >> r.d_start[i] >> r.d_size[i];
00194 return is;
00195 }
00197
00198
00199
00201
00203 public: int beg( size_t i ) const {
00204 return d_start[i];
00205 }
00206
00208 public: int end( size_t i ) const {
00209 return d_start[i] + d_size[i];
00210 }
00211
00213 public: size_t size( size_t i ) const {
00214 return d_size[i];
00215 }
00216
00218
00219
00220
00222
00224 public: int offset ( int i0
00226 ) const {
00227 return (i0-d_start[0]);
00228 }
00229
00231 public: int offset ( int i0
00233 , int i1
00234 ) const {
00235 return (i1-d_start[1]) + d_size[1]*(i0-d_start[0]);
00236 }
00237
00239 public: int offset ( int i0
00241 , int i1
00242 , int i2
00243 ) const {
00244 return (i2-d_start[2]) + d_size[2]*( (i1-d_start[1]) + d_size[1]*(i0-d_start[0]) );
00245 }
00246
00248 public: int offset ( int i0
00250 , int i1
00251 , int i2
00252 , int i3
00253 ) const {
00254 return (i3-d_start[3]) + d_size[3]*( (i2-d_start[2]) + d_size[2]*( (i1-d_start[1]) + d_size[1]*(i0-d_start[0]) ) );
00255 }
00256
00258
00259
00260 };
00261
00262
00263
00264
00265
00266
00283 template < class TYPE, int DIM >
00284 class MultiDimArrayAccess {
00285
00287 private: TYPE *d_ptr;
00289 private: MultiDimArrayIndexRange<DIM> d_range;
00290
00306 public: MultiDimArrayAccess ( TYPE *p=((TYPE*)0)
00308 , const size_t *sz=((size_t*)0)
00309 , const int *st=((int*)0)
00310 , bool reverse=false
00311 )
00312 : d_ptr(p), d_range(sz,st,reverse) {
00313 }
00314
00334 public: MultiDimArrayAccess ( TYPE *p
00336 , const int *si
00337 , const int *sf
00338 , bool reverse=false
00339 )
00340 : d_ptr(p), d_range(si,sf,reverse) {
00341 }
00342
00348 public: MultiDimArrayAccess ( TYPE *p
00350 , const MultiDimArrayIndexRange<DIM> &r
00351 )
00352 : d_ptr(p), d_range(r) {
00353 }
00354
00360 public: MultiDimArrayAccess ( const MultiDimArrayAccess &r
00362 )
00363 : d_ptr(r.d_ptr), d_range(r.d_range) {
00364 }
00365
00371 public: operator bool() const {
00372 return ( d_ptr != (TYPE*)0 );
00373 }
00374
00380 public: operator TYPE*() const {
00381 return d_ptr;
00382 }
00383
00384
00385
00386
00390 public: void setPointer ( TYPE *p
00392 ) {
00393 d_ptr = p;
00394 }
00395
00401 public: const MultiDimArrayIndexRange<DIM> &adjustDim ( int d
00403 , int first
00404 , int final
00405 ) {
00406 d_range.adjustDim(d,first,final);
00407 return d_range;
00408 }
00409
00415 public: void reverseDim() {
00416 d_range.reverseDim();
00417 }
00418
00419
00420
00422
00423 public: const MultiDimArrayIndexRange<DIM> &range() { return d_range; };
00424 public: int beg(size_t i) const { return d_range.beg(i); }
00425 public: int end(size_t i) const { return d_range.end(i); }
00426 public: int size(size_t i) const { return d_range.size(i); }
00427
00429 public: TYPE &operator()
00430 ( int i0
00431 ) const {
00432 return *( d_ptr + d_range.offset(i0) );
00433 }
00434
00436 public: TYPE &operator()
00437 ( int i0
00438 , int i1
00439 ) const {
00440 return *( d_ptr + d_range.offset(i0,i1) );
00441 }
00442
00444 public: TYPE &operator()
00445 ( int i0
00446 , int i1
00447 , int i2
00448 ) const {
00449 return *( d_ptr + d_range.offset(i0,i1,i2) );
00450 }
00451
00453 public: TYPE &operator()
00454 ( int i0
00455 , int i1
00456 , int i2
00457 , int i3
00458 ) const {
00459 return *( d_ptr + d_range.offset(i0,i1,i2,i3) );
00460 }
00461
00463
00464 };
00465
00466
00467
00468
00469
00470
00471
00488 template < class TYPE, int DIM >
00489 class ConstMultiDimArrayAccess {
00490
00492 private: const TYPE *d_ptr;
00494 private: MultiDimArrayIndexRange<DIM> d_range;
00495
00511 public: ConstMultiDimArrayAccess ( const TYPE *p=((TYPE*)0)
00513 , const size_t *sz=((size_t*)0)
00514 , const int *st=((int*)0)
00515 , bool reverse=false
00516 )
00517 : d_ptr(p), d_range(sz,st,reverse) {
00518 }
00519
00539 public: ConstMultiDimArrayAccess ( const TYPE *p
00541 , const int *si
00542 , const int *sf
00543 , bool reverse=false
00544 )
00545 : d_ptr(p), d_range(si,sf,reverse) {
00546 }
00547
00553 public: ConstMultiDimArrayAccess ( const TYPE *p
00555 , const MultiDimArrayIndexRange<DIM> &r
00556 )
00557 : d_ptr(p), d_range(r) {
00558 }
00559
00565 public: ConstMultiDimArrayAccess ( const ConstMultiDimArrayAccess &r
00567 )
00568 : d_ptr(r.d_ptr), d_range(r.d_range) {
00569 }
00570
00576 public: operator bool() const {
00577 return ( d_ptr != (TYPE*)0 );
00578 }
00579
00585 public: operator const TYPE*() const {
00586 return d_ptr;
00587 }
00588
00595 public: ConstMultiDimArrayAccess ( const MultiDimArrayAccess<TYPE,DIM> &r
00597 )
00598 : d_ptr((TYPE*)0), d_range() {
00599 if ( r ) {
00600 d_ptr = r;
00601 int beg[DIM]; size_t size[DIM];
00602 for ( int i=0; i<DIM; ++i ) {
00603 beg[i] = r.beg(i);
00604 size[i] = r.size(i);
00605 }
00606 d_range.setSizeAndStart(size,beg);
00607 }
00608 }
00609
00610
00614 public: void setPointer ( const TYPE *p
00616 ) {
00617 d_ptr = p;
00618 }
00619
00625 public: const MultiDimArrayIndexRange<DIM> &adjustDim ( int d
00627 , int first
00628 , int final
00629 ) {
00630 d_range.adjustDim(d,first,final);
00631 return d_range;
00632 }
00633
00639 public: void reverseDim() {
00640 d_range.reverseDim();
00641 }
00642
00643
00644
00646
00647 public: const MultiDimArrayIndexRange<DIM> &range() { return d_range; };
00648 public: int beg(size_t i) const { return d_range.beg(i); }
00649 public: int end(size_t i) const { return d_range.end(i); }
00650 public: int size(size_t i) const { return d_range.size(i); }
00651
00653 public: const TYPE &operator()
00654 ( int i0
00655 ) const {
00656 return *( d_ptr + d_range.offset(i0) );
00657 }
00658
00660 public: const TYPE &operator()
00661 ( int i0
00662 , int i1
00663 ) const {
00664 return *( d_ptr + d_range.offset(i0,i1) );
00665 }
00666
00668 public: const TYPE &operator()
00669 ( int i0
00670 , int i1
00671 , int i2
00672 ) const {
00673 return *( d_ptr + d_range.offset(i0,i1,i2) );
00674 }
00675
00677 public: const TYPE &operator()
00678 ( int i0
00679 , int i1
00680 , int i2
00681 , int i3
00682 ) const {
00683 return *( d_ptr + d_range.offset(i0,i1,i2,i3) );
00684 }
00685
00687
00688 };
00689
00690
00691
00692
00693
00694 #endif // include_MultiDimArrayAccess_h