From c76a7f434938458427616ea7d565000dffbd1a2e Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 19 Jun 2024 01:17:07 +0100 Subject: [PATCH] Allow GetBitMaskSC to be used with mask size equal to type size --- src/core/bitmath_func.hpp | 9 ++++++--- src/tests/bitmath_func.cpp | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 5863cfe807..6af7a133d1 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -11,6 +11,7 @@ #define BITMATH_FUNC_HPP #include +#include #include /** @@ -192,14 +193,16 @@ constexpr T ToggleBit(T &x, const uint8_t y) * * @param start The start bit * @param count The number of bits - * @pre start + count < sizeof(T) * 8 * @return The bit mask */ template constexpr T GetBitMaskSC(const uint8_t start, const uint8_t count) { - typename std::make_unsigned::type mask = 1; - return (T)(((mask << count) - 1) << start); + using U = typename std::make_unsigned::type; + constexpr uint BIT_WIDTH = std::numeric_limits::digits; + + U mask = ((static_cast(1) << (count & (BIT_WIDTH - 1))) - 1) | (count >= BIT_WIDTH ? ~static_cast(0) : 0); + return (T)(mask << start); } /** diff --git a/src/tests/bitmath_func.cpp b/src/tests/bitmath_func.cpp index 9b23684174..7f18a27661 100644 --- a/src/tests/bitmath_func.cpp +++ b/src/tests/bitmath_func.cpp @@ -71,8 +71,12 @@ TEST_CASE("SetBitIterator tests") TEST_CASE("GetBitMaskSC tests") { - CHECK(GetBitMaskSC(4, 4) == 0xF0); - CHECK(GetBitMaskSC(28, 4) == 0xF0000000); + CHECK(GetBitMaskSC(36, 4) == 0xF000000000ULL); + CHECK(GetBitMaskSC(60, 4) == 0xF000000000000000ULL); + CHECK(GetBitMaskSC(0, 64) == 0xFFFFFFFFFFFFFFFFULL); + CHECK(GetBitMaskSC(4, 4) == 0xF0); + CHECK(GetBitMaskSC(28, 4) == 0xF0000000); + CHECK(GetBitMaskSC(0, 32) == 0xFFFFFFFF); CHECK(GetBitMaskSC(7, 1) == 0x80); CHECK(GetBitMaskSC(0, 1) == 1); CHECK(GetBitMaskSC(0, 0) == 0); @@ -81,8 +85,12 @@ TEST_CASE("GetBitMaskSC tests") TEST_CASE("GetBitMaskFL tests") { - CHECK(GetBitMaskFL(4, 7) == 0xF0); - CHECK(GetBitMaskFL(28, 31) == 0xF0000000); + CHECK(GetBitMaskFL(36, 39) == 0xF000000000ULL); + CHECK(GetBitMaskFL(60, 63) == 0xF000000000000000ULL); + CHECK(GetBitMaskFL(0, 63) == 0xFFFFFFFFFFFFFFFFULL); + CHECK(GetBitMaskFL(4, 7) == 0xF0); + CHECK(GetBitMaskFL(28, 31) == 0xF0000000); + CHECK(GetBitMaskFL(0, 31) == 0xFFFFFFFF); CHECK(GetBitMaskFL(7, 7) == 0x80); CHECK(GetBitMaskFL(0, 0) == 1); CHECK(GetBitMaskFL(3, 4) == 0x18);