ALPS Project: alps library

Header file osiris/dump.h

This header contains the abstract base classes for object serialization.

The alps serialization mechanism

The foundation of the dump mechanism are the two abstract classes ODump and IDump that are used to write a representation of an object or to reconstruct an object respectively. The actual classes used ( e.g. IXDRFileDump and OXDRFileDump are derived from these abstract base classes.
The dump mechanism is similar to the std::ostream and std::istream classes of the standard C++ library, with a few major differences:
  1. There is a one-to-one correspondence between the object and its representation on a dump. An object can be completely reconstructed from a dump.
  2. This requires a one-to-one correspondence of the operator<< used to write an object and the operator>> used to reconstruct it. Note that this one-to-one correspondence is not given for writing/reading a std::string to a standard I/O stream.
  3. The representation is usually in a binary format, and thus formatting does not apply.
In this library dumps are used mainly for two purposes:
  1. for architecture independent storage in disk files, e.g. for checkpoints and binary result files.
  2. to send an object to a remote process in a network or on a parallel computer.
Other uses are of course possible.

An abstract base class Dumpable with two pure virtual functions save and load is provided to support polymorphism with serialization.

Pointers can be serialized after the object being pointed to has been serialized. In order to do so, the object address must first be registered with the ODump, and is assigned a unique integer identifier. This identifier is then written instead of the pointer. When deserializing the new object address has again to be registered with the IDump, to allow conversion of the pointer identifier to the new pointer.

Serialization for your own classes can be provided either by deriving them from Dumpable and implementing the save and load functions or by providing the appropriate operator<< and operator>>.

Synopsis

namespace alps {
class ODump
{
public:
  ODump(uint32_t v=0);
  uint32_t version();
  
  virtual void write_simple(bool x) ;
  virtual void write_simple(char x);
  virtual void write_simple(signed char x);
  virtual void write_simple(unsigned char x);
  virtual void write_simple(short x);
  virtual void write_simple(unsigned short x);
  virtual void write_simple(int x) = 0;
  virtual void write_simple(unsigned int x);
  virtual void write_simple(long x);
  virtual void write_simple(unsigned long x);
  virtual void write_simple(long long x);
  virtual void write_simple(unsigned long long x);
  virtual void write_simple(float x);
  virtual void write_simple(double x) = 0;
  virtual void write_simple(long double x) ;

  virtual void write_array(std::size_t n, const bool* p);
  virtual void write_array(std::size_t n, const char* p);
  virtual void write_array(std::size_t n, const signed char* p);
  virtual void write_array(std::size_t n, const unsigned char* p);
  virtual void write_array(std::size_t n, const short* p);
  virtual void write_array(std::size_t n, const unsigned short* p);
  virtual void write_array(std::size_t n, const int* p);
  virtual void write_array(std::size_t n, const unsigned int* p);
  virtual void write_array(std::size_t n, const long* p);
  virtual void write_array(std::size_t n, const unsigned long* p);
  virtual void write_array(std::size_t n, const long long* p);
  virtual void write_array(std::size_t n, const unsigned long long* p);
  virtual void write_array(std::size_t n, const float* p);
  virtual void write_array(std::size_t n, const double* p);
  virtual void write_array(std::size_t n, const long double* p);
  virtual void write_array(std::size_t n, const bool* p);
  template <class T> void write_array(std::size_t n, const std::complex<T>* p);
  
  virtual void write_string(std::size_t n, const char* s);

  void registerObjectAddress(void* p);
  void writePointer(void* p);
};

class IDump
{
public:
  IDump(uint32_t v=0);
  uint32_t version();

  virtual void read_simple(bool& x);
  virtual void read_simple(char& x);
  virtual void read_simple(signed char& x);
  virtual void read_simple(unsigned char& x);
  virtual void read_simple(short& x);
  virtual void read_simple(unsigned short& x);
  virtual void read_simple(int& x) =0;
  virtual void read_simple(unsigned int& x);
  virtual void read_simple(long& x);
  virtual void read_simple(unsigned long& x);
  virtual void read_simple(long long& x);
  virtual void read_simple(unsigned long long& x);
  virtual void read_simple(float& x);
  virtual void read_simple(double& x) =0;
  virtual void read_simple(long double& x);

  virtual void read_array(std::size_t n, bool* p);
  virtual void read_array(std::size_t n, char* p);
  virtual void read_array(std::size_t n, signed char* p);
  virtual void read_array(std::size_t n, unsigned char* p);
  virtual void read_array(std::size_t n, short* p);
  virtual void read_array(std::size_t n, unsigned short* p);
  virtual void read_array(std::size_t n, int* p);
  virtual void read_array(std::size_t n, unsigned int* p);
  virtual void read_array(std::size_t n, long* p);
  virtual void read_array(std::size_t n, unsigned long* p);
  virtual void read_array(std::size_t n, long long* p);
  virtual void read_array(std::size_t n, unsigned long long* p);
  virtual void read_array(std::size_t n, float* p);
  virtual void read_array(std::size_t n, double* p);
  virtual void read_array(std::size_t n, long double* p);
  virtual void read_array(std::size_t n, bool* p);
  template <class T> void read_array(std::size_t n, std::complex<T>* p);

  operator bool();
  operator char();
  operator signed char();
  operator unsigned char();
  operator short();
  operator unsigned short();
  operator int();
  operator unsigned int();
  operator long();
  operator unsigned long();
  operator long long();
  operator unsigned long long();
  operator float();
  operator double();
  operator long double();
  template <class T> operator std::complex<T>();

  template <class T> T get();
  
  bool test();

  void registerObjectAddress(void* p);
  void* readPointer();
};

ODump& operator<<(ODump& dump, bool x);
ODump& operator<<(ODump& dump, char x);
ODump& operator<<(ODump& dump, unsigned char x);
ODump& operator<<(ODump& dump, signed char x);
ODump& operator<<(ODump& dump, short x);
ODump& operator<<(ODump& dump, unsigned short x);
ODump& operator<<(ODump& dump, int x);
ODump& operator<<(ODump& dump, unsigned int x);
ODump& operator<<(ODump& dump, long x);
ODump& operator<<(ODump& dump, unsigned long x);
ODump& operator<<(ODump& dump, float x);
ODump& operator<<(ODump& dump, long long x);
ODump& operator<<(ODump& dump, unsigned long long x);
ODump& operator<<(ODump& dump, double x);
ODump& operator<<(ODump& dump, long double x);
ODump& operator<<(ODump& dump, bool x);
template <class T> ODump& operator<<(ODump& dump, std::complex<T> x);
 
IDump& operator>>(IDump& dump, bool& x);
IDump& operator>>(IDump& dump, char& x);
IDump& operator>>(IDump& dump, signed char& x);
IDump& operator>>(IDump& dump, unsigned char& x);
IDump& operator>>(IDump& dump, short& x);
IDump& operator>>(IDump& dump, unsigned short& x);
IDump& operator>>(IDump& dump, int& x);
IDump& operator>>(IDump& dump, unsigned int& x);
IDump& operator>>(IDump& dump, long& x);
IDump& operator>>(IDump& dump, unsigned long& x);
IDump& operator>>(IDump& dump, long long& x);
IDump& operator>>(IDump& dump, unsigned long long& x);
IDump& operator>>(IDump& dump, float& x);
IDump& operator>>(IDump& dump, double& x);
IDump& operator>>(IDump& dump, long double& x);
template <class T> IDump& operator>>(IDump& dump, std::complex<T>& x);
}

The ODump class

is the abstract base class for serialization.

Constructor

ODump(uint32_t v=0);
The constructor takes an optional version number that can freely be defined and used by the library user.

Information

uint32_t version() const;
returns the version number passed to the constructor. This can be used e.g. to serialize an object differently for different versions of an output file.

Serializing objects

Objects are serialized using the operator<<.
ODump& operator<<(ODump& dump, bool x);
ODump& operator<<(ODump& dump, char x);
ODump& operator<<(ODump& dump, unsigned char x);
ODump& operator<<(ODump& dump, signed char x);
ODump& operator<<(ODump& dump, short x);
ODump& operator<<(ODump& dump, unsigned short x);
ODump& operator<<(ODump& dump, int x);
ODump& operator<<(ODump& dump, unsigned int x);
ODump& operator<<(ODump& dump, long x);
ODump& operator<<(ODump& dump, unsigned long x);
ODump& operator<<(ODump& dump, float x);
ODump& operator<<(ODump& dump, long long x);
ODump& operator<<(ODump& dump, unsigned long long x);
ODump& operator<<(ODump& dump, double x);
ODump& operator<<(ODump& dump, long double x);
ODump& operator<<(ODump& dump, bool x);
serialize the basic simple data types.
template <class T> ODump& operator<<(ODump& dump, std::complex<T> x);
serializes complex numbers by serializing their real and imaginary parts.
virtual void write_array(std::size_t n, const bool* p);
virtual void write_array(std::size_t n, const char* p);
virtual void write_array(std::size_t n, const signed char* p);
virtual void write_array(std::size_t n, const unsigned char* p);
virtual void write_array(std::size_t n, const short* p);
virtual void write_array(std::size_t n, const unsigned short* p);
virtual void write_array(std::size_t n, const int* p);
virtual void write_array(std::size_t n, const unsigned int* p);
virtual void write_array(std::size_t n, const long* p);
virtual void write_array(std::size_t n, const unsigned long* p);
virtual void write_array(std::size_t n, const long long* p);
virtual void write_array(std::size_t n, const unsigned long long* p);
virtual void write_array(std::size_t n, const float* p);
virtual void write_array(std::size_t n, const double* p);
virtual void write_array(std::size_t n, const long double* p);
virtual void write_array(std::size_t n, const bool* p);
serialize a C-style array of basic data types with n elements. The default version just calls the corresponding operator<< n times.
template <class T> void write_array(std::size_t n, const std::complex<T>* p);
serializes an array of complex numbers by interpreting it as a twice as large array of real numbers.
virtual void write_string(std::size_t n, const char* s);
serializes a C-style string, optionally performing character translations. Note that the string need not be null-terminated. The default version just calls operator>>(char&) n times.

Serializing pointers

void registerObjectAddress(void* p);
registers a pointer. Before a pointer to an object can be serialized, it needs to be registered with the ODump, after the object itself has been serialized.
void writePointer(void* p);
writes a unique integer identifier of a previously registered pointer to the ODump, allowing for a conversion back to a pointer upon deserialization. If the pointer has not been registered a std::runtime_error is thrown.

Functions for implementors

virtual void write_simple(bool x) ;
virtual void write_simple(char x);
virtual void write_simple(signed char x);
virtual void write_simple(unsigned char x);
virtual void write_simple(short x);
virtual void write_simple(unsigned short x);
virtual void write_simple(int x) = 0;
virtual void write_simple(unsigned int x);
virtual void write_simple(long x);
virtual void write_simple(unsigned long x);
virtual void write_simple(long long x);
virtual void write_simple(unsigned long long x);
virtual void write_simple(float x);
virtual void write_simple(double x) = 0;
virtual void write_simple(long double x) ;
implement serialization of basic data types. It is recommended that all these functions be implemented and optimized versions of write_array and write_string be provided. The minimal requirement is an implementation for int32 and for double. The default versions of the other types call the signed version for unsigned integers, the int version for other integer sizes, and the double version for other floating point types.

The IDump class

is the abstract base class for deserialization.
IDump(uint32_t v=0);
The constructor takes an optional version number that can freely be defined and used by the library user.

Information

uint32_t version() const;
returns the version number passed to the constructor. This can be used e.g. to serialize an object differently for different versions of an output file.

Deserializing objects

Objects are serialized using the operator>>.
ODump& operator<<(ODump& dump, bool x);
ODump& operator<<(ODump& dump, char x);
ODump& operator<<(ODump& dump, unsigned char x);
ODump& operator<<(ODump& dump, signed char x);
ODump& operator<<(ODump& dump, short x);
ODump& operator<<(ODump& dump, unsigned short x);
ODump& operator<<(ODump& dump, int x);
ODump& operator<<(ODump& dump, unsigned int x);
ODump& operator<<(ODump& dump, long x);
ODump& operator<<(ODump& dump, unsigned long x);
ODump& operator<<(ODump& dump, float x);
ODump& operator<<(ODump& dump, long long x);
ODump& operator<<(ODump& dump, unsigned long long x);
ODump& operator<<(ODump& dump, double x);
ODump& operator<<(ODump& dump, long double x);
ODump& operator<<(ODump& dump, bool x);
deserialize the basic simple data types.
template <class T> ODump& operator<<(ODump& dump, std::complex<T> x);
deserializes complex numbers by deserializing their real and imaginary parts.
virtual void read_array(std::size_t n, bool* p);
virtual void read_array(std::size_t n, char* p);
virtual void read_array(std::size_t n, signed char* p);
virtual void read_array(std::size_t n, unsigned char* p);
virtual void read_array(std::size_t n, short* p);
virtual void read_array(std::size_t n, unsigned short* p);
virtual void read_array(std::size_t n, int* p);
virtual void read_array(std::size_t n, unsigned int* p);
virtual void read_array(std::size_t n, long* p);
virtual void read_array(std::size_t n, unsigned long* p);
virtual void read_array(std::size_t n, long long* p);
virtual void read_array(std::size_t n, unsigned long long* p);
virtual void read_array(std::size_t n, float* p);
virtual void read_array(std::size_t n, double* p);
virtual void read_array(std::size_t n, long double* p);
virtual void read_array(std::size_t n, bool* p);
deserializes a C-style array of basic data types with n elements. Enough memory must have been allocated before calling this function. The default version just calls the corresponding operator>> n times.
Note to implementors: optimized functions for serializing C-style arrays can be provided by overriding these virtual functions.
template <class T> void read_array(std::size_t n, std::complex<T>* p);
deserializes an array of complex numbers by interpreting it as a twice as large array of real numbers.
virtual void read_string(std::size_t n, char* s);
deserialzes a C-style string and places a trailing 0 into the string, if it is not present. Enough memory must have been allocated before calling this function. The default version just calls operator>>(char&) n times.

Conversion operators

operator bool();
operator char();
operator signed char();
operator unsigned char();
operator short();
operator unsigned short();
operator int();
operator unsigned int();
operator long();
operator unsigned long();
operator long long();
operator unsigned long long();
operator float();
operator double();
operator long double();
template <class T> operator std::complex<T>();
use the corresponding operator>> to read an object of the type from the IDump and return it.
template <class T> T get();
use the corresponding operator>>(T&) to read an object of the type from the IDump and return it.
bool test();
same as operator bool().

Deserializing pointers

void registerObjectAddress(void* p);
registers a pointer. Before a pointer to an object can be deserialized, it needs to be registered with the IDump, after the object itself has been deserialized.
void readPointer(void* p);
reads a unique integer identifier of a previously registered pointer from the IDump and converts it to a pointer. If the corresponding pointer has not been registered a std::runtime_error is thrown.

Functions for implementors

virtual void read_simple(bool& x);
virtual void read_simple(char& x);
virtual void read_simple(signed char& x);
virtual void read_simple(unsigned char& x);
virtual void read_simple(short& x);
virtual void read_simple(unsigned short& x);
virtual void read_simple(int& x) =0;
virtual void read_simple(unsigned int& x);
virtual void read_simple(long& x);
virtual void read_simple(unsigned long& x);
virtual void read_simple(long long& x);
virtual void read_simple(unsigned long long& x);
virtual void read_simple(float& x);
virtual void read_simple(double& x) =0;
virtual void read_simple(long double& x);
implement deserialization of basic data types. It is recommended that all these functions be implemented and optimized versions of read_array and read_stringbe provided. The minimal requirement is an implementation for int32 and for double. The default versions of the other types call the signed version for unsigned integers, the int version for other integer sizes, and the double version for other floating point types.

copyright (c) 1994-2010 by Matthias Troyer

Distributed under the Boost Software License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)