[+] AuBitScanReverse
This commit is contained in:
parent
a81e51c0fb
commit
3200e9cb46
@ -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
|
Loading…
Reference in New Issue
Block a user