//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // // $NoKeywords: $ //============================================================================= #pragma once #if !defined(BITVEC_H) #define BITVEC_H #include #include class CBitVecAccessor { public: CBitVecAccessor( unsigned long *pDWords, int iBit ); void operator=( int val ); operator unsigned long(); private: unsigned long *m_pDWords; int m_iBit; }; // CBitVec allows you to store a list of bits and do operations on them like they were // an atomic type. template class CBitVec { public: CBitVec(); // Set all values to the specified value (0 or 1..) void Init( int val = 0 ); // Access the bits like an array. CBitVecAccessor operator[]( int i ); // Operations on other bit vectors. CBitVec& operator=( CBitVec const &other ); bool operator==( CBitVec const &other ); bool operator!=( CBitVec const &other ); // Get underlying dword representations of the bits. int GetNumDWords(); unsigned long GetDWord( int i ); void SetDWord( int i, unsigned long val ); int GetNumBits(); private: enum { NUM_DWORDS = NUM_BITS / 32 + !!( NUM_BITS & 31 ) }; unsigned long m_DWords[NUM_DWORDS]; }; // ------------------------------------------------------------------------ // // CBitVecAccessor inlines. // ------------------------------------------------------------------------ // inline CBitVecAccessor::CBitVecAccessor(unsigned long *pDWords, int iBit) { m_pDWords = pDWords; m_iBit = iBit; } inline void CBitVecAccessor::operator=( int val ) { if( val ) m_pDWords[m_iBit >> 5] |= ( 1 << ( m_iBit & 31 ) ); else m_pDWords[m_iBit >> 5] &= ~(unsigned long)( 1 << ( m_iBit & 31 ) ); } inline CBitVecAccessor::operator unsigned long() { return m_pDWords[m_iBit >> 5] & ( 1 << ( m_iBit & 31 ) ); } // ------------------------------------------------------------------------ // // CBitVec inlines. // ------------------------------------------------------------------------ // template inline int CBitVec::GetNumBits() { return NUM_BITS; } template inline CBitVec::CBitVec() { for( int i = 0; i < NUM_DWORDS; i++ ) m_DWords[i] = 0; } template inline void CBitVec::Init( int val ) { for( int i = 0; i < GetNumBits(); i++ ) { ( *this )[i] = val; } } template inline CBitVec& CBitVec::operator=( CBitVec const &other ) { memcpy( m_DWords, other.m_DWords, sizeof(m_DWords) ); return *this; } template inline CBitVecAccessor CBitVec::operator[]( int i ) { assert( i >= 0 && i < GetNumBits() ); return CBitVecAccessor( m_DWords, i ); } template inline bool CBitVec::operator==( CBitVec const &other ) { for( int i = 0; i < NUM_DWORDS; i++ ) if( m_DWords[i] != other.m_DWords[i] ) return false; return true; } template inline bool CBitVec::operator!=( CBitVec const &other ) { return !( *this == other ); } template inline int CBitVec::GetNumDWords() { return NUM_DWORDS; } template inline unsigned long CBitVec::GetDWord( int i ) { assert( i >= 0 && i < NUM_DWORDS ); return m_DWords[i]; } template inline void CBitVec::SetDWord( int i, unsigned long val ) { assert( i >= 0 && i < NUM_DWORDS ); m_DWords[i] = val; } #endif // BITVEC_H