hlsdk-xash3d/game_shared/bitvec.h

158 lines
3.5 KiB
C
Raw Permalink Normal View History

//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
2016-06-04 15:24:23 +02:00
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
2021-06-20 00:53:07 +02:00
#if !defined(BITVEC_H)
#define BITVEC_H
2016-06-04 15:24:23 +02:00
#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