mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-16 00:12:51 +00:00
Allow GetBitMaskSC to be used with mask size equal to type size
This commit is contained in:
parent
0129b2c9d3
commit
c76a7f4349
@ -11,6 +11,7 @@
|
|||||||
#define BITMATH_FUNC_HPP
|
#define BITMATH_FUNC_HPP
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
#include <limits>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,14 +193,16 @@ constexpr T ToggleBit(T &x, const uint8_t y)
|
|||||||
*
|
*
|
||||||
* @param start The start bit
|
* @param start The start bit
|
||||||
* @param count The number of bits
|
* @param count The number of bits
|
||||||
* @pre start + count < sizeof(T) * 8
|
|
||||||
* @return The bit mask
|
* @return The bit mask
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr T GetBitMaskSC(const uint8_t start, const uint8_t count)
|
constexpr T GetBitMaskSC(const uint8_t start, const uint8_t count)
|
||||||
{
|
{
|
||||||
typename std::make_unsigned<T>::type mask = 1;
|
using U = typename std::make_unsigned<T>::type;
|
||||||
return (T)(((mask << count) - 1) << start);
|
constexpr uint BIT_WIDTH = std::numeric_limits<U>::digits;
|
||||||
|
|
||||||
|
U mask = ((static_cast<U>(1) << (count & (BIT_WIDTH - 1))) - 1) | (count >= BIT_WIDTH ? ~static_cast<U>(0) : 0);
|
||||||
|
return (T)(mask << start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,8 +71,12 @@ TEST_CASE("SetBitIterator tests")
|
|||||||
|
|
||||||
TEST_CASE("GetBitMaskSC tests")
|
TEST_CASE("GetBitMaskSC tests")
|
||||||
{
|
{
|
||||||
CHECK(GetBitMaskSC<uint>(4, 4) == 0xF0);
|
CHECK(GetBitMaskSC<uint64_t>(36, 4) == 0xF000000000ULL);
|
||||||
CHECK(GetBitMaskSC<uint>(28, 4) == 0xF0000000);
|
CHECK(GetBitMaskSC<uint64_t>(60, 4) == 0xF000000000000000ULL);
|
||||||
|
CHECK(GetBitMaskSC<uint64_t>(0, 64) == 0xFFFFFFFFFFFFFFFFULL);
|
||||||
|
CHECK(GetBitMaskSC<uint32_t>(4, 4) == 0xF0);
|
||||||
|
CHECK(GetBitMaskSC<uint32_t>(28, 4) == 0xF0000000);
|
||||||
|
CHECK(GetBitMaskSC<uint32_t>(0, 32) == 0xFFFFFFFF);
|
||||||
CHECK(GetBitMaskSC<uint8_t>(7, 1) == 0x80);
|
CHECK(GetBitMaskSC<uint8_t>(7, 1) == 0x80);
|
||||||
CHECK(GetBitMaskSC<uint8_t>(0, 1) == 1);
|
CHECK(GetBitMaskSC<uint8_t>(0, 1) == 1);
|
||||||
CHECK(GetBitMaskSC<uint8_t>(0, 0) == 0);
|
CHECK(GetBitMaskSC<uint8_t>(0, 0) == 0);
|
||||||
@ -81,8 +85,12 @@ TEST_CASE("GetBitMaskSC tests")
|
|||||||
|
|
||||||
TEST_CASE("GetBitMaskFL tests")
|
TEST_CASE("GetBitMaskFL tests")
|
||||||
{
|
{
|
||||||
CHECK(GetBitMaskFL<uint>(4, 7) == 0xF0);
|
CHECK(GetBitMaskFL<uint64_t>(36, 39) == 0xF000000000ULL);
|
||||||
CHECK(GetBitMaskFL<uint>(28, 31) == 0xF0000000);
|
CHECK(GetBitMaskFL<uint64_t>(60, 63) == 0xF000000000000000ULL);
|
||||||
|
CHECK(GetBitMaskFL<uint64_t>(0, 63) == 0xFFFFFFFFFFFFFFFFULL);
|
||||||
|
CHECK(GetBitMaskFL<uint32_t>(4, 7) == 0xF0);
|
||||||
|
CHECK(GetBitMaskFL<uint32_t>(28, 31) == 0xF0000000);
|
||||||
|
CHECK(GetBitMaskFL<uint32_t>(0, 31) == 0xFFFFFFFF);
|
||||||
CHECK(GetBitMaskFL<uint8_t>(7, 7) == 0x80);
|
CHECK(GetBitMaskFL<uint8_t>(7, 7) == 0x80);
|
||||||
CHECK(GetBitMaskFL<uint8_t>(0, 0) == 1);
|
CHECK(GetBitMaskFL<uint8_t>(0, 0) == 1);
|
||||||
CHECK(GetBitMaskFL<uint8_t>(3, 4) == 0x18);
|
CHECK(GetBitMaskFL<uint8_t>(3, 4) == 0x18);
|
||||||
|
Loading…
Reference in New Issue
Block a user