#ifndef MXBITSET_H #define MXBITSET_H #pragma warning(disable : 4237) #include "mxtypes.h" #include <assert.h> #include <limits.h> // CHAR_BIT template <size_t N> class MxBitset { public: MxBitset() { Tidy(); } // SIZE 0x08 class Reference { friend class MxBitset<N>; public: Reference& Flip() { m_bitset->Flip(m_offset); return (*this); } bool operator~() const { return (!m_bitset->Test(m_offset)); } operator bool() const { return (m_bitset->Test(m_offset)); } private: Reference(MxBitset<N>& p_bitset, size_t p_offset) : m_bitset(&p_bitset), m_offset(p_offset) {} MxBitset<N>* m_bitset; // 0x00 size_t m_offset; // 0x04 }; Reference operator[](size_t p_bit) { return (Reference(*this, p_bit)); } MxBitset<N>& Flip(size_t p_bit) { if (N <= p_bit) { Xran(); } m_blocks[p_bit / e_bitsPerBlock] ^= 1 << p_bit % e_bitsPerBlock; return (*this); } size_t Count() { // debug only, intentionally unimplemented return 0; } bool Test(MxU32 p_bit) { if (p_bit >= N) { Xran(); } return (m_blocks[p_bit / e_bitsPerBlock] & (1 << p_bit % e_bitsPerBlock)) != 0; } MxU32 Size() const { return N; } private: void Tidy(MxU32 p_value = 0) { for (MxS32 i = e_blocksRequired; i >= 0; --i) { m_blocks[i] = p_value; } // No need to trim if all bits were zeroed out if (p_value != 0) { Trim(); } } // Apply bit mask to most significant block void Trim() { if (N % e_bitsPerBlock != 0) { m_blocks[e_blocksRequired] &= ((1 << (N % e_bitsPerBlock)) - 1); } } void Xran() { assert("invalid MxBitset<N> position" == NULL); } // Not a real enum. This is how STL BITSET defines these constants. enum { e_bitsPerBlock = CHAR_BIT * sizeof(MxU32), e_blocksRequired = N == 0 ? 0 : (N - 1) / e_bitsPerBlock }; MxU32 m_blocks[e_blocksRequired + 1]; // 0x00 }; // TEMPLATE: BETA10 0x10146600 // MxBitset<2>::MxBitset<2> // TEMPLATE: BETA10 0x101464e0 // MxBitset<22>::MxBitset<22> // TEMPLATE: BETA10 0x10146510 // MxBitset<22>::Tidy // TEMPLATE: BETA10 0x10146570 // MxBitset<22>::Trim // TEMPLATE: BETA10 0x10146630 // MxBitset<2>::Tidy // TEMPLATE: BETA10 0x10146690 // MxBitset<2>::Trim // TEMPLATE: BETA10 0x10146880 // MxBitset<22>::Size // TEMPLATE: BETA10 0x101469d0 // MxBitset<2>::Size // TEMPLATE: BETA10 0x101587a0 // MxBitset<22>::Reference::Flip // TEMPLATE: BETA10 0x101587d0 // MxBitset<22>::Reference::operator int // TEMPLATE: BETA10 0x10158800 // MxBitset<22>::operator[] // TEMPLATE: BETA10 0x10158830 // MxBitset<22>::Reference::Reference // TEMPLATE: BETA10 0x10158860 // MxBitset<22>::Flip // STUB: BETA10 0x101588b0 // MxBitset<22>::Count // TEMPLATE: BETA10 0x10158930 // MxBitset<22>::Test // TEMPLATE: BETA10 0x10158990 // MxBitset<22>::Xran // TEMPLATE: BETA10 0x10158b70 // MxBitset<2>::Reference::Flip // TEMPLATE: BETA10 0x10158ba0 // MxBitset<2>::Reference::operator int // TEMPLATE: BETA10 0x10158bd0 // MxBitset<2>::operator[] // TEMPLATE: BETA10 0x10158c00 // MxBitset<2>::Reference::Reference // TEMPLATE: BETA10 0x10158c30 // MxBitset<2>::Flip // STUB: BETA10 0x10158c80 // MxBitset<2>::Count // TEMPLATE: BETA10 0x10158d00 // MxBitset<2>::Test // TEMPLATE: BETA10 0x10158d60 // MxBitset<2>::Xran #endif // MXBITSET_H