#pragma once #include #include namespace rsx { template void unpack_bitset(const std::bitset& block, u64* values) { for (int bit = 0, n = -1, shift = 0; bit < N; ++bit, ++shift) { if ((bit % 64) == 0) { values[++n] = 0; shift = 0; } if (block[bit]) { values[n] |= (1ull << shift); } } } template void pack_bitset(std::bitset& block, u64* values) { for (int n = 0, shift = 0; shift < N; ++n, shift += 64) { std::bitset tmp = values[n]; tmp <<= shift; block |= tmp; } } template requires std::is_integral_v&& std::is_enum_v class atomic_bitmask_t { private: atomic_t m_data{ 0 }; public: atomic_bitmask_t() = default; T load() const { return static_cast(m_data.load()); } void store(T value) { m_data.store(static_cast(value)); } bool operator & (T mask) const { return ((m_data.load() & static_cast(mask)) != 0); } T operator | (T mask) const { return static_cast(m_data.load() | static_cast(mask)); } void operator &= (T mask) { m_data.fetch_and(static_cast(mask)); } void operator |= (T mask) { m_data.fetch_or(static_cast(mask)); } bool test_and_set(T mask) { const auto old = m_data.fetch_or(static_cast(mask)); return (old & static_cast(mask)) != 0; } auto clear(T mask) { bitmask_type clear_mask = ~(static_cast(mask)); return m_data.and_fetch(clear_mask); } void clear() { m_data.release(0); } operator bool () const { return m_data.observe() != 0; } }; template requires std::is_integral_v && std::is_enum_v class bitmask_t { private: bitmask_type m_data = 0; public: bitmask_t() = default; bitmask_type load() const { return m_data; } bool operator & (bitmask_type mask) const { return !!(m_data & mask); } bitmask_type operator | (bitmask_type mask) const { return m_data | mask; } void operator &= (bitmask_type mask) { m_data &= mask; } void operator |= (bitmask_type mask) { m_data |= mask; } bool test(T mask) { return !!(m_data & static_cast(mask)); } void set(T mask) { m_data |= static_cast(mask); } bool test_and_set(T mask) { const auto old = m_data; m_data |= static_cast(mask); return !!(old & mask); } template requires std::is_same_v || std::is_same_v void clear(U mask) { const bitmask_type clear_mask = ~(static_cast(mask)); m_data &= clear_mask; } void clear() { m_data = 0; } operator bool() const { return !!m_data; } }; }