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