Skip to content

Commit

Permalink
Flatten float serialization, remove last bits of BitCast
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexMax committed Jan 22, 2024
1 parent d0e55ee commit f604484
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 35 deletions.
15 changes: 0 additions & 15 deletions include/lexio/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,6 @@ constexpr const TYPE &Max(const TYPE &a, const TYPE &b)
return a < b ? b : a;
}

/**
* @see https://en.cppreference.com/w/cpp/numeric/bit_cast
*/
template <class TO, class FROM>
inline std::enable_if_t<
sizeof(TO) == sizeof(FROM) && std::is_trivially_copyable<FROM>::value && std::is_trivially_copyable<TO>::value, TO>
BitCast(const FROM &src) noexcept
{
static_assert(std::is_trivially_constructible<TO>::value, "BitCast TO must be trivially constructible.");

TO dst;
std::memcpy(&dst, &src, sizeof(TO));
return dst;
}

/**
* @see https://en.cppreference.com/w/cpp/types/void_t
*/
Expand Down
88 changes: 68 additions & 20 deletions include/lexio/serialize/tryfloat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,17 @@ using float64_t = double;
*/
inline bool TryReadFloat32LE(float32_t &out, const ReaderRef &reader)
{
uint32_t bits = 0;
if (!TryReadU32LE(bits, reader))
uint8_t buf[sizeof(uint32_t)] = {0};
const size_t count = Read(buf, reader);
if (count != sizeof(buf))
{
return false;
}
out = Detail::BitCast<float32_t>(bits);

uint32_t bits = 0;
std::memcpy(&bits, buf, sizeof(bits));
bits = LEXIO_IF_BE_BSWAP32(bits);
std::memcpy(&out, &bits, sizeof(out));
return true;
}

Expand All @@ -56,12 +61,17 @@ inline bool TryReadFloat32LE(float32_t &out, const ReaderRef &reader)
*/
inline bool TryReadFloat32BE(float32_t &out, const ReaderRef &reader)
{
uint32_t bits = 0;
if (!TryReadU32BE(bits, reader))
uint8_t buf[sizeof(uint32_t)] = {0};
const size_t count = Read(buf, reader);
if (count != sizeof(buf))
{
return false;
}
out = Detail::BitCast<float32_t>(bits);

uint32_t bits = 0;
std::memcpy(&bits, buf, sizeof(bits));
bits = LEXIO_IF_LE_BSWAP32(bits);
std::memcpy(&out, &bits, sizeof(out));
return true;
}

Expand All @@ -74,8 +84,15 @@ inline bool TryReadFloat32BE(float32_t &out, const ReaderRef &reader)
*/
inline bool TryWriteFloat32LE(const WriterRef &writer, float32_t value)
{
const uint32_t bits = Detail::BitCast<uint32_t>(value);
return TryWriteU32LE(writer, bits);
uint32_t bits = 0;
std::memcpy(&bits, &value, sizeof(bits));

uint8_t buf[sizeof(bits)] = {0};
bits = LEXIO_IF_BE_BSWAP32(bits);
std::memcpy(buf, &bits, sizeof(buf));

const size_t count = Write(writer, buf, sizeof(buf));
return count == sizeof(buf);
}

/**
Expand All @@ -87,8 +104,15 @@ inline bool TryWriteFloat32LE(const WriterRef &writer, float32_t value)
*/
inline bool TryWriteFloat32BE(const WriterRef &writer, float32_t value)
{
const uint32_t bits = Detail::BitCast<uint32_t>(value);
return TryWriteU32BE(writer, bits);
uint32_t bits = 0;
std::memcpy(&bits, &value, sizeof(bits));

uint8_t buf[sizeof(bits)] = {0};
bits = LEXIO_IF_LE_BSWAP32(bits);
std::memcpy(buf, &bits, sizeof(buf));

const size_t count = Write(writer, buf, sizeof(buf));
return count == sizeof(buf);
}

//******************************************************************************
Expand All @@ -102,12 +126,17 @@ inline bool TryWriteFloat32BE(const WriterRef &writer, float32_t value)
*/
inline bool TryReadFloat64LE(float64_t &out, const ReaderRef &reader)
{
uint64_t bits = 0;
if (!TryReadU64LE(bits, reader))
uint8_t buf[sizeof(uint64_t)] = {0};
const size_t count = Read(buf, reader);
if (count != sizeof(buf))
{
return false;
}
out = Detail::BitCast<float64_t>(bits);

uint64_t bits = 0;
std::memcpy(&bits, buf, sizeof(bits));
bits = LEXIO_IF_BE_BSWAP64(bits);
std::memcpy(&out, &bits, sizeof(out));
return true;
}

Expand All @@ -120,12 +149,17 @@ inline bool TryReadFloat64LE(float64_t &out, const ReaderRef &reader)
*/
inline bool TryReadFloat64BE(float64_t &out, const ReaderRef &reader)
{
uint64_t bits = 0;
if (!TryReadU64BE(bits, reader))
uint8_t buf[sizeof(uint64_t)] = {0};
const size_t count = Read(buf, reader);
if (count != sizeof(buf))
{
return false;
}
out = Detail::BitCast<float64_t>(bits);

uint64_t bits = 0;
std::memcpy(&bits, buf, sizeof(bits));
bits = LEXIO_IF_LE_BSWAP64(bits);
std::memcpy(&out, &bits, sizeof(out));
return true;
}

Expand All @@ -138,8 +172,15 @@ inline bool TryReadFloat64BE(float64_t &out, const ReaderRef &reader)
*/
inline bool TryWriteFloat64LE(const WriterRef &writer, float64_t value)
{
const uint64_t bits = Detail::BitCast<uint64_t>(value);
return TryWriteU64LE(writer, bits);
uint64_t bits = 0;
std::memcpy(&bits, &value, sizeof(bits));

uint8_t buf[sizeof(bits)] = {0};
bits = LEXIO_IF_BE_BSWAP64(bits);
std::memcpy(buf, &bits, sizeof(buf));

const size_t count = Write(writer, buf, sizeof(buf));
return count == sizeof(buf);
}

/**
Expand All @@ -151,8 +192,15 @@ inline bool TryWriteFloat64LE(const WriterRef &writer, float64_t value)
*/
inline bool TryWriteFloat64BE(const WriterRef &writer, float64_t value)
{
const uint64_t bits = Detail::BitCast<uint64_t>(value);
return TryWriteU64BE(writer, bits);
uint64_t bits = 0;
std::memcpy(&bits, &value, sizeof(bits));

uint8_t buf[sizeof(bits)] = {0};
bits = LEXIO_IF_LE_BSWAP64(bits);
std::memcpy(buf, &bits, sizeof(buf));

const size_t count = Write(writer, buf, sizeof(buf));
return count == sizeof(buf);
}

} // namespace LexIO

0 comments on commit f604484

Please sign in to comment.