[util] Implement bit vector

This commit is contained in:
Robin Kertels 2022-11-20 22:17:51 +01:00 committed by Joshie
parent d0a10cc9f8
commit 1a3b576d35
1 changed files with 111 additions and 0 deletions

View File

@ -32,6 +32,7 @@
#include <cstring>
#include <iterator>
#include <type_traits>
#include <vector>
namespace dxvk::bit {
@ -337,6 +338,116 @@ namespace dxvk::bit {
};
class bitvector {
public:
bool get(uint32_t idx) const {
uint32_t dword = idx / 32;
uint32_t bit = idx % 32;
return m_dwords[dword] & (1u << bit);
}
void ensureSize(uint32_t bitCount) {
uint32_t dword = bitCount / 32;
if (unlikely(dword >= m_dwords.size())) {
m_dwords.resize(dword + 1);
}
m_bitCount = std::max(m_bitCount, bitCount);
}
void set(uint32_t idx, bool value) {
ensureSize(idx + 1);
uint32_t dword = 0;
uint32_t bit = idx;
if (value)
m_dwords[dword] |= 1u << bit;
else
m_dwords[dword] &= ~(1u << bit);
}
bool exchange(uint32_t idx, bool value) {
ensureSize(idx + 1);
bool oldValue = get(idx);
set(idx, value);
return oldValue;
}
void flip(uint32_t idx) {
ensureSize(idx + 1);
uint32_t dword = idx / 32;
uint32_t bit = idx % 32;
m_dwords[dword] ^= 1u << bit;
}
void setAll() {
if (m_bitCount % 32 == 0) {
for (size_t i = 0; i < m_dwords.size(); i++)
m_dwords[i] = std::numeric_limits<uint32_t>::max();
}
else {
for (size_t i = 0; i < m_dwords.size() - 1; i++)
m_dwords[i] = std::numeric_limits<uint32_t>::max();
m_dwords[m_dwords.size() - 1] = (1u << (m_bitCount % 32)) - 1;
}
}
void clearAll() {
for (size_t i = 0; i < m_dwords.size(); i++)
m_dwords[i] = 0;
}
bool any() const {
for (size_t i = 0; i < m_dwords.size(); i++) {
if (m_dwords[i] != 0)
return true;
}
return false;
}
uint32_t& dword(uint32_t idx) {
return m_dwords[idx];
}
size_t bitCount() const {
return m_bitCount;
}
size_t dwordCount() const {
return m_dwords.size();
}
bool operator [] (uint32_t idx) const {
return get(idx);
}
void setN(uint32_t bits) {
ensureSize(bits);
uint32_t fullDwords = bits / 32;
uint32_t offset = bits % 32;
for (size_t i = 0; i < fullDwords; i++)
m_dwords[i] = std::numeric_limits<uint32_t>::max();
if (offset > 0)
m_dwords[fullDwords] = (1u << offset) - 1;
}
private:
std::vector<uint32_t> m_dwords;
uint32_t m_bitCount = 0;
};
class BitMask {
public: