File indexing completed on 2025-01-30 09:48:27
0001
0002
0003
0004
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 }
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
0041
0042
0043
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
0049
0050
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
0080
0081
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
0105
0106
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
0127
0128
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
0145
0146
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
0161
0162
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
0173
0174
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
0185
0186
0187 bool s = val.sign();
0188 ar& s;
0189 ar.save_binary(val.limbs(), sizeof(*val.limbs()));
0190 }
0191
0192 }
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 )
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
0203 cpp_int_detail::do_serialize(ar, val, save_tag(), trivial_tag(), binary_tag());
0204 }
0205
0206 }
0207 }
0208
0209 #endif
0210
0211 #endif