]>
Commit | Line | Data |
---|---|---|
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 | ||
9 | namespace boost { | |
10 | ||
92f5a8d4 | 11 | namespace archive { |
7c673cae FG |
12 | |
13 | class binary_oarchive; | |
14 | class binary_iarchive; | |
15 | ||
92f5a8d4 | 16 | } // namespace archive |
7c673cae FG |
17 | |
18 | namespace serialization { | |
19 | ||
20 | namespace mp = boost::multiprecision; | |
21 | ||
92f5a8d4 | 22 | namespace cpp_int_detail { |
7c673cae FG |
23 | |
24 | using namespace boost::multiprecision; | |
25 | using namespace boost::multiprecision::backends; | |
26 | ||
27 | template <class T> | |
92f5a8d4 TL |
28 | struct is_binary_archive : public mpl::false_ |
29 | {}; | |
7c673cae | 30 | template <> |
92f5a8d4 TL |
31 | struct is_binary_archive<boost::archive::binary_oarchive> : public mpl::true_ |
32 | {}; | |
7c673cae | 33 | template <> |
92f5a8d4 TL |
34 | struct 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 | // | |
43 | template <class Archive, class Int> | |
44 | void 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 | } | |
74 | template <class Archive, class Int> | |
75 | void 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 | } | |
99 | template <class Archive, class Int> | |
100 | void 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 | } | |
121 | template <class Archive, class Int> | |
122 | void 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 | } | |
139 | template <class Archive, class Int> | |
140 | void 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 | } | |
155 | template <class Archive, class Int> | |
156 | void 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 | } | |
167 | template <class Archive, class Int> | |
168 | void 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 | } | |
179 | template <class Archive, class Int> | |
180 | void 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 |
192 | template <class Archive, unsigned MinBits, unsigned MaxBits, mp::cpp_integer_type SignType, mp::cpp_int_check_type Checked, class Allocator> |
193 | void 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 |