Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:48:27

0001 ///////////////////////////////////////////////////////////////
0002 //  Copyright 2013 John Maddock. Distributed under the Boost
0003 //  Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
0005 
0006 #ifndef BOOST_MP_CPP_INT_SERIALIZE_HPP
0007 #define BOOST_MP_CPP_INT_SERIALIZE_HPP
0008 
0009 #ifndef BOOST_MP_STANDALONE
0010 
0011 namespace boost {
0012 
0013 namespace archive {
0014 
0015 class binary_oarchive;
0016 class binary_iarchive;
0017 
0018 } // namespace archive
0019 
0020 namespace serialization {
0021 
0022 namespace mp = boost::multiprecision;
0023 
0024 namespace cpp_int_detail {
0025 
0026 using namespace boost::multiprecision;
0027 using namespace boost::multiprecision::backends;
0028 
0029 template <class T>
0030 struct is_binary_archive : public std::integral_constant<bool, false>
0031 {};
0032 template <>
0033 struct is_binary_archive<boost::archive::binary_oarchive> : public std::integral_constant<bool, true>
0034 {};
0035 template <>
0036 struct is_binary_archive<boost::archive::binary_iarchive> : public std::integral_constant<bool, true>
0037 {};
0038 
0039 //
0040 // We have 8 serialization methods to fill out (and test), they are all permutations of:
0041 // Load vs Store.
0042 // Trivial or non-trivial cpp_int type.
0043 // Binary or not archive.
0044 //
0045 template <class Archive, class Int>
0046 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&)
0047 {
0048    // Load.
0049    // Non-trivial.
0050    // Non binary.
0051 
0052    using boost::make_nvp;
0053    bool        s;
0054    ar&         make_nvp("sign", s);
0055    std::size_t limb_count;
0056    std::size_t byte_count;
0057    ar&         make_nvp("byte-count", byte_count);
0058    limb_count = byte_count / sizeof(limb_type) + ((byte_count % sizeof(limb_type)) ? 1 : 0);
0059    val.resize(limb_count, limb_count);
0060    limb_type* pl = val.limbs();
0061    for (std::size_t i = 0; i < limb_count; ++i)
0062    {
0063       pl[i] = 0;
0064       for (std::size_t j = 0; (j < sizeof(limb_type)) && byte_count; ++j)
0065       {
0066          unsigned char byte;
0067          ar&           make_nvp("byte", byte);
0068          pl[i] |= static_cast<limb_type>(byte) << (j * CHAR_BIT);
0069          --byte_count;
0070       }
0071    }
0072    if (s != val.sign())
0073       val.negate();
0074    val.normalize();
0075 }
0076 template <class Archive, class Int>
0077 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&)
0078 {
0079    // Store.
0080    // Non-trivial.
0081    // Non binary.
0082 
0083    using boost::make_nvp;
0084    bool        s = val.sign();
0085    ar&         make_nvp("sign", s);
0086    limb_type*  pl         = val.limbs();
0087    std::size_t limb_count = val.size();
0088    std::size_t byte_count = limb_count * sizeof(limb_type);
0089    ar&         make_nvp("byte-count", byte_count);
0090 
0091    for (std::size_t i = 0; i < limb_count; ++i)
0092    {
0093       limb_type l = pl[i];
0094       for (std::size_t j = 0; j < sizeof(limb_type); ++j)
0095       {
0096          unsigned char byte = static_cast<unsigned char>((l >> (j * CHAR_BIT)) & ((1u << CHAR_BIT) - 1));
0097          ar&           make_nvp("byte", byte);
0098       }
0099    }
0100 }
0101 template <class Archive, class Int>
0102 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&)
0103 {
0104    // Load.
0105    // Trivial.
0106    // Non binary.
0107    using boost::make_nvp;
0108    bool                          s;
0109    typename Int::local_limb_type l = 0;
0110    ar&                           make_nvp("sign", s);
0111    std::size_t                   byte_count;
0112    ar&                           make_nvp("byte-count", byte_count);
0113    for (std::size_t i = 0; i < byte_count; ++i)
0114    {
0115       unsigned char b;
0116       ar&           make_nvp("byte", b);
0117       l |= static_cast<typename Int::local_limb_type>(b) << (i * CHAR_BIT);
0118    }
0119    *val.limbs() = l;
0120    if (s != val.sign())
0121       val.negate();
0122 }
0123 template <class Archive, class Int>
0124 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&)
0125 {
0126    // Store.
0127    // Trivial.
0128    // Non binary.
0129    using boost::make_nvp;
0130    bool                          s = val.sign();
0131    typename Int::local_limb_type l = *val.limbs();
0132    ar&                           make_nvp("sign", s);
0133    std::size_t                   limb_count = sizeof(l);
0134    ar&                           make_nvp("byte-count", limb_count);
0135    for (std::size_t i = 0; i < limb_count; ++i)
0136    {
0137       unsigned char b = static_cast<unsigned char>(static_cast<typename Int::local_limb_type>(l >> (i * CHAR_BIT)) & static_cast<typename Int::local_limb_type>((1u << CHAR_BIT) - 1));
0138       ar&           make_nvp("byte", b);
0139    }
0140 }
0141 template <class Archive, class Int>
0142 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&)
0143 {
0144    // Load.
0145    // Non-trivial.
0146    // Binary.
0147    bool        s;
0148    std::size_t c;
0149    ar&         s;
0150    ar&         c;
0151    val.resize(c, c);
0152    ar.load_binary(val.limbs(), c * sizeof(limb_type));
0153    if (s != val.sign())
0154       val.negate();
0155    val.normalize();
0156 }
0157 template <class Archive, class Int>
0158 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&)
0159 {
0160    // Store.
0161    // Non-trivial.
0162    // Binary.
0163    bool        s = val.sign();
0164    std::size_t c = val.size();
0165    ar&         s;
0166    ar&         c;
0167    ar.save_binary(val.limbs(), c * sizeof(limb_type));
0168 }
0169 template <class Archive, class Int>
0170 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, false> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&)
0171 {
0172    // Load.
0173    // Trivial.
0174    // Binary.
0175    bool s;
0176    ar&  s;
0177    ar.load_binary(val.limbs(), sizeof(*val.limbs()));
0178    if (s != val.sign())
0179       val.negate();
0180 }
0181 template <class Archive, class Int>
0182 void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&, std::integral_constant<bool, true> const&)
0183 {
0184    // Store.
0185    // Trivial.
0186    // Binary.
0187    bool s = val.sign();
0188    ar&  s;
0189    ar.save_binary(val.limbs(), sizeof(*val.limbs()));
0190 }
0191 
0192 } // namespace cpp_int_detail
0193 
0194 template <class Archive, std::size_t MinBits, std::size_t MaxBits, mp::cpp_integer_type SignType, mp::cpp_int_check_type Checked, class Allocator>
0195 void serialize(Archive& ar, mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& val, const unsigned int /*version*/)
0196 {
0197    using archive_save_tag = typename Archive::is_saving                                ;
0198    using save_tag = std::integral_constant<bool, archive_save_tag::value>      ;
0199    using trivial_tag = std::integral_constant<bool, mp::backends::is_trivial_cpp_int<mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>;
0200    using binary_tag = typename cpp_int_detail::is_binary_archive<Archive>::type  ;
0201 
0202    // Just dispatch to the correct method:
0203    cpp_int_detail::do_serialize(ar, val, save_tag(), trivial_tag(), binary_tag());
0204 }
0205 
0206 } // namespace serialization
0207 } // namespace boost
0208 
0209 #endif // BOOST_MP_STANDALONE
0210 
0211 #endif // BOOST_MP_CPP_INT_SERIALIZE_HPP