182 lines
4.8 KiB
C
182 lines
4.8 KiB
C
|
#ifndef _INC_DSKQUOTA_BITSET_H
|
||
|
#define _INC_DSKQUOTA_BITSET_H
|
||
|
|
||
|
#ifndef _INC_DSKQUOTA_EXCEPT_H
|
||
|
# include "except.h"
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// Macros & Constants
|
||
|
//
|
||
|
// ELEMENT_TYPE
|
||
|
// This macro defines the type of each "element" in the bit buffer.
|
||
|
// This type must be an integral type that can be used as an operand
|
||
|
// in bitwise expressions. If it is changed, the macros
|
||
|
// ELEMENT_BITNUM_MASK and ELEMENT_SHIFT must also be changed as
|
||
|
// follows:
|
||
|
//
|
||
|
// ELEMENT_TYPE ELEMENT_BITNUM_MASK ELEMENT_SHIFT
|
||
|
// ---------------- ----------------------- -------------------
|
||
|
// BYTE 0x00000007 3
|
||
|
// WORD 0x0000000F 4
|
||
|
// DWORD 0x0000001F 5
|
||
|
//
|
||
|
// ELEMENT_BITNUM_MASK
|
||
|
// This macro defines the mask used to extract the number of the
|
||
|
// bit in the array element from the number of the bit being accessed.
|
||
|
//
|
||
|
// ELEMENT_SHIFT
|
||
|
// This macro defines the number of bits to right shift the bit number
|
||
|
// to obtain the number of the array element.
|
||
|
//
|
||
|
//
|
||
|
#define ELEMENT_TYPE BYTE
|
||
|
const int ELEMENT_BITNUM_MASK = 0x00000007;
|
||
|
const int ELEMENT_SHIFT = 3;
|
||
|
|
||
|
//
|
||
|
// Forward declaration.
|
||
|
//
|
||
|
class BitSet;
|
||
|
|
||
|
//
|
||
|
// This is a "helper" class that aids BitSet::operator[]. So that
|
||
|
// BitSet::operator[] functions properly for both lvalue and rvalue
|
||
|
// conditions, it returns a "Bit" object. The bit object retains the
|
||
|
// bit number and a pointer to the "owner" BitSet object. It also
|
||
|
// overloads the bool conversion operator and assignment operator.
|
||
|
// Knowing the bit number and the owner BitSet, the class can set or
|
||
|
// obtain the value of the bit in the BitSet's array.
|
||
|
//
|
||
|
class Bit
|
||
|
{
|
||
|
public:
|
||
|
Bit(int iBit, BitSet *pOwnerSet = NULL)
|
||
|
: m_iBit(iBit),
|
||
|
m_pOwnerSet(pOwnerSet) { }
|
||
|
|
||
|
Bit(Bit& bit)
|
||
|
: m_iBit(bit.m_iBit),
|
||
|
m_pOwnerSet(bit.m_pOwnerSet) { }
|
||
|
|
||
|
//
|
||
|
// Convert value of bit to a bool.
|
||
|
//
|
||
|
operator bool () const;
|
||
|
|
||
|
//
|
||
|
// Set bit to a bool value.
|
||
|
//
|
||
|
bool operator = (bool bState);
|
||
|
|
||
|
private:
|
||
|
DWORD m_iBit; // Number of bit in BitSet [0 to n-1]
|
||
|
BitSet *m_pOwnerSet; // Ptr to BitSet object.
|
||
|
};
|
||
|
|
||
|
|
||
|
class BitSet
|
||
|
{
|
||
|
public:
|
||
|
BitSet(int cBits = 1);
|
||
|
~BitSet(void);
|
||
|
|
||
|
BitSet(const BitSet& rhs);
|
||
|
BitSet& operator = (const BitSet& rhs);
|
||
|
|
||
|
void Initialize(int cBits);
|
||
|
|
||
|
int Count(void) const
|
||
|
{ return m_cBits; }
|
||
|
|
||
|
int CountSet(void) const
|
||
|
{ return m_cSet; }
|
||
|
|
||
|
int CountClr(void) const
|
||
|
{ return m_cBits - m_cSet; }
|
||
|
|
||
|
bool IsSet(int iBit) const
|
||
|
{ return GetBitState(iBit); }
|
||
|
|
||
|
bool IsClr(int iBit) const
|
||
|
{ return !GetBitState(iBit); }
|
||
|
|
||
|
void Complement(void);
|
||
|
|
||
|
//
|
||
|
// SetBitState and GetBitState are the fastest
|
||
|
// ways to alter or retrieve the state of a bit.
|
||
|
//
|
||
|
void SetBitState(int iBit, bool bSet);
|
||
|
bool GetBitState(int iBit) const;
|
||
|
|
||
|
//
|
||
|
// Set and Clr are the next fastest ways to alter
|
||
|
// or retrieve the state of a bit.
|
||
|
//
|
||
|
void Set(int iBit)
|
||
|
{ SetBitState(iBit, TRUE); }
|
||
|
void Clr(int iBit)
|
||
|
{ SetBitState(iBit, FALSE); }
|
||
|
|
||
|
//
|
||
|
// Using the subscript operator is the slowest way
|
||
|
// to alter/retrieve the state of a bit.
|
||
|
//
|
||
|
Bit operator [] (int iBit)
|
||
|
{ return Bit(iBit, this); }
|
||
|
|
||
|
void ClrAll(void)
|
||
|
{ ZeroMemory(m_pBuffer, sizeof(ELEMENT_TYPE) * m_cElements); m_cSet = 0; }
|
||
|
void SetAll(void)
|
||
|
{ FillMemory(m_pBuffer, sizeof(ELEMENT_TYPE) * m_cElements, (BYTE)0xFF); m_cSet = m_cBits; }
|
||
|
|
||
|
#if DBG
|
||
|
void Dump(void) const;
|
||
|
#endif
|
||
|
|
||
|
private:
|
||
|
ELEMENT_TYPE *m_pBuffer; // Array of elements.
|
||
|
int m_cBits; // Bits supported in set.
|
||
|
int m_cSet; // Number of bits set to '1'.
|
||
|
int m_cElements; // Number of elements in array.
|
||
|
|
||
|
//
|
||
|
// Inline functions for calculating bit/element positions in array.
|
||
|
//
|
||
|
DWORD BitInElement(int iBit) const
|
||
|
{ return (iBit & ELEMENT_BITNUM_MASK); }
|
||
|
|
||
|
DWORD ElementInBuffer(int iBit) const
|
||
|
{ return (iBit >> ELEMENT_SHIFT); }
|
||
|
|
||
|
ELEMENT_TYPE MaskFromBit(int iBit) const
|
||
|
{ return 1 << BitInElement(iBit); }
|
||
|
|
||
|
void ValidateBitNumber(int iBit) const
|
||
|
{
|
||
|
if (iBit >= m_cBits)
|
||
|
throw CMemoryException(CMemoryException::index);
|
||
|
}
|
||
|
|
||
|
friend class Bit;
|
||
|
};
|
||
|
|
||
|
inline
|
||
|
Bit::operator bool () const
|
||
|
{
|
||
|
return m_pOwnerSet->GetBitState(m_iBit);
|
||
|
}
|
||
|
|
||
|
inline bool
|
||
|
Bit::operator = (bool bState)
|
||
|
{
|
||
|
m_pOwnerSet->SetBitState(m_iBit, bState);
|
||
|
return bState;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#endif // _INC_DSKQUOTA_BITSET_H
|