Simpatico  v1.10
MemoryOArchive.h
1 #ifndef UTIL_MEMORY_O_ARCHIVE_H
2 #define UTIL_MEMORY_O_ARCHIVE_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 "Byte.h"
12 #include "serialize.h"
13 
14 #include <util/space/Vector.h>
15 #include <util/space/IntVector.h>
16 
17 #include <complex>
18 #include <string>
19 #include <vector>
20 
21 namespace Util
22 {
23 
24  class MemoryIArchive;
25 
32  {
33 
34  public:
35 
37  static bool is_saving();
38 
40  static bool is_loading();
41 
46 
50  virtual ~MemoryOArchive();
51 
57  virtual void allocate(size_t capacity);
58 
62  void clear();
63 
67  template <typename T>
68  void operator & (T& data);
69 
73  template <typename T>
74  MemoryOArchive& operator << (T& data);
75 
79  template <typename T>
80  void pack(const T& data);
81 
88  template <typename T>
89  void pack(const T* array, int n);
90 
102  template <typename T>
103  void pack(const T* array, int m, int n, int np);
104 
105  #ifdef UTIL_MPI
106 
112  void send(MPI::Intracomm& comm, int dest);
113 
121  void iSend(MPI::Intracomm& comm, MPI::Request& req, int dest);
122  #endif
123 
127  Byte* begin() const;
128 
132  Byte* cursor() const;
133 
137  size_t capacity() const;
138 
142  bool isAllocated() const;
143 
144  private:
145 
147  Byte* buffer_;
148 
150  Byte* begin_;
151 
153  Byte* cursor_;
154 
156  Byte* endAllocated_;
157 
159  size_t capacity_;
160 
162  unsigned int version_;
163 
165  bool isLocked_;
166 
168  bool ownsData_;
169 
173  MemoryOArchive (const MemoryOArchive& other);
174 
178  MemoryOArchive& operator = (const MemoryOArchive& other);
179 
180  // friends:
181 
182  friend class MemoryIArchive;
183 
184  };
185 
186  // Inline methods
187 
189  { return true; }
190 
192  { return false; }
193 
194  // Inline non-static methods
195 
196  /*
197  * Has a memory block been allocated?
198  */
199  inline bool MemoryOArchive::isAllocated() const
200  { return (bool) begin_; }
201 
202  /*
203  * Return capacity in Bytes.
204  */
205  inline size_t MemoryOArchive::capacity() const
206  { return capacity_; }
207 
208  /*
209  * Return pointer to beginning of block.
210  */
211  inline Byte* MemoryOArchive::begin() const
212  { return begin_; }
213 
214  /*
215  * Return pointer to cursor position.
216  */
217  inline Byte* MemoryOArchive::cursor() const
218  { return cursor_; }
219 
220  /*
221  * Save one object.
222  */
223  template <typename T>
224  inline void MemoryOArchive::operator & (T& data)
225  { serialize(*this, data, version_); }
226 
227  /*
228  * Save one object.
229  */
230  template <typename T>
232  {
233  serialize(*this, data, version_);
234  return *this;
235  }
236 
237  // Method templates
238 
239  /*
240  * Save a single object of type T.
241  */
242  template <typename T>
243  inline void MemoryOArchive::pack(const T& data)
244  {
245  if (isLocked_) {
246  UTIL_THROW("Locked archive");
247  }
248  if (cursor_ + sizeof(data) > endAllocated_) {
249  UTIL_THROW("Attempted write past end of allocated block");
250  }
251  T* ptr = (T *)cursor_;
252  *ptr = data;
253  ++ptr;
254  cursor_ = (Byte *)ptr;
255  }
256 
257  /*
258  * Save a C-array of objects of type T.
259  */
260  template <typename T>
261  inline void MemoryOArchive::pack(const T* array, int n)
262  {
263  if (isLocked_) {
264  UTIL_THROW("Locked archive");
265  }
266  if (cursor_ + n*sizeof(T) > endAllocated_) {
267  UTIL_THROW("Attempted write past end of allocated block");
268  }
269  T* ptr = (T *)cursor_;
270  for (int i=0; i < n; ++i) {
271  *ptr = array[i];
272  ++ptr;
273  }
274  cursor_ = (Byte *)ptr;
275  }
276 
277  /*
278  * Bitwise pack a 2D C-array of objects of type T.
279  */
280  template <typename T>
281  inline void MemoryOArchive::pack(const T* array, int m, int n, int np)
282  {
283  if (isLocked_) {
284  UTIL_THROW("Locked archive");
285  }
286  if (cursor_ + m*n*sizeof(T) > endAllocated_) {
287  UTIL_THROW("Attempted write past end of allocated block");
288  }
289  int i, j;
290  T* ptr = (T *)cursor_;
291  for (i=0; i < m; ++i) {
292  for (j=0; j < n; ++j) {
293  *ptr = array[i*np + j];
294  ++ptr;
295  }
296  }
297  cursor_ = (Byte *)ptr;
298  }
299 
300  // Explicit serialize functions for primitive types
301 
302  /*
303  * Save a bool to a MemoryOArchive.
304  */
305  template <>
306  inline void serialize(MemoryOArchive& ar, bool& data,
307  const unsigned int version)
308  { ar.pack(data); }
309 
310  /*
311  * Save a char to a MemoryOArchive.
312  */
313  template <>
314  inline void serialize(MemoryOArchive& ar, char& data,
315  const unsigned int version)
316  { ar.pack(data); }
317 
318  /*
319  * Save an unsigned int to a MemoryOArchive.
320  */
321  template <>
322  inline void serialize(MemoryOArchive& ar, unsigned int& data,
323  const unsigned int version)
324  { ar.pack(data); }
325 
326  /*
327  * Save an int to a MemoryOArchive.
328  */
329  template <>
330  inline void serialize(MemoryOArchive& ar, int& data,
331  const unsigned int version)
332  { ar.pack(data); }
333 
334  /*
335  * Save a unsigned long int to a MemoryOArchive.
336  */
337  template <>
338  inline void serialize(MemoryOArchive& ar, unsigned long& data,
339  const unsigned int version)
340  { ar.pack(data); }
341 
342  /*
343  * Save a long int to a MemoryOArchive.
344  */
345  template <>
346  inline void serialize(MemoryOArchive& ar, long& data,
347  const unsigned int version)
348  { ar.pack(data); }
349 
350  /*
351  * Save a float to a MemoryOArchive.
352  */
353  template <>
354  inline void serialize(MemoryOArchive& ar, float& data,
355  const unsigned int version)
356  { ar.pack(data); }
357 
358  /*
359  * Save an double to a MemoryOArchive.
360  */
361  template <>
362  inline void serialize(MemoryOArchive& ar, double& data,
363  const unsigned int version)
364  { ar.pack(data); }
365 
366  /*
367  * Save a std::vector to a MemoryOArchive.
368  */
369  template <typename T>
370  void serialize(MemoryOArchive& ar, std::vector<T>& data,
371  const unsigned int version)
372  {
373  size_t size = data.size();
374  ar.pack(size);
375  for (size_t i = 0; i < size; ++i) {
376  ar & data[i];
377  }
378  }
379 
380  // Explicit serialize functions for standard library types
381 
382  /*
383  * Save a std::complex<float> to a MemoryOArchive.
384  */
385  template <>
386  inline void serialize(MemoryOArchive& ar, std::complex<float>& data,
387  const unsigned int version)
388  { ar.pack(data); }
389 
390  /*
391  * Save a std::complex<double> to a MemoryOArchive.
392  */
393  template <>
394  inline void serialize(MemoryOArchive& ar, std::complex<double>& data,
395  const unsigned int version)
396  { ar.pack(data); }
397 
398  /*
399  * Save a std::string to a MemoryOArchive.
400  */
401  template <>
402  inline void serialize(MemoryOArchive& ar, std::string& data,
403  const unsigned int version)
404  {
405  size_t size = data.size() + 1; // the +1 is for the NULL
406  ar.pack(size);
407  const char* temp = data.c_str();
408  ar.pack(temp, size);
409  }
410 
411  // Explicit serialize functions for namespace Util
412 
413  /*
414  * Save a Util::Vector to a MemoryOArchive.
415  */
416  template <>
417  inline void serialize(MemoryOArchive& ar, Vector& data,
418  const unsigned int version)
419  { ar.pack(data); }
420 
421  /*
422  * Save a Util::IntVector to a MemoryOArchive.
423  */
424  template <>
425  inline void serialize(MemoryOArchive& ar, IntVector& data,
426  const unsigned int version)
427  { ar.pack(data); }
428 
429 }
430 #endif
void send(MPI::Intracomm &comm, int dest)
Send packed data via MPI.
static bool is_saving()
Returns true;.
A Vector is a Cartesian vector.
Definition: Vector.h:75
Byte * begin() const
Return pointer to beginning of block.
size_t capacity() const
Return capacity in Bytes.
Byte * cursor() const
Return pointer to current position (cursor).
virtual ~MemoryOArchive()
Destructor.
void pack(const T &data)
Pack a T object.
bool isAllocated() const
Has memory been allocated?
unsigned char Byte
Define a "Byte" type.
Definition: Byte.h:19
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
MemoryOArchive()
Constructor.
Save archive for packed heterogeneous binary data.
Utility classes for scientific computation.
Definition: accumulators.mod:1
void operator&(T &data)
Save one object.
MemoryOArchive & operator<<(T &data)
Save one object.
static bool is_loading()
Returns false;.
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
void serialize(Archive &ar, T &data, const unsigned int version)
Serialize one object of type T.
Definition: serialize.h:29
void iSend(MPI::Intracomm &comm, MPI::Request &req, int dest)
Send packed data via MPI (non-blocking)
virtual void allocate(size_t capacity)
Allocate memory.
Input archive for packed heterogeneous binary data.
void clear()
Resets the cursor to the beginning.