Sending and returning custom classes
We have seen previously that all STL containers can be
serialized and deserialized by Thallium. Thallium can also
serialize and deserialize user-defined classes, with a little help.
This help comes in the form of a serialize
function template
put inside the class.
3D point example
Here is an example with a point class representing a 3d point.
class point {
private:
double x;
double y;
double z;
public:
point(double a=0.0, double b=0.0, double c=0.0)
: x(a), y(b), z(c) {}
template<typename A>
void serialize(A& ar) {
ar & x;
ar & y;
ar & z;
}
};
You will also need the class to be default-constructible.
The template parameter (A) and the function’s parameter (ar)
represent an archive, from which one can serialize/deserialize data.
Note that you don’t need to provide two separate functions:
Thallium is smart enough to use the same serialize
function for
both reading and writing, depending on the context.
The serialize
function calls the operator &
of
the archive to either write or read the class’ data members.
Provided that those data members are basic types, user-defined
types with a serialize
method, or STL containers of a
serializable type, Thallium will know how to serialize the class.
Important
Thallium needs classes used as RPC argument/response to be default-constructible (i.e. provide a constructor that takes no argument).
Asymmetric serialization
In some cases it may not be possible for the serialize
function to present a symmetric behavior for reading and for
writing. For instance this may happen if the deserialization
function needs to allocate a pointer. In these cases, one can,
instead of a serialize
method, provide a save
method and a load
method. save
will be used
for serialization, load
will be used for deserialization.
Reading/writing raw data
It may also be convenient to read or write raw data from/to
the archive. For this, note that archive objects used for
serialization provide a write
method:
template<typename T> write(T* const t, std::size_t count=1)
and archive objects used for deserialization provide a read
method:
template<typename T> read(T* t, std::size_t count=1)
The write
method should be used only in a save
template
method, while the read
method should be used only in a load
template method.
Non-member serialization functions
In some contexts it may not be possible to add member functions to a class.
In those cases, you can add serialize
or load
/save
functions
outside of the class, as follows:
template<typename A>
void serialize(A& ar, MyType& x) {
...
}
or
template<typename A>
void save(A& ar, const MyType& x) {
...
}
template<typename A>
void load(A& ar, MyType& x) {
...
}