Integer serialisation#
Preliminaries#
Let us load the mp++ runtime, include the headers and import the user-defined literals:
#pragma cling add_include_path("$CONDA_PREFIX/include")
#pragma cling add_library_path("$CONDA_PREFIX/lib")
#pragma cling load("mp++")
#include <mp++/integer.hpp>
using namespace mppp::literals;
using int_t = mppp::integer<1>;
Let us also includes a couple of bits from the standard library:
#include <iostream>
#include <sstream>
#include <vector>
And a few headers from the Boost.Serialization library:
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
Boost.Serialization support#
Like all the other mp++ classes, and if the MPPP_WITH_BOOST_S11N
option was turned on at build time, integer
supports serialisation via Boost.Serialization. Let us see a simple example using binary archives:
{
auto n = -42_z1;
std::cout << "n initialised to " << n << '\n';
std::stringstream ss;
// Serialise n into ss.
{
boost::archive::binary_oarchive oa(ss);
oa << n;
}
n = -1;
std::cout << "After serialisation, n has been set to " << n << '\n';
// Deserialise the contents of ss into n.
{
boost::archive::binary_iarchive ia(ss);
ia >> n;
}
std::cout << "After deserialisation, n is again " << n << '\n';
}
n initialised to -42
After serialisation, n has been set to -1
After deserialisation, n is again -42
Here we (de)serialised into a stringstream using a binary format, but the code for (de)serialisation into a file (or any other input/output stream) would have been identical.
Binary archives in Boost.Serialization are platform-dependent and thus non-portable. If portability across platforms is required, one can use text archives:
{
auto n = -42_z1;
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
oa << n;
}
n = -1;
std::cout << "Contents of the text archive: " << ss.str() << "\n";
{
boost::archive::text_iarchive ia(ss);
ia >> n;
}
}
Contents of the text archive: 22 serialization::archive 19 0 0 3 -42
Please refer to the Boost docs for more information on how to use Boost.Serialization.
Low-level serialisation primitives#
In addition to supporting serialisation via Boost.Serialization, the integer
class also provides a low-level binary serialisation API which does not depend on Boost. Let us see a simple example:
{
auto a = 42_z1, b = 0_z1;
std::cout << "a initialised to " << a << ", b initialised to " << b << '\n';
// An initially-empty vector buffer.
std::vector<char> buffer;
// Serialise a into the buffer.
a.binary_save(buffer);
std::cout << "The serialisation of a required " << buffer.size() << " bytes\n";
// Deserialise the content of the buffer into b.
b.binary_load(buffer);
std::cout << "After deserialisation, b is " << b << '\n';
}
a initialised to 42, b initialised to 0
The serialisation of a required 12 bytes
After deserialisation, b is 42
The binary_save()/binary_load()
member functions (and their free-function counterparts) save/load the contents of an integer object into/from a char
memory buffer. In this specific case we used a std::vector
, but the API supports also std::array
, raw char
pointers and standard iostreams. The integer docs explain in detail how the binary_save()/binary_load()
overloads can be used.
NOTE: the current binary serialisation format is compiler, platform and architecture specific, it is not portable and it might be subject to changes in future versions of mp++. Users are thus advised not to use the binary serialisation format for long-term persistence or as a data exchange format: for such purposes, it is better to use the string representation of integer objects.