casacore
Array.h
Go to the documentation of this file.
1 //# Array.h: A templated N-D Array class with zero origin
2 //# Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2015
3 //# Associated Universities, Inc. Washington DC, USA,
4 //# National Astronomical Observatory of Japan
5 //# 2-21-1, Osawa, Mitaka, Tokyo, 181-8588, Japan.
6 //#
7 //# This library is free software; you can redistribute it and/or modify it
8 //# under the terms of the GNU Library General Public License as published by
9 //# the Free Software Foundation; either version 2 of the License, or (at your
10 //# option) any later version.
11 //#
12 //# This library is distributed in the hope that it will be useful, but WITHOUT
13 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 //# License for more details.
16 //#
17 //# You should have received a copy of the GNU Library General Public License
18 //# along with this library; if not, write to the Free Software Foundation,
19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20 //#
21 //# Correspondence concerning AIPS++ should be addressed as follows:
22 //# Internet email: aips2-request@nrao.edu.
23 //# Postal address: AIPS++ Project Office
24 //# National Radio Astronomy Observatory
25 //# 520 Edgemont Road
26 //# Charlottesville, VA 22903-2475 USA
27 //#
28 //# $Id: Array.h 21545 2015-01-22 19:36:35Z gervandiepen $
29 
30 #ifndef CASA_ARRAY_H
31 #define CASA_ARRAY_H
32 
33 //# Includes
34 #include <casacore/casa/aips.h>
35 #include <casacore/casa/Arrays/ArrayBase.h>
36 #include <casacore/casa/Containers/Block.h>
37 #include <casacore/casa/Utilities/CountedPtr.h>
38 #include <casacore/casa/Arrays/MaskLogiArrFwd.h>
39 #include <casacore/casa/Arrays/IPosition.h>
40 #include <casacore/casa/ostream.h>
41 #include <iterator>
42 #if defined(WHATEVER_VECTOR_FORWARD_DEC)
44 #else
45 #include <casacore/casa/stdvector.h>
46 #endif
47 
48 namespace casacore { //#Begin casa namespace
49 //# Forward Declarations
50 class AipsIO;
51 class Slice;
52 class Slicer;
53 template<class T> class Matrix;
54 template<class T> class ArrayIterator;
55 template<class T> class MaskedArray;
56 template<class Domain, class Range> class Functional;
57 //template <class T, class U> class vector;
58 
59 
60 // <summary> A templated N-D Array class with zero origin </summary>
61 
62 // Array<T> is a templated, N-dimensional, Array class. The origin is zero,
63 // but by default indices are zero-based. This Array class is the
64 // base class for specialized Vector<T>, Matrix<T>, and Cube<T> classes.
65 //
66 // Indexing into the array, and positions in general, are given with IPosition
67 // (essentially a vector of integers) objects. That is, an N-dimensional
68 // array requires a length-N IPosition to define a position within the array.
69 // Unlike C, indexing is done with (), not []. Also, the storage order
70 // is the same as in FORTRAN, i.e. memory varies most rapidly with the first
71 // index.
72 // <srcblock>
73 // // axisLengths = [1,2,3,4,5]
74 // IPosition axisLengths(5, 1, 2, 3, 4, 5);
75 // Array<Int> ai(axisLengths); // ai is a 5 dimensional array of
76 // // integers; indices are 0-based
77 // // => ai.nelements() == 120
78 // Array<Int> ai2(axisLengths); // The first element is at index 0
79 // IPosition zero(5); zero = 0; // [0,0,0,0,0]
80 // //...
81 // </srcblock>
82 // Indexing into an N-dimensional array is relatively expensive. Normally
83 // you will index into a Vector, Matrix, or Cube. These may be obtained from
84 // an N-dimensional array by creating a reference, or by using an
85 // ArrayIterator. The "shape" of the array is an IPosition which gives the
86 // length of each axis.
87 //
88 // An Array may be standalone, or it may refer to another array, or to
89 // part of another array (by refer we mean that if you change a pixel in
90 // the current array, a pixel in the referred to array also changes, i.e.
91 // they share underlying storage).
92 // <note role=warning>
93 // One way one array can reference another is through the copy
94 // constructor. While this might be what you want, you should
95 // probably use the reference() member function to make it explicit.
96 // The copy constructor is used when arguments are passed by value;
97 // normally functions should not pass Arrays by value, rather they
98 // should pass a reference or a const reference. On the positive
99 // side, returning an array from a function is efficient since no
100 // copying need be done.
101 // </note>
102 //
103 // Aside from the explicit reference() member function, a user will
104 // most commonly encounter an array which references another array
105 // when he takes an array slice (or section). A slice is a sub-region of
106 // an array (which might also have a stride: every nth row, every mth column,
107 // ...).
108 // <srcblock>
109 // IPosition lengths(3,10,20,30);
110 // Array<Int> ai(lengths); // A 10x20x30 cube
111 // Cube<Int> ci;
112 // //...
113 // ci.reference(ai1); // ci and ai now reference the same
114 // // storage
115 // ci(0,0,0) = 123; // Can use Cube indexing
116 // ci.xyPlane(2) = 0; // and other member functions
117 // IPosition zero(3,0,0,0);
118 // assert(ai(zero) == 123); // True because ai, ci are references
119 // //...
120 // Array<Int> subArray;
121 // IPosition blc(3,0,0,0), trc(3,5,5,5);
122 // subArray.reference(ai(blc, trc));
123 // subArray = 10; // All of subArray, which is the
124 // // subcube from 0,0,0 to 5,5,5 in
125 // // ai, has the value 10.
126 // </srcblock>
127 // While the last example has an array slice referenced explicitly by another
128 // array variable, normally the user will often only use the slice as
129 // a temporary in an expresion, for example:
130 // <srcblock>
131 // Array<Complex> array;
132 // IPosition blc, trc, offset;
133 // //...
134 // // Copy from one region of the array into another
135 // array(blc, trc) = array(blc+offset, trc+offset);
136 // </srcblock>
137 //
138 // The Array classes are intended to operate on relatively large
139 // amounts of data. While they haven't been extensively tuned yet,
140 // they are relatively efficient in terms of speed. Presently they
141 // are not space efficient -- the overhead is about 15 words. While
142 // this will be improved (probably to about 1/2 that), these array
143 // classes are not appropriate for very large numbers of very small
144 // arrays. The Block<T> class may be what you want in this circumstance.
145 //
146 // Element by element mathematical and logical operations are available
147 // for arrays (defined in aips/ArrayMath.h and aips/ArrayLogical.h).
148 // Because arithmetic and logical functions are split out, it is possible
149 // to create an Array<T> (and hence Vector<T> etc) for any type T that has
150 // a default constructor, assignment operator, and copy constructor. In
151 // particular, Array<String> works.
152 //
153 // If compiled with the preprocessor symbol AIPS_DEBUG symbol, array
154 // consistency ("invariants") will be checked in most member
155 // functions, and indexing will be range-checked. This should not be
156 // defined for production runs.
157 //
158 // <note role=tip>
159 // Most of the data members and functions which are "protected" should
160 // likely become "private".
161 // </note>
162 //
163 // <todo asof="1999/12/30">
164 // <li> Integrate into the Lattice hierarchy
165 // <li> Factor out the common functions (shape etc) into a type-independent
166 // base class.
167 // </todo>
168 
169 template<class T> class Array : public ArrayBase
170 {
171 public:
172 
173  // Result has dimensionality of zero, and nelements is zero.
174  // Storage will be allocated by <src>DefaultAllocator<T></src>.
175  Array();
176 
177  // Create an array of the given shape, i.e. after construction
178  // array.ndim() == shape.nelements() and array.shape() == shape.
179  // The origin of the Array is zero.
180  // Storage is allocated by <src>DefaultAllocator<T></src>.
181  // Without initPolicy parameter, the initialization of elements depends on type <src>T</src>.
182  // When <src>T</src> is a fundamental type like <src>int</src>, elements are NOT initialized.
183  // When <src>T</src> is a class type like <src>casa::Complex</src> or <src>std::string</src>, elements are initialized.
184  // This inconsistent behavior confuses programmers and make it hard to write efficient and generic code using template.
185  // Especially when <src>T</src> is of type <src>Complex</src> or <src>DComplex</src> and it is unnecessary to initialize,
186  // provide initPolicy with value <src>NO_INIT</src> to skip the initialization.
187  // Therefore, it is strongly recommended to explicitly provide initPolicy parameter,
188  explicit Array(const IPosition &shape);
189 
190  // Create an array of the given shape, i.e. after construction
191  // array.ndim() == shape.nelements() and array.shape() == shape.
192  // The origin of the Array is zero.
193  // Storage is allocated by <src>DefaultAllocator<T></src>.
194  // When initPolicy parameter is <src>INIT</src>, elements are initialized with the default value of <src>T()</src>.
195  // When initPolicy parameter is <src>NO_INIT</src>, elements are NOT initialized and programmers are responsible to
196  // initialize elements before they are referred, especially when <src>T</src> is such type like <src>std::string</src>.
197  // <srcblock>
198  // IPosition shape(1, 10);
199  // Array<Int> ai(shape, ArrayInitPolicy::NO_INIT);
200  // size_t nread = fread(ai.data(), sizeof(Int), ai.nelements(), fp);
201  // </srcblock>
202  Array(const IPosition &shape, ArrayInitPolicy initPolicy);
203 
204  // Create an array of the given shape and initialize it with the
205  // initial value.
206  // Storage is allocated by <src>DefaultAllocator<T></src>.
207  Array(const IPosition &shape, const T &initialValue);
208 
209  // After construction, this and other reference the same storage.
210  Array(const Array<T> &other);
211 
212  // Create an Array of a given shape from a pointer.
213  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>DefaultAllocator<T></src>.
214  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by <src>NewDelAllocator<T></src>.
215  // It is strongly recommended to supply an appropriate <src>allocator</src> argument explicitly
216  // whenever <src>policy</src> == <src>TAKE_OVER</src>
217  // to let <src>Array</src> to know how to release the <src>storage</src>.
218  Array(const IPosition &shape, T *storage, StorageInitPolicy policy = COPY);
219 
220  // Create an Array of a given shape from a pointer.
221  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by the specified allocator.
222  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by the specified allocator.
223  // Otherwise, <src>allocator</src> is ignored.
224  // It is strongly recommended to allocate and initialize <src>storage</src> with <src>DefaultAllocator<T></src>
225  // rather than new[] or <src>NewDelAllocator<T></src> because new[] can't decouple allocation and initialization.
226  // <src>DefaultAllocator<T>::type</src> is a subclass of std::allocator. You can allocate <src>storage</src> via
227  // the allocator as below.
228  // <srcblock>
229  // FILE *fp = ...;
230  // typedef DefaultAllocator<Int> Alloc;
231  // Alloc::type alloc;
232  // IPosition shape(1, 10);
233  // Int *ptr = alloc.allocate(shape.product());
234  // size_t nread = fread(ptr, sizeof(Int), shape.product(), fp);
235  // Array<Int> ai(shape, ptr, TAKE_OVER, Alloc::value);
236  // </srcblock>
237  Array(const IPosition &shape, T *storage, StorageInitPolicy policy, AbstractAllocator<T> const &allocator);
238 
239  // Create an Array of a given shape from a pointer. Because the pointer
240  // is const, a copy is always made.
241  // The copy is allocated by <src>DefaultAllocator<T></src>.
242  Array(const IPosition &shape, const T *storage);
243 
244  // Frees up storage only if this array was the last reference to it.
245  virtual ~Array();
246 
247  // Make an empty array of the same template type.
248  virtual CountedPtr<ArrayBase> makeArray() const;
249 
250  // Assign the other array to this array.
251  // If the shapes mismatch, this array is resized.
252  // <group>
253  virtual void assign (const Array<T>& other);
254  virtual void assignBase (const ArrayBase& other, Bool checkType=True);
255  // </group>
256 
257  // Set every element of the array to "value." Also could use the
258  // assignment operator which assigns an array from a scalar.
259  void set(const T &value);
260 
261  // Apply the function to every element of the array. This modifies
262  // the array in place.
263  // <group>
264  // This version takes a function which takes a T and returns a T.
265  void apply(T (*function)(T));
266  // This version takes a function which takes a const T reference and
267  // returns a T.
268  void apply(T (*function)(const T &));
269  // This version applies a functional.
270  void apply(const Functional<T,T> &function);
271  // </group>
272 
273  // After invocation, this array and other reference the same storage. That
274  // is, modifying an element through one will show up in the other. The
275  // arrays appear to be identical; they have the same shape.
276  // <br>Please note that this function makes it possible to reference a
277  // const Array, thus effectively it makes a const Array non-const.
278  // Although this may seem undesirable at first sight, it is necessary to
279  // be able to make references to temporary Array objects, in particular to
280  // Array slices. Otherwise one first needs to use the copy constructor.
281  //# The const has been introduced on 2005-Mar-31 because of the hassle
282  //# involved in calling the copy ctor before reference.
283  virtual void reference(const Array<T> &other);
284 
285  // Copy the values in other to this. If the array on the left hand
286  // side has no elements, then it is resized to be the same size as
287  // as the array on the right hand side. Otherwise, the arrays must
288  // conform (same shapes).
289  // <srcblock>
290  // IPosition shape(2,10,10); // some shape
291  // Array<Double> ad(shape);
292  // //...
293  // Array<Double> ad2; // N.B. ad2.nelements() == 0
294  // ad2 = ad; // ad2 resizes, then elements
295  // // are copied.
296  // shape = 20;
297  // Array<Double> ad3(shape);
298  // ad3 = ad; // Error: arrays do not conform
299  // </srcblock>
300  // Note that the assign function can be used to assign a
301  // non-conforming array.
302  virtual Array<T> &operator=(const Array<T> &other);
303 
304  // Set every element of this array to "value". In other words, a scalar
305  // behaves as if it were a constant conformant array.
306  Array<T> &operator=(const T &value);
307 
308  // Copy to this those values in marray whose corresponding elements
309  // in marray's mask are True.
310  //
311  // <thrown>
312  // <li> ArrayConformanceError
313  // </thrown>
314  //
315  Array<T> &operator= (const MaskedArray<T> &marray);
316 
317  // This makes a copy of the array and returns it. This can be
318  // useful for, e.g. making working copies of function arguments
319  // that you can write into.
320  // <srcblock>
321  // void someFunction(const Array<Int> &arg)
322  // {
323  // Array<Int> tmp(arg.copy());
324  // // ...
325  // }
326  // </srcblock>
327  // Note that since the copy constructor makes a reference, if we just
328  // created used to copy constructor, modifying "tmp" would also
329  // modify "arg". Clearly another alternative would simply be:
330  // <srcblock>
331  // void someFunction(const Array<Int> &arg)
332  // {
333  // Array<Int> tmp;
334  // tmp = arg;
335  // // ...
336  // }
337  // </srcblock>
338  // which likely would be simpler to understand. (Should copy()
339  // be deprecated and removed?)
340  //
341  Array<T> copy(ArrayInitPolicy policy = ArrayInitPolicy::NO_INIT) const; // Make a copy of this
342 
343  // This function copies the matching part of from array to this array.
344  // The matching part is the part with the minimum size for each axis.
345  // E.g. if this array has shape [4,5,6] and from array has shape [7,3],
346  // the matching part has shape [4,3].
347  // <br>Note it is used by the resize function if
348  // <src>copyValues==True</src>.
349  void copyMatchingPart (const Array<T> &from);
350 
351  // This ensures that this array does not reference any other storage.
352  // <note role=tip>
353  // When a section is taken of an array with non-unity strides,
354  // storage can be wasted if the array, which originally contained
355  // all the data, goes away. unique() also reclaims storage. This
356  // is an optimization users don't normally need to understand.
357  //
358  // <srcblock>
359  // IPosition shape(...), blc(...), trc(...), inc(...);
360  // Array<Float> af(shape);
361  // inc = 2; // or anything > 1
362  // Array<Float> aSection.reference(af(blc, trc, inc));
363  // af.reference(anotherArray);
364  // // aSection now references storage that has a stride
365  // // in it, but nothing else is. Storage is wasted.
366  // aSection.unique();
367  // </srcblock>
368  // </note>
369  void unique();
370 
371  // Create an STL vector from an Array. The created vector is a linear
372  // representation of the Array memory. See
373  // <linkto class=Vector>Vector</linkto> for
374  // details of the operation and its reverse (i.e. creating a
375  // <src>Vector</src> from a <src>vector</src>), and for details of
376  // definition and instantiation.
377  // <group>
378  template <class U>
379  void tovector(vector<T, U> &out) const;
380 
381  vector<T> tovector() const;
382  // </group>
383 
384  // It is occasionally useful to have an array which access the same
385  // storage appear to have a different shape. For example,
386  // turning an N-dimensional array into a Vector.
387  // <br>When the array data are contiguous, the array can be reshaped
388  // to any form as long as the number of elements stays the same.
389  // When not contiguous, it is only possible to remove or add axes
390  // with length 1.
391  // <srcblock>
392  // IPosition squareShape(2,5,5);
393  // Array<Float> square(squareShape);
394  // IPosition lineShape(1,25);
395  // Vector<Float> line(square.reform(lineShape));
396  // // "square"'s storage may now be accessed through Vector "line"
397  // </srcblock>
398  Array<T> reform(const IPosition &shape) const;
399 
400  // Having an array that can be reused without requiring reallocation can
401  // be useful for large arrays. The method reformOrResize permits this
402  // usage.
403  //
404  // The reformOrResize method first attempts to reform the matrix so that
405  // it reuses the existing storage for an array with a new shape. If the
406  // existing storage will not hold the new shape, then the method will
407  // resize the array when resizeIfNeeded is true; if a resize is needed and
408  // resizeIfNeeded is false, then an ArrayConformanceError is thrown. The
409  // copyDataIfNeeded parameter is passed to resize if resizing is performed.
410  // resizePercentage is the percent of additional storage to be addeed when
411  // a resize is performed; this allows the allocations to be amortized when
412  // the caller expects to be calling this method again in the future. The
413  // parameter is used to define an allocation shape which is larger than
414  // the newShape by increasing the last dimension by resizePercentage percent
415  // (i.e., lastDim = (lastDim * (100 + resizePercentage)) / 100). If
416  // resizePercentage <= 0 then resizing uses newShape as-is. Returns true
417  // if resizing (allocation) was performed.
418  //
419  // To truncate the array so that it no longer holds additional storage,
420  // use the resize method.
421  //
422  // Array may not be shared with another Array object during this call.
423  // Exception thrown if it is shared.
424 
425  bool reformOrResize (const IPosition & newShape,
426  uInt resizePercentage = 0,
427  Bool resizeIfNeeded = True);
428 
429  // Use this method to extend or reduce the last dimension of an array. If
430  // sufficient excess capacity exists then the bookkeeping is adjusted to
431  // support the new shape. If insufficient storage exists then a new array
432  // is allocated (unless resizeIfNeeded is false; then an exception is thrown).
433  // If resizing is not required then the data remains untouched; if resizing
434  // is required then the data is copied into the new storage. The resizePercentage
435  // works the same as for reformOrResize (see above). This method never releases
436  // extra storage; use "resize" to do this. Array may not be sharing storage
437  // with another array at call time; an exception will be thrown if the array is shared.
438  // Returns true if the array was extension required a Array<T>::resize operation.
439 
440  bool adjustLastAxis (const IPosition & newShape,
441  uInt resizePercentage = 0,
442  bool resizeIfNeeded = True);
443 
444  // Returns the number of elements allocated. This value is >= to the value returned
445  // by size().
446 
447  size_t capacity () const;
448 
449  // These member functions remove degenerate (ie. length==1) axes from
450  // Arrays. Only axes greater than startingAxis are considered (normally
451  // one wants to remove trailing axes). The first two of these functions
452  // return an Array reference with axes removed. The latter two functions
453  // let this Array object reference the 'other' array with degenerated axes
454  // removed.
455  // <br>
456  // Unless throwIfError is False, an exception will be thrown if
457  // startingAxis exceeds the array's dimensionality.
458  // <br>
459  // The functions with argument <src>ignoreAxes</src> do
460  // not consider the axes given in that argument. In this way it can be
461  // achieved that degenerate axes are kept.
462  // <note role=caution> When the two functions returning <src>void</src>
463  // are invoked on a derived object (e.g. Matrix), an exception is
464  // thrown if removing the degenerate axes from other does not result
465  // in a correct number of axes.
466  // </note>
467  // <group>
468  Array<T> nonDegenerate(uInt startingAxis=0, Bool throwIfError=True) const;
469  Array<T> nonDegenerate(const IPosition& ignoreAxes) const;
470  void nonDegenerate(const Array<T> &other, uInt startingAxis=0,
471  Bool throwIfError=True);
472  void nonDegenerate(const Array<T> &other, const IPosition &ignoreAxes)
473  { doNonDegenerate (other, ignoreAxes); }
474  // </group>
475 
476  // Remove degenerate axes from this Array object.
477  // Note it does not make sense to use these functions on a derived object
478  // like Matrix, because it is not possible to remove axes from them.
479  // <group>
480  void removeDegenerate(uInt startingAxis=0,
481  Bool throwIfError=True);
482  void removeDegenerate(const IPosition &ignoreAxes);
483  // </group>
484 
485  // This member function returns an Array reference with the specified
486  // number of extra axes, all of length one, appended to the end of the
487  // Array. Note that the <src>reform</src> function can also be
488  // used to add extra axes.
489  // <group>
490  const Array<T> addDegenerate(uInt numAxes) const;
491  Array<T> addDegenerate(uInt numAxes);
492  // </group>
493 
494  // Make this array a different shape. If <src>copyValues==True</src>
495  // the old values are copied over to the new array.
496  // Copying is done on a per axis basis, thus a subsection with the
497  // minimum of the old and new shape is copied.
498  // <br>Resize without argument is equal to resize(IPosition()).
499  // <br>It is important to note that if multiple Array objects
500  // reference the same data storage, this Array object still references
501  // the same data storage as the other Array objects if the shape does
502  // not change. Otherwise this Array object references newly allocated
503  // storage, while the other Array objects still reference the existing
504  // data storage.
505  // <br>If you want to be sure that the data storage of this Array object
506  // is not referenced by other Array objects, the function unique should
507  // be called first.
508  // <group>
509  virtual void resize();
510  virtual void resize(const IPosition &newShape, Bool copyValues=False);
511  virtual void resize(const IPosition &newShape, Bool copyValues, ArrayInitPolicy policy);
512  // </group>
513 
514  // Access a single element of the array. This is relatively
515  // expensive. Extensive indexing should be done through one
516  // of the Array specializations (Vector, Matrix, Cube). If
517  // AIPS_DEBUG is defined, index checking will be performed.
518  // <group>
519  T &operator()(const IPosition &);
520  const T &operator()(const IPosition &) const;
521  // </group>
522 
523  // Get a reference to an array section extending
524  // from start to end (inclusive).
525  // <group>
526  Array<T> operator()(const IPosition &start,
527  const IPosition &end);
528  const Array<T> operator()(const IPosition &start,
529  const IPosition &end) const;
530  // Along the ith axis, every inc[i]'th element is chosen.
531  Array<T> operator()(const IPosition &start,
532  const IPosition &end,
533  const IPosition &inc);
534  const Array<T> operator()(const IPosition &start,
535  const IPosition &end,
536  const IPosition &inc) const;
537  // </group>
538 
539  // Get a reference to an array section using a Slicer.
540  // <group>
541  Array<T> operator()(const Slicer&);
542  const Array<T> operator()(const Slicer&) const;
543  // </group>
544 
545  // Get a reference to a section of an array.
546  // This is the same as operator(), but can be used in a type-agnostic way.
547  virtual CountedPtr<ArrayBase> getSection (const Slicer&) const;
548 
549  // Get the subset given by the i-th value of the last axis. So for a cube
550  // it returns the i-th xy plane. For a Matrix it returns the i-th row.
551  // The returned array references the original array data; its dimensionality
552  // is one less. For a 1-dim array it still returns a 1-dim array.
553  // <note>This function should not be used in tight loops as it is (much)
554  // slower than iterating using begin() and end(), ArrayIter, or
555  // ArrayAccessor.</note>
556  Array<T> operator[] (size_t i) const;
557 
558 
559  // The array is masked by the input LogicalArray.
560  // This mask must conform to the array.
561  // <group>
562  const MaskedArray<T> operator() (const LogicalArray &mask) const;
563  MaskedArray<T> operator() (const LogicalArray &mask);
564  // </group>
565 
566  // The array is masked by the input MaskedLogicalArray.
567  // The mask is effectively the AND of the internal LogicalArray
568  // and the internal mask of the MaskedLogicalArray.
569  // The MaskedLogicalArray must conform to the array.
570  // <group>
571  const MaskedArray<T> operator() (const MaskedLogicalArray &mask) const;
572  MaskedArray<T> operator() (const MaskedLogicalArray &mask);
573  // </group>
574 
575  // The number of references the underlying storage has assigned to it.
576  // It is 1 unless there are outstanding references to the storage (e.g.,
577  // through a slice). Normally you have no need to do this since the
578  // arrays handle all of the references for you.
579  uInt nrefs() const;
580 
581  // Check to see if the Array is consistent. This is about the same thing
582  // as checking for invariants. If AIPS_DEBUG is defined, this is invoked
583  // after construction and on entry to most member functions.
584  virtual Bool ok() const;
585 
586  // Are the shapes identical?
587  // <group>
588  Bool conform (const Array<T> &other) const
589  { return conform2(other); }
590  Bool conform (const MaskedArray<T> &other) const;
591  // </group>
592 
593  // Get a pointer to the beginning of the array.
594  // Note that the array may not be contiguous.
595  // <group>
596  T* data()
597  { return begin_p; }
598  const T* data() const
599  { return begin_p; }
600  // </group>
601 
602  // Generally use of this should be shunned, except to use a FORTRAN routine
603  // or something similar. Because you can't know the state of the underlying
604  // data layout (in particular, if there are increments) sometimes the
605  // pointer returned will be to a copy, but often this won't be necessary.
606  // A boolean is returned which tells you if this is a copy (and hence the
607  // storage must be deleted). Note that if you don't do anything unusual,
608  // getStorage followed by freeStorage or putStorage will do the deletion
609  // for you (if required). e.g.:
610  // <srcblock>
611  // Array<Int> a(shape); ...
612  // Bool deleteIt; Int *storage = a.getStorage(deleteIt);
613  // foo(storage, a.nelements()); a.puStorage(storage, deleteIt);
614  // // or a.freeStorage(storage, deleteIt) if a is const.
615  // </srcblock>
616  // NB: However, if you only use getStorage, you will have to delete the
617  // pointer yourself using freeStorage().
618  //
619  // It would probably be useful to have corresponding "copyin" "copyout"
620  // functions that used a user supplied buffer.
621  // Note that deleteIt is set in this function.
622  // <group>
623  T *getStorage(Bool &deleteIt);
624  const T *getStorage(Bool &deleteIt) const
625  {
626  // The cast is OK because the return pointer will be cast to const
627  return const_cast<Array<T>*>(this)->getStorage(deleteIt);
628  }
629  virtual void *getVStorage(Bool &deleteIt);
630  virtual const void *getVStorage(Bool &deleteIt) const;
631  // </group>
632 
633  // putStorage() is normally called after a call to getStorage() (cf).
634  // The "storage" pointer is set to zero.
635  void putStorage(T *&storage, Bool deleteAndCopy);
636  virtual void putVStorage(void *&storage, Bool deleteAndCopy);
637 
638  // If deleteIt is set, delete "storage". Normally freeStorage calls
639  // will follow calls to getStorage. The reason the pointer is "const"
640  // is because only const pointers are released from const arrays.
641  // The "storage" pointer is set to zero.
642  void freeStorage(const T *&storage, Bool deleteIt) const;
643  void freeVStorage(const void *&storage, Bool deleteIt) const;
644 
645  // Replace the data values with those in the pointer <src>storage</src>.
646  // The results are undefined if storage does not point at nelements() or
647  // more data elements. After takeStorage() is called, <src>nrefs()</src>
648  // is 1.
649  // <group>
650  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>DefaultAllocator<T></src>.
651  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by <src>NewDelAllocator<T></src>.
652  // It is strongly recommended to supply an appropriate <src>allocator</src> argument explicitly
653  // whenever <src>policy</src> == <src>TAKE_OVER</src>
654  // to let <src>Array</src> to know how to release the <src>storage</src>.
655  virtual void takeStorage(const IPosition &shape, T *storage,
656  StorageInitPolicy policy = COPY);
657 
658  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>allocator</src>.
659  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by <src>allocator</src>.
660  // Otherwise, <src>storage</src> is ignored.
661  virtual void takeStorage(const IPosition &shape, T *storage,
662  StorageInitPolicy policy, AbstractAllocator<T> const &allocator);
663 
664  // Since the pointer is const, a copy is always taken.
665  // Storage of a new copy is allocated by <src>DefaultAllocator<T></src>.
666  virtual void takeStorage(const IPosition &shape, const T *storage);
667 
668  // Since the pointer is const, a copy is always taken.
669  // Storage of a new copy is allocated by the specified allocator.
670  virtual void takeStorage(const IPosition &shape, const T *storage,
671  AbstractAllocator<T> const &allocator);
672  // </group>
673 
674 
675  // Used to iterate through Arrays. Derived classes VectorIterator and
676  // MatrixIterator are probably more useful.
677  friend class ArrayIterator<T>;
678 
679  // Create an ArrayIterator object of the correct type.
681 
682  // Needed to be a friend for Matrix<T>::reference()
683  friend class Matrix<T>;
684 
685 
686  // <group name=STL-iterator>
687  // See the function begin() and end() for a detailed description
688  // of the STL iterator capability.
689  class BaseIteratorSTL
690  {
691  public:
692  // Create the begin const_iterator object for an Array.
693  explicit BaseIteratorSTL (const Array<T>&);
694  // Create the end const_iterator object for an Array.
695  // It also acts as the default constructor.
696  explicit BaseIteratorSTL (const T* end = 0)
698  itsArray(0), itsContig(False) {}
699 
700  void nextElem()
701  {
702  itsPos++;
703  if (!itsContig) {
704  itsPos += itsLineIncr;
705  if (itsPos > itsLineEnd) increment();
706  }
707  }
708  void nextLine()
709  {
710  itsPos = itsLineEnd;
711  increment();
712  }
713 
714  bool operator== (const BaseIteratorSTL& other) const
715  { return itsPos == other.itsPos; }
716 
717  bool operator!= (const BaseIteratorSTL& other) const
718  { return itsPos != other.itsPos; }
719 
720  T* getPos()
721  { return const_cast<T*>(itsPos); }
722 
723  friend ostream& operator<< (ostream& os, const BaseIteratorSTL& iter)
724  { os << iter.itsPos; return os; }
725 
726  protected:
727  // Increment iterator for a non-contiguous array.
728  void increment();
729 
730  const T* itsPos;
731  const T* itsLineEnd;
732  size_t itsLineIncr;
738  };
739 
741  {
742  public:
743  // <group name=STL-iterator-typedefs>
744  typedef T value_type;
745  typedef value_type* pointer;
746  typedef value_type& reference;
747  typedef std::size_t size_type;
748  typedef ptrdiff_t difference_type;
749  typedef std::forward_iterator_tag iterator_category;
750  // </group>
751 
752  // Create the begin iterator object for an Array.
753  explicit IteratorSTL (Array<T>& arr)
754  : BaseIteratorSTL (arr) {}
755  // Create the end iterator object for an Array.
756  // It also acts as the default constructor.
757  explicit IteratorSTL (const T* end = 0)
758  : BaseIteratorSTL (end) {}
759 
761  {
762  this->nextElem();
763  return *this;
764  }
766  {
767  IteratorSTL old(*this);
768  this->nextElem();
769  return old;
770  }
771 
773  { return *this->getPos(); }
775  { return this->getPos(); }
776  };
777 
779  {
780  public:
781  // <group name=STL-iterator-typedefs>
782  typedef T value_type;
783  typedef const value_type* pointer;
784  typedef const value_type& reference;
785  typedef std::size_t size_type;
786  typedef ptrdiff_t difference_type;
787  typedef std::forward_iterator_tag iterator_category;
788  // </group>
789 
790  // Create the begin const_iterator object for an Array.
791  explicit ConstIteratorSTL (const Array<T>& arr)
792  : BaseIteratorSTL (arr) {}
793  // Create the end const_iterator object for an Array.
794  // It also acts as the default constructor.
795  explicit ConstIteratorSTL (const T* end = 0)
796  : BaseIteratorSTL (end) {}
797  // Create from a non-const iterator.
799  : BaseIteratorSTL (iter) {}
800 
802  {
803  this->nextElem();
804  return *this;
805  }
807  {
808  ConstIteratorSTL old(*this);
809  this->nextElem();
810  return old;
811  }
812 
813  const T& operator*() const
814  { return *this->itsPos; }
815  const T* operator->()
816  { return this->itsPos; }
817 
818  const T* pos() const
819  { return this->itsPos; }
820  };
821  // </group>
822 
823  // Define the STL-style iterator functions (only forward iterator).
824  // It makes it possible to iterate through all data elements of an array
825  // and to use it common STL functions.
826  // The end() function is relatively expensive, so it should not be
827  // used inside a for statement. It is much better to call it beforehand
828  // as shown in the example below. Furthermore it is very important to
829  // use <src>++iter</src>, because <src>iter++</src> is 4 times slower.
830  // <srcblock>
831  // Array<Int> arr(shape);
832  // Array<Int>::iterator iterend(arr.end());
833  // for (Array<Int>::iterator iter=arr.begin(); iter!=iterend; ++iter) {
834  // *iter += 1;
835  // }
836  // </srcblock>
837  // The Array class supports random access, so in principle a random
838  // iterator could be implemented, but its performance would not be great,
839  // especially for non-contiguous arrays.
840  // <br>Some other STL like functions exist for performance reasons.
841  // If the array is contiguous, it is possible to use the
842  // <src>cbegin</src> and <src>cend</src> functions which are
843  // about 10% faster.
844  // <group name=STL-iterator>
845  // STL-style typedefs.
846  // <group>
847  typedef T value_type;
848  typedef IteratorSTL iterator;
849  typedef ConstIteratorSTL const_iterator;
850  typedef T* contiter;
851  typedef const T* const_contiter;
852  // </group>
853  // Get the begin iterator object for any array.
854  // <group>
855  iterator begin()
856  { return iterator (*this); }
857  const_iterator begin() const
858  { return const_iterator (*this); }
859  iterator end()
860  { return iterator(end_p); }
861  const_iterator end() const
862  { return const_iterator(end_p); }
863  // </group>
864 
865  // Get the begin iterator object for a contiguous array.
866  // <group>
867  contiter cbegin()
868  { return begin_p; }
869  const_contiter cbegin() const
870  { return begin_p; }
871  contiter cend()
872  { return end_p; }
873  const_contiter cend() const
874  { return end_p; }
875  // </group>
876 
877  // </group>
878 
879 
880 private:
883  // Makes a copy using the allocator.
885  // If the current allocator is NewDelAllocator<T>, BulkAllocator for DefaultAllocator<T> is returned,
886  // otherwise BulkAllocator for the current allocator is returned.
888 protected:
891  }
892  // pre/post processing hook of takeStorage() for subclasses.
893  virtual void preTakeStorage(const IPosition &) {}
894  virtual void postTakeStorage() {}
895  static void copyToContiguousStorage(T *dst, Array<T> const & src, ArrayInitPolicy policy);
896 
897  // Remove the degenerate axes from the Array object.
898  // This is the implementation of the nonDegenerate functions.
899  // It has a different name to be able to make it virtual without having
900  // the "hide virtual function" message when compiling derived classes.
901  virtual void doNonDegenerate(const Array<T> &other,
902  const IPosition &ignoreAxes);
903 
904 
905  // Reference counted block that contains the storage.
907 
908  // This pointer is adjusted to point to the first element of the array.
909  // It is not necessarily the same thing as data->storage() since
910  // this array might be a section, e.g. have a blc which shifts us forward
911  // into the block.
913 
914  // The end for an STL-style iteration.
915  T* end_p;
916 
917 
918  // Fill the steps and the end for a derived class.
919  void makeSteps()
920  { baseMakeSteps(); this->setEndIter(); }
921 
922  // Set the end iterator.
923  void setEndIter()
924  { end_p = (nels_p==0 ? 0 : (contiguous_p ? begin_p + nels_p :
925  begin_p + size_t(length_p(ndim()-1)) * steps_p(ndim()-1))); }
926 };
927 
928 
929 //# Declare extern templates for often used types.
930 #ifdef AIPS_CXX11
931  extern template class Array<Bool>;
932  extern template class Array<Char>;
933  extern template class Array<Short>;
934  extern template class Array<uShort>;
935  extern template class Array<Int>;
936  extern template class Array<uInt>;
937  extern template class Array<Int64>;
938  extern template class Array<Float>;
939  extern template class Array<Double>;
940  extern template class Array<Complex>;
941  extern template class Array<DComplex>;
942  extern template class Array<String>;
943 #endif
944 
945 }//#End casa namespace
946 
947 
948 #ifndef CASACORE_NO_AUTO_TEMPLATES
949 #include <casacore/casa/Arrays/Array.tcc>
950 #endif //# CASACORE_NO_AUTO_TEMPLATES
951 #endif
ConstIteratorSTL(const T *end=0)
Create the end const_iterator object for an Array.
Definition: Array.h:795
Bool contiguous_p
Are the data contiguous?
Definition: ArrayBase.h:262
A Vector of integers, for indexing into Array<T> objects.
Definition: IPosition.h:119
ConstIteratorSTL operator++(int)
Definition: Array.h:806
virtual Bool ok() const
Check to see if the Array is consistent.
virtual void assignBase(const ArrayBase &other, Bool checkType=True)
Assign the source array to this array.
const_iterator end() const
Definition: Array.h:861
Non-templated base class for templated Array class.
Definition: ArrayBase.h:74
void putStorage(T *&storage, Bool deleteAndCopy)
putStorage() is normally called after a call to getStorage() (cf).
static ArrayInitPolicy defaultArrayInitPolicy()
Definition: Array.h:889
static void copyToContiguousStorage(T *dst, Array< T > const &src, ArrayInitPolicy policy)
const_iterator begin() const
Definition: Array.h:857
virtual void preTakeStorage(const IPosition &)
pre/post processing hook of takeStorage() for subclasses.
Definition: Array.h:893
Map a domain object into a range object via operator().
Definition: Array.h:56
IteratorSTL(Array< T > &arr)
Create the begin iterator object for an Array.
Definition: Array.h:753
Allocator_private::BulkAllocator< T > * nonNewDelAllocator() const
If the current allocator is NewDelAllocator<T>, BulkAllocator for DefaultAllocator<T> is returned...
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
ConstIteratorSTL(const IteratorSTL &iter)
Create from a non-const iterator.
Definition: Array.h:798
IPosition steps_p
Used to hold the step to next element in each dimension.
Definition: ArrayBase.h:267
static ArrayInitPolicy const NO_INIT
Don&#39;t initialize elements in the array.
Definition: Allocator.h:60
Array< T > nonDegenerate(uInt startingAxis=0, Bool throwIfError=True) const
These member functions remove degenerate (ie.
const_contiter cbegin() const
Definition: Array.h:869
StorageInitPolicy
A global enum used by some Array constructors.
Definition: ArrayBase.h:53
bool adjustLastAxis(const IPosition &newShape, uInt resizePercentage=0, bool resizeIfNeeded=True)
Use this method to extend or reduce the last dimension of an array.
virtual ~Array()
Frees up storage only if this array was the last reference to it.
size_t nels_p
Number of elements in the array.
Definition: ArrayBase.h:258
void makeSteps()
Fill the steps and the end for a derived class.
Definition: Array.h:919
static bool init_anyway()
Definition: Block.h:755
const value_type * pointer
Definition: Array.h:784
Array< T > copy(ArrayInitPolicy policy=ArrayInitPolicy::NO_INIT) const
This makes a copy of the array and returns it.
virtual void * getVStorage(Bool &deleteIt)
The following functions behave the same as the corresponding getStorage functions in the derived temp...
See the function begin() and end() for a detailed description of the STL iterator capability...
Definition: Array.h:690
A 2-D Specialization of the Array class.
Definition: Array.h:53
T * contiter
Definition: Array.h:850
iterator begin()
Get the begin iterator object for any array.
Definition: Array.h:855
const T * pos() const
Definition: Array.h:818
virtual void assign(const Array< T > &other)
Assign the other array to this array.
void copyMatchingPart(const Array< T > &from)
This function copies the matching part of from array to this array.
#define WHATEVER_VECTOR_FORWARD_DEC
Definition: aipsdef.h:108
contiter cbegin()
Get the begin iterator object for a contiguous array.
Definition: Array.h:867
A global enum used by some Array/Block constructors.
Definition: Allocator.h:57
Iterate an Array cursor through another Array.
Definition: Array.h:54
virtual CountedPtr< ArrayPositionIterator > makeIterator(uInt byDim) const
Create an ArrayIterator object of the correct type.
virtual void reference(const Array< T > &other)
After invocation, this array and other reference the same storage.
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array...
Definition: ArrayBase.h:265
contiter cend()
Definition: Array.h:871
Bool conform(const Array< T > &other) const
Are the shapes identical?
Definition: Array.h:588
virtual void doNonDegenerate(const Array< T > &other, const IPosition &ignoreAxes)
Remove the degenerate axes from the Array object.
friend ostream & operator<<(ostream &os, const BaseIteratorSTL &iter)
Definition: Array.h:723
T * data()
Get a pointer to the beginning of the array.
Definition: Array.h:596
Class for masking an Array for operations on that Array.
Definition: Array.h:55
T * getStorage(Bool &deleteIt)
Generally use of this should be shunned, except to use a FORTRAN routine or something similar...
virtual void resize()
Make this array a different shape.
bool operator!=(const BaseIteratorSTL &other) const
Definition: Array.h:717
virtual CountedPtr< ArrayBase > getSection(const Slicer &) const
Get a reference to a section of an array.
Array< T > operator[](size_t i) const
Get the subset given by the i-th value of the last axis.
void increment()
Increment iterator for a non-contiguous array.
Referenced counted pointer for constant data.
Definition: CountedPtr.h:86
T value_type
Define the STL-style iterator functions (only forward iterator).
Definition: Array.h:847
uInt ndim() const
The dimensionality of this array.
Definition: ArrayBase.h:94
bool operator==(const BaseIteratorSTL &other) const
Definition: Array.h:714
const Array< T > * itsArray
Definition: Array.h:736
static ArrayInitPolicy const INIT
Initialize all elements in the array with the default value.
Definition: Allocator.h:62
virtual Array< T > & operator=(const Array< T > &other)
Copy the values in other to this.
std::forward_iterator_tag iterator_category
Definition: Array.h:788
BaseIteratorSTL(const Array< T > &)
Create the begin const_iterator object for an Array.
void nonDegenerate(const Array< T > &other, const IPosition &ignoreAxes)
Definition: Array.h:472
Array()
Result has dimensionality of zero, and nelements is zero.
IteratorSTL operator++(int)
Definition: Array.h:765
T * end_p
The end for an STL-style iteration.
Definition: Array.h:915
T & operator()(const IPosition &)
Access a single element of the array.
ConstIteratorSTL(const Array< T > &arr)
Create the begin const_iterator object for an Array.
Definition: Array.h:791
const_contiter cend() const
Definition: Array.h:873
vector< T > tovector() const
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:39
const IteratorSTL & operator++()
Definition: Array.h:760
void removeDegenerate(uInt startingAxis=0, Bool throwIfError=True)
Remove degenerate axes from this Array object.
T * begin_p
This pointer is adjusted to point to the first element of the array.
Definition: Array.h:912
const T * const_contiter
Definition: Array.h:851
void apply(T(*function)(T))
Apply the function to every element of the array.
void setEndIter()
Set the end iterator.
Definition: Array.h:923
const Bool False
Definition: aipstype.h:41
std::forward_iterator_tag iterator_category
Definition: Array.h:750
virtual void postTakeStorage()
Definition: Array.h:894
template <class T, class U> class vector;
Definition: Array.h:169
void baseMakeSteps()
Make the indexing step sizes.
Specify which elements to extract from an n-dimensional array.
Definition: Slicer.h:275
Bool conform2(const ArrayBase &other) const
Are the shapes identical?
Definition: ArrayBase.h:233
COPY is used when an internal copy of the storage is to be made.
Definition: ArrayBase.h:56
bool reformOrResize(const IPosition &newShape, uInt resizePercentage=0, Bool resizeIfNeeded=True)
Having an array that can be reused without requiring reallocation can be useful for large arrays...
Array< T > reform(const IPosition &shape) const
It is occasionally useful to have an array which access the same storage appear to have a different s...
const T & operator*() const
Definition: Array.h:813
iterator end()
Definition: Array.h:859
virtual void takeStorage(const IPosition &shape, T *storage, StorageInitPolicy policy=COPY)
Replace the data values with those in the pointer storage.
CountedPtr< Block< T > > data_p
Reference counted block that contains the storage.
Definition: Array.h:906
virtual CountedPtr< ArrayBase > makeArray() const
Make an empty array of the same template type.
const ConstIteratorSTL & operator++()
Definition: Array.h:801
const Array< T > addDegenerate(uInt numAxes) const
This member function returns an Array reference with the specified number of extra axes...
void unique()
This ensures that this array does not reference any other storage.
uInt nrefs() const
The number of references the underlying storage has assigned to it.
void freeStorage(const T *&storage, Bool deleteIt) const
If deleteIt is set, delete "storage".
const Bool True
Definition: aipstype.h:40
const T * data() const
Definition: Array.h:598
void freeVStorage(const void *&storage, Bool deleteIt) const
this file contains all the compiler specific defines
Definition: mainpage.dox:28
value_type * pointer
Definition: Array.h:746
const T * getStorage(Bool &deleteIt) const
Definition: Array.h:624
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
unsigned int uInt
Definition: aipstype.h:48
size_t capacity() const
Returns the number of elements allocated.
const IPosition & shape() const
The length of each axis.
Definition: ArrayBase.h:121
ConstIteratorSTL const_iterator
Definition: Array.h:849
IteratorSTL iterator
Definition: Array.h:848
IteratorSTL(const T *end=0)
Create the end iterator object for an Array.
Definition: Array.h:757
virtual void putVStorage(void *&storage, Bool deleteAndCopy)