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