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.