Skip to content

Commit b7a11bc

Browse files
committed
Add floating point constants, assert equality with Boost's fpclassify
1 parent 0c089bd commit b7a11bc

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

src/portable_archive/portable_oarchive.hpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,28 @@
1010
#include <boost/archive/basic_binary_oarchive.hpp>
1111
#endif
1212

13+
#include <cstring>
14+
15+
template <typename T> struct FPTraits {};
16+
template <> struct FPTraits<double> {
17+
using bits = uint64_t;
18+
static constexpr bits sign = (0x80000000ull) << 32, exponent = (0x7ff00000ll) << 32,
19+
significand = ((0x000fffffll) << 32) + (0xfffffffful);
20+
bits get_bits(double f) {
21+
bits b;
22+
std::memcpy(&b, &f, sizeof(bits));
23+
return b;
24+
}
25+
};
26+
template <> struct FPTraits<float> {
27+
using bits = uint32_t;
28+
static constexpr bits sign = 0x80000000u, exponent = 0x7f800000, significand = 0x007fffff;
29+
bits get_bits(float f) {
30+
bits b;
31+
std::memcpy(&b, &f, sizeof(bits));
32+
return b;
33+
}
34+
};
1335

1436
namespace eos {
1537

@@ -195,6 +217,9 @@ namespace eos {
195217
save(const T & t, dummy<3> = 0)
196218
{
197219
using traits = typename fp::detail::fp_traits<T>::type;
220+
using newtraits = FPTraits<T>;
221+
static_assert(std::is_same<typename traits::bits, typename newtraits::bits>::value,
222+
"Wrong corresponding int type");
198223

199224
// if the no_infnan flag is set we must throw here
200225
if (get_flags() & no_infnan && !fp::isfinite(t))
@@ -207,9 +232,13 @@ namespace eos {
207232
// after reading the note above you still might decide to
208233
// deactivate this static assert and try if it works out.
209234
typename traits::bits bits;
210-
BOOST_STATIC_ASSERT(sizeof(bits) == sizeof(T));
211-
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_iec559);
212-
235+
static_assert(sizeof(bits) == sizeof(T), "mismatching type sizes");
236+
static_assert(std::numeric_limits<T>::is_iec559, "float representation differs from IEC559");
237+
238+
static_assert(traits::exponent == newtraits::exponent, "mismatching exponent");
239+
static_assert(traits::significand == newtraits::significand, "mismatching significand");
240+
static_assert(traits::sign == newtraits::sign, "mismatching sign bit");
241+
213242
switch (fp::fpclassify(t)) {
214243
case FP_NAN: bits = traits::exponent | traits::significand; break;
215244
case FP_INFINITE: bits = traits::exponent | (t<0) * traits::sign; break;

0 commit comments

Comments
 (0)