00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef CASA_ARRAYACCESSOR_H
00030 #define CASA_ARRAYACCESSOR_H
00031
00032
00033 #include <casacore/casa/aips.h>
00034 #include <casacore/casa/Arrays/Array.h>
00035
00036 namespace casacore {
00037
00038
00039 template <class T> class ArrayBaseAccessor;
00040
00041 template <class T, class U> class ArrayAccessor;
00042
00043
00044
00045 namespace {
00046
00047 template <uInt AX> struct Axis {
00048 enum {
00049
00050 N=AX
00051 };
00052 };
00053
00054 struct AxisN {
00055
00056 explicit AxisN(const uInt n) : N(n) {}
00057
00058 uInt N;
00059 };
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069 template <class T> class ArrayBaseAccessor {
00070 protected:
00071
00072
00073
00074 ArrayBaseAccessor() : arrayPtr_p(0), axis_p(0), ptr_p(0),
00075 step_p(0), begin_p(0), end_p(0) {;}
00076
00077
00078 explicit ArrayBaseAccessor(const Array<T> &arr) :
00079 arrayPtr_p(&arr), axis_p(0), ptr_p(const_cast<T*>(arrayPtr_p->data())),
00080 step_p(0), begin_p(0), end_p(0) {;}
00081 ArrayBaseAccessor(const Array<T> &arr, const uInt ax) :
00082 arrayPtr_p(&arr), axis_p(ax), ptr_p(const_cast<T*>(arrayPtr_p->data())),
00083 step_p(0), begin_p(0), end_p(0) {;}
00084
00085
00086
00087 ArrayBaseAccessor(const ArrayBaseAccessor<T> &other) :
00088 arrayPtr_p(other.arrayPtr_p), axis_p(other.axis_p), ptr_p(other.ptr_p),
00089 step_p(other.step_p), begin_p(other.begin_p), end_p(other.end_p) {;}
00090 ArrayBaseAccessor(const ArrayBaseAccessor<T> &other, const uInt ax) :
00091 arrayPtr_p(other.arrayPtr_p), axis_p(ax), ptr_p(other.ptr_p),
00092 step_p(other.step_p), begin_p(other.begin_p), end_p(other.end_p) {;}
00093
00094
00095
00096
00097 ~ArrayBaseAccessor() {;}
00098
00099
00100
00101 ArrayBaseAccessor &operator=(const ArrayBaseAccessor<T> &other) {
00102 if (&other != this) {
00103 arrayPtr_p = other.arrayPtr_p; ptr_p = other.ptr_p;
00104 }; return *this; }
00105
00106
00107 void init(const Array<T> &arr) { arrayPtr_p = &arr;
00108 ptr_p = const_cast<T*>(arrayPtr_p->data()); }
00109 void init(const Array<T> &arr, const uInt ax) { arrayPtr_p = &arr;
00110 axis_p = ax; ptr_p = const_cast<T*>(arrayPtr_p->data()); }
00111 void init(const uInt ax) { arrayPtr_p = 0; axis_p = ax; ptr_p = 0; }
00112
00113
00114 public:
00115
00116
00117
00118 void operator+=(const uInt ix) { ptr_p += ix*step_p; }
00119 void operator-=(const uInt ix) { ptr_p -= ix*step_p; }
00120 void operator++() { ptr_p += step_p; }
00121 void operator++(int) { ptr_p += step_p; }
00122 void operator--() { ptr_p -= step_p; }
00123 void operator--(int) { ptr_p -= step_p; }
00124
00125
00126
00127
00128 const T &operator*() const { return *ptr_p; }
00129 T &operator*() { return *ptr_p; }
00130 T *data() { return ptr_p; }
00131 const Array<T> &baseArray() { return *arrayPtr_p; }
00132 uInt step() { return step_p; }
00133
00134
00135
00136
00137 const T &operator[](const Int ix) const { return *(ptr_p + ix*step_p); };
00138 T &operator[](const Int ix) { return *(ptr_p + ix*step_p); }
00139
00140
00141
00142
00143 const T *end() { return end_p; }
00144 const T *end(const Int n) { return end_p + n*step_p; }
00145
00146
00147
00148
00149 const T *begin() { return begin_p; }
00150 const T *begin(const Int n) { return begin_p + n*step_p; }
00151
00152
00153
00154
00155 const T *rend() { return begin_p-step_p; }
00156 const T *rend(const Int n) { return begin_p + (n-1)*step_p; }
00157
00158
00159
00160
00161 const T *rbegin() { return end_p-step_p; }
00162 const T *rbegin(const Int n) { return end_p + (n-1)*step_p; }
00163
00164
00165 protected:
00166
00167
00168 const Array<T> *arrayPtr_p;
00169
00170 uInt axis_p;
00171
00172 T *ptr_p;
00173
00174 Int step_p;
00175
00176 const T *begin_p;
00177
00178 const T *end_p;
00179
00180 };
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 template <class T, uInt U> class ArrayAccessor<T, Axis<U> > :
00351 public ArrayBaseAccessor<T> {
00352 public:
00353
00354
00355
00356
00357 ArrayAccessor() : ArrayBaseAccessor<T>() {;}
00358
00359
00360
00361 explicit ArrayAccessor(const Array<T> &arr) :
00362 ArrayBaseAccessor<T>(arr) { initStep(); }
00363
00364
00365 ArrayAccessor(const ArrayAccessor<T, Axis<U> > &other) :
00366 ArrayBaseAccessor<T>(other) {;}
00367
00368
00369
00370
00371 template <uInt X>
00372 explicit ArrayAccessor(const ArrayAccessor<T, Axis<X> > &other) :
00373 ArrayBaseAccessor<T>(other) { initStep(); }
00374 explicit ArrayAccessor(const ArrayAccessor<T, AxisN > &other) :
00375 ArrayBaseAccessor<T>(other) { initStep(); }
00376
00377
00378
00379 ~ArrayAccessor() {;}
00380
00381
00382
00383
00384
00385 ArrayAccessor &operator=(const ArrayAccessor<T, Axis<U> > &other) {
00386 if (&other != this) {
00387 ArrayBaseAccessor<T>::operator=(other); this->step_p = other.step_p;
00388 this->begin_p = other.begin_p; this->end_p = other.end_p;
00389 }; return *this; }
00390
00391 template <uInt X>
00392 ArrayAccessor &operator=(const ArrayAccessor<T, Axis<X> > &other) {
00393 ArrayBaseAccessor<T>::operator=(other); initStep();
00394 return *this; }
00395
00396 ArrayAccessor &operator=(const ArrayAccessor<T, AxisN> &other) {
00397 ArrayBaseAccessor<T>::operator=(other); initStep(); return *this; }
00398
00399
00400
00401 void init(const Array<T> &arr) { ArrayBaseAccessor<T>::init(arr);
00402 initStep(); }
00403
00404
00405
00406 void reset() { this->ptr_p = const_cast<T *>(this->begin_p); }
00407 void reset(const T * p) { this->ptr_p = const_cast<T *>(p); initStep(); }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 template <class X>
00418 const T &next() const
00419 { return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]); }
00420 template <class X>
00421 T &next() { return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]); }
00422
00423
00424
00425
00426 template <class X>
00427 const T &prev() const
00428 { return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]); }
00429 template <class X>
00430 T &prev() { return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]); }
00431
00432
00433
00434
00435 const T &next(const AxisN ax) const
00436 { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
00437 T &next(const AxisN ax)
00438 { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
00439 const T &prev(const AxisN ax) const
00440 { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
00441 T &prev(const AxisN ax)
00442 { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
00443
00444
00445
00446
00447
00448
00449 template <class X>
00450 const T &index(const Int ix) const
00451 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[X::N]); }
00452 template <class X>
00453 T &index(const Int ix)
00454 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[X::N]); }
00455 const T &index(const Int ix, const AxisN ax) const
00456 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[ax.N]); }
00457 T &index(const Int ix, const AxisN ax)
00458 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[ax.N]); }
00459
00460
00461
00462
00463
00464
00465 Bool operator==(const ArrayAccessor<T, Axis<U> > &other) const {
00466 return this->ptr_p == other.ptr_p; }
00467 Bool operator!=(const ArrayAccessor<T, Axis<U> > &other) const {
00468 return this->ptr_p != other.ptr_p; }
00469 Bool operator==(const T *other) const { return this->ptr_p == other; }
00470 Bool operator!=(const T *other) const { return this->ptr_p != other; }
00471
00472
00473 private:
00474
00475 Int initOff(Int x, uInt ax) {
00476 uInt st = this->arrayPtr_p->steps()[ax];
00477 return ((st) ? (ax == Axis<U>::N ? x/st : initOff(x%st, ax-1)) : 0); }
00478
00479 void initStep() {
00480 this->step_p = this->arrayPtr_p->steps()[Axis<U>::N];
00481 this->begin_p = this->end_p = this->ptr_p
00482 - initOff(this->ptr_p - this->arrayPtr_p->data(),
00483 this->arrayPtr_p->ndim()-1)*this->step_p;
00484 this->end_p += this->arrayPtr_p->shape()[Axis<U>::N]*this->step_p; }
00485
00486 };
00487
00488 #define ArrayAccessor_RT ArrayAccessor
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 template <class T> class ArrayAccessor_RT<T, AxisN> :
00504 public ArrayBaseAccessor<T> {
00505 public:
00506
00507
00508 explicit ArrayAccessor_RT(const AxisN ax=AxisN(0)) :
00509 ArrayBaseAccessor<T>() { this->axis_p = ax.N; }
00510 explicit ArrayAccessor_RT(Array<T> &arr, const AxisN ax=AxisN(0)) :
00511 ArrayBaseAccessor<T>(arr, ax.N) { initStep(); }
00512 ArrayAccessor_RT(ArrayAccessor_RT<T, AxisN> &other) :
00513 ArrayBaseAccessor<T>(other) {;}
00514 explicit ArrayAccessor_RT(ArrayAccessor_RT<T, AxisN> &other,
00515 const AxisN ax) :
00516 ArrayBaseAccessor<T>(other, ax.N) { initStep(); }
00517 template <uInt X>
00518 explicit ArrayAccessor_RT(ArrayAccessor_RT<T, Axis<X> > &other,
00519 const AxisN ax=AxisN(0)) :
00520 ArrayBaseAccessor<T>(other, ax.N) { initStep(); }
00521 ArrayAccessor_RT &operator=(const ArrayAccessor_RT<T, AxisN> &other) {
00522 if (&other != this) {
00523 ArrayBaseAccessor<T>::operator=(other);
00524 initStep();
00525 }; return *this; }
00526 template <uInt X>
00527 ArrayAccessor_RT &operator=(const ArrayAccessor_RT<T, Axis<X> > &other) {
00528 ArrayBaseAccessor<T>::operator=(other);
00529 initStep(); return *this; }
00530
00531
00532
00533 ~ArrayAccessor_RT() {;}
00534
00535
00536
00537
00538 void init(const Array<T> &arr, const AxisN ax)
00539 { ArrayBaseAccessor<T>::init(arr, ax.N); initStep(); }
00540 void init(const AxisN ax)
00541 { ArrayBaseAccessor<T>::init(ax.N); }
00542
00543
00544
00545
00546 void reset() { this->ptr_p = const_cast<T *>(this->begin_p); }
00547 void reset(const T *p) { this->ptr_p = const_cast<T *>(p); initStep(); }
00548
00549
00550
00551
00552
00553
00554 template <class X>
00555 const T &next() const
00556 { return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]); }
00557 template <class X>
00558 T &next() { return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]); }
00559 template <class X>
00560 const T &prev() const
00561 { return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]); }
00562 template <class X>
00563 T &prev() { return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]); }
00564 const T &next(const AxisN ax) const
00565 { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
00566 T &next(const AxisN ax)
00567 { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
00568 const T &prev(const AxisN ax) const
00569 { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
00570 T &prev(const AxisN ax)
00571 { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
00572 template <class X>
00573 const T &index(const Int ix) const
00574 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[X::N]); }
00575 template <class X>
00576 T &index(const Int ix)
00577 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[X::N]); }
00578 const T &index(const Int ix, const AxisN(ax)) const
00579 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[ax.N]); }
00580 T &index(const Int ix, const AxisN(ax))
00581 { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[ax.N]); }
00582
00583
00584
00585
00586 Bool operator==(const ArrayAccessor_RT<T, AxisN> &other) const {
00587 return this->ptr_p == other.ptr_p; }
00588 Bool operator!=(const ArrayAccessor_RT<T, AxisN> &other) const {
00589 return this->ptr_p != other.ptr_p; }
00590 Bool operator==(const T *other) const { return this->ptr_p == other; }
00591 Bool operator!=(const T *other) const { return this->ptr_p != other; }
00592
00593
00594 private:
00595
00596 Int initOff(Int x, uInt ax) {
00597 uInt st = this->arrayPtr_p->steps()[ax];
00598 return ((st) ? (ax == this->axis_p ? x/st : initOff(x%st, ax-1)) : 0); }
00599
00600 void initStep() {
00601 this->step_p = this->arrayPtr_p->steps()[this->axis_p];
00602 this->begin_p = this->end_p = this->ptr_p
00603 - initOff(this->ptr_p - this->arrayPtr_p->data(),
00604 this->arrayPtr_p->ndim()-1)*this->step_p;
00605 this->end_p += this->arrayPtr_p->shape()[this->axis_p]*this->step_p; }
00606
00607 };
00608
00609 #undef ArrayAccessor_RT
00610
00611 }
00612 #endif