|
|
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============ |
|
|
// |
|
|
// Purpose: |
|
|
// |
|
|
// $NoKeywords: $ |
|
|
//============================================================================= |
|
|
#if !defined(BITVEC_H) |
|
|
#define BITVEC_H |
|
|
|
|
|
#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 |
|
|
|
|
|
|