casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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_2_H
31 #define CASA_ARRAY_2_H
32 
33 //# Includes
34 #include "ArrayBase.h"
35 #include "ArrayError.h"
36 #include "IPosition.h"
37 #include "MaskLogiArrFwd.h"
38 #include "Storage.h"
39 
40 #include <complex>
41 #include <iterator>
42 #include <initializer_list>
43 #include <type_traits>
44 
45 namespace casacore { //#Begin casa namespace
46 
47 // <summary> A templated N-D %Array class with zero origin. </summary>
48 
49 // Array<T, Alloc> is a templated, N-dimensional, %Array class. The origin is zero,
50 // but by default indices are zero-based. This Array class is the
51 // base class for the Vector, Matrix, and Cube subclasses.
52 //
53 // Indexing into the array, and positions in general, are given with IPosition
54 // (essentially a vector of integers) objects. That is, an N-dimensional
55 // array requires a length-N IPosition to define a position within the array.
56 // Unlike C, indexing is done with (), not []. Also, the storage order
57 // is the same as in FORTRAN, i.e. memory varies most rapidly with the first
58 // index.
59 // <srcblock>
60 // // axisLengths = [1,2,3,4,5]
61 // IPosition axisLengths(5, 1, 2, 3, 4, 5);
62 // Array<int> ai(axisLengths); // ai is a 5 dimensional array of
63 // // integers; indices are 0-based
64 // // => ai.nelements() == 120
65 // Array<int> ai2(axisLengths); // The first element is at index 0
66 // IPosition zero(5); zero = 0; // [0,0,0,0,0]
67 // //...
68 // </srcblock>
69 // Indexing into an N-dimensional array is relatively expensive. Normally
70 // you will index into a Vector, Matrix, or Cube. These may be obtained from
71 // an N-dimensional array by creating a reference, or by using an
72 // ArrayIterator. The "shape" of the array is an IPosition which gives the
73 // length of each axis.
74 //
75 // An Array may be standalone, or it may refer to another array, or to
76 // part of another array (by refer we mean that if you change a pixel in
77 // the current array, a pixel in the referred to array also changes, i.e.
78 // they share underlying storage).
79 // <note role=warning>
80 // One way one array can reference another is through the copy
81 // constructor. While this might be what you want, you should
82 // probably use the reference() member function to make it explicit.
83 // The copy constructor is used when arguments are passed by value;
84 // normally functions should not pass Arrays by value, rather they
85 // should pass a reference or a const reference. On the positive
86 // side, returning an array from a function is efficient since no
87 // copying need be done.
88 // </note>
89 //
90 // Aside from the explicit reference() member function, a user will
91 // most commonly encounter an array which references another array
92 // when he takes an array slice (or section). A slice is a sub-region of
93 // an array (which might also have a stride: every nth row, every mth column,
94 // ...).
95 // <srcblock>
96 // IPosition lengths(3,10,20,30);
97 // Array<int> ai(lengths); // A 10x20x30 cube
98 // Cube<int> ci;
99 // //...
100 // ci.reference(ai1); // ci and ai now reference the same
101 // // storage
102 // ci(0,0,0) = 123; // Can use Cube indexing
103 // ci.xyPlane(2) = 0; // and other member functions
104 // IPosition zero(3,0,0,0);
105 // assert(ai(zero) == 123); // true because ai, ci are references
106 // //...
107 // Array<int> subArray;
108 // IPosition blc(3,0,0,0), trc(3,5,5,5);
109 // subArray.reference(ai(blc, trc));
110 // subArray = 10; // All of subArray, which is the
111 // // subcube from 0,0,0 to 5,5,5 in
112 // // ai, has the value 10.
113 // </srcblock>
114 // While the last example has an array slice referenced explicitly by another
115 // array variable, normally the user will often only use the slice as
116 // a temporary in an expresion, for example:
117 // <srcblock>
118 // Array<Complex> array;
119 // IPosition blc, trc, offset;
120 // //...
121 // // Copy from one region of the array into another
122 // array(blc, trc) = array(blc+offset, trc+offset);
123 // </srcblock>
124 //
125 // The Array classes are intended to operate on relatively large
126 // amounts of data. While they haven't been extensively tuned yet,
127 // they are relatively efficient in terms of speed. Presently they
128 // are not space efficient -- the overhead is about 15 words. While
129 // this will be improved (probably to about 1/2 that), these array
130 // classes are not appropriate for very large numbers of very small
131 // arrays. The Block<T> class may be what you want in this circumstance.
132 //
133 // Element by element mathematical and logical operations are available
134 // for arrays (defined in aips/ArrayMath.h and aips/ArrayLogical.h).
135 // Because arithmetic and logical functions are split out, it is possible
136 // to create an Array<T, Alloc> (and hence Vector<T> etc) for any type T that has
137 // a default constructor, assignment operator, and copy constructor. In
138 // particular, Array<String> works.
139 //
140 // If compiled with the preprocessor symbol AIPS_DEBUG symbol, array
141 // consistency ("invariants") will be checked in most member
142 // functions, and indexing will be range-checked. This should not be
143 // defined for production runs.
144 //
145 // <note role=tip>
146 // Most of the data members and functions which are "protected" should
147 // likely become "private".
148 // </note>
149 //
150 // <todo asof="1999/12/30">
151 // <li> Integrate into the Lattice hierarchy
152 // <li> Factor out the common functions (shape etc) into a type-independent
153 // base class.
154 // </todo>
155 
156 template<typename T, typename Alloc> class Array : public ArrayBase
157 {
158 public:
159  // Result has dimensionality of zero, and nelements is zero.
160  Array(const Alloc& allocator = Alloc());
161 
162  // Create an array of the given shape, i.e. after construction
163  // array.ndim() == shape.nelements() and array.shape() == shape.
164  // The origin of the Array is zero.
165  // Storage is allocated by <src>DefaultAllocator<T></src>.
166  // Without initPolicy parameter, the initialization of elements depends on type <src>T</src>.
167  // When <src>T</src> is a fundamental type like <src>int</src>, elements are NOT initialized.
168  // When <src>T</src> is a class type like <src>casacore::Complex</src> or <src>std::string</src>, elements are initialized.
169  // This inconsistent behavior confuses programmers and make it hard to write efficient and generic code using template.
170  // Especially when <src>T</src> is of type <src>Complex</src> or <src>DComplex</src> and it is unnecessary to initialize,
171  // provide initPolicy with value <src>NO_INIT</src> to skip the initialization.
172  // Therefore, it is strongly recommended to explicitly provide initPolicy parameter,
173  explicit Array(const IPosition &shape, const Alloc& allocator = Alloc());
174 
175  // Create an array of the given shape and initialize it with the
176  // initial value.
177  // Storage is allocated by <src>DefaultAllocator<T></src>.
178  Array(const IPosition &shape, const T &initialValue, const Alloc& allocator = Alloc());
179 
180  // This is a tag for the constructor that may be used to construct an uninitialized Array.
182 
183  // Constructor to create an uninitialized array. This constructor can for example
184  // be called with:
185  // <srcblock>
186  // Array<int> a(shape, Array<int>::uninitialized);
187  // </srcblock>
188  Array(const IPosition& shape, uninitializedType, const Alloc& allocator = Alloc());
189 
190  // Construct a one-dimensional array from an initializer list.
191  // Example:
192  // <srcblock>
193  // Array<int> a({5, 6, 7, 8});
194  // </srcblock>
195  Array(std::initializer_list<T> list, const Alloc& allocator = Alloc());
196 
197  // After construction, this and other reference the same storage.
198  Array(const Array<T, Alloc> &other);
199 
200  // Source will be empty after this call.
201  Array(Array<T, Alloc>&& source) noexcept;
202 
203  // Create an Array of a given shape from a pointer.
204  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>DefaultAllocator<T></src>.
205  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by the specified allocator.
206  // <srcblock>
207  // FILE *fp = ...;
208  // typedef DefaultAllocator<int> Alloc;
209  // Alloc::type alloc;
210  // IPosition shape(1, 10);
211  // int *ptr = alloc.allocate(shape.product());
212  // size_t nread = fread(ptr, sizeof(int), shape.product(), fp);
213  // Array<int> ai(shape, ptr, TAKE_OVER, Alloc::value);
214  // </srcblock>
215  Array(const IPosition &shape, T *storage, StorageInitPolicy policy = COPY, const Alloc& allocator = Alloc());
216 
217  // Create an Array of a given shape from a pointer. Because the pointer
218  // is const, a copy is always made.
219  // The copy is allocated by <src>DefaultAllocator<T></src>.
220  Array(const IPosition &shape, const T *storage);
221 
222  // Construct an array from an iterator and a shape.
223  template<typename InputIterator>
224  Array(const IPosition &shape, InputIterator startIter, const Alloc& allocator = Alloc());
225 
226  // Frees up storage only if this array was the last reference to it.
227  virtual ~Array() noexcept;
228 
229  // Make an empty array of the same template type.
230  virtual std::unique_ptr<ArrayBase> makeArray() const override;
231 
232  // Retrieve the allocator associated with this array.
233  // @{
234  Alloc& allocator() { return *data_p; }
235  const Alloc& allocator() const { return *data_p; }
236  // @}
237 
238  // Assign the other array to this array.
239  // If the shapes mismatch, this array is resized.
240  // <group>
241  void assign (const Array<T, Alloc>& other);
242 
243  void assignBase (const ArrayBase& other, bool checkType=true) override;
244  // </group>
245 
246  // Set every element of the array to "value." Also could use the
247  // assignment operator which assigns an array from a scalar.
248  void set(const T &value);
249 
250  // Apply the function to every element of the array. This modifies
251  // the array in place.
252  // (TODO this version made the other versions of apply() redundant)
253  template<typename Callable>
254  void apply(Callable function);
255 
256  // After invocation, this array and other reference the same storage. That
257  // is, modifying an element through one will show up in the other. The
258  // arrays appear to be identical; they have the same shape.
259  // <br>Please note that this function makes it possible to reference a
260  // const Array, thus effectively it makes a const Array non-const.
261  // Although this may seem undesirable at first sight, it is necessary to
262  // be able to make references to temporary Array objects, in particular to
263  // Array slices. Otherwise one first needs to use the copy constructor.
264  //# The const has been introduced on 2005-Mar-31 because of the hassle
265  //# involved in calling the copy ctor before reference.
266  virtual void reference(const Array<T, Alloc> &other);
267 
268  // Copy the values in other to this. If the array on the left hand
269  // side has no elements, then it is resized to be the same size as
270  // as the array on the right hand side. Otherwise, the arrays must
271  // conform (same shapes).
272  // <srcblock>
273  // IPosition shape(2,10,10); // some shape
274  // Array<double> ad(shape);
275  // //...
276  // Array<double> ad2; // N.B. ad2.nelements() == 0
277  // ad2 = ad; // ad2 resizes, then elements
278  // // are copied.
279  // shape = 20;
280  // Array<double> ad3(shape);
281  // ad3 = ad; // Error: arrays do not conform
282  // </srcblock>
283  // Note that the assign function can be used to assign a
284  // non-conforming array.
286  {
287  return assign_conforming_implementation(other, std::is_copy_assignable<T>());
288  }
289 
290  // Copy to this those values in marray whose corresponding elements
291  // in marray's mask are true.
292  // <thrown>
293  // <li> ArrayConformanceError
294  // </thrown>
295  //
296  template<typename MaskAlloc>
298 
299  // TODO we should change the semantics
301  { return assign_conforming(other); }
302 
303  // Calls assign_conforming().
304  template<typename MaskAlloc>
306  { return assign_conforming(marray); }
307 
308  // The move operator takes the storage from the given array. After moving an
309  // Array, the source Array will be left empty.
311 
312  // Set every element of this array to "value". In other words, a scalar
313  // behaves as if it were a constant conformant array.
314  Array<T, Alloc>& operator=(const T& value);
315 
316  // This makes a copy of the array and returns it. This can be
317  // useful for, e.g. making working copies of function arguments
318  // that you can write into.
319  // <srcblock>
320  // void someFunction(const Array<int> &arg)
321  // {
322  // Array<int> tmp(arg.copy());
323  // // ...
324  // }
325  // </srcblock>
326  // Note that since the copy constructor makes a reference, if we just
327  // created used to copy constructor, modifying "tmp" would also
328  // modify "arg". Clearly another alternative would simply be:
329  // <srcblock>
330  // void someFunction(const Array<int> &arg)
331  // {
332  // Array<int> tmp;
333  // tmp = arg;
334  // // ...
335  // }
336  // </srcblock>
337  // which likely would be simpler to understand. (Should copy()
338  // be deprecated and removed?)
339  //
340  // TODO deprecate
341  Array<T, Alloc> copy() const { // Make a copy of this
342  return copy(Alloc());
343  }
344 
345  // This function copies the matching part of from array to this array.
346  // The matching part is the part with the minimum size for each axis.
347  // E.g. if this array has shape [4,5,6] and from array has shape [7,3],
348  // the matching part has shape [4,3].
349  // <br>Note it is used by the resize function if
350  // <src>copyValues==true</src>.
351  void copyMatchingPart (const Array<T, Alloc>& from);
352 
353  // This ensures that this array does not reference any other storage.
354  // <note role=tip>
355  // When a section is taken of an array with non-unity strides,
356  // storage can be wasted if the array, which originally contained
357  // all the data, goes away. unique() also reclaims storage. This
358  // is an optimization users don't normally need to understand.
359  //
360  // <srcblock>
361  // IPosition shape(...), blc(...), trc(...), inc(...);
362  // Array<float> af(shape);
363  // inc = 2; // or anything > 1
364  // Array<float> aSection.reference(af(blc, trc, inc));
365  // af.reference(anotherArray);
366  // // aSection now references storage that has a stride
367  // // in it, but nothing else is. Storage is wasted.
368  // aSection.unique();
369  // </srcblock>
370  // </note>
371  void unique();
372 
373  // Create an STL vector from an Array. The created vector is a linear
374  // representation of the Array memory. See
375  // <linkto class=Vector>Vector</linkto> for
376  // details of the operation and its reverse (i.e. creating a
377  // <src>Vector</src> from a <src>vector</src>), and for details of
378  // definition and instantiation.
379  // <group>
380  template <class U>
381  void tovector(std::vector<T, U>& out) const;
382  std::vector<T> tovector() const;
383  // </group>
384 
385  // It is occasionally useful to have an array which access the same
386  // storage appear to have a different shape. For example,
387  // turning an N-dimensional array into a Vector.
388  // <br>When the array data are contiguous, the array can be reshaped
389  // to any form as long as the number of elements stays the same.
390  // When not contiguous, it is only possible to remove or add axes
391  // with length 1.
392  // <srcblock>
393  // IPosition squareShape(2,5,5);
394  // Array<float> square(squareShape);
395  // IPosition lineShape(1,25);
396  // Vector<float> line(square.reform(lineShape));
397  // // "square"'s storage may now be accessed through Vector "line"
398  // </srcblock>
399  Array<T, Alloc> reform(const IPosition& shape) const;
400 
401  // Having an array that can be reused without requiring reallocation can
402  // be useful for large arrays. The method reformOrResize permits this
403  // usage.
404  //
405  // The reformOrResize method first attempts to reform the matrix so that
406  // it reuses the existing storage for an array with a new shape. If the
407  // existing storage will not hold the new shape, then the method will
408  // resize the array when resizeIfNeeded is true; if a resize is needed and
409  // resizeIfNeeded is false, then an ArrayConformanceError is thrown. The
410  // copyDataIfNeeded parameter is passed to resize if resizing is performed.
411  // resizePercentage is the percent of additional storage to be addeed when
412  // a resize is performed; this allows the allocations to be amortized when
413  // the caller expects to be calling this method again in the future. The
414  // parameter is used to define an allocation shape which is larger than
415  // the newShape by increasing the last dimension by resizePercentage percent
416  // (i.e., lastDim = (lastDim * (100 + resizePercentage)) / 100). If
417  // resizePercentage <= 0 then resizing uses newShape as-is. Returns true
418  // if resizing (allocation) was performed.
419  //
420  // To truncate the array so that it no longer holds additional storage,
421  // use the resize method.
422  //
423  // Array may not be shared with another Array object during this call.
424  // Exception thrown if it is shared.
425 
426  bool reformOrResize (const IPosition & newShape,
427  size_t resizePercentage = 0,
428  bool resizeIfNeeded = true);
429 
430  // Use this method to extend or reduce the last dimension of an array. If
431  // sufficient excess capacity exists then the bookkeeping is adjusted to
432  // support the new shape. If insufficient storage exists then a new array
433  // is allocated (unless resizeIfNeeded is false; then an exception is thrown).
434  // If resizing is not required then the data remains untouched; if resizing
435  // is required then the data is copied into the new storage. The resizePercentage
436  // works the same as for reformOrResize (see above). This method never releases
437  // extra storage; use "resize" to do this. Array may not be sharing storage
438  // with another array at call time; an exception will be thrown if the array is shared.
439  // Returns true if the array was extension required a Array<T>::resize operation.
440 
441  bool adjustLastAxis (const IPosition & newShape,
442  size_t resizePercentage = 0,
443  bool resizeIfNeeded = true);
444 
445  // Returns the number of elements allocated. This value is >= to the value returned
446  // by size().
447 
448  size_t capacity () const;
449 
450  // These member functions remove degenerate (ie. length==1) axes from
451  // Arrays. Only axes greater than startingAxis are considered (normally
452  // one wants to remove trailing axes). The first two of these functions
453  // return an Array reference with axes removed. The latter two functions
454  // let this Array object reference the 'other' array with degenerated axes
455  // removed.
456  // <br>
457  // Unless throwIfError is false, an exception will be thrown if
458  // startingAxis exceeds the array's dimensionality.
459  // <br>
460  // The functions with argument <src>ignoreAxes</src> do
461  // not consider the axes given in that argument. In this way it can be
462  // achieved that degenerate axes are kept.
463  // <note role=caution> When the two functions returning <src>void</src>
464  // are invoked on a derived object (e.g. Matrix), an exception is
465  // thrown if removing the degenerate axes from other does not result
466  // in a correct number of axes.
467  // </note>
468  // <group>
469  Array<T, Alloc> nonDegenerate(size_t startingAxis=0, bool throwIfError=true) const;
470  Array<T, Alloc> nonDegenerate(const IPosition& ignoreAxes) const;
471  void nonDegenerate(const Array<T, Alloc> &other, size_t startingAxis=0,
472  bool throwIfError=true);
473  void nonDegenerate(const Array<T, Alloc> &other, const IPosition &ignoreAxes)
474  { doNonDegenerate (other, ignoreAxes); }
475  // </group>
476 
477  // Remove degenerate axes from this Array object.
478  // Note it does not make sense to use these functions on a derived object
479  // like Matrix, because it is not possible to remove axes from them.
480  // <group>
481  void removeDegenerate(size_t startingAxis=0,
482  bool throwIfError=true);
483  void removeDegenerate(const IPosition &ignoreAxes);
484  // </group>
485 
486  // This member function returns an Array reference with the specified
487  // number of extra axes, all of length one, appended to the end of the
488  // Array. Note that the <src>reform</src> function can also be
489  // used to add extra axes.
490  // <group>
491  const Array<T, Alloc> addDegenerate(size_t numAxes) const;
492  Array<T, Alloc> addDegenerate(size_t numAxes);
493  // </group>
494 
495  // Make this array a different shape. If <src>copyValues==true</src>
496  // the old values are copied over to the new array.
497  // Copying is done on a per axis basis, thus a subsection with the
498  // minimum of the old and new shape is copied.
499  // <br>Resize without argument is equal to resize(IPosition()).
500  // <br>It is important to note that if multiple Array objects
501  // reference the same data storage, this Array object still references
502  // the same data storage as the other Array objects if the shape does
503  // not change. Otherwise this Array object references newly allocated
504  // storage, while the other Array objects still reference the existing
505  // data storage.
506  // <br>If you want to be sure that the data storage of this Array object
507  // is not referenced by other Array objects, the function unique should
508  // be called first.
509  // <group>
510  void resize();
511 
512  void resize(const IPosition &newShape, bool copyValues=false) override;
513  // </group>
514 
515  // Access a single element of the array. This is relatively
516  // expensive. Extensive indexing should be done through one
517  // of the Array specializations (Vector, Matrix, Cube).
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, Alloc> operator()(const IPosition &start,
527  const IPosition &end);
528  const Array<T, Alloc> operator()(const IPosition &start,
529  const IPosition &end) const;
530  // Along the ith axis, every inc[i]'th element is chosen.
531  Array<T, Alloc> operator()(const IPosition &start,
532  const IPosition &end,
533  const IPosition &inc);
534  const Array<T, Alloc> 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>
542  const Array<T, Alloc> 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  std::unique_ptr<ArrayBase> getSection (const Slicer&) const override;
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, Alloc> operator[] (size_t i) const;
557 
558  // Get the diagonal of each matrix part in the full array.
559  // The matrices are taken using axes firstAxes and firstAxis+1.
560  // diag==0 is main diagonal; diag>0 above the main diagonal; diag<0 below.
561  Array<T, Alloc> diagonals (size_t firstAxis=0, long long diag=0) const;
562 
563  // The array is masked by the input LogicalArray.
564  // This mask must conform to the array.
565  // <group>
566  const MaskedArray<T> operator() (const LogicalArray &mask) const;
568  // </group>
569 
570  // The array is masked by the input MaskedLogicalArray.
571  // The mask is effectively the AND of the internal LogicalArray
572  // and the internal mask of the MaskedLogicalArray.
573  // The MaskedLogicalArray must conform to the array.
574  // <group>
577  // </group>
578 
579  // The number of references the underlying storage has assigned to it.
580  // It is 1 unless there are outstanding references to the storage (e.g.,
581  // through a slice). Normally you have no need to do this since the
582  // arrays handle all of the references for you.
583  // NB: Even when nrefs()==1, the array might be shared, because the
584  // the storage itself might be shared. Therefore, this function should
585  // not be used outside debugging.
586  // TODO make protected.
587  size_t nrefs() const;
588 
589  // Check to see if the Array is consistent. This is about the same thing
590  // as checking for invariants. If AIPS_DEBUG is defined, this is invoked
591  // after construction and on entry to most member functions.
592  virtual bool ok() const override;
593 
594  // Are the shapes identical?
595  // <group>
596  bool conform (const Array<T, Alloc> &other) const
597  { return conform2(other); }
598  bool conform (const MaskedArray<T> &other) const;
599  // </group>
600 
601  // Get a pointer to the beginning of the array.
602  // Note that the array may not be contiguous.
603  // <group>
604  T* data()
605  { return begin_p; }
606  const T* data() const
607  { return begin_p; }
608  // </group>
609 
610  // Generally use of this should be shunned, except to use a FORTRAN routine
611  // or something similar. Because you can't know the state of the underlying
612  // data layout (in particular, if there are increments) sometimes the
613  // pointer returned will be to a copy, but often this won't be necessary.
614  // A boolean is returned which tells you if this is a copy (and hence the
615  // storage must be deleted). Note that if you don't do anything unusual,
616  // getStorage followed by freeStorage or putStorage will do the deletion
617  // for you (if required). e.g.:
618  // <srcblock>
619  // Array<int> a(shape); ...
620  // bool deleteIt; int *storage = a.getStorage(deleteIt);
621  // foo(storage, a.nelements()); a.puStorage(storage, deleteIt);
622  // // or a.freeStorage(storage, deleteIt) if a is const.
623  // </srcblock>
624  // NB: However, if you only use getStorage, you will have to delete the
625  // pointer yourself using freeStorage().
626  //
627  // It would probably be useful to have corresponding "copyin" "copyout"
628  // functions that used a user supplied buffer.
629  // Note that deleteIt is set in this function.
630  // <group>
631  T *getStorage(bool& deleteIt);
632  const T *getStorage(bool& deleteIt) const
633  {
634  // The cast is OK because the return pointer will be cast to const
635  return const_cast<Array<T, Alloc>*>(this)->getStorage(deleteIt);
636  }
637  void *getVStorage(bool &deleteIt) override;
638  const void *getVStorage(bool &deleteIt) const override;
639  // </group>
640 
641  // putStorage() is normally called after a call to getStorage() (cf).
642  // The "storage" pointer is set to zero.
643  void putStorage(T *&storage, bool deleteAndCopy);
644  void putVStorage(void *&storage, bool deleteAndCopy) override;
645 
646  // If deleteIt is set, delete "storage". Normally freeStorage calls
647  // will follow calls to getStorage. The reason the pointer is "const"
648  // is because only const pointers are released from const arrays.
649  // The "storage" pointer is set to zero.
650  // TODO this function can not be const for stateful allocators
651  void freeStorage(const T *&storage, bool deleteIt) const;
652  void freeVStorage(const void *&storage, bool deleteIt) const override;
653 
654  // Replace the data values with those in the pointer <src>storage</src>.
655  // The results are undefined if storage does not point at nelements() or
656  // more data elements. After takeStorage() is called, <src>nrefs()</src>
657  // is 1.
658  // <group>
659  // If <src>policy</src> is <src>COPY</src>, storage of a new copy is allocated by <src>allocator</src>.
660  // If <src>policy</src> is <src>TAKE_OVER</src>, <src>storage</src> will be destructed and released by <src>allocator</src>.
661  virtual void takeStorage(const IPosition &shape, T *storage,
662  StorageInitPolicy policy = COPY, const Alloc& allocator = Alloc());
663 
664  // Since the pointer is const, a copy is always taken.
665  // Storage of a new copy is allocated by the specified allocator.
666  virtual void takeStorage(const IPosition &shape, const T *storage,
667  const Alloc& allocator = Alloc());
668  // </group>
669 
670 
671  // Used to iterate through Arrays. Derived classes VectorIterator and
672  // MatrixIterator are probably more useful.
673  friend class ArrayIterator<T, Alloc>;
674 
675  // Create an ArrayIterator object of the correct type.
676  std::unique_ptr<ArrayPositionIterator> makeIterator(size_t byDim) const override;
677 
678  // <group name=STL-iterator>
679  // See the function begin() and end() for a detailed description
680  // of the STL iterator capability.
681  class BaseIteratorSTL
682  {
683  public:
684  // Create the begin const_iterator object for an Array.
685  explicit BaseIteratorSTL (const Array<T, Alloc>&);
686  // Create the end const_iterator object for an Array.
687  // It also acts as the default constructor.
688  explicit BaseIteratorSTL (const T* end = 0)
690  itsArray(0), itsContig(false) {}
691 
692  void nextElem()
693  {
694  itsPos++;
695  if (!itsContig) {
696  itsPos += itsLineIncr;
697  if (itsPos > itsLineEnd) increment();
698  }
699  }
700  void nextLine()
701  {
702  itsPos = itsLineEnd;
703  increment();
704  }
705 
706  bool operator== (const BaseIteratorSTL& other) const
707  { return itsPos == other.itsPos; }
708 
709  bool operator!= (const BaseIteratorSTL& other) const
710  { return itsPos != other.itsPos; }
711 
712  T* getPos()
713  { return const_cast<T*>(itsPos); }
714 
715  friend std::ostream& operator<< (std::ostream& os, const BaseIteratorSTL& iter)
716  { os << iter.itsPos; return os; }
717 
718  protected:
719  // Increment iterator for a non-contiguous array.
720  void increment();
721 
722  const T* itsPos;
723  const T* itsLineEnd;
724  size_t itsLineIncr;
725  size_t itsLineAxis;
729  bool itsContig;
730  };
731 
733  {
734  public:
735  // <group name=STL-iterator-typedefs>
736  typedef T value_type;
737  typedef value_type* pointer;
739  typedef std::size_t size_type;
740  typedef ptrdiff_t difference_type;
741  typedef std::forward_iterator_tag iterator_category;
742  // </group>
743 
744  // Create the begin iterator object for an Array.
745  explicit IteratorSTL (Array<T, Alloc>& arr)
746  : BaseIteratorSTL (arr) {}
747  // Create the end iterator object for an Array.
748  // It also acts as the default constructor.
749  explicit IteratorSTL (const T* end = 0)
750  : BaseIteratorSTL (end) {}
751 
753  {
754  this->nextElem();
755  return *this;
756  }
758  {
759  IteratorSTL old(*this);
760  this->nextElem();
761  return old;
762  }
763 
765  { return *this->getPos(); }
767  { return this->getPos(); }
768  };
769 
771  {
772  public:
773  // <group name=STL-const-iterator-typedefs>
774  typedef T value_type;
775  typedef const value_type* pointer;
776  typedef const value_type& reference;
777  typedef std::size_t size_type;
778  typedef ptrdiff_t difference_type;
779  typedef std::forward_iterator_tag iterator_category;
780  // </group>
781 
782  // Create the begin const_iterator object for an Array.
783  explicit ConstIteratorSTL (const Array<T, Alloc>& arr)
784  : BaseIteratorSTL (arr) {}
785  // Create the end const_iterator object for an Array.
786  // It also acts as the default constructor.
787  explicit ConstIteratorSTL (const T* end = 0)
788  : BaseIteratorSTL (end) {}
789  // Create from a non-const iterator.
791  : BaseIteratorSTL (iter) {}
792 
794  {
795  this->nextElem();
796  return *this;
797  }
799  {
800  ConstIteratorSTL old(*this);
801  this->nextElem();
802  return old;
803  }
804 
805  const T& operator*() const
806  { return *this->itsPos; }
807  const T* operator->()
808  { return this->itsPos; }
809 
810  const T* pos() const
811  { return this->itsPos; }
812  };
813  // </group>
814 
815  // Define the STL-style iterator functions (only forward iterator).
816  // It makes it possible to iterate through all data elements of an array
817  // and to use it common STL functions.
818  // The end() function is relatively expensive, so it should not be
819  // used inside a for statement. It is much better to call it beforehand
820  // as shown in the example below. Furthermore it is very important to
821  // use <src>++iter</src>, because <src>iter++</src> is 4 times slower.
822  // <srcblock>
823  // Array<int> arr(shape);
824  // Array<int>::iterator iterend(arr.end());
825  // for (Array<int>::iterator iter=arr.begin(); iter!=iterend; ++iter) {
826  // *iter += 1;
827  // }
828  // </srcblock>
829  // The Array class supports random access, so in principle a random
830  // iterator could be implemented, but its performance would not be great,
831  // especially for non-contiguous arrays.
832  // <br>Some other STL like functions exist for performance reasons.
833  // If the array is contiguous, it is possible to use the
834  // <src>cbegin</src> and <src>cend</src> functions which are
835  // about 10% faster.
836  // <group name=iterator-typedefs>
837  // STL-style typedefs.
838  // <group>
839 
840  // Type of allocator used to allocate and deallocate space
841  typedef Alloc allocator_type;
842  // Element type
843  typedef T value_type;
844  // TODO This is how std containers define a reference type, but
845  // the name 'reference' is already taken by a method.
846  // typedef T& reference;
847  typedef const T& const_reference;
848  // Pointer to an element type
849  typedef T* pointer;
850  // Constant pointer to the element type
851  typedef const T* const_pointer;
852  typedef IteratorSTL iterator;
853  typedef ConstIteratorSTL const_iterator;
854  typedef T* contiter;
855  typedef const T* const_contiter;
856  // </group>
857  // Get the begin iterator object for any array.
858  // <group>
860  { return iterator (*this); }
862  { return const_iterator (*this); }
864  { return iterator(end_p); }
866  { return const_iterator(end_p); }
867  // </group>
868 
869  // Get the begin iterator object for a contiguous array.
870  // <group>
872  { return begin_p; }
874  { return begin_p; }
876  { return end_p; }
878  { return end_p; }
879  // </group>
880 
881  // </group>
882 
883 
884 private:
885  // Implementation of constructor taking a Shape, a Templated parameter and an allocator.
886  // This method implements it for when T is integral, in which case the templated parameter
887  // is the initial value.
888  template<typename Integral>
889  Array(const IPosition &shape, Integral startIter, const Alloc& allocator, std::true_type /*is_integral*/ );
890 
891  // Implementation of constructor taking a Shape, a Templated parameter and an allocator.
892  // This method implements it for when T is NOT integral, in which case the templated parameter
893  // is an iterator.
894  template<typename InputIterator>
895  Array(const IPosition &shape, InputIterator startIter, const Alloc& allocator, std::false_type /*is_integral*/ );
896 
897  // Makes a copy using the allocator.
898  Array<T, Alloc> copy(const Alloc& allocator) const;
899 
900  // Implementation for assign for copyable types
901  Array<T, Alloc>& assign_conforming_implementation (const Array<T, Alloc>& other, std::true_type);
902  // Implementation for assign for non-copyable types: can not be assigned
904  {
905  throw ArrayError("Can not assign from non-copyable object");
906  }
907  static void copyToContiguousStorage(T *dst, Array<T, Alloc> const& src, std::true_type);
908  static void copyToContiguousStorage(T*, Array<T, Alloc> const&, std::false_type)
909  {
910  throw ArrayError("Can not coy from non-copyable object");
911  }
912 
913  // An Array is unique when the container is shared and when nrefs==1.
914  bool isUnique() const
915  {
916  return !data_p->is_shared() && nrefs()==1;
917  }
918 
919 protected:
920  // Source will be empty with given shape after this call.
921  Array(Array<T, Alloc>&& source, const IPosition& shapeForSource) noexcept;
922 
923  template<typename ST, typename SAlloc>
924  friend void swap(Array<ST, SAlloc>& left, Array<ST, SAlloc>& right);
925 
926  // Swap this array with another array.
927  // Normally, casacore::swap() should be used instead.
928  void swap(Array<T, Alloc>& other);
929 
930  // pre/post processing hook of takeStorage() for subclasses.
931  virtual void preTakeStorage(const IPosition &) {}
932 
933  virtual void postTakeStorage() {}
934 
935  // This function is called when this array is about to be resized, before
936  // any work is done. Subclasses can throw an exception if the size doesn't
937  // match, e.g. if a Matrix is resized to have 3 dimensions.
938  // Before this function existed, assign-like functions had to be virtual.
939  // However, for non-copyable types, assign can't exist. This is fine for
940  // non-virtual methods (they just can't be called), but virtual methods
941  // cause the who class to fail to be instantiatable.
942  void checkBeforeResize(const IPosition &newShape)
943  {
944  if(fixedDimensionality() !=0 && newShape.size() != fixedDimensionality())
945  throw(ArrayNDimError(fixedDimensionality(), newShape.size(),
946  std::string("Invalid size given to ") + typeid(*this).name() +
947  ": should have dimensionality of " + std::to_string(fixedDimensionality())));
948  }
949 
950  // Subclasses can return their dimensionality. The Array class will make sure
951  // that whenever it is resized, the dimensionality is checked.
952  // Array's constructors do not check the dimensionality, because the subclass
953  // hasn't been created yet at that point. Subclasses should therefore make
954  // sure to call the constructors appropriately.
955  // For classes that return 0, any resize will be allowed.
956  virtual size_t fixedDimensionality() const { return 0; }
957 
958  virtual void checkAssignableType(ArrayBase& arrayBase) const
959  {
960  const Array<T, Alloc>* pa = dynamic_cast<const Array<T, Alloc>*>(&arrayBase);
961  if (pa == nullptr) {
962  throw ArrayError("ArrayBase& has incorrect template type");
963  }
964  }
965 
966  static void copyToContiguousStorage(T *dst, Array<T, Alloc> const& src)
967  {
968  copyToContiguousStorage(dst, src, std::is_copy_assignable<T>());
969  }
970 
971  // Remove the degenerate axes from the Array object.
972  // This is the implementation of the nonDegenerate functions.
973  // It has a different name to be able to make it virtual without having
974  // the "hide virtual function" message when compiling derived classes.
975  virtual void doNonDegenerate(const Array<T, Alloc> &other,
976  const IPosition &ignoreAxes);
977 
978 
979  // Shared pointer to a Storage that contains the data.
980  std::shared_ptr<arrays_internal::Storage<T, Alloc>> data_p;
981 
982  // This pointer is adjusted to point to the first element of the array.
983  // It is not necessarily the same thing as data->storage() since
984  // this array might be a section, e.g. have a blc which shifts us forward
985  // into the block.
987 
988  // The end for an STL-style iteration.
989  T* end_p;
990 
991 
992  // Fill the steps and the end for a derived class.
993  void makeSteps()
994  { baseMakeSteps(); this->setEndIter(); }
995 
996  // Set the end iterator.
997  void setEndIter()
998  { end_p = (nels_p==0 ? 0 : (contiguous_p ? begin_p + nels_p :
999  begin_p + size_t(length_p(ndim()-1)) * steps_p(ndim()-1))); }
1000 };
1001 
1002 // Swap the first array with the second.
1003 // This is more efficient than std::swap()
1004 template<typename T, typename Alloc>
1006 {
1007  first.swap(second);
1008 }
1009 
1010 //# Declare extern templates for often used types.
1011 extern template class Array<bool, std::allocator<bool>>;
1012 extern template class Array<char, std::allocator<char>>;
1013 extern template class Array<unsigned char, std::allocator<unsigned char>>;
1014 extern template class Array<short, std::allocator<short>>;
1015 extern template class Array<unsigned short, std::allocator<unsigned short>>;
1016 extern template class Array<int, std::allocator<int>>;
1017 extern template class Array<long long, std::allocator<long long>>;
1018 extern template class Array<float, std::allocator<float>>;
1019 extern template class Array<double, std::allocator<double>>;
1020 
1021 }//#End casa namespace
1022 
1023 #include "ArrayStr.h"
1024 #include "Array.tcc"
1025 
1026 #endif
const Array< T, Alloc > * itsArray
Definition: Array.h:728
A Vector of integers, for indexing into Array&lt;T&gt; objects.
Definition: IPosition.h:118
bool conform2(const ArrayBase &other) const
Are the shapes identical?
Definition: ArrayBase.h:247
void set(const T &value)
Set every element of the array to &quot;value.&quot; Also could use the assignment operator which assigns an ar...
void * getVStorage(bool &deleteIt) override
The following functions behave the same as the corresponding getStorage functions in the derived temp...
T * pointer
Pointer to an element type.
Definition: Array.h:849
void increment()
Increment iterator for a non-contiguous array.
const ConstIteratorSTL & operator++()
Definition: Array.h:793
void checkBeforeResize(const IPosition &newShape)
This function is called when this array is about to be resized, before any work is done...
Definition: Array.h:942
Non-templated base class for templated Array class.
Definition: ArrayBase.h:72
const IteratorSTL & operator++()
Definition: Array.h:752
bool contiguous_p
Are the data contiguous?
Definition: ArrayBase.h:273
This is a tag for the constructor that may be used to construct an uninitialized Array.
Definition: Array.h:181
value_type * pointer
Definition: Array.h:738
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
IteratorSTL operator++(int)
Definition: Array.h:757
IteratorSTL(Array< T, Alloc > &arr)
Create the begin iterator object for an Array.
Definition: Array.h:745
IPosition steps_p
Used to hold the step to next element in each dimension.
Definition: ArrayBase.h:278
Array< T, Alloc > & operator=(const Array< T, Alloc > &other)
TODO we should change the semantics.
Definition: Array.h:300
const T & operator*() const
Definition: Array.h:805
static struct casacore::Array::uninitializedType uninitialized
struct Node * first
Definition: malloc.h:330
const_iterator begin() const
Definition: Array.h:861
StorageInitPolicy
A global enum used by some Array constructors.
Definition: ArrayBase.h:51
Array< T, Alloc > reform(const IPosition &shape) const
It is occasionally useful to have an array which access the same storage appear to have a different s...
Array(const Alloc &allocator=Alloc())
Result has dimensionality of zero, and nelements is zero.
size_t nels_p
Number of elements in the array.
Definition: ArrayBase.h:269
Array< T, Alloc > diagonals(size_t firstAxis=0, long long diag=0) const
Get the diagonal of each matrix part in the full array.
The base class for all Array exception classes.
Definition: ArrayError.h:59
void putStorage(T *&storage, bool deleteAndCopy)
putStorage() is normally called after a call to getStorage() (cf).
See the function begin() and end() for a detailed description of the STL iterator capability...
Definition: Array.h:682
T * contiter
Definition: Array.h:854
virtual std::unique_ptr< ArrayBase > makeArray() const override
Make an empty array of the same template type.
const value_type & reference
Definition: Array.h:777
virtual size_t fixedDimensionality() const
Subclasses can return their dimensionality.
Definition: Array.h:956
TableExprNode marray(const TableExprNode &array, const TableExprNode &mask)
Form a masked array.
Definition: ExprNode.h:1935
size_t ndim() const
The dimensionality of this array.
Definition: ArrayBase.h:98
void makeSteps()
Fill the steps and the end for a derived class.
Definition: Array.h:993
T * end_p
The end for an STL-style iteration.
Definition: Array.h:989
size_t nrefs() const
The number of references the underlying storage has assigned to it.
contiter cend()
Definition: Array.h:875
iterator end()
Definition: Array.h:863
friend std::ostream & operator<<(std::ostream &os, const BaseIteratorSTL &iter)
Definition: Array.h:715
const_contiter cend() const
Definition: Array.h:877
Iterate an Array cursor through another Array.
Definition: ArrayFwd.h:18
IteratorSTL iterator
Definition: Array.h:852
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array...
Definition: ArrayBase.h:276
void copyMatchingPart(const Array< T, Alloc > &from)
This function copies the matching part of from array to this array.
Array< T, Alloc > operator[](size_t i) const
Get the subset given by the i-th value of the last axis.
friend void swap(Array< ST, SAlloc > &left, Array< ST, SAlloc > &right)
Class for masking an Array for operations on that Array.
Definition: ArrayFwd.h:14
size_t size() const
Definition: IPosition.h:572
const T * const_pointer
Constant pointer to the element type.
Definition: Array.h:851
T & operator()(const IPosition &)
Access a single element of the array.
static void copyToContiguousStorage(T *dst, Array< T, Alloc > const &src, std::true_type)
bool operator!=(const BaseIteratorSTL &other) const
Definition: Array.h:709
void assign(const Array< T, Alloc > &other)
Assign the other array to this array.
BaseIteratorSTL(const Array< T, Alloc > &)
Create the begin const_iterator object for an Array.
LatticeExprNode pa(const LatticeExprNode &left, const LatticeExprNode &right)
This function finds 180/pi*atan2(left,right)/2.
void freeStorage(const T *&storage, bool deleteIt) const
If deleteIt is set, delete &quot;storage&quot;.
Array< T, Alloc > nonDegenerate(size_t startingAxis=0, bool throwIfError=true) const
These member functions remove degenerate (ie.
std::forward_iterator_tag iterator_category
Definition: Array.h:780
void assignBase(const ArrayBase &other, bool checkType=true) override
Assign the source array to this array.
ConstIteratorSTL operator++(int)
Definition: Array.h:798
ConstIteratorSTL(const T *end=0)
Create the end const_iterator object for an Array.
Definition: Array.h:787
T * begin_p
This pointer is adjusted to point to the first element of the array.
Definition: Array.h:986
void removeDegenerate(size_t startingAxis=0, bool throwIfError=true)
Remove degenerate axes from this Array object.
std::string to_string(const IPosition &ip)
bool reformOrResize(const IPosition &newShape, size_t resizePercentage=0, bool resizeIfNeeded=true)
Having an array that can be reused without requiring reallocation can be useful for large arrays...
Alloc & allocator()
Retrieve the allocator associated with this array.
Definition: Array.h:234
const Array< T, Alloc > addDegenerate(size_t numAxes) const
This member function returns an Array reference with the specified number of extra axes...
Array< T, Alloc > copy() const
This makes a copy of the array and returns it.
Definition: Array.h:341
void swap(Array< T, Alloc > &first, Array< T, Alloc > &second)
Swap the first array with the second.
Definition: Array.h:1005
Array< T, Alloc > & assign_conforming_implementation(const Array< T, Alloc > &other, std::true_type)
Implementation for assign for copyable types.
void nonDegenerate(const Array< T, Alloc > &other, const IPosition &ignoreAxes)
Definition: Array.h:473
const_contiter cbegin() const
Definition: Array.h:873
std::shared_ptr< arrays_internal::Storage< T, Alloc > > data_p
Shared pointer to a Storage that contains the data.
Definition: Array.h:980
bool isUnique() const
An Array is unique when the container is shared and when nrefs==1.
Definition: Array.h:914
A templated N-D Array class with zero origin. Array&lt;T, Alloc&gt; is a templated, N-dimensional, Array class. The origin is zero, but by default indices are zero-based. This Array class is the base class for the Vector, Matrix, and Cube subclasses.
Definition: Array.h:156
void baseMakeSteps()
Make the indexing step sizes.
void freeVStorage(const void *&storage, bool deleteIt) const override
bool adjustLastAxis(const IPosition &newShape, size_t resizePercentage=0, bool resizeIfNeeded=true)
Use this method to extend or reduce the last dimension of an array.
virtual void takeStorage(const IPosition &shape, T *storage, StorageInitPolicy policy=COPY, const Alloc &allocator=Alloc())
Replace the data values with those in the pointer storage.
const T * const_contiter
Definition: Array.h:855
Specify which elements to extract from an n-dimensional array.
Definition: Slicer.h:288
const Double second
Time interval [T]:
Array< T, Alloc > & assign_conforming(const Array< T, Alloc > &other)
Copy the values in other to this.
Definition: Array.h:285
const T * data() const
Definition: Array.h:606
std::vector< T > tovector() const
virtual void doNonDegenerate(const Array< T, Alloc > &other, const IPosition &ignoreAxes)
Remove the degenerate axes from the Array object.
COPY is used when an internal copy of the storage is to be made.
Definition: ArrayBase.h:54
virtual void reference(const Array< T, Alloc > &other)
After invocation, this array and other reference the same storage.
virtual bool ok() const override
Check to see if the Array is consistent.
IteratorSTL(const T *end=0)
Create the end iterator object for an Array.
Definition: Array.h:749
std::unique_ptr< ArrayBase > getSection(const Slicer &) const override
Get a reference to a section of an array.
ConstIteratorSTL const_iterator
Definition: Array.h:853
void unique()
This ensures that this array does not reference any other storage.
void setEndIter()
Set the end iterator.
Definition: Array.h:997
bool conform(const Array< T, Alloc > &other) const
Are the shapes identical?
Definition: Array.h:596
void resize()
Make this array a different shape.
Array< T, Alloc > & assign_conforming_implementation(const Array< T, Alloc > &, std::false_type)
Implementation for assign for non-copyable types: can not be assigned.
Definition: Array.h:903
static void copyToContiguousStorage(T *, Array< T, Alloc > const &, std::false_type)
Definition: Array.h:908
const Alloc & allocator() const
Definition: Array.h:235
iterator begin()
Get the begin iterator object for any array.
Definition: Array.h:859
std::forward_iterator_tag iterator_category
Definition: Array.h:742
Thrown when two arrays have different dimensionality.
Definition: ArrayError.h:134
T * getStorage(bool &deleteIt)
Generally use of this should be shunned, except to use a FORTRAN routine or something similar...
void apply(Callable function)
Apply the function to every element of the array.
const T * pos() const
Definition: Array.h:810
contiter cbegin()
Get the begin iterator object for a contiguous array.
Definition: Array.h:871
const value_type * pointer
Definition: Array.h:776
virtual void checkAssignableType(ArrayBase &arrayBase) const
Definition: Array.h:958
Array< T, Alloc > & operator=(const MaskedArray< T, Alloc, MaskAlloc > &marray)
Calls assign_conforming().
Definition: Array.h:305
static void copyToContiguousStorage(T *dst, Array< T, Alloc > const &src)
Definition: Array.h:966
bool operator==(const BaseIteratorSTL &other) const
Definition: Array.h:706
const T & const_reference
TODO This is how std containers define a reference type, but the name &#39;reference&#39; is already taken by...
Definition: Array.h:847
virtual void preTakeStorage(const IPosition &)
pre/post processing hook of takeStorage() for subclasses.
Definition: Array.h:931
std::unique_ptr< ArrayPositionIterator > makeIterator(size_t byDim) const override
Create an ArrayIterator object of the correct type.
ConstIteratorSTL(const Array< T, Alloc > &arr)
Create the begin const_iterator object for an Array.
Definition: Array.h:783
Alloc allocator_type
Define the STL-style iterator functions (only forward iterator).
Definition: Array.h:841
value_type & reference
Definition: Array.h:739
const_iterator end() const
Definition: Array.h:865
T * data()
Get a pointer to the beginning of the array.
Definition: Array.h:604
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
size_t capacity() const
Returns the number of elements allocated.
virtual void postTakeStorage()
Definition: Array.h:933
T value_type
Element type.
Definition: Array.h:843
ConstIteratorSTL(const IteratorSTL &iter)
Create from a non-const iterator.
Definition: Array.h:790
const IPosition & shape() const
The length of each axis.
Definition: ArrayBase.h:125
void putVStorage(void *&storage, bool deleteAndCopy) override
const T * getStorage(bool &deleteIt) const
Definition: Array.h:632