endian: prefer bit_cast over union type punning

This commit is contained in:
Danny Robson 2022-02-07 12:14:24 +10:00
parent 1dd516d1ed
commit c963fce304

View File

@ -9,6 +9,7 @@
#pragma once #pragma once
#include "std.hpp" #include "std.hpp"
#include "cast.hpp"
#include "types/sized.hpp" #include "types/sized.hpp"
#include <compare> #include <compare>
@ -48,21 +49,18 @@ namespace cruft {
constexpr uint64_t bswap (uint64_t v) noexcept { return __builtin_bswap64 (v); } constexpr uint64_t bswap (uint64_t v) noexcept { return __builtin_bswap64 (v); }
// use a type-punning union to punt the byte swapping operation to the //-------------------------------------------------------------------------
// unsigned integer code. constexpr f32
// bswap (f32 v) noexcept
// this is debatably safe under production compilers like gcc + clang
// despite what the standard may say about unions.
constexpr float
bswap (float v) noexcept
{ {
union { return cruft::cast::bit<f32> (bswap (cruft::cast::bit<u32> (v)));
float f; }
uint32_t u;
} temp { .f = v };
temp.u = bswap (temp.u);
return temp.f; constexpr f64
bswap (f64 v) noexcept
{
return cruft::cast::bit<f64> (bswap (cruft::cast::bit<u64> (v)));
} }