ef2gamesource/dlls/game/bit_vector.h

763 lines
18 KiB
C++

//-----------------------------------------------------------------------------
//
// $Logfile:: /Code/DLLs/game/bit_vector.h $
// $Revision:: 4 $
// $Author:: Steven $
// $Date:: 10/13/03 8:53a $
//
// Copyright (C) 2001 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
//
// DESCRIPTION:
// This class is to used to manage arrays of bits.
//=======================================
//Forward Declarations
//=======================================
class BitVector;
class BitReference;
#ifndef __BIT_VECTOR_H__
#define __BIT_VECTOR_H__
//================================================================
//
// Class: BitVector
//
// Description: The BitVector class is basically a class made to simplify
// working with an array/vector of bits.
//
//================================================================
class BitVector
{
public:
// Constructors / destructors
BitVector( unsigned int numBits, bool value = false );
BitVector( const BitVector &old );
~BitVector();
// Bit manipulation
void SetBit( unsigned int index, bool value = true );
void ClearBit( unsigned int index );
void FlipBit( unsigned int index );
bool GetBit( unsigned int index ) const;
// Bit array manipulation
void Set( void );
void Clear( void );
void Flip( void );
// Bit range manipulation
void SetRange( unsigned int first_index, unsigned int last_index, bool value = true );
void ClearRange( unsigned int first_index, unsigned int last_index );
// Info
unsigned int BitSize( void ) const;
unsigned int ByteSize( void ) const;
unsigned int Count( void ) const;
bool Any( void ) const;
bool None( void ) const;
// Operators
bool operator[]( unsigned int index ) const;
BitReference operator[]( unsigned int index );
bool operator== ( const BitVector &other );
bool operator!= ( const BitVector &other );
void operator|= ( const BitVector &other );
void operator&= ( const BitVector &other );
BitVector operator~ ( void );
private:
// Data
unsigned char *_bytes;
unsigned int _numBytes;
unsigned int _numBits;
// Friends
friend BitVector operator| ( const BitVector &left, const BitVector &right );
friend BitVector operator& ( const BitVector &left, const BitVector &right );
friend BitReference;
};
//================================================================
//
// Class: BitReference
//
// Description: The BitReference class is a go between for the BitVector
// class to allow the operator[] to work exactly as you
// would expect it to for an array. This makes it possible
// to do the following:
// bits[ 2 ] = true;
// bit = bits[ 2 ];
// bits[ 2 ] = other_bits[ 5 ];
//
//================================================================
class BitReference
{
public:
// Operators
BitReference& operator= ( bool b );
BitReference& operator= ( const BitReference &other );
operator bool() const;
private:
// Data
BitVector *_vector;
unsigned int _index;
// Setup only called by BitVector class
void Setup( BitVector *vector, unsigned int index );
// Friends
friend BitVector;
};
//================================================================
// Name: BitVector
// Class: BitVector
//
// Description: Constructor
//
// Parameters: unsigned int numBits - number of bits in the array
// bool value - value to default all bits to (defaults to false)
//
// Returns: None
//================================================================
BitVector::BitVector( unsigned int numBits, bool value )
{
// Setup data
_numBits = numBits;
_numBytes = ( _numBits + 7 ) >> 3;
_bytes = new unsigned char[ _numBytes ];
// Initialize all bits
if ( value )
Set();
else
Clear();
}
//================================================================
// Name: BitVector
// Class: BitVector
//
// Description: Constructor (copy)
//
// Parameters: const BitVector &old - bit array to copy
//
// Returns: None
//================================================================
BitVector::BitVector( const BitVector &old )
{
int i;
// Setup data
_numBits = old._numBits;
_numBytes = old._numBytes;
_bytes = new unsigned char[ _numBytes ];
// Copy bits
for ( i = 0 ; i < _numBytes ; i++ )
_bytes[ i ] = old._bytes[ i ];
}
//================================================================
// Name: ~BitVector
// Class: BitVector
//
// Description: Deconstructor
//
// Parameters: None
//
// Returns: None
//================================================================
BitVector::~BitVector()
{
// Free the bit array
delete[] _bytes;
}
//================================================================
// Name: SetBit
// Class: BitVector
//
// Description: Sets the specified bit with the value
//
// Parameters: unsigned int index - index of bit
// bool value - value of bit to set (defaults to true)
//
// Returns: None
//================================================================
inline void BitVector::SetBit( unsigned int index, bool value )
{
if ( index < _numBits )
{
if ( value )
_bytes[ index >> 3 ] |= ( 1 << ( index & 7 ) ); // Set the bit
else
_bytes[ index >> 3 ] &= ~( 1 << ( index & 7 ) ); // Clear the bit
}
}
//================================================================
// Name: ClearBit
// Class: BitVector
//
// Description: Clears the specified bit (sets it to 0)
//
// Parameters: unsigned int index - index of bit
//
// Returns: None
//================================================================
inline void BitVector::ClearBit( unsigned int index )
{
SetBit( index, false );
}
//================================================================
// Name: FlipBit
// Class: BitVector
//
// Description: Flips the specified bit
//
// Parameters: unsigned int index - index of bit
//
// Returns: None
//================================================================
inline void BitVector::FlipBit( unsigned int index )
{
bool value;
value = GetBit( index );
SetBit( index, !value );
}
//================================================================
// Name: GetBit
// Class: BitVector
//
// Description: Returns the specified bit
//
// Parameters: unsigned int index - index of bit
//
// Returns: None
//================================================================
inline bool BitVector::GetBit( unsigned int index ) const
{
if ( index < _numBits )
return ( ( _bytes[ index >> 3 ] & ( 1 << ( index & 7 ) ) ) != 0 );
else
return false;
}
//================================================================
// Name: Set
// Class: BitVector
//
// Description: Sets every bit in bit array to 1
//
// Parameters: None
//
// Returns: None
//================================================================
inline void BitVector::Set( void )
{
unsigned int i;
for ( i = 0 ; i < _numBytes ; i++ )
_bytes[ i ] = (unsigned char)0xFF;
}
//================================================================
// Name: Clear
// Class: BitVector
//
// Description: Clears every bit in array (sets to 0)
//
// Parameters: None
//
// Returns: None
//================================================================
inline void BitVector::Clear( void )
{
unsigned int i;
for ( i = 0 ; i < _numBytes ; i++ )
_bytes[ i ] = 0;
}
//================================================================
// Name: Flip
// Class: BitVector
//
// Description: Flips every bit in array
//
// Parameters: None
//
// Returns: None
//================================================================
inline void BitVector::Flip( void )
{
unsigned int i;
for ( i = 0 ; i < _numBytes ; i++ )
{
_bytes[ i ] = ~_bytes[ i ];
}
}
//================================================================
// Name: SetRange
// Class: BitVector
//
// Description: Sets the specified range of bits to the value
//
// Parameters: unsigned int first_index - index of first bit
// unsigned int last_index - index of last bit
// bool value - value to set bits to (defaults to true)
//
// Returns: None
//================================================================
inline void BitVector::SetRange( unsigned int first_index, unsigned int last_index, bool value )
{
unsigned int i;
for ( i = first_index ; i < last_index ; i++ )
SetBit( i, value );
}
//================================================================
// Name: ClearRange
// Class: BitVector
//
// Description: Clears a range of bits (sets to 0)
//
// Parameters: unsigned int first_index - index of first bit
// unsigned int last_index - index of last bit
//
// Returns: None
//================================================================
inline void BitVector::ClearRange( unsigned int first_index, unsigned int last_index )
{
SetRange( first_index, last_index, false );
}
//================================================================
// Name: BitSize
// Class: BitVector
//
// Description: Returns the number of bits
//
// Parameters: None
//
// Returns: unsigned int - number of bits
//================================================================
inline unsigned int BitVector::BitSize( void ) const
{
return _numBits;
}
//================================================================
// Name: ByteSize
// Class: BitVector
//
// Description: Returns the number of bytes in the array
//
// Parameters: None
//
// Returns: unsigned int - number of bytes in array
//================================================================
inline unsigned int BitVector::ByteSize( void ) const
{
return _numBytes;
}
//================================================================
// Name: Count
// Class: BitVector
//
// Description: Returns the number of bits set to 1
//
// Parameters: None
//
// Returns: unsigned int - number of bits set to 1
//================================================================
inline unsigned int BitVector::Count( void ) const
{
unsigned int i;
unsigned count;
count = 0;
for ( i = 0 ; i < _numBits ; i++ )
{
if ( GetBit( i ) )
count++;
}
return count;
}
//================================================================
// Name: Any
// Class: BitVector
//
// Description: Returns whether or not any bits are set to 1
//
// Parameters: None
//
// Returns: bool - if any bits are set to 1
//================================================================
inline bool BitVector::Any( void ) const
{
unsigned int i;
for ( i = 0 ; i < _numBits ; i++ )
{
if ( GetBit( i ) )
return true;
}
return false;
}
//================================================================
// Name: None
// Class: BitVector
//
// Description: Returns whether or not none of the bits are set to 1
//
// Parameters: None
//
// Returns: bool - if none of the bits are set to 1
//================================================================
inline bool BitVector::None( void ) const
{
return !Any();
}
//================================================================
// Name: operator[]
// Class: BitVector
//
// Description: Returns the referenced bit
//
// Parameters: unsigned int index - index of bit
//
// Returns: bool - bit
//================================================================
inline bool BitVector::operator[]( unsigned int index ) const
{
return GetBit( index );
}
//================================================================
// Name: operator[]
// Class: BitVector
//
// Description: Returns a reference to the bit in question
//
// Parameters: unsigned int index - index of bit
//
// Returns: BitReference - reference of bit
//================================================================
inline BitReference BitVector::operator[]( unsigned int index )
{
BitReference bitRef;
bitRef.Setup( this, index );
return bitRef;
}
//================================================================
// Name: operator==
// Class: BitVector
//
// Description: Returns whether or not this bitvector equals another
//
// Parameters: const BitVector &other - the other BitVector to compare to
//
// Returns: bool - if equal
//================================================================
inline bool BitVector::operator== ( const BitVector &other )
{
unsigned int i;
if ( BitSize() != other.BitSize() )
return false;
for ( i = 0 ; i < _numBytes ; i++ )
{
if ( _bytes[ i ] != other._bytes[ i ] )
return false;
}
return true;
}
//================================================================
// Name: operator!=
// Class: BitVector
//
// Description: Returns whether or not this bitvector doesn't equal another
//
// Parameters: const BitVector &other - the other BitVector to compare to
//
// Returns: bool - if not equal
//================================================================
inline bool BitVector::operator!= ( const BitVector &other )
{
unsigned int i;
if ( BitSize() != other.BitSize() )
return true;
for ( i = 0 ; i < _numBytes ; i++ )
{
if ( _bytes[ i ] != other._bytes[ i ] )
return true;
}
return false;
}
//================================================================
// Name: operator|=
// Class: BitVector
//
// Description: Ors together this BitVector with the specified BitVector (bit or)
//
// Parameters: const BitVector &other - the other BitVector to or with
//
// Returns: None
//================================================================
inline void BitVector::operator|= ( const BitVector &other )
{
unsigned int i;
if ( BitSize() != other.BitSize() )
return;
for ( i = 0 ; i < _numBytes ; i++ )
{
_bytes[ i ] |= other._bytes[ i ];
}
}
//================================================================
// Name: operator&=
// Class: BitVector
//
// Description: Ands together this BitVector with the specified BitVector (bit and)
//
// Parameters: const BitVector &other - the other BitVector to and with
//
// Returns: None
//================================================================
inline void BitVector::operator&= ( const BitVector &other )
{
unsigned int i;
if ( BitSize() != other.BitSize() )
return;
for ( i = 0 ; i < _numBytes ; i++ )
{
_bytes[ i ] &= other._bytes[ i ];
}
}
//================================================================
// Name: operator~
// Class: BitVector
//
// Description: Returns a not'ed version of the bitarray
//
// Parameters: None
//
// Returns: BitVector - bitwise xor'ed version
//================================================================
inline BitVector BitVector::operator~ ( void )
{
BitVector temp_bits( _numBits );
unsigned int i;
for ( i = 0 ; i < _numBytes ; i++ )
{
temp_bits._bytes[ i ] = ~_bytes[ i ];
}
return temp_bits;
}
//================================================================
// Name: operator|
// Class:
//
// Description: Ors together 2 BitVectors
//
// Parameters: const BitVector &left - BitVector on left of |
// const BitVector &right - BitVector on right of |
//
// Returns: None
//================================================================
inline BitVector operator| ( const BitVector &left, const BitVector &right )
{
BitVector temp_bits( left );
temp_bits |= right;
return temp_bits;
}
//================================================================
// Name: operator&
// Class:
//
// Description: Ands together 2 BitVectors
//
// Parameters: const BitVector &left - BitVector on left of &
// const BitVector &right - BitVector on right of &
//
// Returns: None
//================================================================
inline BitVector operator& ( const BitVector &left, const BitVector &right )
{
BitVector temp_bits( left );
temp_bits &= right;
return temp_bits;
}
//================================================================
// Name: operator=
// Class: BitReference
//
// Description: Sets the saved indexed bit to the value
//
// Parameters: bool b - value to set bit to
//
// Returns: BitReference& - the reference of this bit
//================================================================
inline BitReference& BitReference::operator= ( bool b )
{
if ( _vector )
_vector->SetBit( _index, b );
return *this;
}
//================================================================
// Name: operator=
// Class: BitReference
//
// Description: Sets the saved indexed bit to the saved index bit in the passed in BitReference
//
// Parameters: const BitReference &other - reference of the bit/BitVector to get bit from
//
// Returns: BitReference& - the reference of this bit
//================================================================
inline BitReference& BitReference::operator= ( const BitReference &other )
{
if ( _vector )
_vector->SetBit( _index, other._vector->GetBit( other._index ) );
return *this;
}
//================================================================
// Name: operator bool
// Class: BitVector
//
// Description: Returns bit that is referenced
//
// Parameters: None
//
// Returns: bool - referenced bit
//================================================================
inline BitReference::operator bool() const
{
if ( _vector )
return _vector->GetBit( _index );
else
return false;
}
//================================================================
// Name: Setup
// Class: BitVector
//
// Description: Sets up the BitReference
//
// Parameters: BitVector *vector - vector to reference
// unsigned int index - index of the bit to reference
//
// Returns: None
//================================================================
inline void BitReference::Setup( BitVector *vector, unsigned int index )
{
_vector = vector;
_index = index;
}
#endif // __BIT_VECTOR_H__