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
size_t capacity() const
Returns the number of elements allocated.
virtual void assignBase(const ArrayBase &other, Bool checkType=True)
Assign the source array to this array.
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
const T * getStorage(Bool &deleteIt) const
Definition: Array.h:624
static void copyToContiguousStorage(T *dst, Array< T > const &src, ArrayInitPolicy policy)
void freeStorage(const T *&storage, Bool deleteIt) const
If deleteIt is set, delete "storage".
vector< T > tovector() const
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
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
uInt ndim() const
The dimensionality of this array.
Definition: ArrayBase.h:94
const IPosition & shape() const
The length of each axis.
Definition: ArrayBase.h:121
IPosition steps_p
Used to hold the step to next element in each dimension.
Definition: ArrayBase.h:267
const T * pos() const
Definition: Array.h:818
static ArrayInitPolicy const NO_INIT
Don&#39;t initialize elements in the array.
Definition: Allocator.h:60
Array< T > operator[](size_t i) const
Get the subset given by the i-th value of the last axis.
uInt nrefs() const
The number of references the underlying storage has assigned to it.
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.
bool operator!=(const BaseIteratorSTL &other) const
Definition: Array.h:717
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
const Array< T > addDegenerate(uInt numAxes) const
This member function returns an Array reference with the specified number of extra axes...
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
Allocator_private::BulkAllocator< T > * nonNewDelAllocator() const
If the current allocator is NewDelAllocator<T>, BulkAllocator for DefaultAllocator<T> is returned...
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
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 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
virtual Bool ok() const
Check to see if the Array is consistent.
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.
const_contiter cbegin() const
Definition: Array.h:869
Bool conform2(const ArrayBase &other) const
Are the shapes identical?
Definition: ArrayBase.h:233
void increment()
Increment iterator for a non-contiguous array.
const T & operator*() const
Definition: Array.h:813
Referenced counted pointer for constant data.
Definition: CountedPtr.h:86
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...
T value_type
Define the STL-style iterator functions (only forward iterator).
Definition: Array.h:847
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.
const_iterator end() const
Definition: Array.h:861
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
Array< T > copy(ArrayInitPolicy policy=ArrayInitPolicy::NO_INIT) const
This makes a copy of the array and returns it.
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 freeVStorage(const void *&storage, Bool deleteIt) const
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.
const_contiter cend() const
Definition: Array.h:873
Specify which elements to extract from an n-dimensional array.
Definition: Slicer.h:275
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...
virtual CountedPtr< ArrayBase > getSection(const Slicer &) const
Get a reference to a section of an array.
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.
Array< T > nonDegenerate(uInt startingAxis=0, Bool throwIfError=True) const
These member functions remove degenerate (ie.
CountedPtr< Block< T > > data_p
Reference counted block that contains the storage.
Definition: Array.h:906
const ConstIteratorSTL & operator++()
Definition: Array.h:801
virtual CountedPtr< ArrayPositionIterator > makeIterator(uInt byDim) const
Create an ArrayIterator object of the correct type.
const T * data() const
Definition: Array.h:598
Bool conform(const Array< T > &other) const
Are the shapes identical?
Definition: Array.h:588
void unique()
This ensures that this array does not reference any other storage.
bool operator==(const BaseIteratorSTL &other) const
Definition: Array.h:714
const_iterator begin() const
Definition: Array.h:857
const Bool True
Definition: aipstype.h:40
this file contains all the compiler specific defines
Definition: mainpage.dox:28
value_type * pointer
Definition: Array.h:746
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
virtual CountedPtr< ArrayBase > makeArray() const
Make an empty array of the same template type.
unsigned int uInt
Definition: aipstype.h:48
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)