2016-06-04 15:24:23 +02:00
|
|
|
|
//========= Copyright <20> 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:
|
2016-07-31 15:48:50 +02:00
|
|
|
|
CBitVecAccessor( unsigned long *pDWords, int iBit );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
2016-07-31 15:48:50 +02:00
|
|
|
|
void operator=( int val );
|
|
|
|
|
operator unsigned long();
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
|
|
|
|
private:
|
2016-07-31 15:48:50 +02:00
|
|
|
|
unsigned long *m_pDWords;
|
|
|
|
|
int m_iBit;
|
2016-06-04 15:24:23 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 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:
|
2016-07-31 15:48:50 +02:00
|
|
|
|
CBitVec();
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
|
|
|
|
// Set all values to the specified value (0 or 1..)
|
2016-07-31 15:48:50 +02:00
|
|
|
|
void Init( int val = 0 );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
|
|
|
|
// Access the bits like an array.
|
2016-07-31 15:48:50 +02:00
|
|
|
|
CBitVecAccessor operator[]( int i );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
|
|
|
|
// Operations on other bit vectors.
|
2016-07-31 15:48:50 +02:00
|
|
|
|
CBitVec& operator=( CBitVec<NUM_BITS> const &other );
|
|
|
|
|
bool operator==( CBitVec<NUM_BITS> const &other );
|
|
|
|
|
bool operator!=( CBitVec<NUM_BITS> const &other );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
|
|
|
|
// Get underlying dword representations of the bits.
|
2016-07-31 15:48:50 +02:00
|
|
|
|
int GetNumDWords();
|
|
|
|
|
unsigned long GetDWord( int i );
|
|
|
|
|
void SetDWord( int i, unsigned long val );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
2016-07-31 15:48:50 +02:00
|
|
|
|
int GetNumBits();
|
2016-06-04 15:24:23 +02:00
|
|
|
|
|
|
|
|
|
private:
|
2016-07-31 15:48:50 +02:00
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
NUM_DWORDS = NUM_BITS / 32 + !!( NUM_BITS & 31 )
|
|
|
|
|
};
|
|
|
|
|
unsigned long m_DWords[NUM_DWORDS];
|
2016-06-04 15:24:23 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------ //
|
|
|
|
|
// CBitVecAccessor inlines.
|
|
|
|
|
// ------------------------------------------------------------------------ //
|
|
|
|
|
inline CBitVecAccessor::CBitVecAccessor(unsigned long *pDWords, int iBit)
|
|
|
|
|
{
|
|
|
|
|
m_pDWords = pDWords;
|
|
|
|
|
m_iBit = iBit;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline void CBitVecAccessor::operator=( int val )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
if( val )
|
|
|
|
|
m_pDWords[m_iBit >> 5] |= ( 1 << ( m_iBit & 31 ) );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
else
|
2016-07-31 15:48:50 +02:00
|
|
|
|
m_pDWords[m_iBit >> 5] &= ~(unsigned long)( 1 << ( m_iBit & 31 ) );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline CBitVecAccessor::operator unsigned long()
|
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
return m_pDWords[m_iBit >> 5] & ( 1 << ( m_iBit & 31 ) );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------ //
|
|
|
|
|
// CBitVec inlines.
|
|
|
|
|
// ------------------------------------------------------------------------ //
|
|
|
|
|
template<int NUM_BITS>
|
|
|
|
|
inline int CBitVec<NUM_BITS>::GetNumBits()
|
|
|
|
|
{
|
|
|
|
|
return NUM_BITS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
|
|
|
|
inline CBitVec<NUM_BITS>::CBitVec()
|
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
for( int i = 0; i < NUM_DWORDS; i++ )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
m_DWords[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline void CBitVec<NUM_BITS>::Init( int val )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
for( int i = 0; i < GetNumBits(); i++ )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
( *this )[i] = val;
|
2016-06-04 15:24:23 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline CBitVec<NUM_BITS>& CBitVec<NUM_BITS>::operator=( CBitVec<NUM_BITS> const &other )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
memcpy( m_DWords, other.m_DWords, sizeof(m_DWords) );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline CBitVecAccessor CBitVec<NUM_BITS>::operator[]( int i )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
assert( i >= 0 && i < GetNumBits() );
|
|
|
|
|
return CBitVecAccessor( m_DWords, i );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline bool CBitVec<NUM_BITS>::operator==( CBitVec<NUM_BITS> const &other )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
for( int i = 0; i < NUM_DWORDS; i++ )
|
|
|
|
|
if( m_DWords[i] != other.m_DWords[i] )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline bool CBitVec<NUM_BITS>::operator!=( CBitVec<NUM_BITS> const &other )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
return !( *this == other );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
|
|
|
|
inline int CBitVec<NUM_BITS>::GetNumDWords()
|
|
|
|
|
{
|
|
|
|
|
return NUM_DWORDS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline unsigned long CBitVec<NUM_BITS>::GetDWord( int i )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
assert( i >= 0 && i < NUM_DWORDS );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
return m_DWords[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM_BITS>
|
2016-07-31 15:48:50 +02:00
|
|
|
|
inline void CBitVec<NUM_BITS>::SetDWord( int i, unsigned long val )
|
2016-06-04 15:24:23 +02:00
|
|
|
|
{
|
2016-07-31 15:48:50 +02:00
|
|
|
|
assert( i >= 0 && i < NUM_DWORDS );
|
2016-06-04 15:24:23 +02:00
|
|
|
|
m_DWords[i] = val;
|
|
|
|
|
}
|
|
|
|
|
#endif // BITVEC_H
|