casacore
Loading...
Searching...
No Matches
ArrayBase.h
Go to the documentation of this file.
1// # ArrayBase.h: Non-templated base class for templated Array class
2// # Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003
3// # Associated Universities, Inc. Washington DC, USA,
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_ARRAYBASE_2_H
27#define CASA_ARRAYBASE_2_H
28
29// # Includes
30#include "IPosition.h"
31
32#include <memory>
33
34namespace casacore { // # NAMESPACE CASACORE - BEGIN
35
36// # Forward declarations.
38class Slicer;
39
40// <summary>
41// A global enum used by some Array constructors.
42// </summary>
43// <synopsis>
44// StorageInitPolicy is used in functions where an array is formed from
45// a shape and an ordinary pointer. This enum should be in Array but that
46// causes gcc to be unhappy.
47// </synopsis>
49 // COPY is used when an internal copy of the storage is to be made.
50 // The array is NOT responsible for deleting the external storage.
52 // TAKE_OVER is used to indicate that the Array should just use the
53 // external storage (i.e., no copy is made). The Array class is now
54 // responsible for deleting the storage (hence it must have come from
55 // a call to new[]).
57 // Share means that the Array will just use the pointer (no copy), however
58 // the Array will NOT delete it upon destruction.
60};
61
62// <summary>
63// Non-templated base class for templated Array class.
64// </summary>
65
66// ArrayBase is only used to factor out common code from the templated
67// Array class.
68
69class ArrayBase {
70 public:
71 ArrayBase() noexcept;
72
73 // Create an array of the given shape, i.e. after construction
74 // array.ndim() == shape.nelements() and array.shape() == shape.
75 // The origin of the Array is zero.
76 explicit ArrayBase(const IPosition& shape);
77
78 // Copy constructor.
79 ArrayBase(const ArrayBase& other);
80
81 ArrayBase(ArrayBase&& source) noexcept;
82
83 // Assignment.
85
86 ArrayBase& operator=(const ArrayBase&) = delete;
87
88 ArrayBase& operator=(ArrayBase&&) noexcept;
89
90 // Destructor.
91 virtual ~ArrayBase() noexcept;
92
93 // The dimensionality of this array.
94 size_t ndim() const { return ndimen_p; }
95
96 // How many elements does this array have? Product of all axis lengths.
97 // <group>
98 size_t nelements() const { return nels_p; }
99 size_t size() const { return nels_p; }
100 // </group>
101
102 // Is the array empty (i.e. no elements)?
103 bool empty() const { return nels_p == 0; }
104
105 // Are the array data contiguous?
106 // If they are not contiguous, <src>getStorage</src> (see below)
107 // needs to make a copy.
108 bool contiguousStorage() const { return contiguous_p; }
109
110 // Check to see if the Array is consistent. This is about the same thing
111 // as checking for invariants. If AIPS_DEBUG is defined, this is invoked
112 // after construction and on entry to most member functions.
113 virtual bool ok() const;
114
115 // The length of each axis.
116 const IPosition& shape() const { return length_p; }
117
118 // A convenience function: endPosition(i) = shape(i) - 1; i.e. this
119 // is the IPosition of the last element of the Array.
121
122 // Return steps to be made if stepping one element in a dimension.
123 // This is the 'physical' step, thus it also works correctly for
124 // non-contiguous arrays. E.g. <src>data() + steps(0)</src> gives
125 // the second element of the first axis.
126 const IPosition& steps() const { return steps_p; }
127
128 // Array version for major change (used by ArrayIO).
129 // enum did not work properly with cfront 3.0.1), so replaced
130 // by a static inline function. Users won't normally use this.
131 static unsigned arrayVersion() { return 3; }
132
133 // Make an empty array of the same type.
134 // <br>The default implementation in ArrayBase throws an exception.
135 virtual std::unique_ptr<ArrayBase> makeArray() const;
136
137 // Resize the array and optionally copy the values.
138 // <br>The default implementation in ArrayBase throws an exception.
139 virtual void resize(const IPosition& newShape, bool copyValues = false);
140
141 // Resize the array and optionally copy the values.
142 // <br>The default implementation in ArrayBase throws an exception.
143 // virtual void resize(const IPosition &newShape, bool copyValues, ArrayInitPolicy policy);
144
145 // Create an ArrayIterator object of the correct type.
146 // This is implemented in the derived Array classes.
147 // <br>The default implementation in ArrayBase throws an exception.
148 virtual std::unique_ptr<ArrayPositionIterator> makeIterator(size_t byDim) const;
149
150 // Get a reference to a section of an array.
151 // This is the same as Array<T>::operator(), but without having to know
152 // the exact template type.
153 // <br>The default implementation in ArrayBase throws an exception.
154 virtual std::unique_ptr<ArrayBase> getSection(const Slicer&) const;
155
156 // Assign the source array to this array.
157 // If <src>checkType==true</src>, it is checked if the underlying template
158 // types match. Otherwise, it is only checked in debug mode (for performance).
159 // <br>The default implementation in ArrayBase throws an exception.
160 virtual void assignBase(const ArrayBase& source, bool checkType = true);
161
162 // The following functions behave the same as the corresponding getStorage
163 // functions in the derived templated Array class.
164 // They handle a pointer to a contiguous block of array data.
165 // If the array is not contiguous, a copy is used to make it contiguous.
166 // <group>
167 virtual void* getVStorage(bool& deleteIt);
168 virtual const void* getVStorage(bool& deleteIt) const;
169 virtual void putVStorage(void*& storage, bool deleteAndCopy);
170 virtual void freeVStorage(const void*& storage, bool deleteIt) const;
171 // <group>
172
173 protected:
174 // For subclasses, this move constructor allows the moved-from object to
175 // obtain a given shape after resizing. This way, e.g. a source Matrix can
176 // still kee a dimensionality of 2.
177 ArrayBase(ArrayBase&& source, const IPosition& shapeForSource) noexcept;
178
179 void swap(ArrayBase& source) noexcept;
180
181 // Either reforms the array if size permits or resizes it to the new shape.
182 // Implementation of Array<T>::reformOrResize (slightly different signature).
183
184 bool reformOrResize(const IPosition& newShape, bool resizeIfNeeded, size_t nReferences,
185 long long nElementsAllocated, bool copyDataIfNeeded, size_t resizePercentage);
186
187 // Determine if the storage of a subset is contiguous.
189
190 // Check if the shape of a vector is correct. If possible, adjust if not.
191 // It is possible if at most one axis has length > 1.
193
194 // Check if the shape of a matrix is correct. Adjust it if smaller.
196
197 // Check if the shape of a cube is correct. Adjust it if smaller.
199
200 // Reform the array to a shape with the same nr of elements. If nonStrict then
201 // caller assumes responsibility for not overrunning storage (avoid or use with extreme care).
202 void baseReform(ArrayBase& tmp, const IPosition& shape, bool strict = true) const;
203
204 // Remove the degenerate axes from the Array object.
205 // This is the implementation of the nonDegenerate functions.
206 // It has a different name to be able to make it virtual without having
207 // the "hide virtual function" message when compiling derived classes.
208 void baseNonDegenerate(const ArrayBase& other, const IPosition& ignoreAxes);
209
210 // These member functions return an Array reference with the specified
211 // number of extra axes, all of length one, appended to the end of the
212 // Array. Note that the <src>reform</src> function can also be
213 // used to add extra axes.
214 void baseAddDegenerate(ArrayBase&, size_t numAxes);
215
216 // Make a subset of an array.
217 // It checks if start,end,incr are within the array limits.
218 // It returns the offset of the subset in the (original) array.
219 size_t makeSubset(ArrayBase& out, const IPosition& b, const IPosition& e, const IPosition& i);
220
221 // Set the length and stride such that the diagonal of the matrices
222 // defined by two consecutive axes is formed.
223 // <src>diag</src> == 0 indicates the main diagonal, >0 above, <0 below.
224 // It returns the offset of the diagonal in the (original) array.
225 size_t makeDiagonal(size_t firstAxis, long long diag);
226
227 // Are the shapes identical?
228 bool conform2(const ArrayBase& other) const { return length_p.isEqual(other.length_p); }
229
230 // Make the indexing step sizes.
232
233 // Helper function for templated Vector class.
234 // It returns if this and other are conformant.
235 bool copyVectorHelper(const ArrayBase& other);
236
237 public:
238 // Various helper functions.
239 // <group>
240 void validateConformance(const ArrayBase&) const;
241 void validateIndex(const IPosition&) const;
242 void validateIndex(size_t index) const;
243 void validateIndex(size_t index1, size_t index2) const;
244 void validateIndex(size_t index1, size_t index2, size_t index3) const;
245 // </group>
246
247 protected:
248 // Number of elements in the array. Cached rather than computed.
249 size_t nels_p;
250 // Dimensionality of the array.
251 size_t ndimen_p;
252 // Are the data contiguous?
254 // Used to hold the shape, increment into the underlying storage
255 // and originalLength of the array.
257 // Used to hold the step to next element in each dimension.
259};
260
261// <summary> General global functions for Arrays. </summary>
262// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArray">
263//
264// <prerequisite>
265// <li> <linkto class=Array>Array</linkto>
266// </prerequisite>
267//
268// <synopsis>
269// These are generally useful global functions which operate on all
270// Arrays.
271// </synopsis>
272//
273// <linkfrom anchor="Array general global functions" classes="Array Vector Matrix Cube">
274// <here>Array general global functions</here> -- General global functions
275// for Arrays.
276// </linkfrom>
277//
278// <group name="Array general global functions">
279
280//
281// What is the volume of an N-dimensional array.
282// Shape[0]*Shape[1]*...*Shape[N-1]. An Array helper function.
283// # Implemented in Array2.cc.
284size_t ArrayVolume(size_t Ndim, const int* Shape);
285
286//
287// What is the linear index into an "Ndim" dimensional array of the given
288// "Shape", "Origin", and "Increment" for a given IPosition Index.
289// An Array helper function.
290// <group>
291// # Implemented in Array2.cc.
292size_t ArrayIndexOffset(size_t Ndim, const ssize_t* Shape, const ssize_t* Origin,
293 const ssize_t* Inc, const IPosition& Index);
294size_t ArrayIndexOffset(size_t Ndim, const ssize_t* Shape, const ssize_t* Inc,
295 const IPosition& Index);
296// </group>
297
298// Function to check the shapes. It throws an exception if not equal.
299// <group>
300void throwArrayShapes(const IPosition& shape1, const IPosition& shape2, const char* name);
301inline void checkArrayShapes(const ArrayBase& left, const ArrayBase& right, const char* name) {
302 if (!left.shape().isEqual(right.shape())) {
303 throwArrayShapes(left.shape(), right.shape(), name);
304 }
305}
306// </group>
307
308// </group>
309
310} // namespace casacore
311
312#endif
Non-templated base class for templated Array class.
Definition ArrayBase.h:69
virtual bool ok() const
Check to see if the Array is consistent.
void validateIndex(size_t index1, size_t index2, size_t index3) const
static unsigned arrayVersion()
Array version for major change (used by ArrayIO).
Definition ArrayBase.h:131
void validateConformance(const ArrayBase &) const
Various helper functions.
ArrayBase & assign(const ArrayBase &)
Assignment.
void baseNonDegenerate(const ArrayBase &other, const IPosition &ignoreAxes)
Remove the degenerate axes from the Array object.
void baseReform(ArrayBase &tmp, const IPosition &shape, bool strict=true) const
Reform the array to a shape with the same nr of elements.
bool copyVectorHelper(const ArrayBase &other)
Helper function for templated Vector class.
virtual const void * getVStorage(bool &deleteIt) const
const IPosition & steps() const
Return steps to be made if stepping one element in a dimension.
Definition ArrayBase.h:126
void checkMatrixShape()
Check if the shape of a matrix is correct.
ArrayBase(ArrayBase &&source, const IPosition &shapeForSource) noexcept
For subclasses, this move constructor allows the moved-from object to obtain a given shape after resi...
size_t ndim() const
The dimensionality of this array.
Definition ArrayBase.h:94
size_t nels_p
Number of elements in the array.
Definition ArrayBase.h:249
void swap(ArrayBase &source) noexcept
void validateIndex(const IPosition &) const
ArrayBase() noexcept
virtual void assignBase(const ArrayBase &source, bool checkType=true)
Assign the source array to this array.
size_t nelements() const
How many elements does this array have?
Definition ArrayBase.h:98
virtual std::unique_ptr< ArrayBase > getSection(const Slicer &) const
Get a reference to a section of an array.
size_t size() const
Definition ArrayBase.h:99
virtual std::unique_ptr< ArrayBase > makeArray() const
Make an empty array of the same type.
size_t makeSubset(ArrayBase &out, const IPosition &b, const IPosition &e, const IPosition &i)
Make a subset of an array.
size_t ndimen_p
Dimensionality of the array.
Definition ArrayBase.h:251
bool contiguous_p
Are the data contiguous?
Definition ArrayBase.h:253
void baseAddDegenerate(ArrayBase &, size_t numAxes)
These member functions return an Array reference with the specified number of extra axes,...
virtual void freeVStorage(const void *&storage, bool deleteIt) const
IPosition originalLength_p
Definition ArrayBase.h:256
void baseMakeSteps()
Make the indexing step sizes.
bool reformOrResize(const IPosition &newShape, bool resizeIfNeeded, size_t nReferences, long long nElementsAllocated, bool copyDataIfNeeded, size_t resizePercentage)
Either reforms the array if size permits or resizes it to the new shape.
bool contiguousStorage() const
Are the array data contiguous?
Definition ArrayBase.h:108
bool empty() const
Is the array empty (i.e.
Definition ArrayBase.h:103
void validateIndex(size_t index1, size_t index2) const
const IPosition & shape() const
The length of each axis.
Definition ArrayBase.h:116
void validateIndex(size_t index) const
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array.
Definition ArrayBase.h:256
virtual void * getVStorage(bool &deleteIt)
The following functions behave the same as the corresponding getStorage functions in the derived temp...
size_t makeDiagonal(size_t firstAxis, long long diag)
Set the length and stride such that the diagonal of the matrices defined by two consecutive axes is f...
virtual void resize(const IPosition &newShape, bool copyValues=false)
Resize the array and optionally copy the values.
void checkVectorShape()
Check if the shape of a vector is correct.
virtual std::unique_ptr< ArrayPositionIterator > makeIterator(size_t byDim) const
Resize the array and optionally copy the values.
virtual void putVStorage(void *&storage, bool deleteAndCopy)
IPosition steps_p
Used to hold the step to next element in each dimension.
Definition ArrayBase.h:258
bool conform2(const ArrayBase &other) const
Are the shapes identical?
Definition ArrayBase.h:228
IPosition endPosition() const
A convenience function: endPosition(i) = shape(i) - 1; i.e.
void checkCubeShape()
Check if the shape of a cube is correct.
bool isStorageContiguous() const
Determine if the storage of a subset is contiguous.
bool isEqual(const IPosition &other) const
Element-by-element comparison for equality.
StorageInitPolicy
Definition ArrayBase.h:48
size_t ArrayVolume(size_t Ndim, const int *Shape)
General global functions for Arrays.
@ COPY
COPY is used when an internal copy of the storage is to be made.
Definition ArrayBase.h:51
@ SHARE
Share means that the Array will just use the pointer (no copy), however the Array will NOT delete it ...
Definition ArrayBase.h:59
@ TAKE_OVER
TAKE_OVER is used to indicate that the Array should just use the external storage (i....
Definition ArrayBase.h:56
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
void checkArrayShapes(const ArrayBase &left, const ArrayBase &right, const char *name)
Definition ArrayBase.h:301
size_t ArrayIndexOffset(size_t Ndim, const ssize_t *Shape, const ssize_t *Origin, const ssize_t *Inc, const IPosition &Index)
What is the linear index into an "Ndim" dimensional array of the given "Shape", "Origin",...
T * storage()
If you really, really, need a "raw" pointer to the beginning of the storage area this will give it to...
Definition Block.h:559
String name() const
Return the name of the field.
void throwArrayShapes(const IPosition &shape1, const IPosition &shape2, const char *name)
Function to check the shapes.