PSCF v1.4.0
DArray.h
1#ifndef UTIL_D_ARRAY_H
2#define UTIL_D_ARRAY_H
3
4/*
5* Util Package - C++ Utilities for Scientific Computation
6*
7* Copyright 2010 - 2017, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include <util/containers/Array.h>
12#include <util/misc/Memory.h>
13#include <util/global.h>
14
15namespace Util
16{
17
30 template <typename Data>
31 class DArray : public Array<Data>
32 {
33
34 public:
35
40
47
55 DArray(DArray<Data> const & other);
56
62 virtual ~DArray();
63
78
93 DArray<Data>& operator = (Array<Data> const & other);
94
103
110
123
127 bool isAllocated() const;
128
135 template <class Archive>
136 void serialize(Archive& ar, const unsigned int version);
137
138 protected:
139
140 using Array<Data>::data_;
141 using Array<Data>::capacity_;
142
143 };
144
145 // Inline member function definition
146
147 /*
148 * Return true iff the data pointer is non-null, false otherwise.
149 */
150 template <typename Data> inline
152 { return (bool)data_; }
153
154 // Non-inline member function definitions
155
156 /*
157 * Default constructor.
158 */
159 template <typename Data>
161 : Array<Data>()
162 {}
163
164 /*
165 * Allocating constructor.
166 */
167 template <typename Data>
169 : Array<Data>()
170 { allocate(capacity); }
171
172 /*
173 * Copy constructor.
174 *
175 * Allocates memory and copies all elements by value.
176 *
177 *\param other the DArray to be copied.
178 */
179 template <typename Data>
181 : Array<Data>()
182 {
183 if (!other.isAllocated()) {
184 UTIL_THROW("Other DArray must be allocated.");
185 }
187 capacity_ = other.capacity_;
188 for (int i = 0; i < capacity_; ++i) {
189 data_[i] = other.data_[i];
190 }
191 }
192
193 /*
194 * Destructor.
195 */
196 template <typename Data>
198 {
199 if (isAllocated()) {
201 capacity_ = 0;
202 }
203 }
204
205 /*
206 * Assignment, element-by-element.
207 *
208 * This operator will allocate memory if not allocated previously.
209 */
210 template <typename Data>
212 {
213 // Check for self assignment
214 if (this == &other) return *this;
215
216 // Precondition - require that other (RHS) array is allocated
217 if (!other.isAllocated()) {
218 UTIL_THROW("Other DArray must be allocated.");
219 }
220
221 // Allocate this (LHS) array if necessary
222 if (!isAllocated()) {
223 allocate(other.capacity());
224 }
225
226 // Require equal capacities
227 if (capacity_ != other.capacity_) {
228 UTIL_THROW("Cannot assign DArrays of unequal capacity");
229 }
230
231 // Copy all elements
232 for (int i = 0; i < capacity_; ++i) {
233 data_[i] = other[i];
234 }
235
236 return *this;
237 }
238
239 /*
240 * Assignment from an Array<Data> (deep copy).
241 */
242 template <typename Data>
243 DArray<Data>& DArray<Data>::operator = (Array<Data> const & other)
244 {
245 // Check for self assignment
246 if (dynamic_cast< Array<Data>* >(this) == &other) return *this;
247
248 // Precondition - other RHS array must be allocated
249 UTIL_CHECK(other.capacity() > 0);
250
251 // If this LHS array is not allocated, then allocate
252 if (!isAllocated()) {
253 allocate(other.capacity());
254 }
255
256 // Copy elements
257 UTIL_CHECK(capacity_ == other.capacity());
258 for (int i = 0; i < capacity_; ++i) {
259 data_[i] = other[i];
260 }
261
262 return *this;
263 }
264
265 /*
266 * Allocate the underlying C array.
267 */
268 template <typename Data>
270 {
271 if (capacity <= 0) {
272 UTIL_THROW("Attempt to allocate with capacity <= 0");
273 }
274 if (isAllocated()) {
275 UTIL_THROW("Attempt to re-allocate a DArray");
276 }
279 }
280
281 /*
282 * Deallocate the underlying C array.
283 */
284 template <typename Data>
286 {
287 if (!isAllocated()) {
288 UTIL_THROW("Array is not allocated");
289 }
291 capacity_ = 0;
292 }
293
294 /*
295 * Reallocate and copy the underlying C array.
296 */
297 template <typename Data>
310
311 /*
312 * Serialize a DArray to/from an Archive.
313 */
314 template <typename Data>
315 template <class Archive>
316 void DArray<Data>::serialize(Archive& ar, const unsigned int version)
317 {
318 int capacity;
319 if (Archive::is_saving()) {
321 }
322 ar & capacity;
323 if (Archive::is_loading()) {
324 if (!isAllocated()) {
325 if (capacity > 0) {
327 }
328 } else {
329 if (capacity != capacity_) {
330 UTIL_THROW("Inconsistent DArray capacities");
331 }
332 }
333 }
334 if (isAllocated()) {
335 for (int i = 0; i < capacity_; ++i) {
336 ar & data_[i];
337 }
338 }
339 }
340
341}
342#endif
int capacity() const
Definition Array.h:144
DArray(DArray< Data > const &other)
Copy constructor.
Definition DArray.h:180
void allocate(int capacity)
Allocate the underlying C array.
Definition DArray.h:269
void deallocate()
Deallocate the underlying C array.
Definition DArray.h:285
void serialize(Archive &ar, const unsigned int version)
Serialize a DArray to/from an Archive.
Definition DArray.h:316
DArray()
Default constructor.
Definition DArray.h:160
bool isAllocated() const
Return true if this DArray has been allocated, false otherwise.
Definition DArray.h:151
virtual ~DArray()
Destructor.
Definition DArray.h:197
void reallocate(int capacity)
Reallocate the underlying C array and copy to new location.
Definition DArray.h:298
DArray(int capacity)
Allocating constructor.
Definition DArray.h:168
DArray< Data > & operator=(DArray< Data > const &other)
Assignment from a DArray<Data> container.
Definition DArray.h:211
static void deallocate(Data *&ptr, size_t size)
Deallocate a C++ array.
Definition Memory.h:157
static void reallocate(Data *&ptr, size_t oldSize, size_t newSize)
Reallocate a C++ array.
Definition Memory.h:175
static void allocate(Data *&ptr, size_t size)
Allocate a C++ array.
Definition Memory.h:136
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition global.h:49
Utility classes for scientific computation.