mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-20 02:42:26 +00:00
Add missing serialization file
[SVN r85213]
This commit is contained in:
201
include/boost/multiprecision/cpp_int/serialize.hpp
Normal file
201
include/boost/multiprecision/cpp_int/serialize.hpp
Normal file
@@ -0,0 +1,201 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Copyright 2013 John Maddock. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
|
||||
|
||||
#ifndef BOOST_MP_CPP_INT_SERIALIZE_HPP
|
||||
#define BOOST_MP_CPP_INT_SERIALIZE_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace archive{
|
||||
|
||||
class binary_oarchive;
|
||||
class binary_iarchive;
|
||||
|
||||
}
|
||||
|
||||
namespace serialization {
|
||||
|
||||
namespace mp = boost::multiprecision;
|
||||
|
||||
namespace cpp_int_detail{
|
||||
|
||||
using namespace boost::multiprecision;
|
||||
using namespace boost::multiprecision::backends;
|
||||
|
||||
template <class T>
|
||||
struct is_binary_archive : public mpl::false_ {};
|
||||
template <>
|
||||
struct is_binary_archive<boost::archive::binary_oarchive> : public mpl::true_ {};
|
||||
template <>
|
||||
struct is_binary_archive<boost::archive::binary_iarchive> : public mpl::true_ {};
|
||||
|
||||
//
|
||||
// We have 8 serialization methods to fill out (and test), they are all permutations of:
|
||||
// Load vs Store.
|
||||
// Trivial or non-trivial cpp_int type.
|
||||
// Binary or not archive.
|
||||
//
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&, mpl::false_ const&)
|
||||
{
|
||||
// Load.
|
||||
// Non-trivial.
|
||||
// Non binary.
|
||||
|
||||
bool s;
|
||||
ar & s;
|
||||
std::size_t limb_count;
|
||||
std::size_t byte_count;
|
||||
ar & byte_count;
|
||||
limb_count = byte_count / sizeof(limb_type) + (byte_count % sizeof(limb_type) ? 1 : 0);
|
||||
val.resize(limb_count, limb_count);
|
||||
limb_type* pl = val.limbs();
|
||||
for(std::size_t i = 0; i < limb_count; ++i)
|
||||
{
|
||||
pl[i] = 0;
|
||||
for(std::size_t j = 0; j < sizeof(limb_type); ++j)
|
||||
{
|
||||
limb_type byte;
|
||||
ar & byte;
|
||||
byte <<= (j * CHAR_BIT);
|
||||
pl[i] |= byte;
|
||||
}
|
||||
}
|
||||
if(s != val.sign())
|
||||
val.negate();
|
||||
val.normalize();
|
||||
}
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::false_ const&, mpl::false_ const&)
|
||||
{
|
||||
// Store.
|
||||
// Non-trivial.
|
||||
// Non binary.
|
||||
|
||||
bool s = val.sign();
|
||||
ar & s;
|
||||
limb_type* pl = val.limbs();
|
||||
std::size_t limb_count = val.size();
|
||||
std::size_t byte_count = limb_count * sizeof(limb_count);
|
||||
ar & byte_count;
|
||||
|
||||
for(std::size_t i = 0; i < limb_count; ++i)
|
||||
{
|
||||
limb_type l = pl[i];
|
||||
for(std::size_t j = 0; j < sizeof(limb_type); ++j)
|
||||
{
|
||||
unsigned byte = (l >> (j * CHAR_BIT)) & ((1u << CHAR_BIT) - 1);
|
||||
ar & byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::true_ const&, mpl::false_ const&)
|
||||
{
|
||||
// Load.
|
||||
// Trivial.
|
||||
// Non binary.
|
||||
bool s;
|
||||
typename Int::local_limb_type l = 0;
|
||||
ar & s;
|
||||
std::size_t limb_count;
|
||||
ar & limb_count;
|
||||
for(std::size_t i = 0; i < limb_count; ++i)
|
||||
{
|
||||
typename Int::local_limb_type b;
|
||||
ar & b;
|
||||
l |= b << (i * CHAR_BIT);
|
||||
}
|
||||
*val.limbs() = l;
|
||||
if(s != val.sign())
|
||||
val.negate();
|
||||
}
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::true_ const&, mpl::false_ const&)
|
||||
{
|
||||
// Store.
|
||||
// Trivial.
|
||||
// Non binary.
|
||||
bool s = val.sign();
|
||||
typename Int::local_limb_type l = *val.limbs();
|
||||
ar & s;
|
||||
std::size_t limb_count = sizeof(l);
|
||||
ar & limb_count;
|
||||
for(std::size_t i = 0; i < limb_count; ++i)
|
||||
{
|
||||
typename Int::local_limb_type b = static_cast<typename Int::local_limb_type>(l >> (i * CHAR_BIT)) & static_cast<typename Int::local_limb_type>((1u << CHAR_BIT) - 1);
|
||||
ar & b;
|
||||
}
|
||||
}
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&, mpl::true_ const&)
|
||||
{
|
||||
// Load.
|
||||
// Non-trivial.
|
||||
// Binary.
|
||||
bool s;
|
||||
std::size_t c;
|
||||
ar & s;
|
||||
ar & c;
|
||||
val.resize(c, c);
|
||||
for(unsigned i = 0; i < c; ++i)
|
||||
ar & val.limbs()[i];
|
||||
if(s != val.sign())
|
||||
val.negate();
|
||||
val.normalize();
|
||||
}
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::false_ const&, mpl::true_ const&)
|
||||
{
|
||||
// Store.
|
||||
// Non-trivial.
|
||||
// Binary.
|
||||
bool s = val.sign();
|
||||
std::size_t c = val.size();
|
||||
ar & s;
|
||||
ar & c;
|
||||
for(unsigned i = 0; i < c; ++i)
|
||||
ar & val.limbs()[i];
|
||||
}
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::true_ const&, mpl::true_ const&)
|
||||
{
|
||||
// Load.
|
||||
// Trivial.
|
||||
// Binary.
|
||||
bool s;
|
||||
ar & s;
|
||||
ar & *val.limbs();
|
||||
if(s != val.sign())
|
||||
val.negate();
|
||||
}
|
||||
template <class Archive, class Int>
|
||||
void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::true_ const&, mpl::true_ const&)
|
||||
{
|
||||
// Store.
|
||||
// Trivial.
|
||||
// Binary.
|
||||
bool s = val.sign();
|
||||
ar & s;
|
||||
ar & *val.limbs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<class Archive, unsigned MinBits, unsigned MaxBits, mp::cpp_integer_type SignType, mp::cpp_int_check_type Checked, class Allocator>
|
||||
void serialize(Archive & ar, mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& val, const unsigned int /*version*/)
|
||||
{
|
||||
typedef typename Archive::is_saving save_tag;
|
||||
typedef mpl::bool_<mp::backends::is_trivial_cpp_int<mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value> trivial_tag;
|
||||
typedef typename cpp_int_detail::is_binary_archive<Archive>::type binary_tag;
|
||||
|
||||
// Just dispatch to the correct method:
|
||||
cpp_int_detail::do_serialize(ar, val, save_tag(), trivial_tag(), binary_tag());
|
||||
}
|
||||
|
||||
}} // namespaces
|
||||
|
||||
#endif // BOOST_MP_CPP_INT_SERIALIZE_HPP
|
||||
|
||||
Reference in New Issue
Block a user