PSCF v1.1
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
48 DArray(DArray<Data> const & other);
49
55 virtual ~DArray();
56
71
79 void allocate(int capacity);
80
86 void deallocate();
87
97
101 bool isAllocated() const;
102
109 template <class Archive>
110 void serialize(Archive& ar, const unsigned int version);
111
112 protected:
113
114 using Array<Data>::data_;
115 using Array<Data>::capacity_;
116
117 };
118
119
120 /*
121 * Constructor.
122 */
123 template <class Data>
125 : Array<Data>()
126 {}
127
128 /*
129 * Copy constructor.
130 *
131 * Allocates new memory and copies all elements by value.
132 *
133 *\param other the DArray to be copied.
134 */
135 template <class Data>
137 : Array<Data>()
138 {
139 if (!other.isAllocated()) {
140 UTIL_THROW("Other DArray must be allocated.");
141 }
143 capacity_ = other.capacity_;
144 for (int i = 0; i < capacity_; ++i) {
145 data_[i] = other.data_[i];
146 }
147 }
148
149 /*
150 * Destructor.
151 */
152 template <class Data>
154 {
155 if (isAllocated()) {
156 Memory::deallocate<Data>(data_, capacity_);
157 capacity_ = 0;
158 }
159 }
160
161 /*
162 * Assignment, element-by-element.
163 *
164 * This operator will allocate memory if not allocated previously.
165 */
166 template <class Data>
168 {
169 // Check for self assignment
170 if (this == &other) return *this;
171
172 // Precondition
173 if (!other.isAllocated()) {
174 UTIL_THROW("Other DArray must be allocated.");
175 }
176
177 if (!isAllocated()) {
178 allocate(other.capacity());
179 } else if (capacity_ != other.capacity_) {
180 UTIL_THROW("Cannot assign DArrays of unequal capacity");
181 }
182
183 // Copy elements
184 for (int i = 0; i < capacity_; ++i) {
185 data_[i] = other[i];
186 }
187
188 return *this;
189 }
190
191 /*
192 * Allocate the underlying C array.
193 *
194 * Throw an Exception if this DArray is already allocated.
195 *
196 * \param capacity number of elements to allocate.
197 */
198 template <class Data>
199 void DArray<Data>::allocate(int capacity)
200 {
201 if (isAllocated()) {
202 UTIL_THROW("Attempt to re-allocate a DArray");
203 }
204 if (capacity <= 0) {
205 UTIL_THROW("Attempt to allocate with capacity <= 0");
206 }
207 Memory::allocate<Data>(data_, capacity);
208 capacity_ = capacity;
209 }
210
211 /*
212 * Deallocate the underlying C array.
213 *
214 * Throw an Exception if this DArray is not allocated.
215 */
216 template <class Data>
218 {
219 if (!isAllocated()) {
220 UTIL_THROW("Array is not allocated");
221 }
222 Memory::deallocate<Data>(data_, capacity_);
223 capacity_ = 0;
224 }
225
226 /*
227 * Reallocate and copy the underlying C array.
228 */
229 template <class Data>
230 void DArray<Data>::reallocate(int capacity)
231 {
232 UTIL_CHECK(capacity >= 0);
233 if (capacity == capacity_) return;
234 UTIL_CHECK(capacity > capacity_);
235 if (isAllocated()) {
236 Memory::reallocate<Data>(data_, capacity_, capacity);
237 } else {
238 Memory::allocate<Data>(data_, capacity);
239 }
240 capacity_ = capacity;
241 }
242
243 /*
244 * Return true if the DArray has been allocated, false otherwise.
245 */
246 template <class Data>
247 inline bool DArray<Data>::isAllocated() const
248 { return (bool)data_; }
249
250 /*
251 * Serialize a DArray to/from an Archive.
252 */
253 template <class Data>
254 template <class Archive>
255 void DArray<Data>::serialize(Archive& ar, const unsigned int version)
256 {
257 int capacity;
258 if (Archive::is_saving()) {
259 capacity = capacity_;
260 }
261 ar & capacity;
262 if (Archive::is_loading()) {
263 if (!isAllocated()) {
264 if (capacity > 0) {
265 allocate(capacity);
266 }
267 } else {
268 if (capacity != capacity_) {
269 UTIL_THROW("Inconsistent DArray capacities");
270 }
271 }
272 }
273 if (isAllocated()) {
274 for (int i = 0; i < capacity_; ++i) {
275 ar & data_[i];
276 }
277 }
278 }
279
280}
281#endif
Array container class template.
Definition: Array.h:34
Data * data_
Pointer to an array of Data elements.
Definition: Array.h:109
int capacity() const
Return allocated size.
Definition: Array.h:159
int capacity_
Allocated size of the data_ array.
Definition: Array.h:112
Dynamically allocatable contiguous array template.
Definition: DArray.h:32
DArray(DArray< Data > const &other)
Copy constructor.
Definition: DArray.h:136
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:199
void deallocate()
Dellocate the underlying C array.
Definition: DArray.h:217
void serialize(Archive &ar, const unsigned int version)
Serialize a DArray to/from an Archive.
Definition: DArray.h:255
DArray()
Default constructor.
Definition: DArray.h:124
bool isAllocated() const
Return true if this DArray has been allocated, false otherwise.
Definition: DArray.h:247
virtual ~DArray()
Destructor.
Definition: DArray.h:153
void reallocate(int capacity)
Reallocate the underlying C array and copy to new location.
Definition: DArray.h:230
DArray< Data > & operator=(DArray< Data > const &other)
Assignment operator.
Definition: DArray.h:167
static void allocate(Data *&ptr, size_t size)
Allocate a C++ array.
Definition: Memory.h:132
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:51
Utility classes for scientific computation.
Definition: accumulators.mod:1