casacore
Loading...
Searching...
No Matches
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
45namespace 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
156template<typename T, typename Alloc> class Array : public ArrayBase
157{
158public:
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>
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.
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>.
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>
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;
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>
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>
527 const IPosition &end);
529 const IPosition &end) const;
530 // Along the ith axis, every inc[i]'th element is chosen.
532 const IPosition &end,
533 const IPosition &inc);
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>
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>
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
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) {
697 if (itsPos > itsLineEnd) increment();
698 }
699 }
700 void nextLine()
701 {
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
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;
730 };
731
733 {
734 public:
735 // <group name=STL-iterator-typedefs>
736 typedef T value_type;
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.
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;
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
884private:
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
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
919protected:
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.
990
991
992 // Fill the steps and the end for a derived class.
994 { baseMakeSteps(); this->setEndIter(); }
995
996 // Set the end iterator.
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()
1004template<typename T, typename Alloc>
1006{
1007 first.swap(second);
1008}
1009
1010//# Declare extern templates for often used types.
1011extern template class Array<bool, std::allocator<bool>>;
1012extern template class Array<char, std::allocator<char>>;
1013extern template class Array<unsigned char, std::allocator<unsigned char>>;
1014extern template class Array<short, std::allocator<short>>;
1015extern template class Array<unsigned short, std::allocator<unsigned short>>;
1016extern template class Array<int, std::allocator<int>>;
1017extern template class Array<long long, std::allocator<long long>>;
1018extern template class Array<float, std::allocator<float>>;
1019extern template class Array<double, std::allocator<double>>;
1020
1021}//#End casa namespace
1022
1023#include "ArrayStr.h"
1024#include "Array.tcc"
1025
1026#endif
Non-templated base class for templated Array class.
Definition ArrayBase.h:73
size_t ndim() const
The dimensionality of this array.
Definition ArrayBase.h:98
size_t nels_p
Number of elements in the array.
Definition ArrayBase.h:269
bool contiguous_p
Are the data contiguous?
Definition ArrayBase.h:273
void baseMakeSteps()
Make the indexing step sizes.
const IPosition & shape() const
The length of each axis.
Definition ArrayBase.h:125
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array.
Definition ArrayBase.h:276
IPosition steps_p
Used to hold the step to next element in each dimension.
Definition ArrayBase.h:278
bool conform2(const ArrayBase &other) const
Are the shapes identical?
Definition ArrayBase.h:247
Thrown when two arrays have different dimensionality.
Definition ArrayError.h:135
bool operator!=(const BaseIteratorSTL &other) const
Definition Array.h:709
const Array< T, Alloc > * itsArray
Definition Array.h:728
void increment()
Increment iterator for a non-contiguous array.
bool operator==(const BaseIteratorSTL &other) const
Definition Array.h:706
BaseIteratorSTL(const Array< T, Alloc > &)
Create the begin const_iterator object for an Array.
friend std::ostream & operator<<(std::ostream &os, const BaseIteratorSTL &iter)
Definition Array.h:715
BaseIteratorSTL(const T *end=0)
Create the end const_iterator object for an Array.
Definition Array.h:689
ConstIteratorSTL(const T *end=0)
Create the end const_iterator object for an Array.
Definition Array.h:787
ConstIteratorSTL(const IteratorSTL &iter)
Create from a non-const iterator.
Definition Array.h:790
const T & operator*() const
Definition Array.h:805
std::forward_iterator_tag iterator_category
Definition Array.h:780
const value_type & reference
Definition Array.h:777
const ConstIteratorSTL & operator++()
Definition Array.h:793
ConstIteratorSTL operator++(int)
Definition Array.h:798
const value_type * pointer
Definition Array.h:776
ConstIteratorSTL(const Array< T, Alloc > &arr)
Create the begin const_iterator object for an Array.
Definition Array.h:783
std::forward_iterator_tag iterator_category
Definition Array.h:742
IteratorSTL operator++(int)
Definition Array.h:757
IteratorSTL(Array< T, Alloc > &arr)
Create the begin iterator object for an Array.
Definition Array.h:745
const IteratorSTL & operator++()
Definition Array.h:752
IteratorSTL(const T *end=0)
Create the end iterator object for an Array.
Definition Array.h:749
void resize(const IPosition &newShape, bool copyValues=false) override
Resize the array and optionally copy the values.
virtual size_t fixedDimensionality() const
Subclasses can return their dimensionality.
Definition Array.h:956
friend void swap(Array< ST, SAlloc > &left, Array< ST, SAlloc > &right)
std::unique_ptr< ArrayBase > getSection(const Slicer &) const override
Get a reference to a section of an array.
Array< T, Alloc > copy() const
This makes a copy of the array and returns it.
Definition Array.h:341
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.
virtual void reference(const Array< T, Alloc > &other)
After invocation, this array and other reference the same storage.
void freeVStorage(const void *&storage, bool deleteIt) const override
size_t capacity() const
Returns the number of elements allocated.
Array(const IPosition &shape, const T *storage)
Create an Array of a given shape from a pointer.
Array< T, Alloc > operator()(const IPosition &start, const IPosition &end, const IPosition &inc)
Along the ith axis, every inc[i]'th element is chosen.
const_iterator end() const
Definition Array.h:865
const T & operator()(const IPosition &) const
Alloc allocator_type
Define the STL-style iterator functions (only forward iterator).
Definition Array.h:841
void set(const T &value)
Set every element of the array to "value." Also could use the assignment operator which assigns an ar...
void putVStorage(void *&storage, bool deleteAndCopy) override
const Alloc & allocator() const
Definition Array.h:235
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
const Array< T, Alloc > operator()(const IPosition &start, const IPosition &end) const
static struct casacore::Array::uninitializedType uninitialized
Array< T, Alloc > operator[](size_t i) const
Get the subset given by the i-th value of the last axis.
void freeStorage(const T *&storage, bool deleteIt) const
If deleteIt is set, delete "storage".
void tovector(std::vector< T, U > &out) const
Create an STL vector from an Array.
Array(const IPosition &shape, T *storage, StorageInitPolicy policy=COPY, const Alloc &allocator=Alloc())
Create an Array of a given shape from a pointer.
virtual ~Array() noexcept
Frees up storage only if this array was the last reference to it.
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.
void putStorage(T *&storage, bool deleteAndCopy)
putStorage() is normally called after a call to getStorage() (cf).
Array(const IPosition &shape, Integral startIter, const Alloc &allocator, std::true_type)
Implementation of constructor taking a Shape, a Templated parameter and an allocator.
const T * data() const
Definition Array.h:606
Array< T, Alloc > & operator=(const MaskedArray< T, Alloc, MaskAlloc > &marray)
Calls assign_conforming().
Definition Array.h:305
Array< T, Alloc > & operator=(const Array< T, Alloc > &other)
TODO we should change the semantics.
Definition Array.h:300
void copyMatchingPart(const Array< T, Alloc > &from)
This function copies the matching part of from array to this array.
static void copyToContiguousStorage(T *dst, Array< T, Alloc > const &src)
Definition Array.h:966
Array(const Alloc &allocator=Alloc())
Result has dimensionality of zero, and nelements is zero.
Array< T, Alloc > nonDegenerate(size_t startingAxis=0, bool throwIfError=true) const
These member functions remove degenerate (ie.
Array< T, Alloc > copy(const Alloc &allocator) const
Makes a copy using the allocator.
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 > diagonals(size_t firstAxis=0, long long diag=0) const
Get the diagonal of each matrix part in the full array.
void * getVStorage(bool &deleteIt) override
The following functions behave the same as the corresponding getStorage functions in the derived temp...
void apply(Callable function)
Apply the function to every element of the array.
virtual void postTakeStorage()
Definition Array.h:933
T * data()
Get a pointer to the beginning of the array.
Definition Array.h:604
const void * getVStorage(bool &deleteIt) const override
Array< T, Alloc > & operator=(const T &value)
Set every element of this array to "value".
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
IteratorSTL iterator
Definition Array.h:852
Array(Array< T, Alloc > &&source, const IPosition &shapeForSource) noexcept
Source will be empty with given shape after this call.
void removeDegenerate(const IPosition &ignoreAxes)
bool conform(const MaskedArray< T > &other) const
void resize()
Make this array a different shape.
const T * getStorage(bool &deleteIt) const
Definition Array.h:632
T * pointer
Pointer to an element type.
Definition Array.h:849
Array< T, Alloc > operator()(const Slicer &)
Get a reference to an array section using a Slicer.
contiter cbegin()
Get the begin iterator object for a contiguous array.
Definition Array.h:871
void swap(Array< T, Alloc > &other)
Swap this array with another array.
Array(std::initializer_list< T > list, const Alloc &allocator=Alloc())
Construct a one-dimensional array from an initializer list.
Array(const IPosition &shape, InputIterator startIter, const Alloc &allocator=Alloc())
Construct an array from an iterator and a shape.
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< T, Alloc > operator()(const IPosition &start, const IPosition &end)
Get a reference to an array section extending from start to end (inclusive).
T value_type
Element type.
Definition Array.h:843
Array< T, Alloc > & operator=(Array< T, Alloc > &&other)
The move operator takes the storage from the given array.
T * getStorage(bool &deleteIt)
Generally use of this should be shunned, except to use a FORTRAN routine or something similar.
T * begin_p
This pointer is adjusted to point to the first element of the array.
Definition Array.h:986
virtual std::unique_ptr< ArrayBase > makeArray() const override
Make an empty array of the same template type.
Array(const IPosition &shape, uninitializedType, const Alloc &allocator=Alloc())
Constructor to create an uninitialized array.
const_contiter cbegin() const
Definition Array.h:873
Array< T, Alloc > & assign_conforming_implementation(const Array< T, Alloc > &other, std::true_type)
Implementation for assign for copyable types.
Array(const IPosition &shape, const T &initialValue, const Alloc &allocator=Alloc())
Create an array of the given shape and initialize it with the initial value.
contiter cend()
Definition Array.h:875
virtual void doNonDegenerate(const Array< T, Alloc > &other, const IPosition &ignoreAxes)
Remove the degenerate axes from the Array object.
iterator begin()
Get the begin iterator object for any array.
Definition Array.h:859
void assign(const Array< T, Alloc > &other)
Assign the other array to this array.
const T & const_reference
TODO This is how std containers define a reference type, but the name 'reference' is already taken by...
Definition Array.h:847
const Array< T, Alloc > operator()(const IPosition &start, const IPosition &end, const IPosition &inc) const
T & operator()(const IPosition &)
Access a single element of the array.
void unique()
This ensures that this array does not reference any other storage.
Array(const IPosition &shape, InputIterator startIter, const Alloc &allocator, std::false_type)
Implementation of constructor taking a Shape, a Templated parameter and an allocator.
std::vector< T > tovector() const
const_contiter cend() const
Definition Array.h:877
Array(Array< T, Alloc > &&source) noexcept
Source will be empty after this call.
const T * const_pointer
Constant pointer to the element type.
Definition Array.h:851
Array(const IPosition &shape, const Alloc &allocator=Alloc())
Create an array of the given shape, i.e.
Array< T, Alloc > addDegenerate(size_t numAxes)
virtual void checkAssignableType(ArrayBase &arrayBase) const
Definition Array.h:958
void nonDegenerate(const Array< T, Alloc > &other, size_t startingAxis=0, bool throwIfError=true)
const T * const_contiter
Definition Array.h:855
T * end_p
The end for an STL-style iteration.
Definition Array.h:989
bool conform(const Array< T, Alloc > &other) const
Are the shapes identical?
Definition Array.h:596
void setEndIter()
Set the end iterator.
Definition Array.h:997
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.
void assignBase(const ArrayBase &other, bool checkType=true) override
Assign the source array to this array.
void removeDegenerate(size_t startingAxis=0, bool throwIfError=true)
Remove degenerate axes from this Array object.
Array< T, Alloc > & assign_conforming(const MaskedArray< T, Alloc, MaskAlloc > &marray)
Copy to this those values in marray whose corresponding elements in marray's mask are true.
size_t nrefs() const
The number of references the underlying storage has assigned to it.
static void copyToContiguousStorage(T *, Array< T, Alloc > const &, std::false_type)
Definition Array.h:908
std::shared_ptr< arrays_internal::Storage< T, Alloc > > data_p
Shared pointer to a Storage that contains the data.
Definition Array.h:980
static void copyToContiguousStorage(T *dst, Array< T, Alloc > const &src, std::true_type)
virtual void preTakeStorage(const IPosition &)
pre/post processing hook of takeStorage() for subclasses.
Definition Array.h:931
void makeSteps()
Fill the steps and the end for a derived class.
Definition Array.h:993
virtual bool ok() const override
Check to see if the Array is consistent.
iterator end()
Definition Array.h:863
void nonDegenerate(const Array< T, Alloc > &other, const IPosition &ignoreAxes)
Definition Array.h:473
const_iterator begin() const
Definition Array.h:861
Array< T, Alloc > & assign_conforming(const Array< T, Alloc > &other)
Copy the values in other to this.
Definition Array.h:285
Alloc & allocator()
Retrieve the allocator associated with this array.
Definition Array.h:234
bool isUnique() const
An Array is unique when the container is shared and when nrefs==1.
Definition Array.h:914
Array< T, Alloc > nonDegenerate(const IPosition &ignoreAxes) const
Array(const Array< T, Alloc > &other)
After construction, this and other reference the same storage.
std::unique_ptr< ArrayPositionIterator > makeIterator(size_t byDim) const override
Create an ArrayIterator object of the correct type.
const Array< T, Alloc > operator()(const Slicer &) const
ConstIteratorSTL const_iterator
Definition Array.h:853
size_t size() const
Definition IPosition.h:572
StorageInitPolicy
Definition ArrayBase.h:51
@ COPY
COPY is used when an internal copy of the storage is to be made.
Definition ArrayBase.h:54
struct Node * first
Definition malloc.h:330
this file contains all the compiler specific defines
Definition mainpage.dox:28
LatticeExprNode pa(const LatticeExprNode &left, const LatticeExprNode &right)
This function finds 180/pi*atan2(left,right)/2.
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
TableExprNode marray(const TableExprNode &array, const TableExprNode &mask)
Form a masked array.
Definition ExprNode.h:1935
void swap(Array< T, Alloc > &first, Array< T, Alloc > &second)
Swap the first array with the second.
Definition Array.h:1005
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
Definition Complex.h:352
This is a tag for the constructor that may be used to construct an uninitialized Array.
Definition Array.h:181