From f191ade18bd9b993ddcf621eddff0770fed9848f Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 18 Mar 2019 19:26:58 -0500 Subject: [PATCH] [ox/mc] Make VLI encode/decode constexpr --- deps/ox/src/ox/mc/intops.hpp | 34 +++++++++++++++------------------- deps/ox/src/ox/std/memops.cpp | 17 ----------------- deps/ox/src/ox/std/memops.hpp | 17 +++++++++++++++-- 3 files changed, 30 insertions(+), 38 deletions(-) diff --git a/deps/ox/src/ox/mc/intops.hpp b/deps/ox/src/ox/mc/intops.hpp index b4602aff..cc70d8fd 100644 --- a/deps/ox/src/ox/mc/intops.hpp +++ b/deps/ox/src/ox/mc/intops.hpp @@ -49,22 +49,18 @@ static_assert(highestBit(uint64_t(1) << 31) == 31); static_assert(highestBit(uint64_t(1) << 63) == 63); struct McInt { - uint8_t data[9]; + uint8_t data[9] = {0}; // length of integer in bytes std::size_t length = 0; }; -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-align" -#endif - template -[[nodiscard]] McInt encodeInteger(I input) noexcept { +[[nodiscard]] constexpr McInt encodeInteger(I input) noexcept { McInt out; // move input to uint64_t to allow consistent bit manipulation, and to avoid // overflow concerns - uint64_t val = *reinterpret_cast*>(&input); + uint64_t val = 0; + ox_memcpy(&val, &input, sizeof(I)); if (val) { // bits needed to represent number factoring in space possibly // needed for signed bit @@ -83,19 +79,20 @@ template // move sign bit if constexpr(ox::is_signed) { if (val < 0) { - *reinterpret_cast(&val) ^= uint64_t(1) << (sizeof(I) * 8 - 1); - *reinterpret_cast(&val) |= uint64_t(1) << (bitsAvailable - 1); + val ^= uint64_t(1) << (sizeof(I) * 8 - 1); + val |= uint64_t(1) << (bitsAvailable - 1); } } // ensure we are copying from little endian represenstation LittleEndian leVal = val; if (bytes == 9) { out.data[0] = bytesIndicator; - *reinterpret_cast(&out.data[1]) = leVal.raw(); + ox_memcpy(&out.data[1], &leVal, sizeof(I)); } else { - *reinterpret_cast(&out.data[0]) = + auto intermediate = static_cast(leVal.raw()) << bytes | static_cast(bytesIndicator); + ox_memcpy(out.data, &intermediate, sizeof(intermediate)); } out.length = bytes; } @@ -123,11 +120,13 @@ static_assert(countBytes(0b01111111) == 8); static_assert(countBytes(0b11111111) == 9); template -[[nodiscard]] ValErr decodeInteger(uint8_t buff[9], std::size_t buffLen, std::size_t *bytesRead) noexcept { +[[nodiscard]] constexpr ValErr decodeInteger(uint8_t buff[9], std::size_t buffLen, std::size_t *bytesRead) noexcept { const auto bytes = countBytes(buff[0]); if (bytes == 9) { *bytesRead = bytes; - return {LittleEndian(*reinterpret_cast(&buff[1])), 0}; + I out; + ox_memcpy(&out, &buff[1], sizeof(I)); + return {LittleEndian(out), 0}; } else if (buffLen >= bytes) { *bytesRead = bytes; uint64_t decoded = 0; @@ -142,17 +141,14 @@ template // remove sign decoded &= uint64_t(~0) ^ (uint64_t(1) << valBits); // set sign - *reinterpret_cast*>(&out) |= sign << (Bits - 1); + decoded |= sign << (Bits - 1); + ox_memcpy(&out, &decoded, sizeof(out)); } return {out, 0}; } return {0, OxError(1)}; } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - template [[nodiscard]] ValErr decodeInteger(McInt m) noexcept { std::size_t bytesRead; diff --git a/deps/ox/src/ox/std/memops.cpp b/deps/ox/src/ox/std/memops.cpp index 39f3696d..2c8b7450 100644 --- a/deps/ox/src/ox/std/memops.cpp +++ b/deps/ox/src/ox/std/memops.cpp @@ -23,20 +23,3 @@ int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept { } return retval; } - -void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept { - auto srcBuf = static_cast(src); - auto dstBuf = static_cast(dest); - for (std::size_t i = 0; i < size; i++) { - dstBuf[i] = static_cast(srcBuf[i]); - } - return dest; -} - -void *ox_memset(void *ptr, int val, std::size_t size) noexcept { - auto buf = static_cast(ptr); - for (std::size_t i = 0; i < size; i++) { - buf[i] = val; - } - return ptr; -} diff --git a/deps/ox/src/ox/std/memops.hpp b/deps/ox/src/ox/std/memops.hpp index 142aeb80..8b5abd01 100644 --- a/deps/ox/src/ox/std/memops.hpp +++ b/deps/ox/src/ox/std/memops.hpp @@ -11,6 +11,19 @@ int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept; -void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept; +constexpr void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept { + auto srcBuf = static_cast(src); + auto dstBuf = static_cast(dest); + for (std::size_t i = 0; i < size; i++) { + dstBuf[i] = static_cast(srcBuf[i]); + } + return dest; +} -void *ox_memset(void *ptr, int val, std::size_t size) noexcept; +constexpr void *ox_memset(void *ptr, int val, std::size_t size) noexcept { + auto buf = static_cast(ptr); + for (std::size_t i = 0; i < size; i++) { + buf[i] = val; + } + return ptr; +}