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