[+] AuBitScanReverse

This commit is contained in:
Reece Wilson 2022-10-14 01:27:17 +01:00
parent a81e51c0fb
commit 3200e9cb46

View File

@ -13,18 +13,36 @@ static auline bool AuTestBit(T value, AuUInt8 idx)
return value & (T(1) << T(idx));
}
template <class T>
static auline bool AuBitTest(T value, AuUInt8 idx)
{
return value & (T(1) << T(idx));
}
template <class T>
static auline void AuSetBit(T &value, AuUInt8 idx)
{
value |= T(1) << T(idx);
}
template <class T>
static auline void AuBitSet(T &value, AuUInt8 idx)
{
value |= T(1) << T(idx);
}
template <class T>
static auline void AuClearBit(T &value, AuUInt8 idx)
{
value &= ~(T(1) << T(idx));
}
template <class T>
static auline void AuBitClear(T &value, AuUInt8 idx)
{
value &= ~(T(1) << T(idx));
}
template <class T>
static auline bool AuBitScanForward(AuUInt8 &index, T value)
{
@ -92,6 +110,73 @@ static auline bool AuBitScanForward(AuUInt8 &index, T value)
return success;
}
template <class T>
static auline bool AuBitScanReverse(AuUInt8 &index, T value)
{
unsigned long ret;
bool success;
success = false;
index = 0;
#if defined(AURORA_COMPILER_MSVC)
if constexpr (sizeof(T) == sizeof(AuUInt64))
{
#if defined(AURORA_IS_32BIT)
if (!(success = _BitScanReverse(&ret, static_cast<AuUInt32>((value >> 32) & 0xffffffff))))
{
if (!_BitScanReverse(&ret, static_cast<AuUInt32>(value & 0xffffffff)))
{
return false;
}
ret += 32;
}
#else
success = _BitScanReverse64(&ret, static_cast<AuUInt64>(value));
#endif
}
else
{
success = _BitScanReverse(&ret, static_cast<unsigned long>(value));
}
#elif defined(AURORA_COMPILER_GCC) || defined(AURORA_COMPILER_CLANG)
if (value == 0)
{
return false;
}
if constexpr (sizeof(T) == sizeof(AuUInt64))
{
#if defined(AURORA_IS_32BIT)
auto lower = static_cast<AuUInt32>((value >> 32) & 0xffffffff);
if (lower == 0)
{
ret = __builtin_clzl(static_cast<AuUInt32>(value & 0xffffffff)));
ret += 32;
}
else
{
ret = __builtin_clzl(static_cast<AuUInt32>(lower));
}
#else
ret = __builtin_clzll(static_cast<AuUInt64>(value));
#endif
}
else if constexpr (sizeof(T) == sizeof(unsigned long))
{
ret = __builtin_clzl(static_cast<unsigned long>(value));
}
else if constexpr (sizeof(T) == sizeof(unsigned int))
{
ret = __builtin_clz(static_cast<unsigned int>(value));
}
success = true;
#endif
index = ret;
return success;
}
template <class T>
struct AuHalfWord
{
@ -223,5 +308,3 @@ static AuUInt8 AuPopCnt(T in)
return {};
}
// TODO: AuBitScanReverse