From c963fce3046b0a6f4df5421fc0ba80bc43eff28d Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 7 Feb 2022 12:14:24 +1000 Subject: [PATCH] endian: prefer bit_cast over union type punning --- endian.hpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/endian.hpp b/endian.hpp index 0e3c02a9..f86e108d 100644 --- a/endian.hpp +++ b/endian.hpp @@ -9,6 +9,7 @@ #pragma once #include "std.hpp" +#include "cast.hpp" #include "types/sized.hpp" #include @@ -48,21 +49,18 @@ namespace cruft { 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. - // - // this is debatably safe under production compilers like gcc + clang - // despite what the standard may say about unions. - constexpr float - bswap (float v) noexcept + //------------------------------------------------------------------------- + constexpr f32 + bswap (f32 v) noexcept { - union { - float f; - uint32_t u; - } temp { .f = v }; + return cruft::cast::bit (bswap (cruft::cast::bit (v))); + } - temp.u = bswap (temp.u); - return temp.f; + + constexpr f64 + bswap (f64 v) noexcept + { + return cruft::cast::bit (bswap (cruft::cast::bit (v))); }