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