casa  5.7.0-16
 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_H
30 #define CASA_ARRAYACCESSOR_H
31 
32 //# Includes
33 #include <casacore/casa/aips.h>
35 
36 namespace casacore { //#Begin casa namespace
37 
38 //# Forward Declarations
39 template <class T> class ArrayBaseAccessor;
40 //# Next one suffices as declaration: only (part) specialisations allowed
41 template <class T, class U> class ArrayAccessor;
42 
43 //# Hide simple Axis classes names from outside module
44 
45 namespace {
46  // <summary> Class to enumerate compile-time axis numeration </summary>
47  template <uInt AX> struct Axis {
48  enum {
49  // Specify the constant axis
50  N=AX
51  };
52  };
53  // <summary>Class to specify run-time axis values</summary>
54  struct AxisN {
55  // Construct the run-time axis number
56  explicit AxisN(const uInt n) : N(n) {}
57  // Axis number
58  uInt N;
59  };
60 }
61 
62 // <summary> Axis independent base for the ArrayAccessor classes </summary>
63 // <use visibility=local>
64 // <synopsis>
65 // The ArrayBaseAccessor class implements the axis independent parts of the
66 // ArrayAccessor class. It can only be used from the ArrayAccessor class.
67 // </synopsis>
68 
69 template <class T> class ArrayBaseAccessor {
70  protected:
71  //# Constructors
72  // <group>
73  // Default constructor (for use in e.g. containers)
75  step_p(0), begin_p(0), end_p(0) {;}
76  // Construct from an Array
77  // <group>
78  explicit ArrayBaseAccessor(const Array<T> &arr) :
79  arrayPtr_p(&arr), axis_p(0), ptr_p(const_cast<T*>(arrayPtr_p->data())),
80  step_p(0), begin_p(0), end_p(0) {;}
81  ArrayBaseAccessor(const Array<T> &arr, const uInt ax) :
82  arrayPtr_p(&arr), axis_p(ax), ptr_p(const_cast<T*>(arrayPtr_p->data())),
83  step_p(0), begin_p(0), end_p(0) {;}
84  // </group>
85  // Copy constructor (copy semantics)
86  // <group>
88  arrayPtr_p(other.arrayPtr_p), axis_p(other.axis_p), ptr_p(other.ptr_p),
89  step_p(other.step_p), begin_p(other.begin_p), end_p(other.end_p) {;}
90  ArrayBaseAccessor(const ArrayBaseAccessor<T> &other, const uInt ax) :
91  arrayPtr_p(other.arrayPtr_p), axis_p(ax), ptr_p(other.ptr_p),
92  step_p(other.step_p), begin_p(other.begin_p), end_p(other.end_p) {;}
93  // </group>
94 
95  //# Destructor
96  // Destructor
98  // </group>
99 
100  // Assignment (copy semantics)
102  if (&other != this) {
103  arrayPtr_p = other.arrayPtr_p; ptr_p = other.ptr_p;
104  }; return *this; }
105  // (Re-)initialize from Array
106  // <group>
107  void init(const Array<T> &arr) { arrayPtr_p = &arr;
108  ptr_p = const_cast<T*>(arrayPtr_p->data()); }
109  void init(const Array<T> &arr, const uInt ax) { arrayPtr_p = &arr;
110  axis_p = ax; ptr_p = const_cast<T*>(arrayPtr_p->data()); }
111  void init(const uInt ax) { arrayPtr_p = 0; axis_p = ax; ptr_p = 0; }
112  // </group>
113 
114  public:
115  //# Operators
116  // Iterator-like operations.
117  // <group>
118  void operator+=(const uInt ix) { ptr_p += ix*step_p; }
119  void operator-=(const uInt ix) { ptr_p -= ix*step_p; }
120  void operator++() { ptr_p += step_p; }
121  void operator++(int) { ptr_p += step_p; }
122  void operator--() { ptr_p -= step_p; }
123  void operator--(int) { ptr_p -= step_p; }
124  // </group>
125 
126  // Dereferencing.
127  // <group>
128  const T &operator*() const { return *ptr_p; }
129  T &operator*() { return *ptr_p; }
130  T *data() { return ptr_p; }
131  const Array<T> &baseArray() { return *arrayPtr_p; }
132  uInt step() { return step_p; }
133  // </group>
134 
135  // Index along current axis
136  // <group>
137  const T &operator[](const Int ix) const { return *(ptr_p + ix*step_p); };
138  T &operator[](const Int ix) { return *(ptr_p + ix*step_p); }
139  // </group>
140 
141  // End of index on line
142  // <group>
143  const T *end() { return end_p; }
144  const T *end(const Int n) { return end_p + n*step_p; }
145  // </group>
146 
147  // Start of index on line
148  // <group>
149  const T *begin() { return begin_p; }
150  const T *begin(const Int n) { return begin_p + n*step_p; }
151  // </group>
152 
153  // End when reverse indexing
154  // <group>
155  const T *rend() { return begin_p-step_p; }
156  const T *rend(const Int n) { return begin_p + (n-1)*step_p; }
157  // </group>
158 
159  // Begin when reverse indexing
160  // <group>
161  const T *rbegin() { return end_p-step_p; }
162  const T *rbegin(const Int n) { return end_p + (n-1)*step_p; }
163  // </group>
164 
165  protected:
166  //# Data
167  // The pointer to belonging array
169  // Current run-time axis
171  // Current access pointer
172  T *ptr_p;
173  // The increment to go from one point along an axis, to the next.
175  // The start element of array
176  const T *begin_p;
177  // The one element beyond last on line
178  const T *end_p;
179 
180 };
181 
182 // <summary> Fast 1D accessor/iterator for nD array classes </summary>
183 // <use visibility=export>
184 // <reviewed reviewer="Ger van Diepen" date="2002/12/01" tests="tArrayAccessor" demos="dArrayAccessor">
185 // </reviewed>
186 // <prerequisite>
187 // <li> Array indexing and access methods
188 // (<linkto class=Array>Array</linkto>)
189 // </prerequisite>
190 //
191 // <etymology>
192 // Array and access, rather than Iterator, which would suggest more
193 // standard-like interfaces
194 // </etymology>
195 //
196 // <synopsis>
197 // Accessing a large multi-dimensional array by varying the indices of the
198 // array can be a slow process. Timing indications are that for a cube
199 // indexing with 3 indices was about seven times slower than using a
200 // standard 1D C-like index into an array of basic Int types.
201 // Improvements have made this less, partly due to some pre-calculation
202 // necessary for this class, but can still be a factor of more than 3
203 // slower. There are a variety of ways to access elements
204 // <src>cube(i,j,k)</src>:
205 // <ul>
206 // <li> Complete random access in all dimensions will need the
207 // use of the indexing: <src>cube(i,j,k);</src> or
208 // <src>cube(IPosition(3))</src> as described in the
209 // <linkto class=Array>Array</linkto> and
210 // <linkto class=Cube>Cube</linkto> classes
211 // <li> Ordered access of all (or most) elements in an Array
212 // (in memory order) can be best achieved by the use of Array's
213 // <linkto class="Array#STL-iterator">STLIterator</linkto> classes.
214 // This is the fastest way for non-contiguous arrays, and only slightly
215 // slower than the use of <src>getStorage</src> for contiguous arrays.
216 // <li> Ordered access along memory order can also be achieved by the use
217 // of the
218 // <linkto class="Array:getStorage(Bool&)">
219 // <src>getStorage()</src></linkto> method.
220 // For contiguous arrays this could be slightly faster than the use of
221 // the <src>STLIterator</src> (about 10% faster), but slower for
222 // non-contiguous arrays. In addition it needs additional memory
223 // resources, which will lead to extra overhead. The general use of
224 // getStorage is discouraged with the introduction of the STLIterator.
225 // It should only be used when an interface to routines in
226 // other languages is needed (like Fortran), or when a large Array is
227 // known to be contiguous, and the data have to be referenced many times.
228 // <li> Access along one or more axes of a (large) multi-dimensional array
229 // is best achieved using the ArrayAccessor class. Its total
230 // access time is about 2 times faster than indexing (for cubes,
231 // more for more indices),
232 // <li> Special iteration (like in chunks) are catered for by the
233 // <linkto class=ArrayIterator>ArrayIterator</linkto>,
234 // <linkto class=MatrixIterator>MatrixIterator</linkto>,
235 // <linkto class=VectorIterator>VectorIterator</linkto> classes.
236 // </ul>
237 // The ArrayAccessor class is an iterator like pointer to the data
238 // in the array. It is a 1-dimensional accessor. It is created with either
239 // a constant (at compile time) axis indicator, or with a run-time
240 // axis selector. ArrayAccessor constructor accepts a <src>const Array<></src>.
241 // However, the underlying Array class can be modified at this moment. In
242 // future a ConstArrayAccessor class is foreseen.
243 // <srcblock>
244 // Matrix<Double> mat(1000,500); // A 1000*500 matrix
245 // // Fill Matrix ...
246 // // Loop over index 1, than index 0:
247 // for (ArrayAccessor<Double, Axis<1> > i(mat); i != i.end(); ++i) {
248 // for (ArrayAccessor<Double, Axis<0> > j(i); j |= j.end(); ++j) {
249 // // Actions on *j (which points to mat(j,i)) or j[n]
250 // // (which points to mat(j+n,i))
251 // }}
252 // </srcblock>
253 // For run-time indices it would look like:
254 // <srcblock>
255 // Matrix<Double> mat(1000,500); // A 1000*500 matrix
256 // // Fill Matrix ...
257 // // Loop over index 1, than index 0:
258 // for (ArrayAccessor<Double, AxisN> i(mat, AxisN(1));
259 // i != i.end(); ++i) {
260 // for (ArrayAccessor<Double, AxisN> j(i,AxisN(0)); j |= j.end(); ++j) {
261 // // Actions on *j (which points to mat(j,i)) or j[n]
262 // // (which points to mat(j+n,i))
263 // }}
264 // </srcblock>
265 // Compile-time and run-time axes can be mixed in constructors and assignments.
266 //
267 // <note role=tip> Like in all comparable situations, memory allocation
268 // within a loop can slow down processes. For that reason the example above
269 // can be better written (about 25% faster) as:
270 // <srcblock>
271 // Matrix<Double> mat(1000,500); // A 1000*500 matrix
272 // ArrayAccessor<Double, Axis<0> > j; // accessor pre-allocated
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 (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 // </note>
282 // <note role=tip> The underlying Array classes are structured with the
283 // first index varying fastest. This means that in general (due to caching and
284 // swapping) operations are fastest when <src>Axis<0> ></src> is in the
285 // innermost loop (if possible of course).
286 // </note>
287 // The demonstrator and test programs have more examples.
288 //
289 // The accessors can be dereferenced by the dereference operator (<src>*</src>)
290 // and by the index operator (<src>[Int]</src>), which can handle negative
291 // values.
292 // Points around the accessor in any axis direction can be addressed
293 // along any axis by the templated methods <src>next()</src>,
294 // <src>prev()</src> and <src>index(Int)</src>. Either run-time or
295 // compile-time axes can be used (see example).
296 //
297 // An accessor can be re-initialized with the init() function. It can also
298 // be reset() to any pointer value. Mthods <src>end()</src>,
299 // <src>begin()</src>, <src>rbegin()</src> and <src>rend()</src> are available
300 // for loop control (like in the STL iterators). In addition each of these
301 // can have an optional integer argument, specifying an offset (in points
302 // along the current axis).
303 //
304 // Operations <src>++ -- += -=</src> are available.
305 //
306 // This class is available for <src>Axis<n></src> and <src>AxisN</src>
307 // specializations only.
308 // </synopsis>
309 //
310 // <example>
311 // <srcblock>
312 // // get a cube and fill it
313 // Cube<Double> cub(5,2,4);
314 // indgen(cub);
315 // // Loop over axes 2-0 and use index() over axis 1
316 // for (ArrayAccessor<Double, Axis<2> > i(cub); i != i.end() ; ++i) {
317 // for (ArrayAccessor<Double, Axis<0> > j(i);
318 // j != j.end(); ++j) {
319 // // show result
320 // cout << *j << ", " << j.index<Axis<1> >(1) << endl;
321 // };
322 // };
323 // </srcblock>
324 // See the demonstrator program in
325 // <src>aips/implement/Arrays/test/dArrayAccessor.cc</src> and the
326 // test program <src>tArrayAccessor</src> for more examples.
327 // </example>
328 //
329 // <motivation>
330 // To speed up especially interpolation code
331 // </motivation>
332 //
333 // <templating arg=T>
334 // <li> Any valid Array templating argument
335 // </templating>
336 // <templating arg=U>
337 // <li> A class <src>Axis<n></src>
338 // <li> Class AxisN
339 // </templating>
340 //
341 // <thrown>
342 // <li> Exceptions created in the Array class
343 // <li> Addressing errors
344 // </thrown>
345 //
346 // <todo asof="2002/11/06">
347 // <li> add a ConstArrayAccessor class
348 // </todo>
349 //
350 template <class T, uInt 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 <uInt 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 <uInt 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, uInt ax) {
476  uInt 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 #define ArrayAccessor_RT ArrayAccessor
489 
490 // <summary> Specialization for run-time axes </summary>
491 // <use visibility=export>
492 // <synopsis>
493 // This class is a specialization for run-time axis selection within the
494 // array accessor. The axis is specified in the constructors and in the
495 // special indexing operators (<src>prev, next, index</src>) with
496 // a parameter <src>AxisN(n)</src> in stead of a template parameter
497 // <src><Axis<n> ></src>.
498 //
499 // Note that the name of the class is <src>ArrayAccessor</src>. The special
500 // name is only to bypass cxx2html problems with duplicate class names.
501 // </synopsis>
502 //
503 template <class T> class ArrayAccessor_RT<T, AxisN> :
504 public ArrayBaseAccessor<T> {
505  public:
506  // Constructors
507  // <group>
508  explicit ArrayAccessor_RT(const AxisN ax=AxisN(0)) :
509  ArrayBaseAccessor<T>() { this->axis_p = ax.N; }
510  explicit ArrayAccessor_RT(Array<T> &arr, const AxisN ax=AxisN(0)) :
511  ArrayBaseAccessor<T>(arr, ax.N) { initStep(); }
513  ArrayBaseAccessor<T>(other) {;}
515  const AxisN ax) :
516  ArrayBaseAccessor<T>(other, ax.N) { initStep(); }
517  template <uInt X>
518  explicit ArrayAccessor_RT(ArrayAccessor_RT<T, Axis<X> > &other,
519  const AxisN ax=AxisN(0)) :
520  ArrayBaseAccessor<T>(other, ax.N) { initStep(); }
522  if (&other != this) {
524  initStep();
525  }; return *this; }
526  template <uInt X>
527  ArrayAccessor_RT &operator=(const ArrayAccessor_RT<T, Axis<X> > &other) {
529  initStep(); return *this; }
530  // </group>
531 
532  // Destructor
534 
535  // (Re-)initialization to start of array (i.e. element (0,0,0,...)) or
536  // re-initialize to an axis.
537  // <group>
538  void init(const Array<T> &arr, const AxisN ax)
539  { ArrayBaseAccessor<T>::init(arr, ax.N); initStep(); }
540  void init(const AxisN ax)
541  { ArrayBaseAccessor<T>::init(ax.N); }
542  // </group>
543 
544  // Reset to start of dimension or to specified pointer
545  // <group>
546  void reset() { this->ptr_p = const_cast<T *>(this->begin_p); }
547  void reset(const T *p) { this->ptr_p = const_cast<T *>(p); initStep(); }
548  // </group>
549 
550  // Indexing operations along another axis than the one of the current
551  // object. See for the indexing and iterator operations along the
552  // object's axis <linkto class=ArrayBaseAccessor>ArrayBaseAccessor</linkto>
553  // <group>
554  template <class X>
555  const T &next() const
556  { return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]); }
557  template <class X>
558  T &next() { return *(this->ptr_p + this->arrayPtr_p->steps()[X::N]); }
559  template <class X>
560  const T &prev() const
561  { return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]); }
562  template <class X>
563  T &prev() { return *(this->ptr_p - this->arrayPtr_p->steps()[X::N]); }
564  const T &next(const AxisN ax) const
565  { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
566  T &next(const AxisN ax)
567  { return *(this->ptr_p + this->arrayPtr_p->steps()[ax.N]); }
568  const T &prev(const AxisN ax) const
569  { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
570  T &prev(const AxisN ax)
571  { return *(this->ptr_p - this->arrayPtr_p->steps()[ax.N]); }
572  template <class X>
573  const T &index(const Int ix) const
574  { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[X::N]); }
575  template <class X>
576  T &index(const Int ix)
577  { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[X::N]); }
578  const T &index(const Int ix, const AxisN(ax)) const
579  { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[ax.N]); }
580  T &index(const Int ix, const AxisN(ax))
581  { return *(this->ptr_p + ix*this->arrayPtr_p->steps()[ax.N]); }
582  // </group>
583 
584  // Comparisons
585  // <group>
587  return this->ptr_p == other.ptr_p; }
589  return this->ptr_p != other.ptr_p; }
590  Bool operator==(const T *other) const { return this->ptr_p == other; }
591  Bool operator!=(const T *other) const { return this->ptr_p != other; }
592  // </group>
593 
594  private:
595  // Get proper offset
596  Int initOff(Int x, uInt ax) {
597  uInt st = this->arrayPtr_p->steps()[ax];
598  return ((st) ? (ax == this->axis_p ? x/st : initOff(x%st, ax-1)) : 0); }
599  // Initialize some internal values
600  void initStep() {
601  this->step_p = this->arrayPtr_p->steps()[this->axis_p];
602  this->begin_p = this->end_p = this->ptr_p
603  - initOff(this->ptr_p - this->arrayPtr_p->data(),
604  this->arrayPtr_p->ndim()-1)*this->step_p;
605  this->end_p += this->arrayPtr_p->shape()[this->axis_p]*this->step_p; }
606 
607 };
608 
609 #undef ArrayAccessor_RT
610 
611 } //#End casa namespace
612 #endif
Int step_p
The increment to go from one point along an axis, to the next.
~ArrayBaseAccessor()
Destructor.
Definition: ArrayAccessor.h:97
void reset()
Reset to start of dimension or to specified pointer.
void init(const uInt ax)
int Int
Definition: aipstype.h:50
const T & index(const Int ix, const AxisN ax) const
void reset()
Reset to start of dimension or to specified pointer.
ArrayBaseAccessor & operator=(const ArrayBaseAccessor< T > &other)
Assignment (copy semantics)
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.
Bool operator!=(const T *other) const
Bool operator!=(const ArrayAccessor_RT< T, AxisN > &other) const
const T & next() const
Indexing operations along another axis than the one of the current object.
ArrayAccessor_RT(ArrayAccessor_RT< T, AxisN > &other)
ArrayAccessor(const ArrayAccessor< T, Axis< U > > &other)
Construct from an ArrayAccessor along same axis.
ArrayAccessor_RT & operator=(const ArrayAccessor_RT< T, Axis< X > > &other)
const T * rend()
End when reverse indexing.
const T * begin(const Int n)
ArrayAccessor & operator=(const ArrayAccessor< T, AxisN > &other)
Assign from run-time accessor along any axis.
const T * end()
End of index on line.
Bool operator!=(const T *other) const
void operator+=(const uInt ix)
Iterator-like operations.
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< X > > &other)
Assign from other compile-time accessor along another axis.
const T * end_p
The one element beyond last on line.
const T & prev(const AxisN ax) const
ArrayBaseAccessor(const ArrayBaseAccessor< T > &other, const uInt ax)
Definition: ArrayAccessor.h:90
const Array< T > & baseArray()
const T & next(const AxisN ax) const
const T & operator[](const Int ix) const
Index along current axis.
ArrayBaseAccessor()
Default constructor (for use in e.g.
Definition: ArrayAccessor.h:74
ArrayAccessor(const ArrayAccessor< T, AxisN > &other)
const T & index(const Int ix) const
Give the value indexed with respect to the current accessor value along the axis specified as either ...
const T & prev(const AxisN ax) const
uInt axis_p
Current run-time axis.
const T * begin()
Start of index on line.
ArrayAccessor(const Array< T > &arr)
Construct an accessor from specified Array along the selected axis.
const T * rbegin(const Int n)
const T & index(const Int ix) const
const T & next(const AxisN ax) const
Get the next or previous along the specified run-time axis.
ArrayBaseAccessor(const Array< T > &arr)
Construct from an Array.
Definition: ArrayAccessor.h:78
ArrayAccessor_RT(ArrayAccessor_RT< T, Axis< X > > &other, const AxisN ax=AxisN(0))
void initStep()
Initialize some internal values.
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
void initStep()
Initialize some internal values.
Bool operator!=(const ArrayAccessor< T, Axis< U > > &other) const
#define ArrayAccessor_RT
Bool operator==(const T *other) const
template &lt;class T, class U&gt; class vector;
Definition: MSFlagger.h:37
const T & index(const Int ix, const AxisN(ax)) const
void operator-=(const uInt ix)
const T & next() const
Indexing operations along another axis than the one of the current object.
T * ptr_p
Current access pointer.
uInt N
Axis number.
Definition: ArrayAccessor.h:60
Bool operator==(const T *other) const
ArrayAccessor_RT(Array< T > &arr, const AxisN ax=AxisN(0))
const T * begin_p
The start element of array.
Bool operator==(const ArrayAccessor_RT< T, AxisN > &other) const
Comparisons.
ArrayAccessor & operator=(const ArrayAccessor< T, Axis< U > > &other)
Assignment (copy semantics)
ArrayAccessor_RT(ArrayAccessor_RT< T, AxisN > &other, const AxisN ax)
Int initOff(Int x, uInt ax)
Get proper offset.
Specialization for run-time axes.
const T * rend(const Int n)
Bool operator==(const ArrayAccessor< T, Axis< U > > &other) const
Comparison.
void init(const Array< T > &arr, const AxisN ax)
(Re-)initialization to start of array (i.e.
T & index(const Int ix, const AxisN(ax))
ArrayAccessor_RT(const AxisN ax=AxisN(0))
Constructors.
T & operator[](const Int ix)
const Array< T > * arrayPtr_p
The pointer to belonging array.
ArrayBaseAccessor(const Array< T > &arr, const uInt ax)
Definition: ArrayAccessor.h:81
Int initOff(Int x, uInt ax)
Get proper offset.
ArrayBaseAccessor(const ArrayBaseAccessor< T > &other)
Copy constructor (copy semantics)
Definition: ArrayAccessor.h:87
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:39
void init(const Array< T > &arr, const uInt ax)
ArrayAccessor_RT & operator=(const ArrayAccessor_RT< T, AxisN > &other)
T * ptr_p
Definition: PtrHolder.h:147
unsigned int uInt
Definition: aipstype.h:51
T & index(const Int ix, const AxisN ax)
const T * end(const Int n)
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42