diff --git a/.clang-format b/.clang-format index dcde4599ba..ec49b6a333 100644 --- a/.clang-format +++ b/.clang-format @@ -12,7 +12,7 @@ MaxEmptyLinesToKeep: 1 InsertBraces: true RemoveSemicolon: true PackConstructorInitializers: Never -RequiresClausePosition: WithPreceding +RequiresClausePosition: OwnLine # QualifierOrder: [ 'friend', 'inline', 'static', 'const', 'volatile', 'constexpr', 'restrict', 'type' ] IndentWidth: 2 diff --git a/modules/core/inc/tactile/core/platform/bits.hpp b/modules/core/inc/tactile/core/platform/bits.hpp index af6fa8b910..4a69e49ea3 100644 --- a/modules/core/inc/tactile/core/platform/bits.hpp +++ b/modules/core/inc/tactile/core/platform/bits.hpp @@ -6,7 +6,9 @@ #include // bit_cast, endian, byteswap #include // integral, invocable #include // byte +#include // memcpy #include // has_unique_object_representations_v +#include // is_trivially_copyable_v, is_trivially_constructible_v #include // __cpp_lib_byteswap #include "tactile/core/container/array.hpp" @@ -29,6 +31,22 @@ void each_byte(const IntType value, const CallableType& callable) } } +template + requires(sizeof(To) == sizeof(From) && // + std::is_trivially_copyable_v && // + std::is_trivially_copyable_v && // + std::is_trivially_constructible_v) +[[nodiscard]] auto interpret_as(const From& src) noexcept -> To +{ +#if __cpp_lib_bit_cast >= 201806L + return std::bit_cast(src); +#else + To dst; + std::memcpy(&dst, &src, sizeof dst); + return dst; +#endif +} + /** * \brief Reverses the bytes in an integer value. * @@ -46,10 +64,10 @@ template #else using ByteArray = Array; - const auto bytes = std::bit_cast(value); + const auto bytes = interpret_as(value); std::reverse(bytes.begin(), bytes.end()); - return std::bit_cast(bytes); + return interpret_as(bytes); #endif } diff --git a/modules/core/test/platform/bits_test.cpp b/modules/core/test/platform/bits_test.cpp index 1586a5cd5d..6de171db5d 100644 --- a/modules/core/test/platform/bits_test.cpp +++ b/modules/core/test/platform/bits_test.cpp @@ -17,8 +17,8 @@ TEST(BitUtilities, ReverseBytes) const uint32 original = 0xDEADBEEF; const auto swapped = reverse_bytes(original); - const auto original_bytes = std::bit_cast(original); - const auto swapped_bytes = std::bit_cast(swapped); + const auto original_bytes = interpret_as(original); + const auto swapped_bytes = interpret_as(swapped); EXPECT_EQ(original_bytes.at(0), swapped_bytes.at(3)); EXPECT_EQ(original_bytes.at(1), swapped_bytes.at(2));