casacore
Loading...
Searching...
No Matches
ArrayAccessor.h
Go to the documentation of this file.
1// # ArrayAccessor.h: Fast 1D accessor/iterator for nD array classes
2// # Copyright (C) 2002,2004
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_ARRAYACCESSOR_2_H
27#define CASA_ARRAYACCESSOR_2_H
28
29// # Includes
30#include "Array.h"
31
32namespace casacore { // #Begin casa namespace
33
34// # Hide simple Axis classes names from outside module
35
36namespace {
37// <summary> Class to enumerate compile-time axis numeration </summary>
38template <size_t AX>
39struct Axis {
40 enum {
41 // Specify the constant axis
42 N = AX
43 };
44};
45// <summary>Class to specify run-time axis values</summary>
46struct AxisN {
47 // Construct the run-time axis number
48 explicit AxisN(const size_t n) : N(n) {}
49 // Axis number
50 size_t N;
51};
52} // namespace
53
54// <summary> Axis independent base for the ArrayAccessor classes </summary>
55// <use visibility=local>
56// <synopsis>
57// The ArrayBaseAccessor class implements the axis independent parts of the
58// ArrayAccessor class. It can only be used from the ArrayAccessor class.
59// </synopsis>
60
61template <class T>
63 protected:
64 // # Constructors
65 // <group>
66 // Default constructor (for use in e.g. containers)
67 ArrayBaseAccessor() : arrayPtr_p(0), axis_p(0), ptr_p(0), step_p(0), begin_p(0), end_p(0) { ; }
68 // Construct from an Array
69 // <group>
70 explicit ArrayBaseAccessor(const Array<T> &arr)
71 : arrayPtr_p(&arr),
72 axis_p(0),
73 ptr_p(const_cast<T *>(arrayPtr_p->data())),
74 step_p(0),
75 begin_p(0),
76 end_p(0) {
77 ;
78 }
79 ArrayBaseAccessor(const Array<T> &arr, const size_t ax)
80 : arrayPtr_p(&arr),
81 axis_p(ax),
82 ptr_p(const_cast<T *>(arrayPtr_p->data())),
83 step_p(0),
84 begin_p(0),
85 end_p(0) {
86 ;
87 }
88 // </group>
89 // Copy constructor (copy semantics)
90 // <group>
92 : arrayPtr_p(other.arrayPtr_p),
93 axis_p(other.axis_p),
94 ptr_p(other.ptr_p),
95 step_p(other.step_p),
96 begin_p(other.begin_p),
97 end_p(other.end_p) {
98 ;
99 }
100 ArrayBaseAccessor(const ArrayBaseAccessor<T> &other, const size_t ax)
101 : arrayPtr_p(other.arrayPtr_p),
102 axis_p(ax),
103 ptr_p(other.ptr_p),
104 step_p(other.step_p),
105 begin_p(other.begin_p),
106 end_p(other.end_p) {
107 ;
108 }
109 // </group>
110
111 // # Destructor
112 // Destructor
114 // </group>
115
116 // Assignment (copy semantics)
118 if (&other != this) {
119 arrayPtr_p = other.arrayPtr_p;
120 ptr_p = other.ptr_p;
121 };
122 return *this;
123 }
124 // (Re-)initialize from Array
125 // <group>
126 void init(const Array<T> &arr) {
127 arrayPtr_p = &arr;
128 ptr_p = const_cast<T *>(arrayPtr_p->data());
129 }
130 void init(const Array<T> &arr, const size_t ax) {
131 arrayPtr_p = &arr;
132 axis_p = ax;
133 ptr_p = const_cast<T *>(arrayPtr_p->data());
134 }
135 void init(const size_t ax) {
136 arrayPtr_p = 0;
137 axis_p = ax;
138 ptr_p = 0;
139 }
140 // </group>
141
142 public:
143 // # Operators
144 // Iterator-like operations.
145 // <group>
146 void operator+=(const size_t ix) { ptr_p += ix * step_p; }
147 void operator-=(const size_t ix) { ptr_p -= ix * step_p; }
148 void operator++() { ptr_p += step_p; }
149 void operator++(int) { ptr_p += step_p; }
150 void operator--() { ptr_p -= step_p; }
151 void operator--(int) { ptr_p -= step_p; }
152 // </group>
153
154 // Dereferencing.
155 // <group>
156 const T &operator*() const { return *ptr_p; }
157 T &operator*() { return *ptr_p; }
158 T *data() { return ptr_p; }
159 const Array<T> &baseArray() { return *arrayPtr_p; }
160 size_t step() { return step_p; }
161 // </group>
162
163 // Index along current axis
164 // <group>
165 const T &operator[](const int ix) const { return *(ptr_p + ix * step_p); };
166 T &operator[](const int ix) { return *(ptr_p + ix * step_p); }
167 // </group>
168
169 // End of index on line
170 // <group>
171 const T *end() { return end_p; }
172 const T *end(const int n) { return end_p + n * step_p; }
173 // </group>
174
175 // Start of index on line
176 // <group>
177 const T *begin() { return begin_p; }
178 const T *begin(const int n) { return begin_p + n * step_p; }
179 // </group>
180
181 // End when reverse indexing
182 // <group>
183 const T *rend() { return begin_p - step_p; }
184 const T *rend(const int n) { return begin_p + (n - 1) * step_p; }
185 // </group>
186
187 // Begin when reverse indexing
188 // <group>
189 const T *rbegin() { return end_p - step_p; }
190 const T *rbegin(const int n) { return end_p + (n - 1) * step_p; }
191 // </group>
192
193 protected:
194 // # Data
195 // The pointer to belonging array
197 // Current run-time axis
198 size_t axis_p;
199 // Current access pointer
201 // The increment to go from one point along an axis, to the next.
203 // The start element of array
204 const T *begin_p;
205 // The one element beyond last on line
206 const T *end_p;
207};
208
209// <summary> Fast 1D accessor/iterator for nD array classes </summary>
210// <use visibility=export>
211// <reviewed reviewer="Ger van Diepen" date="2002/12/01" tests="tArrayAccessor"
212// demos="dArrayAccessor">
213// </reviewed>
214// <prerequisite>
215// <li> Array indexing and access methods
216// (<linkto class=Array>Array</linkto>)
217// </prerequisite>
218//
219// <etymology>
220// Array and access, rather than Iterator, which would suggest more
221// standard-like interfaces
222// </etymology>
223//
224// <synopsis>
225// Accessing a large multi-dimensional array by varying the indices of the
226// array can be a slow process. Timing indications are that for a cube
227// indexing with 3 indices was about seven times slower than using a
228// standard 1D C-like index into an array of basic int types.
229// Improvements have made this less, partly due to some pre-calculation
230// necessary for this class, but can still be a factor of more than 3
231// slower. There are a variety of ways to access elements
232// <src>cube(i,j,k)</src>:
233// <ul>
234// <li> Complete random access in all dimensions will need the
235// use of the indexing: <src>cube(i,j,k);</src> or
236// <src>cube(IPosition(3))</src> as described in the
237// <linkto class=Array>Array</linkto> and
238// <linkto class=Cube>Cube</linkto> classes
239// <li> Ordered access of all (or most) elements in an Array
240// (in memory order) can be best achieved by the use of Array's
241// <linkto class="Array#STL-iterator">STLIterator</linkto> classes.
242// This is the fastest way for non-contiguous arrays, and only slightly
243// slower than the use of <src>getStorage</src> for contiguous arrays.
244// <li> Ordered access along memory order can also be achieved by the use
245// of the
246// <linkto class="Array:getStorage(bool&)">
247// <src>getStorage()</src></linkto> method.
248// For contiguous arrays this could be slightly faster than the use of
249// the <src>STLIterator</src> (about 10% faster), but slower for
250// non-contiguous arrays. In addition it needs additional memory
251// resources, which will lead to extra overhead. The general use of
252// getStorage is discouraged with the introduction of the STLIterator.
253// It should only be used when an interface to routines in
254// other languages is needed (like Fortran), or when a large Array is
255// known to be contiguous, and the data have to be referenced many times.
256// <li> Access along one or more axes of a (large) multi-dimensional array
257// is best achieved using the ArrayAccessor class. Its total
258// access time is about 2 times faster than indexing (for cubes,
259// more for more indices),
260// <li> Special iteration (like in chunks) are catered for by the
261// <linkto class=ArrayIterator>ArrayIterator</linkto>,
262// <linkto class=MatrixIterator>MatrixIterator</linkto>,
263// <linkto class=VectorIterator>VectorIterator</linkto> classes.
264// </ul>
265// The ArrayAccessor class is an iterator like pointer to the data
266// in the array. It is a 1-dimensional accessor. It is created with either
267// a constant (at compile time) axis indicator, or with a run-time
268// axis selector. ArrayAccessor constructor accepts a <src>const Array<></src>.
269// However, the underlying Array class can be modified at this moment. In
270// future a ConstArrayAccessor class is foreseen.
271// <srcblock>
272// Matrix<double> mat(1000,500); // A 1000*500 matrix
273// // Fill Matrix ...
274// // Loop over index 1, than index 0:
275// for (ArrayAccessor<double, Axis<1> > i(mat); i != i.end(); ++i) {
276// for (ArrayAccessor<double, Axis<0> > j(i); j |= j.end(); ++j) {
277// // Actions on *j (which points to mat(j,i)) or j[n]
278// // (which points to mat(j+n,i))
279// }}
280// </srcblock>
281// For run-time indices it would look like:
282// <srcblock>
283// Matrix<double> mat(1000,500); // A 1000*500 matrix
284// // Fill Matrix ...
285// // Loop over index 1, than index 0:
286// for (ArrayAccessor<double, AxisN> i(mat, AxisN(1));
287// i != i.end(); ++i) {
288// for (ArrayAccessor<double, AxisN> j(i,AxisN(0)); j |= j.end(); ++j) {
289// // Actions on *j (which points to mat(j,i)) or j[n]
290// // (which points to mat(j+n,i))
291// }}
292// </srcblock>
293// Compile-time and run-time axes can be mixed in constructors and assignments.
294//
295// <note role=tip> Like in all comparable situations, memory allocation
296// within a loop can slow down processes. For that reason the example above
297// can be better written (about 25% faster) as:
298// <srcblock>
299// Matrix<double> mat(1000,500); // A 1000*500 matrix
300// ArrayAccessor<double, Axis<0> > j; // accessor pre-allocated
301// // Fill Matrix ...
302// // Loop over index 1, than index 0:
303// for (ArrayAccessor<double, Axis<1> > i(mat); i != i.end(); ++i) {
304// for (j=i; j |= j.end(); ++j) {
305// // Actions on *j (which points to mat(j,i)) or j[n]
306// // (which points to mat(j+n,i))
307// }}
308// </srcblock>
309// </note>
310// <note role=tip> The underlying Array classes are structured with the
311// first index varying fastest. This means that in general (due to caching and
312// swapping) operations are fastest when <src>Axis<0> ></src> is in the
313// innermost loop (if possible of course).
314// </note>
315// The demonstrator and test programs have more examples.
316//
317// The accessors can be dereferenced by the dereference operator (<src>*</src>)
318// and by the index operator (<src>[int]</src>), which can handle negative
319// values.
320// Points around the accessor in any axis direction can be addressed
321// along any axis by the templated methods <src>next()</src>,
322// <src>prev()</src> and <src>index(int)</src>. Either run-time or
323// compile-time axes can be used (see example).
324//
325// An accessor can be re-initialized with the init() function. It can also
326// be reset() to any pointer value. Mthods <src>end()</src>,
327// <src>begin()</src>, <src>rbegin()</src> and <src>rend()</src> are available
328// for loop control (like in the STL iterators). In addition each of these
329// can have an optional integer argument, specifying an offset (in points
330// along the current axis).
331//
332// Operations <src>++ -- += -=</src> are available.
333//
334// This class is available for <src>Axis<n></src> and <src>AxisN</src>
335// specializations only.
336// </synopsis>
337//
338// <example>
339// <srcblock>
340// // get a cube and fill it
341// Cube<double> cub(5,2,4);
342// indgen(cub);
343// // Loop over axes 2-0 and use index() over axis 1
344// for (ArrayAccessor<double, Axis<2> > i(cub); i != i.end() ; ++i) {
345// for (ArrayAccessor<double, Axis<0> > j(i);
346// j != j.end(); ++j) {
347// // show result
348// cout << *j << ", " << j.index<Axis<1> >(1) << endl;
349// };
350// };
351// </srcblock>
352// See the demonstrator program in
353// <src>aips/implement/Arrays/test/dArrayAccessor.cc</src> and the
354// test program <src>tArrayAccessor</src> for more examples.
355// </example>
356//
357// <motivation>
358// To speed up especially interpolation code
359// </motivation>
360//
361// <templating arg=T>
362// <li> Any valid Array templating argument
363// </templating>
364// <templating arg=U>
365// <li> A class <src>Axis<n></src>
366// <li> Class AxisN
367// </templating>
368//
369// <thrown>
370// <li> Exceptions created in the Array class
371// <li> Addressing errors
372// </thrown>
373//
374// <todo asof="2002/11/06">
375// <li> add a ConstArrayAccessor class
376// </todo>
377//
378// \see ArrayAccessor<T, Axis<U> >
379// \see ArrayAccessor<T, AxisN >
380// # Next one suffices as declaration: only (part) specialisations allowed
381template <class T, class U>
383
384// Specialization for compile-time axes. \see ArrayAccessor
385template <class T, size_t U>
386class ArrayAccessor<T, Axis<U>> : public ArrayBaseAccessor<T> {
387 public:
388 // Constructors
389 // <group>
390 // Default ctor. Note only available to accommodate containers of
391 // ArrayAccessors. Use <src>init()</src> to initialize.
393 // Construct an accessor from specified Array along the selected axis.
394 // The accessor will point to the first element along the axis (i.e.
395 // at (0,0,...)).
396 explicit ArrayAccessor(const Array<T> &arr) : ArrayBaseAccessor<T>(arr) { initStep(); }
397 // Construct from an ArrayAccessor along same axis. The accessor will point
398 // at the same element as the originator.
399 ArrayAccessor(const ArrayAccessor<T, Axis<U>> &other) : ArrayBaseAccessor<T>(other) { ; }
400 // Construct from accessor along another (or run-time) axis.
401 // The accessor will point to the same element (but will be oriented
402 // along another axis).
403 // <group>
404 template <size_t X>
405 explicit ArrayAccessor(const ArrayAccessor<T, Axis<X>> &other) : ArrayBaseAccessor<T>(other) {
406 initStep();
407 }
408 explicit ArrayAccessor(const ArrayAccessor<T, AxisN> &other) : ArrayBaseAccessor<T>(other) {
409 initStep();
410 }
411 // </group>
412
413 // Destructor
415 // </group>
416
417 // Assignment (copy semantics)
418 // <group>
419 // Assign from other compile-time accessor along same axis
420 ArrayAccessor &operator=(const ArrayAccessor<T, Axis<U>> &other) {
421 if (&other != this) {
423 this->step_p = other.step_p;
424 this->begin_p = other.begin_p;
425 this->end_p = other.end_p;
426 };
427 return *this;
428 }
429 // Assign from other compile-time accessor along another axis
430 template <size_t X>
431 ArrayAccessor &operator=(const ArrayAccessor<T, Axis<X>> &other) {
433 initStep();
434 return *this;
435 }
436 // Assign from run-time accessor along any axis
439 initStep();
440 return *this;
441 }
442 // </group>
443
444 // (Re-)initialization to start of array (i.e. element (0,0,0,...))
445 void init(const Array<T> &arr) {
447 initStep();
448 }
449
450 // Reset to start of dimension or to specified pointer
451 // <group>
452 void reset() { this->ptr_p = const_cast<T *>(this->begin_p); }
453 void reset(const T *p) {
454 this->ptr_p = const_cast<T *>(p);
455 initStep();
456 }
457 // </group>
458
459 // Indexing operations along another axis than the one of the current
460 // object. See for the indexing and iterator operations along the
461 // object's axis <linkto class=ArrayBaseAccessor>ArrayBaseAccessor</linkto>
462 // <group>
463 // Get the value 'next' along the specified axis (e.g. with
464 // <src>a.next<Axis<2> >()</src>)
465 // <group>
466 template <class X>
467 const T &next() const {
468 return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]);
469 }
470 template <class X>
471 T &next() {
472 return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]);
473 }
474 // </group>
475 // Get the value 'previous' along the specified axis (e.g. with
476 // <src>a.prev<Axis<2> >()</src>)
477 // <group>
478 template <class X>
479 const T &prev() const {
480 return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]);
481 }
482 template <class X>
483 T &prev() {
484 return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]);
485 }
486 // </group>
487 // Get the next or previous along the specified run-time axis. E.g.
488 // <src>a.prev(AxisN(2))</src>.
489 // <group>
490 const T &next(const AxisN ax) const { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
491 T &next(const AxisN ax) { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
492 const T &prev(const AxisN ax) const { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
493 T &prev(const AxisN ax) { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
494 // </group>
495 // Give the value indexed with respect to the current accessor value
496 // along the axis specified as either a compile-time or a run-time
497 // axis. E.g. <src>a.index<Axis<3> >(5)</src> or
498 // <src>a.index(5, AxisN(3))</src>.
499 // <group>
500 template <class X>
501 const T &index(const int ix) const {
502 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[X::N]);
503 }
504 template <class X>
505 T &index(const int ix) {
506 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[X::N]);
507 }
508 const T &index(const int ix, const AxisN ax) const {
509 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[ax.N]);
510 }
511 T &index(const int ix, const AxisN ax) {
512 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[ax.N]);
513 }
514 // </group>
515 // </group>
516
517 // Comparison. The comparisons are done for the accessor pointer
518 // value. They can be used to control loops.
519 // <group>
520 bool operator==(const ArrayAccessor<T, Axis<U>> &other) const {
521 return this->ptr_p == other.ptr_p;
522 }
523 bool operator!=(const ArrayAccessor<T, Axis<U>> &other) const {
524 return this->ptr_p != other.ptr_p;
525 }
526 bool operator==(const T *other) const { return this->ptr_p == other; }
527 bool operator!=(const T *other) const { return this->ptr_p != other; }
528 // </group>
529
530 private:
531 // Get proper offset
532 int initOff(int x, size_t ax) {
533 size_t st = this->arrayPtr_p->steps()[ax];
534 return ((st) ? (ax == Axis<U>::N ? x / st : initOff(x % st, ax - 1)) : 0);
535 }
536 // Initialize some internal values
537 void initStep() {
538 this->step_p = this->arrayPtr_p->steps()[Axis<U>::N];
539 this->begin_p = this->end_p = this->ptr_p - initOff(this->ptr_p - this->arrayPtr_p->data(),
540 this->arrayPtr_p->ndim() - 1) *
541 this->step_p;
542 this->end_p += this->arrayPtr_p->shape()[Axis<U>::N] * this->step_p;
543 }
544};
545
546// <summary> Specialization for run-time axes </summary>
547// <use visibility=export>
548// <synopsis>
549// This class is a specialization for run-time axis selection within the
550// array accessor. The axis is specified in the constructors and in the
551// special indexing operators (<src>prev, next, index</src>) with
552// a parameter <src>AxisN(n)</src> in stead of a template parameter
553// <src><Axis<n> ></src>.
554// \see ArrayAccessor
555// </synopsis>
556//
557template <class T>
558class ArrayAccessor<T, AxisN> : public ArrayBaseAccessor<T> {
559 public:
560 // Constructors
561 // <group>
562 explicit ArrayAccessor(const AxisN ax = AxisN(0)) : ArrayBaseAccessor<T>() {
563 this->axis_p = ax.N;
564 }
565 explicit ArrayAccessor(Array<T> &arr, const AxisN ax = AxisN(0))
566 : ArrayBaseAccessor<T>(arr, ax.N) {
567 initStep();
568 }
570 explicit ArrayAccessor(ArrayAccessor<T, AxisN> &other, const AxisN ax)
571 : ArrayBaseAccessor<T>(other, ax.N) {
572 initStep();
573 }
574 template <size_t X>
575 explicit ArrayAccessor(ArrayAccessor<T, Axis<X>> &other, const AxisN ax = AxisN(0))
576 : ArrayBaseAccessor<T>(other, ax.N) {
577 initStep();
578 }
580 if (&other != this) {
582 initStep();
583 };
584 return *this;
585 }
586 template <size_t X>
587 ArrayAccessor &operator=(const ArrayAccessor<T, Axis<X>> &other) {
589 initStep();
590 return *this;
591 }
592 // </group>
593
594 // Destructor
596
597 // (Re-)initialization to start of array (i.e. element (0,0,0,...)) or
598 // re-initialize to an axis.
599 // <group>
600 void init(const Array<T> &arr, const AxisN ax) {
602 initStep();
603 }
604 void init(const AxisN ax) { ArrayBaseAccessor<T>::init(ax.N); }
605 // </group>
606
607 // Reset to start of dimension or to specified pointer
608 // <group>
609 void reset() { this->ptr_p = const_cast<T *>(this->begin_p); }
610 void reset(const T *p) {
611 this->ptr_p = const_cast<T *>(p);
612 initStep();
613 }
614 // </group>
615
616 // Indexing operations along another axis than the one of the current
617 // object. See for the indexing and iterator operations along the
618 // object's axis <linkto class=ArrayBaseAccessor>ArrayBaseAccessor</linkto>
619 // <group>
620 template <class X>
621 const T &next() const {
622 return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]);
623 }
624 template <class X>
625 T &next() {
626 return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]);
627 }
628 template <class X>
629 const T &prev() const {
630 return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]);
631 }
632 template <class X>
633 T &prev() {
634 return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]);
635 }
636 const T &next(const AxisN ax) const { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
637 T &next(const AxisN ax) { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
638 const T &prev(const AxisN ax) const { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
639 T &prev(const AxisN ax) { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
640 template <class X>
641 const T &index(const int ix) const {
642 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[X::N]);
643 }
644 template <class X>
645 T &index(const int ix) {
646 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[X::N]);
647 }
648 const T &index(const int ix, const AxisN(ax)) const {
649 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[ax.N]);
650 }
651 T &index(const int ix, const AxisN(ax)) {
652 return *(this->ptr_p + ix * this->arrayPtr_p->steps()[ax.N]);
653 }
654 // </group>
655
656 // Comparisons
657 // <group>
658 bool operator==(const ArrayAccessor<T, AxisN> &other) const { return this->ptr_p == other.ptr_p; }
659 bool operator!=(const ArrayAccessor<T, AxisN> &other) const { return this->ptr_p != other.ptr_p; }
660 bool operator==(const T *other) const { return this->ptr_p == other; }
661 bool operator!=(const T *other) const { return this->ptr_p != other; }
662 // </group>
663
664 private:
665 // Get proper offset
666 int initOff(int x, size_t ax) {
667 size_t st = this->arrayPtr_p->steps()[ax];
668 return ((st) ? (ax == this->axis_p ? x / st : initOff(x % st, ax - 1)) : 0);
669 }
670 // Initialize some internal values
671 void initStep() {
672 this->step_p = this->arrayPtr_p->steps()[this->axis_p];
673 this->begin_p = this->end_p = this->ptr_p - initOff(this->ptr_p - this->arrayPtr_p->data(),
674 this->arrayPtr_p->ndim() - 1) *
675 this->step_p;
676 this->end_p += this->arrayPtr_p->shape()[this->axis_p] * this->step_p;
677 }
678};
679
680} // namespace casacore
681#endif
void init(const Array< T > &arr, const AxisN ax)
(Re-)initialization to start of array (i.e.
const T & next() const
Indexing operations along another axis than the one of the current object.
ArrayAccessor(Array< T > &arr, const AxisN ax=AxisN(0))
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< X > > &other)
ArrayAccessor(const AxisN ax=AxisN(0))
Constructors.
const T & index(const int ix) const
bool operator==(const T *other) const
bool operator==(const ArrayAccessor< T, AxisN > &other) const
Comparisons.
const T & index(const int ix, const AxisN(ax)) const
ArrayAccessor(ArrayAccessor< T, AxisN > &other)
const T & next(const AxisN ax) const
void reset()
Reset to start of dimension or to specified pointer.
int initOff(int x, size_t ax)
Get proper offset.
void initStep()
Initialize some internal values.
T & index(const int ix, const AxisN(ax))
const T & prev(const AxisN ax) const
ArrayAccessor(ArrayAccessor< T, AxisN > &other, const AxisN ax)
ArrayAccessor & operator=(const ArrayAccessor< T, AxisN > &other)
bool operator!=(const ArrayAccessor< T, AxisN > &other) const
ArrayAccessor(ArrayAccessor< T, Axis< X > > &other, const AxisN ax=AxisN(0))
bool operator!=(const T *other) const
bool operator==(const T *other) const
const T & prev() const
Get the value 'previous' along the specified axis (e.g.
T & index(const int ix, const AxisN ax)
ArrayAccessor & operator=(const ArrayAccessor< T, AxisN > &other)
Assign from run-time accessor along any axis.
bool operator!=(const ArrayAccessor< T, Axis< U > > &other) const
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< X > > &other)
Assign from other compile-time accessor along another axis.
ArrayAccessor(const ArrayAccessor< T, Axis< U > > &other)
Construct from an ArrayAccessor along same axis.
const T & next(const AxisN ax) const
Get the next or previous along the specified run-time axis.
const T & prev(const AxisN ax) const
void init(const Array< T > &arr)
(Re-)initialization to start of array (i.e.
ArrayAccessor(const ArrayAccessor< T, AxisN > &other)
ArrayAccessor(const Array< T > &arr)
Construct an accessor from specified Array along the selected axis.
void reset()
Reset to start of dimension or to specified pointer.
ArrayAccessor(const ArrayAccessor< T, Axis< X > > &other)
Construct from accessor along another (or run-time) axis.
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< U > > &other)
Assignment (copy semantics).
bool operator==(const ArrayAccessor< T, Axis< U > > &other) const
Comparison.
const T & index(const int ix, const AxisN ax) const
bool operator!=(const T *other) const
const T & next() const
Indexing operations along another axis than the one of the current object.
void initStep()
Initialize some internal values.
int initOff(int x, size_t ax)
Get proper offset.
const T & index(const int ix) const
Give the value indexed with respect to the current accessor value along the axis specified as either ...
Fast 1D accessor/iterator for nD array classes.
size_t axis_p
Current run-time axis.
void init(const size_t ax)
const T * rbegin(const int n)
ArrayBaseAccessor(const ArrayBaseAccessor< T > &other, const size_t ax)
const Array< T > * arrayPtr_p
The pointer to belonging array.
void init(const Array< T > &arr, const size_t ax)
const T * begin(const int n)
const T * end(const int n)
T & operator[](const int ix)
void operator-=(const size_t ix)
void operator+=(const size_t ix)
Iterator-like operations.
ArrayBaseAccessor()
Default constructor (for use in e.g.
ArrayBaseAccessor(const Array< T > &arr, const size_t ax)
const T & operator*() const
Dereferencing.
const T * rbegin()
Begin when reverse indexing.
const T * end()
End of index on line.
const T * begin_p
The start element of array.
const T * rend(const int n)
const T & operator[](const int ix) const
Index along current axis.
const T * end_p
The one element beyond last on line.
int step_p
The increment to go from one point along an axis, to the next.
const T * rend()
End when reverse indexing.
const Array< T > & baseArray()
ArrayBaseAccessor(const ArrayBaseAccessor< T > &other)
Copy constructor (copy semantics).
T * ptr_p
Current access pointer.
const T * begin()
Start of index on line.
ArrayBaseAccessor(const Array< T > &arr)
Construct from an Array.
void init(const Array< T > &arr)
(Re-)initialize from Array
ArrayBaseAccessor & operator=(const ArrayBaseAccessor< T > &other)
Assignment (copy semantics).
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28