mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-27 04:54:15 +01:00
[util] Generalize bit mask iterator
This commit is contained in:
parent
94b48c1633
commit
5f16faaae0
@ -129,6 +129,32 @@ namespace dxvk::bit {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint32_t bsf(uint32_t n) {
|
||||||
|
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__BMI__) && defined(DXVK_ARCH_X86)
|
||||||
|
uint32_t res;
|
||||||
|
asm ("tzcnt %1,%0"
|
||||||
|
: "=r" (res)
|
||||||
|
: "r" (n)
|
||||||
|
: "cc");
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
return tzcnt(n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t bsf(uint64_t n) {
|
||||||
|
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__BMI__) && defined(DXVK_ARCH_X86_64)
|
||||||
|
uint64_t res;
|
||||||
|
asm ("tzcnt %1,%0"
|
||||||
|
: "=r" (res)
|
||||||
|
: "r" (n)
|
||||||
|
: "cc");
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
return tzcnt(n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32_t lzcnt(uint32_t n) {
|
inline uint32_t lzcnt(uint32_t n) {
|
||||||
#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__LZCNT__)
|
#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__LZCNT__)
|
||||||
return _lzcnt_u32(n);
|
return _lzcnt_u32(n);
|
||||||
@ -490,6 +516,7 @@ namespace dxvk::bit {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
class BitMask {
|
class BitMask {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -497,12 +524,12 @@ namespace dxvk::bit {
|
|||||||
class iterator {
|
class iterator {
|
||||||
public:
|
public:
|
||||||
using iterator_category = std::input_iterator_tag;
|
using iterator_category = std::input_iterator_tag;
|
||||||
using value_type = uint32_t;
|
using value_type = T;
|
||||||
using difference_type = uint32_t;
|
using difference_type = T;
|
||||||
using pointer = const uint32_t*;
|
using pointer = const T*;
|
||||||
using reference = uint32_t;
|
using reference = T;
|
||||||
|
|
||||||
explicit iterator(uint32_t flags)
|
explicit iterator(T flags)
|
||||||
: m_mask(flags) { }
|
: m_mask(flags) { }
|
||||||
|
|
||||||
iterator& operator ++ () {
|
iterator& operator ++ () {
|
||||||
@ -516,17 +543,8 @@ namespace dxvk::bit {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t operator * () const {
|
T operator * () const {
|
||||||
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__BMI__) && defined(DXVK_ARCH_X86)
|
return bsf(m_mask);
|
||||||
uint32_t res;
|
|
||||||
asm ("tzcnt %1,%0"
|
|
||||||
: "=r" (res)
|
|
||||||
: "r" (m_mask)
|
|
||||||
: "cc");
|
|
||||||
return res;
|
|
||||||
#else
|
|
||||||
return tzcnt(m_mask);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == (iterator other) const { return m_mask == other.m_mask; }
|
bool operator == (iterator other) const { return m_mask == other.m_mask; }
|
||||||
@ -534,14 +552,14 @@ namespace dxvk::bit {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32_t m_mask;
|
T m_mask;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BitMask()
|
BitMask()
|
||||||
: m_mask(0) { }
|
: m_mask(0) { }
|
||||||
|
|
||||||
BitMask(uint32_t n)
|
explicit BitMask(T n)
|
||||||
: m_mask(n) { }
|
: m_mask(n) { }
|
||||||
|
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
@ -554,7 +572,7 @@ namespace dxvk::bit {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32_t m_mask;
|
T m_mask;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user