From 4fac7daaef23ead36ac302d7be757cc032d58132 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 29 Dec 2021 12:12:25 -0800 Subject: [PATCH] Cleanup bit_cast --- include/fmt/format.h | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index ea5b9ece..1a5ff230 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -297,28 +297,23 @@ template class formatbuf : public Streambuf { } }; -// An equivalent of `*reinterpret_cast(&source)` that doesn't have -// undefined behavior (e.g. due to type aliasing). -// Example: uint64_t d = bit_cast(2.718); -template -FMT_CONSTEXPR20 auto bit_cast(const Source& source) -> Dest { - static_assert(sizeof(Dest) == sizeof(Source), "size mismatch"); +// Implementation of std::bit_cast for pre-C++20. +template +FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To { + static_assert(sizeof(To) == sizeof(From), "size mismatch"); #ifdef __cpp_lib_bit_cast - if (is_constant_evaluated()) { - return std::bit_cast(source); - } + if (is_constant_evaluated()) return std::bit_cast(from); #endif - Dest dest; - std::memcpy(&dest, &source, sizeof(dest)); - return dest; + auto to = To(); + std::memcpy(&to, &from, sizeof(to)); + return to; } inline auto is_big_endian() -> bool { - const auto u = 1u; struct bytes { - char data[sizeof(u)]; + char data[sizeof(int)]; }; - return bit_cast(u).data[0] == 0; + return bit_cast(1).data[0] == 0; } // A fallback implementation of uintptr_t for systems that lack it. @@ -785,7 +780,8 @@ class basic_memory_buffer final : public detail::buffer { }; template -FMT_CONSTEXPR20 void basic_memory_buffer::grow(size_t size) { +FMT_CONSTEXPR20 void basic_memory_buffer::grow( + size_t size) { #ifdef FMT_FUZZ if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much"); #endif