2
0
mirror of https://github.com/boostorg/mysql.git synced 2026-02-14 12:52:17 +00:00

Fixed float serialization for boost 1.71+

This commit is contained in:
ruben
2020-02-29 15:04:57 +00:00
parent 3d7b4d0957
commit bd5dafcbbf

View File

@@ -2,6 +2,7 @@
#define MYSQL_ASIO_IMPL_SERIALIZATION_HPP
#include <boost/endian/conversion.hpp>
#include <boost/endian/buffers.hpp>
#include <boost/asio/buffer.hpp>
#include <vector>
#include <type_traits>
@@ -98,7 +99,7 @@ private:
using value_type = typename get_value_type<T>::type;
public:
static constexpr bool value =
std::is_arithmetic_v<value_type> && // includes floating point types
std::is_integral_v<value_type> &&
std::is_base_of_v<value_holder<value_type>, T>;
};
@@ -333,6 +334,47 @@ std::size_t get_size(T, const SerializationContext&) noexcept
return get_fixed_size<value_holder<std::underlying_type_t<T>>>::value;
}
// Floating points
template <typename T, typename=std::enable_if_t<std::is_floating_point_v<T>>>
Error deserialize(value_holder<T>& output, DeserializationContext& ctx) noexcept
{
// Size check
if (!ctx.enough_size(sizeof(T))) return Error::incomplete_message;
// Endianness conversion
// Boost.Endian support for floats start at 1.71. TODO: maybe update requirements and CI
#if BOOST_ENDIAN_BIG_BYTE
char buf [sizeof(T)];
std::memcpy(buf, ctx.first(), sizeof(T));
std::reverse(buf, buf + sizeof(T));
std::memcpy(&output.value, buf, sizeof(T));
#else
std::memcpy(&output.value, ctx.first(), sizeof(T));
#endif
ctx.advance(sizeof(T));
return Error::ok;
}
template <typename T, typename=std::enable_if_t<std::is_floating_point_v<T>>>
void serialize(const value_holder<T>& input, SerializationContext& ctx) noexcept
{
// Endianness conversion
#if BOOST_ENDIAN_BIG_BYTE
char buf [sizeof(T)];
std::memcpy(buf, &input.value, sizeof(T));
std::reverse(buf, buf + sizeof(T));
ctx.write(buf, sizeof(T));
#else
ctx.write(&input.value, sizeof(T));
#endif
}
template <typename T, typename=std::enable_if_t<std::is_floating_point_v<T>>>
std::size_t get_size(const value_holder<T>&, const SerializationContext&) noexcept
{
return sizeof(T);
}
// Structs. To allow a limited way of reflection, structs should
// specialize get_struct_fields with a tuple of pointers to members,
// thus defining which fields should be (de)serialized in the struct