endian: prefer bit_cast over union type punning
This commit is contained in:
parent
1dd516d1ed
commit
c963fce304
24
endian.hpp
24
endian.hpp
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user