casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
35 namespace casacore { //#Begin casa namespace
36 
37 //# Hide simple Axis classes names from outside module
38 
39 namespace {
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  };
54 }
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 
63 template <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
166  T *ptr_p;
167  // The increment to go from one point along an axis, to the next.
168  int step_p;
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
347 template <class T, class U> class ArrayAccessor;
348 
349 // Specialization for compile-time axes. \see ArrayAccessor
350 template <class T, size_t U> class ArrayAccessor<T, Axis<U> > :
351 public 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(); }
374  explicit ArrayAccessor(const ArrayAccessor<T, AxisN > &other) :
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 //
499 template <class T> class ArrayAccessor<T, AxisN> :
500 public 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)
537  { ArrayBaseAccessor<T>::init(ax.N); }
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
~ArrayBaseAccessor()
Destructor.
Definition: ArrayAccessor.h:91
bool operator!=(const ArrayAccessor< T, AxisN > &other) const
int step_p
The increment to go from one point along an axis, to the next.
void reset()
Reset to start of dimension or to specified pointer.
Fast 1D accessor/iterator for nD array classes.
bool operator==(const ArrayAccessor< T, Axis< U > > &other) const
Comparison.
ArrayBaseAccessor & operator=(const ArrayBaseAccessor< T > &other)
Assignment (copy semantics)
Definition: ArrayAccessor.h:95
void init(const Array< T > &arr)
(Re-)initialization to start of array (i.e.
const T & operator*() const
Dereferencing.
const T * rbegin()
Begin when reverse indexing.
void init(const Array< T > &arr)
(Re-)initialize from Array
ArrayAccessor(const ArrayAccessor< T, Axis< X > > &other)
Construct from accessor along another (or run-time) axis.
ArrayAccessor(Array< T > &arr, const AxisN ax=AxisN(0))
bool operator==(const ArrayAccessor< T, AxisN > &other) const
Comparisons.
bool operator!=(const T *other) const
const T & next() const
Indexing operations along another axis than the one of the current object.
ArrayAccessor(const ArrayAccessor< T, Axis< U > > &other)
Construct from an ArrayAccessor along same axis.
const T & prev(const AxisN ax) const
bool operator==(const T *other) const
const T * end(const int n)
const T * rend()
End when reverse indexing.
void operator+=(const size_t ix)
Iterator-like operations.
ArrayAccessor & operator=(const ArrayAccessor< T, AxisN > &other)
Assign from run-time accessor along any axis.
const T & index(const int ix) const
const T * end()
End of index on line.
ArrayAccessor(const AxisN ax=AxisN(0))
Constructors.
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< X > > &other)
Assign from other compile-time accessor along another axis.
const T * rend(const int n)
const T * end_p
The one element beyond last on line.
const Array< T > & baseArray()
void init(const Array< T > &arr, const AxisN ax)
(Re-)initialization to start of array (i.e.
ArrayBaseAccessor()
Default constructor (for use in e.g.
Definition: ArrayAccessor.h:68
bool operator!=(const T *other) const
ArrayAccessor(ArrayAccessor< T, Axis< X > > &other, const AxisN ax=AxisN(0))
const T & next() const
Indexing operations along another axis than the one of the current object.
ArrayAccessor(ArrayAccessor< T, AxisN > &other, const AxisN ax)
size_t N
Axis number.
Definition: ArrayAccessor.h:54
ArrayAccessor(ArrayAccessor< T, AxisN > &other)
ArrayAccessor(const ArrayAccessor< T, AxisN > &other)
bool operator==(const T *other) const
const T & prev(const AxisN ax) const
const T * begin()
Start of index on line.
ArrayAccessor(const Array< T > &arr)
Construct an accessor from specified Array along the selected axis.
size_t axis_p
Current run-time axis.
const T & next(const AxisN ax) const
Get the next or previous along the specified run-time axis.
int initOff(int x, size_t ax)
Get proper offset.
ArrayBaseAccessor(const Array< T > &arr)
Construct from an Array.
Definition: ArrayAccessor.h:72
Specialization for run-time axes.
void initStep()
Initialize some internal values.
void init(const Array< T > &arr, const size_t ax)
ArrayBaseAccessor(const Array< T > &arr, const size_t ax)
Definition: ArrayAccessor.h:75
void initStep()
Initialize some internal values.
const T * begin(const int n)
ArrayAccessor & operator=(const ArrayAccessor< T, AxisN > &other)
T * ptr_p
Current access pointer.
const T * begin_p
The start element of array.
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< U > > &other)
Assignment (copy semantics)
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< X > > &other)
T & operator[](const int ix)
bool operator!=(const ArrayAccessor< T, Axis< U > > &other) const
void init(const size_t ax)
const Array< T > * arrayPtr_p
The pointer to belonging array.
const T & index(const int ix, const AxisN(ax)) const
T & index(const int ix, const AxisN(ax))
ArrayBaseAccessor(const ArrayBaseAccessor< T > &other, const size_t ax)
Definition: ArrayAccessor.h:84
T & index(const int ix, const AxisN ax)
ArrayBaseAccessor(const ArrayBaseAccessor< T > &other)
Copy constructor (copy semantics)
Definition: ArrayAccessor.h:81
const T & prev() const
Get the value &#39;previous&#39; along the specified axis (e.g.
Axis independent base for the ArrayAccessor classes.
Definition: ArrayAccessor.h:63
const T & next(const AxisN ax) const
const T * rbegin(const int n)
const T & index(const int ix) const
Give the value indexed with respect to the current accessor value along the axis specified as either ...
T * data()
Get a pointer to the beginning of the array.
Definition: Array.h:604
const T & operator[](const int ix) const
Index along current axis.
T * ptr_p
Definition: PtrHolder.h:147
void reset()
Reset to start of dimension or to specified pointer.
void operator-=(const size_t ix)
int initOff(int x, size_t ax)
Get proper offset.
const T & index(const int ix, const AxisN ax) const