]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/multiprecision/cpp_int/serialize.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / multiprecision / cpp_int / serialize.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////
2// Copyright 2013 John Maddock. Distributed under the Boost
3// Software License, Version 1.0. (See accompanying file
92f5a8d4 4// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
7c673cae
FG
5
6#ifndef BOOST_MP_CPP_INT_SERIALIZE_HPP
7#define BOOST_MP_CPP_INT_SERIALIZE_HPP
8
9namespace boost {
10
92f5a8d4 11namespace archive {
7c673cae
FG
12
13class binary_oarchive;
14class binary_iarchive;
15
92f5a8d4 16} // namespace archive
7c673cae
FG
17
18namespace serialization {
19
20namespace mp = boost::multiprecision;
21
92f5a8d4 22namespace cpp_int_detail {
7c673cae
FG
23
24using namespace boost::multiprecision;
25using namespace boost::multiprecision::backends;
26
27template <class T>
92f5a8d4
TL
28struct is_binary_archive : public mpl::false_
29{};
7c673cae 30template <>
92f5a8d4
TL
31struct is_binary_archive<boost::archive::binary_oarchive> : public mpl::true_
32{};
7c673cae 33template <>
92f5a8d4
TL
34struct is_binary_archive<boost::archive::binary_iarchive> : public mpl::true_
35{};
7c673cae
FG
36
37//
38// We have 8 serialization methods to fill out (and test), they are all permutations of:
39// Load vs Store.
40// Trivial or non-trivial cpp_int type.
41// Binary or not archive.
42//
43template <class Archive, class Int>
44void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&, mpl::false_ const&)
45{
46 // Load.
47 // Non-trivial.
48 // Non binary.
49
92f5a8d4
TL
50 using boost::make_nvp;
51 bool s;
52 ar& make_nvp("sign", s);
7c673cae
FG
53 std::size_t limb_count;
54 std::size_t byte_count;
92f5a8d4 55 ar& make_nvp("byte-count", byte_count);
7c673cae
FG
56 limb_count = byte_count / sizeof(limb_type) + ((byte_count % sizeof(limb_type)) ? 1 : 0);
57 val.resize(limb_count, limb_count);
58 limb_type* pl = val.limbs();
92f5a8d4 59 for (std::size_t i = 0; i < limb_count; ++i)
7c673cae
FG
60 {
61 pl[i] = 0;
92f5a8d4 62 for (std::size_t j = 0; (j < sizeof(limb_type)) && byte_count; ++j)
7c673cae
FG
63 {
64 unsigned char byte;
92f5a8d4 65 ar& make_nvp("byte", byte);
7c673cae
FG
66 pl[i] |= static_cast<limb_type>(byte) << (j * CHAR_BIT);
67 --byte_count;
68 }
69 }
92f5a8d4 70 if (s != val.sign())
7c673cae
FG
71 val.negate();
72 val.normalize();
73}
74template <class Archive, class Int>
75void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::false_ const&, mpl::false_ const&)
76{
77 // Store.
78 // Non-trivial.
79 // Non binary.
80
92f5a8d4
TL
81 using boost::make_nvp;
82 bool s = val.sign();
83 ar& make_nvp("sign", s);
84 limb_type* pl = val.limbs();
7c673cae
FG
85 std::size_t limb_count = val.size();
86 std::size_t byte_count = limb_count * sizeof(limb_type);
92f5a8d4 87 ar& make_nvp("byte-count", byte_count);
7c673cae 88
92f5a8d4 89 for (std::size_t i = 0; i < limb_count; ++i)
7c673cae
FG
90 {
91 limb_type l = pl[i];
92f5a8d4 92 for (std::size_t j = 0; j < sizeof(limb_type); ++j)
7c673cae
FG
93 {
94 unsigned char byte = static_cast<unsigned char>((l >> (j * CHAR_BIT)) & ((1u << CHAR_BIT) - 1));
92f5a8d4 95 ar& make_nvp("byte", byte);
7c673cae
FG
96 }
97 }
98}
99template <class Archive, class Int>
100void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::true_ const&, mpl::false_ const&)
101{
102 // Load.
103 // Trivial.
104 // Non binary.
92f5a8d4
TL
105 using boost::make_nvp;
106 bool s;
7c673cae 107 typename Int::local_limb_type l = 0;
92f5a8d4
TL
108 ar& make_nvp("sign", s);
109 std::size_t byte_count;
110 ar& make_nvp("byte-count", byte_count);
111 for (std::size_t i = 0; i < byte_count; ++i)
7c673cae
FG
112 {
113 unsigned char b;
92f5a8d4 114 ar& make_nvp("byte", b);
7c673cae
FG
115 l |= static_cast<typename Int::local_limb_type>(b) << (i * CHAR_BIT);
116 }
117 *val.limbs() = l;
92f5a8d4 118 if (s != val.sign())
7c673cae
FG
119 val.negate();
120}
121template <class Archive, class Int>
122void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::true_ const&, mpl::false_ const&)
123{
124 // Store.
125 // Trivial.
126 // Non binary.
92f5a8d4
TL
127 using boost::make_nvp;
128 bool s = val.sign();
7c673cae 129 typename Int::local_limb_type l = *val.limbs();
92f5a8d4
TL
130 ar& make_nvp("sign", s);
131 std::size_t limb_count = sizeof(l);
132 ar& make_nvp("byte-count", limb_count);
133 for (std::size_t i = 0; i < limb_count; ++i)
7c673cae
FG
134 {
135 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));
92f5a8d4 136 ar& make_nvp("byte", b);
7c673cae
FG
137 }
138}
139template <class Archive, class Int>
140void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&, mpl::true_ const&)
141{
142 // Load.
143 // Non-trivial.
144 // Binary.
92f5a8d4 145 bool s;
7c673cae 146 std::size_t c;
92f5a8d4
TL
147 ar& s;
148 ar& c;
7c673cae
FG
149 val.resize(c, c);
150 ar.load_binary(val.limbs(), c * sizeof(limb_type));
92f5a8d4 151 if (s != val.sign())
7c673cae
FG
152 val.negate();
153 val.normalize();
154}
155template <class Archive, class Int>
156void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::false_ const&, mpl::true_ const&)
157{
158 // Store.
159 // Non-trivial.
160 // Binary.
92f5a8d4 161 bool s = val.sign();
7c673cae 162 std::size_t c = val.size();
92f5a8d4
TL
163 ar& s;
164 ar& c;
7c673cae
FG
165 ar.save_binary(val.limbs(), c * sizeof(limb_type));
166}
167template <class Archive, class Int>
168void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::true_ const&, mpl::true_ const&)
169{
170 // Load.
171 // Trivial.
172 // Binary.
173 bool s;
92f5a8d4 174 ar& s;
7c673cae 175 ar.load_binary(val.limbs(), sizeof(*val.limbs()));
92f5a8d4 176 if (s != val.sign())
7c673cae
FG
177 val.negate();
178}
179template <class Archive, class Int>
180void do_serialize(Archive& ar, Int& val, mpl::true_ const&, mpl::true_ const&, mpl::true_ const&)
181{
182 // Store.
183 // Trivial.
184 // Binary.
185 bool s = val.sign();
92f5a8d4 186 ar& s;
7c673cae
FG
187 ar.save_binary(val.limbs(), sizeof(*val.limbs()));
188}
189
92f5a8d4 190} // namespace cpp_int_detail
7c673cae 191
92f5a8d4
TL
192template <class Archive, unsigned MinBits, unsigned MaxBits, mp::cpp_integer_type SignType, mp::cpp_int_check_type Checked, class Allocator>
193void serialize(Archive& ar, mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& val, const unsigned int /*version*/)
7c673cae 194{
92f5a8d4 195 typedef typename Archive::is_saving save_tag;
7c673cae 196 typedef mpl::bool_<mp::backends::is_trivial_cpp_int<mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value> trivial_tag;
92f5a8d4 197 typedef typename cpp_int_detail::is_binary_archive<Archive>::type binary_tag;
7c673cae
FG
198
199 // Just dispatch to the correct method:
200 cpp_int_detail::do_serialize(ar, val, save_tag(), trivial_tag(), binary_tag());
201}
202
92f5a8d4
TL
203} // namespace serialization
204} // namespace boost
7c673cae
FG
205
206#endif // BOOST_MP_CPP_INT_SERIALIZE_HPP