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.
37class ArrayPositionIterator;
38class Slicer;
39
40
41// <summary>
42// A global enum used by some Array constructors.
43// </summary>
44// <synopsis>
45// StorageInitPolicy is used in functions where an array is formed from
46// a shape and an ordinary pointer. This enum should be in Array but that
47// causes gcc to be unhappy.
48// </synopsis>
50 // COPY is used when an internal copy of the storage is to be made.
51 // The array is NOT responsible for deleting the external storage.
53 // TAKE_OVER is used to indicate that the Array should just use the
54 // external storage (i.e., no copy is made). The Array class is now
55 // responsible for deleting the storage (hence it must have come from
56 // a call to new[]).
58 // Share means that the Array will just use the pointer (no copy), however
59 // the Array will NOT delete it upon destruction.
61
62
63// <summary>
64// Non-templated base class for templated Array class.
65// </summary>
66
67// ArrayBase is only used to factor out common code from the templated
68// Array class.
69
71{
72public:
73 ArrayBase() noexcept;
74
75 // Create an array of the given shape, i.e. after construction
76 // array.ndim() == shape.nelements() and array.shape() == shape.
77 // The origin of the Array is zero.
78 explicit ArrayBase (const IPosition& shape);
79
80 // Copy constructor.
81 ArrayBase (const ArrayBase& other);
82
83 ArrayBase (ArrayBase&& source) noexcept;
84
85 // Assignment.
87
88 ArrayBase& operator=(const ArrayBase&) = delete;
89
90 ArrayBase& operator=(ArrayBase&&) noexcept;
91
92 // Destructor.
93 virtual ~ArrayBase() noexcept;
94
95 // The dimensionality of this array.
96 size_t ndim() const
97 { return ndimen_p; }
98
99 // How many elements does this array have? Product of all axis lengths.
100 // <group>
101 size_t nelements() const
102 { return nels_p; }
103 size_t size() const
104 { return nels_p; }
105 // </group>
106
107 // Is the array empty (i.e. no elements)?
108 bool empty() const
109 { return nels_p == 0; }
110
111 // Are the array data contiguous?
112 // If they are not contiguous, <src>getStorage</src> (see below)
113 // needs to make a copy.
114 bool contiguousStorage() const
115 { return contiguous_p; }
116
117 // Check to see if the Array is consistent. This is about the same thing
118 // as checking for invariants. If AIPS_DEBUG is defined, this is invoked
119 // after construction and on entry to most member functions.
120 virtual bool ok() const;
121
122 // The length of each axis.
123 const IPosition& shape() const
124 { return length_p; }
125
126 // A convenience function: endPosition(i) = shape(i) - 1; i.e. this
127 // is the IPosition of the last element of the Array.
129
130 // Return steps to be made if stepping one element in a dimension.
131 // This is the 'physical' step, thus it also works correctly for
132 // non-contiguous arrays. E.g. <src>data() + steps(0)</src> gives
133 // the second element of the first axis.
134 const IPosition& steps() const
135 { return steps_p; }
136
137 // Array version for major change (used by ArrayIO).
138 // enum did not work properly with cfront 3.0.1), so replaced
139 // by a static inline function. Users won't normally use this.
140 static unsigned arrayVersion()
141 {return 3;}
142
143 // Make an empty array of the same type.
144 // <br>The default implementation in ArrayBase throws an exception.
145 virtual std::unique_ptr<ArrayBase> makeArray() const;
146
147 // Resize the array and optionally copy the values.
148 // <br>The default implementation in ArrayBase throws an exception.
149 virtual void resize(const IPosition &newShape, bool copyValues=false);
150
151 // Resize the array and optionally copy the values.
152 // <br>The default implementation in ArrayBase throws an exception.
153 //virtual void resize(const IPosition &newShape, bool copyValues, ArrayInitPolicy policy);
154
155 // Create an ArrayIterator object of the correct type.
156 // This is implemented in the derived Array classes.
157 // <br>The default implementation in ArrayBase throws an exception.
158 virtual std::unique_ptr<ArrayPositionIterator> makeIterator (size_t byDim) const;
159
160 // Get a reference to a section of an array.
161 // This is the same as Array<T>::operator(), but without having to know
162 // the exact template type.
163 // <br>The default implementation in ArrayBase throws an exception.
164 virtual std::unique_ptr<ArrayBase> getSection (const Slicer&) const;
165
166 // Assign the source array to this array.
167 // If <src>checkType==true</src>, it is checked if the underlying template
168 // types match. Otherwise, it is only checked in debug mode (for performance).
169 // <br>The default implementation in ArrayBase throws an exception.
170 virtual void assignBase (const ArrayBase& source, bool checkType=true);
171
172 // The following functions behave the same as the corresponding getStorage
173 // functions in the derived templated Array class.
174 // They handle a pointer to a contiguous block of array data.
175 // If the array is not contiguous, a copy is used to make it contiguous.
176 // <group>
177 virtual void* getVStorage (bool& deleteIt);
178 virtual const void* getVStorage (bool& deleteIt) const;
179 virtual void putVStorage(void*& storage, bool deleteAndCopy);
180 virtual void freeVStorage(const void*& storage, bool deleteIt) const;
181 // <group>
182
183protected:
184 // For subclasses, this move constructor allows the moved-from object to
185 // obtain a given shape after resizing. This way, e.g. a source Matrix can
186 // still kee a dimensionality of 2.
187 ArrayBase(ArrayBase&& source, const IPosition& shapeForSource) noexcept;
188
189 void swap(ArrayBase& source) noexcept;
190
191 // Either reforms the array if size permits or resizes it to the new shape.
192 // Implementation of Array<T>::reformOrResize (slightly different signature).
193
194 bool reformOrResize (const IPosition & newShape,
195 bool resizeIfNeeded,
196 size_t nReferences,
197 long long nElementsAllocated,
198 bool copyDataIfNeeded,
199 size_t resizePercentage);
200
201 // Determine if the storage of a subset is contiguous.
203
204 // Check if the shape of a vector is correct. If possible, adjust if not.
205 // It is possible if at most one axis has length > 1.
207
208 // Check if the shape of a matrix is correct. Adjust it if smaller.
210
211 // Check if the shape of a cube is correct. Adjust it if smaller.
213
214 // Reform the array to a shape with the same nr of elements. If nonStrict then
215 // caller assumes responsibility for not overrunning storage (avoid or use with extreme care).
216 void baseReform (ArrayBase& tmp, const IPosition& shape, bool strict=true) const;
217
218 // Remove the degenerate axes from the Array object.
219 // This is the implementation of the nonDegenerate functions.
220 // It has a different name to be able to make it virtual without having
221 // the "hide virtual function" message when compiling derived classes.
222 void baseNonDegenerate (const ArrayBase& other, const IPosition& ignoreAxes);
223
224 // These member functions return an Array reference with the specified
225 // number of extra axes, all of length one, appended to the end of the
226 // Array. Note that the <src>reform</src> function can also be
227 // used to add extra axes.
228 void baseAddDegenerate (ArrayBase&, size_t numAxes);
229
230 // Make a subset of an array.
231 // It checks if start,end,incr are within the array limits.
232 // It returns the offset of the subset in the (original) array.
233 size_t makeSubset (ArrayBase& out,
234 const IPosition& b,
235 const IPosition& e,
236 const IPosition& i);
237
238 // Set the length and stride such that the diagonal of the matrices
239 // defined by two consecutive axes is formed.
240 // <src>diag</src> == 0 indicates the main diagonal, >0 above, <0 below.
241 // It returns the offset of the diagonal in the (original) array.
242 size_t makeDiagonal (size_t firstAxis, long long diag);
243
244 // Are the shapes identical?
245 bool conform2 (const ArrayBase& other) const
246 { return length_p.isEqual (other.length_p); }
247
248 // Make the indexing step sizes.
250
251 // Helper function for templated Vector class.
252 // It returns if this and other are conformant.
253 bool copyVectorHelper (const ArrayBase& other);
254
255public:
256 // Various helper functions.
257 // <group>
258 void validateConformance (const ArrayBase&) const;
259 void validateIndex (const IPosition&) const;
260 void validateIndex (size_t index) const;
261 void validateIndex (size_t index1, size_t index2) const;
262 void validateIndex (size_t index1, size_t index2, size_t index3) const;
263 // </group>
264
265protected:
266 // Number of elements in the array. Cached rather than computed.
267 size_t nels_p;
268 // Dimensionality of the array.
269 size_t ndimen_p;
270 // Are the data contiguous?
272 // Used to hold the shape, increment into the underlying storage
273 // and originalLength of the array.
275 // Used to hold the step to next element in each dimension.
277};
278
279
280// <summary> General global functions for Arrays. </summary>
281// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArray">
282//
283// <prerequisite>
284// <li> <linkto class=Array>Array</linkto>
285// </prerequisite>
286//
287// <synopsis>
288// These are generally useful global functions which operate on all
289// Arrays.
290// </synopsis>
291//
292// <linkfrom anchor="Array general global functions" classes="Array Vector Matrix Cube">
293// <here>Array general global functions</here> -- General global functions
294// for Arrays.
295// </linkfrom>
296//
297// <group name="Array general global functions">
298
299//
300// What is the volume of an N-dimensional array.
301// Shape[0]*Shape[1]*...*Shape[N-1]. An Array helper function.
302//# Implemented in Array2.cc.
303size_t ArrayVolume (size_t Ndim, const int* Shape);
304
305//
306// What is the linear index into an "Ndim" dimensional array of the given
307// "Shape", "Origin", and "Increment" for a given IPosition Index.
308// An Array helper function.
309// <group>
310//# Implemented in Array2.cc.
311size_t ArrayIndexOffset (size_t Ndim, const ssize_t* Shape,
312 const ssize_t* Origin, const ssize_t* Inc,
313 const IPosition& Index);
314size_t ArrayIndexOffset (size_t Ndim, const ssize_t* Shape,
315 const ssize_t* Inc, const IPosition& Index);
316// </group>
317
318// Function to check the shapes. It throws an exception if not equal.
319// <group>
320void throwArrayShapes (const IPosition& shape1,
321 const IPosition& shape2,
322 const char* name);
323inline void checkArrayShapes (const ArrayBase& left, const ArrayBase& right,
324 const char* name)
325{
326 if (! left.shape().isEqual (right.shape())) {
327 throwArrayShapes (left.shape(), right.shape(), name);
328 }
329}
330// </group>
331
332// </group>
333
334} //# NAMESPACE CASACORE - END
335
336#endif
Non-templated base class for templated Array class.
Definition ArrayBase.h:71
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:140
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:134
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:96
size_t nels_p
Number of elements in the array.
Definition ArrayBase.h:267
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? Product of all axis lengths.
Definition ArrayBase.h:101
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:103
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:269
bool contiguous_p
Are the data contiguous?
Definition ArrayBase.h:271
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:274
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? If they are not contiguous, getStorage (see below) needs to make a cop...
Definition ArrayBase.h:114
bool empty() const
Is the array empty (i.e.
Definition ArrayBase.h:108
void validateIndex(size_t index1, size_t index2) const
const IPosition & shape() const
The length of each axis.
Definition ArrayBase.h:123
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:274
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:276
bool conform2(const ArrayBase &other) const
Are the shapes identical?
Definition ArrayBase.h:245
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:49
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:52
@ SHARE
Share means that the Array will just use the pointer (no copy), however the Array will NOT delete it ...
Definition ArrayBase.h:60
@ TAKE_OVER
TAKE_OVER is used to indicate that the Array should just use the external storage (i....
Definition ArrayBase.h:57
this file contains all the compiler specific defines
Definition mainpage.dox:28
void checkArrayShapes(const ArrayBase &left, const ArrayBase &right, const char *name)
Definition ArrayBase.h:323
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",...
void throwArrayShapes(const IPosition &shape1, const IPosition &shape2, const char *name)
Function to check the shapes.