//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // // $NoKeywords: $ //============================================================================= #ifndef BITVEC_H #define BITVEC_H #ifdef _WIN32 #pragma once #endif #include <assert.h> #include <string.h> 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<int NUM_BITS> 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<NUM_BITS> const &other ); bool operator==( CBitVec<NUM_BITS> const &other ); bool operator!=( CBitVec<NUM_BITS> 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<int NUM_BITS> inline int CBitVec<NUM_BITS>::GetNumBits() { return NUM_BITS; } template<int NUM_BITS> inline CBitVec<NUM_BITS>::CBitVec() { for( int i = 0; i < NUM_DWORDS; i++ ) m_DWords[i] = 0; } template<int NUM_BITS> inline void CBitVec<NUM_BITS>::Init( int val ) { for( int i = 0; i < GetNumBits(); i++ ) { ( *this )[i] = val; } } template<int NUM_BITS> inline CBitVec<NUM_BITS>& CBitVec<NUM_BITS>::operator=( CBitVec<NUM_BITS> const &other ) { memcpy( m_DWords, other.m_DWords, sizeof(m_DWords) ); return *this; } template<int NUM_BITS> inline CBitVecAccessor CBitVec<NUM_BITS>::operator[]( int i ) { assert( i >= 0 && i < GetNumBits() ); return CBitVecAccessor( m_DWords, i ); } template<int NUM_BITS> inline bool CBitVec<NUM_BITS>::operator==( CBitVec<NUM_BITS> const &other ) { for( int i = 0; i < NUM_DWORDS; i++ ) if( m_DWords[i] != other.m_DWords[i] ) return false; return true; } template<int NUM_BITS> inline bool CBitVec<NUM_BITS>::operator!=( CBitVec<NUM_BITS> const &other ) { return !( *this == other ); } template<int NUM_BITS> inline int CBitVec<NUM_BITS>::GetNumDWords() { return NUM_DWORDS; } template<int NUM_BITS> inline unsigned long CBitVec<NUM_BITS>::GetDWord( int i ) { assert( i >= 0 && i < NUM_DWORDS ); return m_DWords[i]; } template<int NUM_BITS> inline void CBitVec<NUM_BITS>::SetDWord( int i, unsigned long val ) { assert( i >= 0 && i < NUM_DWORDS ); m_DWords[i] = val; } #endif // BITVEC_H