Find one clear bit 64 bits at a time. (#444)

This commit is contained in:
Branimir Karadžić
2026-10-04 20:21:29 -07:00
committed by GitHub
parent 8633996da6
commit 9521d0b5e2
2 changed files with 53 additions and 0 deletions

View File

@@ -606,8 +606,32 @@ namespace bx
return _endBit;
}
inline uint32_t bitSetFindZero(const uint64_t* _ptr, uint32_t _beginBit, uint32_t _endBit)
{
const uint32_t begin = _beginBit/64;
for (uint32_t ii = begin, end = alignUp(_endBit, 64)/64; ii < end; ++ii)
{
uint64_t zeros = ~_ptr[ii];
zeros &= ii == begin ? UINT64_MAX << (_beginBit & 63) : UINT64_MAX;
if (0 != zeros)
{
const uint32_t idx = ii*64 + countTrailingZeros(zeros);
return idx < _endBit ? idx : kInvalid;
}
}
return kInvalid;
}
inline uint32_t bitSetFind(const uint64_t* _ptr, uint32_t _beginBit, uint32_t _endBit, uint32_t _numBits)
{
if (1 == _numBits)
{
return bitSetFindZero(_ptr, _beginBit, _endBit);
}
if (_numBits >= 127)
{
const uint32_t idx = bitSetFindT<uint64_t>(_ptr, _beginBit, _endBit, (_numBits+63)>>6);

View File

@@ -293,6 +293,35 @@ TEST_CASE("BitArray-find-unset-bit", "[container]")
}
}
TEST_CASE("BitArray-find-unset-bit-in-range", "[container]")
{
uint64_t bits[8];
bx::MutableBitArrayView bs(bits, sizeof(bits) );
const uint32_t num = bs.getCount();
for (uint32_t ii = 0; ii < num; ++ii)
{
bs.set(0, num, true);
bs.set(ii, false);
for (uint32_t begin : { 0u, 1u, 63u, 64u, 65u, 200u })
{
for (uint32_t end : { 66u, 128u, 201u, 511u, 512u })
{
if (begin >= end)
{
continue;
}
const uint32_t expected = ii >= begin && ii < end ? ii : bx::kInvalid;
REQUIRE(expected == bs.find(begin, end, 1) );
REQUIRE(expected == bs.findClear(begin, end) );
}
}
}
}
TEST_CASE("BitArray-find-with-pattern", "[container]")
{
uint64_t bits[8];