Simpatico  v1.10
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 
15 namespace Util
16 {
17 
30  template <typename Data>
31  class DArray : public Array<Data>
32  {
33 
34  public:
35 
39  DArray();
40 
48  DArray(const DArray<Data>& other);
49 
55  virtual ~DArray();
56 
67  DArray<Data>& operator = (const DArray<Data>& other);
68 
76  void allocate(int capacity);
77 
83  void deallocate();
84 
88  bool isAllocated() const;
89 
96  template <class Archive>
97  void serialize(Archive& ar, const unsigned int version);
98 
99  protected:
100 
101  using Array<Data>::data_;
103 
104  };
105 
106 
107  /*
108  * Constructor.
109  */
110  template <class Data>
112  : Array<Data>()
113  {}
114 
115  /*
116  * Copy constructor.
117  *
118  * Allocates new memory and copies all elements by value.
119  *
120  *\param other the DArray to be copied.
121  */
122  template <class Data>
124  : Array<Data>()
125  {
126  if (!other.isAllocated()) {
127  UTIL_THROW("Other DArray must be allocated.");
128  }
130  capacity_ = other.capacity_;
131  for (int i = 0; i < capacity_; ++i) {
132  data_[i] = other.data_[i];
133  }
134  }
135 
136  /*
137  * Destructor.
138  */
139  template <class Data>
141  {
142  if (isAllocated()) {
143  Memory::deallocate<Data>(data_, capacity_);
144  capacity_ = 0;
145  }
146  }
147 
148  /*
149  * Assignment, element-by-element.
150  *
151  * This operator will allocate memory if not allocated previously.
152  *
153  * \throw Exception if other DArray is not allocated.
154  * \throw Exception if both DArrays are allocated with unequal capacities.
155  *
156  * \param other the rhs DArray
157  */
158  template <class Data>
160  {
161  // Check for self assignment
162  if (this == &other) return *this;
163 
164  // Precondition
165  if (!other.isAllocated()) {
166  UTIL_THROW("Other DArray must be allocated.");
167  }
168 
169  if (!isAllocated()) {
170  allocate(other.capacity());
171  } else if (capacity_ != other.capacity_) {
172  UTIL_THROW("Cannot assign DArrays of unequal capacity");
173  }
174 
175  // Copy elements
176  for (int i = 0; i < capacity_; ++i) {
177  data_[i] = other[i];
178  }
179 
180  return *this;
181  }
182 
183  /*
184  * Allocate the underlying C array.
185  *
186  * Throw an Exception if the DArray has already allocated.
187  *
188  * \param capacity number of elements to allocate.
189  */
190  template <class Data>
192  {
193  if (isAllocated()) {
194  UTIL_THROW("Attempt to re-allocate a DArray");
195  }
196  if (capacity <= 0) {
197  UTIL_THROW("Attempt to allocate with capacity <= 0");
198  }
199  Memory::allocate<Data>(data_, capacity);
201  }
202 
203  /*
204  * Deallocate the underlying C array.
205  *
206  * Throw an Exception if this DArray is not allocated.
207  */
208  template <class Data>
210  {
211  if (!isAllocated()) {
212  UTIL_THROW("Array is not allocated");
213  }
214  Memory::deallocate<Data>(data_, capacity_);
215  capacity_ = 0;
216  }
217 
218  /*
219  * Return true if the DArray has been allocated, false otherwise.
220  */
221  template <class Data>
222  inline bool DArray<Data>::isAllocated() const
223  { return (bool)data_; }
224 
225  /*
226  * Serialize a DArray to/from an Archive.
227  */
228  template <class Data>
229  template <class Archive>
230  void DArray<Data>::serialize(Archive& ar, const unsigned int version)
231  {
232  int capacity;
233  if (Archive::is_saving()) {
234  capacity = capacity_;
235  }
236  ar & capacity;
237  if (Archive::is_loading()) {
238  if (!isAllocated()) {
239  if (capacity > 0) {
240  allocate(capacity);
241  }
242  } else {
243  if (capacity != capacity_) {
244  UTIL_THROW("Inconsistent DArray capacities");
245  }
246  }
247  }
248  if (isAllocated()) {
249  for (int i = 0; i < capacity_; ++i) {
250  ar & data_[i];
251  }
252  }
253  }
254 
255 }
256 #endif
Data * data_
Pointer to an array of Data elements.
Definition: Array.h:103
void serialize(Archive &ar, const unsigned int version)
Serialize a DArray to/from an Archive.
Definition: DArray.h:230
int capacity_
Allocated size of the data_ array.
Definition: Array.h:106
Array container class template.
Definition: AutoCorrArray.h:28
File containing preprocessor macros for error handling.
static void allocate(Data *&ptr, size_t size)
Allocate a C array.
Definition: Memory.h:104
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
DArray< Data > & operator=(const DArray< Data > &other)
Assignment operator.
Definition: DArray.h:159
Utility classes for scientific computation.
Definition: accumulators.mod:1
DArray()
Default constructor.
Definition: DArray.h:111
bool isAllocated() const
Return true if the DArray has been allocated, false otherwise.
Definition: DArray.h:222
Dynamically allocatable contiguous array template.
Definition: DArray.h:31
virtual ~DArray()
Destructor.
Definition: DArray.h:140
void deallocate()
Dellocate the underlying C array.
Definition: DArray.h:209
int capacity() const
Return allocated size.
Definition: Array.h:153
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191