fix(ricepp): workaround missing constexpr-ness of Windows _byteswap*

This commit is contained in:
Marcus Holland-Moritz 2024-02-04 14:04:48 +01:00
parent 4811199406
commit 6ca47f5e75

View File

@ -32,6 +32,13 @@ namespace ricepp {
namespace detail {
template <std::unsigned_integral T>
[[nodiscard]] constexpr T byteswap_fallback(T value) noexcept {
auto value_repr = std::bit_cast<std::array<std::byte, sizeof(T)>>(value);
ranges::reverse(value_repr);
return std::bit_cast<T>(value_repr);
}
template <std::unsigned_integral T>
[[nodiscard]] constexpr T byteswap(T value) noexcept {
#if __cpp_lib_byteswap >= 202110L
@ -47,6 +54,9 @@ template <std::unsigned_integral T>
}
#elif defined(_MSC_VER)
static_assert(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
if constexpr (std::is_constant_evaluated()) {
return byteswap_fallback(value);
} else {
if constexpr (sizeof(T) == 2) {
return _byteswap_ushort(value);
} else if constexpr (sizeof(T) == 4) {
@ -54,10 +64,9 @@ template <std::unsigned_integral T>
} else if constexpr (sizeof(T) == 8) {
return _byteswap_uint64(value);
}
}
#else
auto value_repr = std::bit_cast<std::array<std::byte, sizeof(T)>>(value);
ranges::reverse(value_repr);
return std::bit_cast<T>(value_repr);
return byteswap_fallback(value);
#endif
}