#ifndef BITVEC_H #define BITVEC_H #ifdef _WIN32 #pragma once #endif #include #include "dbg.h" #include "basetypes.h" class CBitVecAccessor { public: CBitVecAccessor(uint32* pDWords, int iBit); void operator=(int val); operator uint32(); private: uint32* m_pDWords; int m_iBit; }; #define LOG2_BITS_PER_INT 5 #define BITS_PER_INT 32 #if _WIN32 && !defined(_X360) #include #pragma intrinsic(_BitScanForward) #endif inline int FirstBitInWord(unsigned int elem, int offset) { #if _WIN32 if (!elem) return -1; #if defined( _X360 ) unsigned int mask = elem - 1; unsigned int comp = ~elem; elem = mask & comp; return (32 - _CountLeadingZeros(elem)) + offset; #else unsigned long out; _BitScanForward(&out, elem); return out + offset; #endif #else static unsigned firstBitLUT[256] = { 0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0, 3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0, 3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0, 3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 }; unsigned elemByte; elemByte = (elem & 0xFF); if (elemByte) return offset + firstBitLUT[elemByte]; elem >>= 8; offset += 8; elemByte = (elem & 0xFF); if (elemByte) return offset + firstBitLUT[elemByte]; elem >>= 8; offset += 8; elemByte = (elem & 0xFF); if (elemByte) return offset + firstBitLUT[elemByte]; elem >>= 8; offset += 8; elemByte = (elem & 0xFF); if (elemByte) return offset + firstBitLUT[elemByte]; return -1; #endif } inline unsigned GetEndMask(int numBits) { static unsigned bitStringEndMasks[] = { 0xffffffff, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, }; return bitStringEndMasks[numBits % BITS_PER_INT]; } inline int GetBitForBitnum(int bitNum) { static int bitsForBitnum[] = { (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16), (1 << 17), (1 << 18), (1 << 19), (1 << 20), (1 << 21), (1 << 22), (1 << 23), (1 << 24), (1 << 25), (1 << 26), (1 << 27), (1 << 28), (1 << 29), (1 << 30), (1 << 31), }; return bitsForBitnum[(bitNum) & (BITS_PER_INT - 1)]; } inline int GetBitForBitnumByte(int bitNum) { static int bitsForBitnum[] = { (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), }; return bitsForBitnum[bitNum & 7]; } inline int CalcNumIntsForBits(int numBits) { return (numBits + (BITS_PER_INT - 1)) / BITS_PER_INT; } #ifdef _X360 #define BitVec_Bit( bitNum ) GetBitForBitnum( bitNum ) #define BitVec_BitInByte( bitNum ) GetBitForBitnumByte( bitNum ) #else #define BitVec_Bit( bitNum ) ( 1 << ( (bitNum) & (BITS_PER_INT-1) ) ) #define BitVec_BitInByte( bitNum ) ( 1 << ( (bitNum) & 7 ) ) #endif #define BitVec_Int( bitNum ) ( (bitNum) >> LOG2_BITS_PER_INT ) template class CBitVecT : public BASE_OPS { public: CBitVecT(); CBitVecT(int numBits); void Init(int val = 0); CBitVecAccessor operator[](int i); void And(const CBitVecT& andStr, CBitVecT* out) const; void Or(const CBitVecT& orStr, CBitVecT* out) const; void Xor(const CBitVecT& orStr, CBitVecT* out) const; void Not(CBitVecT* out) const; void CopyTo(CBitVecT* out) const; void Copy(const CBitVecT& other, int nBits = -1); bool Compare(const CBitVecT& other, int nBits = -1) const; bool IsAllClear(void) const; bool IsAllSet(void) const; uint32 Get(uint32 bitNum) const; bool IsBitSet(int bitNum) const; void Set(int bitNum); void Set(int bitNum, bool bNewVal); void Clear(int bitNum); bool TestAndSet(int bitNum); void Set(uint32 offset, uint32 mask); void Clear(uint32 offset, uint32 mask); uint32 Get(uint32 offset, uint32 mask); void SetAll(void); void ClearAll(void); uint32 GetDWord(int i) const; void SetDWord(int i, uint32 val); CBitVecT& operator=(const CBitVecT& other) { other.CopyTo(this); return *this; } bool operator==(const CBitVecT& other) { return Compare(other); } bool operator!=(const CBitVecT& other) { return !operator==(other); } static void GetOffsetMaskForBit(uint32 bitNum, uint32* pOffset, uint32* pMask) { *pOffset = BitVec_Int(bitNum); *pMask = BitVec_Bit(bitNum); } }; template class CVarBitVecBase { public: bool IsFixedSize() const { return false; } int GetNumBits(void) const { return m_numBits; } void Resize(int numBits, bool bClearAll = false); int GetNumDWords() const { return m_numInts; } uint32* Base() { return m_pInt; } const uint32* Base() const { return m_pInt; } void Attach(uint32* pBits, int numBits); bool Detach(uint32** ppBits, int* pNumBits); int FindNextSetBit(int iStartBit) const; protected: CVarBitVecBase(); CVarBitVecBase(int numBits); CVarBitVecBase(const CVarBitVecBase& from); CVarBitVecBase& operator=(const CVarBitVecBase& from); ~CVarBitVecBase(void); void ValidateOperand(const CVarBitVecBase& operand) const { Assert(GetNumBits() == operand.GetNumBits()); } unsigned GetEndMask() const { return ::GetEndMask(GetNumBits()); } private: BITCOUNTTYPE m_numBits; BITCOUNTTYPE m_numInts; uint32 m_iBitStringStorage; uint32* m_pInt; void AllocInts(int numInts); void ReallocInts(int numInts); void FreeInts(void); }; template struct BitCountToEndMask_t { }; template <> struct BitCountToEndMask_t< 0> { enum { MASK = 0xffffffff }; }; template <> struct BitCountToEndMask_t< 1> { enum { MASK = 0x00000001 }; }; template <> struct BitCountToEndMask_t< 2> { enum { MASK = 0x00000003 }; }; template <> struct BitCountToEndMask_t< 3> { enum { MASK = 0x00000007 }; }; template <> struct BitCountToEndMask_t< 4> { enum { MASK = 0x0000000f }; }; template <> struct BitCountToEndMask_t< 5> { enum { MASK = 0x0000001f }; }; template <> struct BitCountToEndMask_t< 6> { enum { MASK = 0x0000003f }; }; template <> struct BitCountToEndMask_t< 7> { enum { MASK = 0x0000007f }; }; template <> struct BitCountToEndMask_t< 8> { enum { MASK = 0x000000ff }; }; template <> struct BitCountToEndMask_t< 9> { enum { MASK = 0x000001ff }; }; template <> struct BitCountToEndMask_t<10> { enum { MASK = 0x000003ff }; }; template <> struct BitCountToEndMask_t<11> { enum { MASK = 0x000007ff }; }; template <> struct BitCountToEndMask_t<12> { enum { MASK = 0x00000fff }; }; template <> struct BitCountToEndMask_t<13> { enum { MASK = 0x00001fff }; }; template <> struct BitCountToEndMask_t<14> { enum { MASK = 0x00003fff }; }; template <> struct BitCountToEndMask_t<15> { enum { MASK = 0x00007fff }; }; template <> struct BitCountToEndMask_t<16> { enum { MASK = 0x0000ffff }; }; template <> struct BitCountToEndMask_t<17> { enum { MASK = 0x0001ffff }; }; template <> struct BitCountToEndMask_t<18> { enum { MASK = 0x0003ffff }; }; template <> struct BitCountToEndMask_t<19> { enum { MASK = 0x0007ffff }; }; template <> struct BitCountToEndMask_t<20> { enum { MASK = 0x000fffff }; }; template <> struct BitCountToEndMask_t<21> { enum { MASK = 0x001fffff }; }; template <> struct BitCountToEndMask_t<22> { enum { MASK = 0x003fffff }; }; template <> struct BitCountToEndMask_t<23> { enum { MASK = 0x007fffff }; }; template <> struct BitCountToEndMask_t<24> { enum { MASK = 0x00ffffff }; }; template <> struct BitCountToEndMask_t<25> { enum { MASK = 0x01ffffff }; }; template <> struct BitCountToEndMask_t<26> { enum { MASK = 0x03ffffff }; }; template <> struct BitCountToEndMask_t<27> { enum { MASK = 0x07ffffff }; }; template <> struct BitCountToEndMask_t<28> { enum { MASK = 0x0fffffff }; }; template <> struct BitCountToEndMask_t<29> { enum { MASK = 0x1fffffff }; }; template <> struct BitCountToEndMask_t<30> { enum { MASK = 0x3fffffff }; }; template <> struct BitCountToEndMask_t<31> { enum { MASK = 0x7fffffff }; }; template class CFixedBitVecBase { public: bool IsFixedSize() const { return true; } int GetNumBits(void) const { return NUM_BITS; } void Resize(int numBits, bool bClearAll = false) { Assert(numBits == NUM_BITS); if (bClearAll) Plat_FastMemset(m_Ints, 0, NUM_INTS * sizeof(uint32)); } int GetNumDWords() const { return NUM_INTS; } uint32* Base() { return m_Ints; } const uint32* Base() const { return m_Ints; } int FindNextSetBit(int iStartBit) const; protected: CFixedBitVecBase() {} CFixedBitVecBase(int numBits) { Assert(numBits == NUM_BITS); } void ValidateOperand(const CFixedBitVecBase& operand) const { } public: unsigned GetEndMask() const { return static_cast(BitCountToEndMask_t::MASK); } private: enum { NUM_INTS = (NUM_BITS + (BITS_PER_INT - 1)) / BITS_PER_INT }; uint32 m_Ints[(NUM_BITS + (BITS_PER_INT - 1)) / BITS_PER_INT]; }; class CVarBitVec : public CBitVecT< CVarBitVecBase > { public: CVarBitVec() { } CVarBitVec(int numBits) : CBitVecT< CVarBitVecBase >(numBits) { } }; class CLargeVarBitVec : public CBitVecT< CVarBitVecBase > { public: CLargeVarBitVec() { } CLargeVarBitVec(int numBits) : CBitVecT< CVarBitVecBase >(numBits) { } }; template < int NUM_BITS > class CBitVec : public CBitVecT< CFixedBitVecBase > { public: CBitVec() { } CBitVec(int numBits) : CBitVecT< CFixedBitVecBase >(numBits) { } }; typedef CBitVec<32> CDWordBitVec; template inline CVarBitVecBase::CVarBitVecBase() { Plat_FastMemset(this, 0, sizeof(*this)); } template inline CVarBitVecBase::CVarBitVecBase(int numBits) { Assert(numBits); m_numBits = numBits; m_numInts = CalcNumIntsForBits(numBits); m_pInt = NULL; AllocInts(m_numInts); } template inline CVarBitVecBase::CVarBitVecBase(const CVarBitVecBase& from) { if (from.m_numInts) { m_numBits = from.m_numBits; m_numInts = from.m_numInts; m_pInt = NULL; AllocInts(m_numInts); memcpy(m_pInt, from.m_pInt, m_numInts * sizeof(int)); } else memset(this, 0, sizeof(*this)); } template inline CVarBitVecBase& CVarBitVecBase::operator=(const CVarBitVecBase& from) { Resize(from.GetNumBits()); if (m_pInt) memcpy(m_pInt, from.m_pInt, m_numInts * sizeof(int)); return (*this); } template inline CVarBitVecBase::~CVarBitVecBase(void) { FreeInts(); } template inline void CVarBitVecBase::Attach(uint32* pBits, int numBits) { FreeInts(); m_numBits = numBits; m_numInts = CalcNumIntsForBits(numBits); if (m_numInts > 1) { m_pInt = pBits; } else { m_iBitStringStorage = *pBits; m_pInt = &m_iBitStringStorage; free(pBits); } } template inline bool CVarBitVecBase::Detach(uint32** ppBits, int* pNumBits) { if (!m_numBits) { return false; } *pNumBits = m_numBits; if (m_numInts > 1) { *ppBits = m_pInt; } else { *ppBits = (uint32*)malloc(sizeof(uint32)); **ppBits = m_iBitStringStorage; free(m_pInt); } memset(this, 0, sizeof(*this)); return true; } template inline CBitVecT::CBitVecT() { COMPILE_TIME_ASSERT(sizeof(int) == 4); ClearAll(); } template inline CBitVecT::CBitVecT(int numBits) : BASE_OPS(numBits) { COMPILE_TIME_ASSERT(sizeof(int) == 4); ClearAll(); } template inline CBitVecAccessor CBitVecT::operator[](int i) { Assert(i >= 0 && i < this->GetNumBits()); return CBitVecAccessor(this->Base(), i); } template inline void CBitVecT::Init(int val) { if (this->Base()) Plat_FastMemset(this->Base(), (val) ? 0xff : 0, this->GetNumDWords() * sizeof(int)); } template inline uint32 CBitVecT::Get(uint32 bitNum) const { Assert(bitNum < (uint32)this->GetNumBits()); const uint32* pInt = this->Base() + BitVec_Int(bitNum); return (*pInt & BitVec_Bit(bitNum)); } template inline bool CBitVecT::IsBitSet(int bitNum) const { Assert(bitNum >= 0 && bitNum < this->GetNumBits()); const uint32* pInt = this->Base() + BitVec_Int(bitNum); return ((*pInt & BitVec_Bit(bitNum)) != 0); } template inline void CBitVecT::Set(int bitNum) { Assert(bitNum >= 0 && bitNum < this->GetNumBits()); uint32* pInt = this->Base() + BitVec_Int(bitNum); *pInt |= BitVec_Bit(bitNum); } template inline bool CBitVecT::TestAndSet(int bitNum) { Assert(bitNum >= 0 && bitNum < this->GetNumBits()); uint32 bitVecBit = BitVec_Bit(bitNum); uint32* pInt = this->Base() + BitVec_Int(bitNum); bool bResult = ((*pInt & bitVecBit) != 0); *pInt |= bitVecBit; return bResult; } template inline void CBitVecT::Clear(int bitNum) { Assert(bitNum >= 0 && bitNum < this->GetNumBits()); uint32* pInt = this->Base() + BitVec_Int(bitNum); *pInt &= ~BitVec_Bit(bitNum); } template inline void CBitVecT::Set(int bitNum, bool bNewVal) { uint32* pInt = this->Base() + BitVec_Int(bitNum); uint32 bitMask = BitVec_Bit(bitNum); if (bNewVal) { *pInt |= bitMask; } else { *pInt &= ~bitMask; } } template inline void CBitVecT::Set(uint32 offset, uint32 mask) { uint32* pInt = this->Base() + offset; *pInt |= mask; } template inline void CBitVecT::Clear(uint32 offset, uint32 mask) { uint32* pInt = this->Base() + offset; *pInt &= ~mask; } template inline uint32 CBitVecT::Get(uint32 offset, uint32 mask) { uint32* pInt = this->Base() + offset; return (*pInt & mask); } template inline void CBitVecT::And(const CBitVecT& addStr, CBitVecT* out) const { this->ValidateOperand(addStr); this->ValidateOperand(*out); uint32* pDest = out->Base(); const uint32* pOperand1 = this->Base(); const uint32* pOperand2 = addStr.Base(); for (int i = this->GetNumDWords() - 1; i >= 0; --i) { pDest[i] = pOperand1[i] & pOperand2[i]; } } template inline void CBitVecT::Or(const CBitVecT& orStr, CBitVecT* out) const { this->ValidateOperand(orStr); this->ValidateOperand(*out); uint32* pDest = out->Base(); const uint32* pOperand1 = this->Base(); const uint32* pOperand2 = orStr.Base(); for (int i = this->GetNumDWords() - 1; i >= 0; --i) { pDest[i] = pOperand1[i] | pOperand2[i]; } } template inline void CBitVecT::Xor(const CBitVecT& xorStr, CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pOperand1 = this->Base(); const uint32* pOperand2 = xorStr.Base(); for (int i = this->GetNumDWords() - 1; i >= 0; --i) { pDest[i] = pOperand1[i] ^ pOperand2[i]; } } template inline void CBitVecT::Not(CBitVecT* out) const { this->ValidateOperand(*out); uint32* pDest = out->Base(); const uint32* pOperand = this->Base(); for (int i = this->GetNumDWords() - 1; i >= 0; --i) { pDest[i] = ~(pOperand[i]); } } template inline void CBitVecT::CopyTo(CBitVecT* out) const { out->Resize(this->GetNumBits()); this->ValidateOperand(*out); Assert(out != this); memcpy(out->Base(), this->Base(), this->GetNumDWords() * sizeof(int)); } template inline bool CBitVecT::IsAllClear(void) const { (const_cast(this))->Base()[this->GetNumDWords() - 1] &= CBitVecT::GetEndMask(); for (int i = this->GetNumDWords() - 1; i >= 0; --i) { if (this->Base()[i] != 0) { return false; } } return true; } template inline bool CBitVecT::IsAllSet(void) const { (const_cast(this))->Base()[this->GetNumDWords() - 1] |= ~CBitVecT::GetEndMask(); for (int i = this->GetNumDWords() - 1; i >= 0; --i) { if (this->Base()[i] != ~0) { return false; } } return true; } template inline void CBitVecT::SetAll(void) { if (this->Base()) Plat_FastMemset(this->Base(), 0xff, this->GetNumDWords() * sizeof(int)); } template inline void CBitVecT::ClearAll(void) { if (this->Base()) Plat_FastMemset(this->Base(), 0, this->GetNumDWords() * sizeof(int)); } template inline void CBitVecT::Copy(const CBitVecT& other, int nBits) { if (nBits == -1) { nBits = other.GetNumBits(); } this->Resize(nBits); this->ValidateOperand(other); Assert(&other != this); memcpy(this->Base(), other.Base(), this->GetNumDWords() * sizeof(uint32)); } template inline bool CBitVecT::Compare(const CBitVecT& other, int nBits) const { if (nBits == -1) { if (other.GetNumBits() != this->GetNumBits()) { return false; } nBits = other.GetNumBits(); } if (nBits > other.GetNumBits() || nBits > this->GetNumBits()) { return false; } (const_cast(this))->Base()[this->GetNumDWords() - 1] &= CBitVecT::GetEndMask(); (const_cast(&other))->Base()[this->GetNumDWords() - 1] &= other.CBitVecT::GetEndMask(); int nBytes = PAD_NUMBER(nBits, 8) >> 3; return (memcmp(this->Base(), other.Base(), nBytes) == 0); } template inline uint32 CBitVecT::GetDWord(int i) const { Assert(i >= 0 && i < this->GetNumDWords()); return this->Base()[i]; } template inline void CBitVecT::SetDWord(int i, uint32 val) { Assert(i >= 0 && i < this->GetNumDWords()); this->Base()[i] = val; } inline unsigned GetStartBitMask(int startBit) { static unsigned int g_StartMask[32] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, }; return g_StartMask[startBit & 31]; } template inline int CVarBitVecBase::FindNextSetBit(int startBit) const { if (startBit < GetNumBits()) { int wordIndex = BitVec_Int(startBit); unsigned int startMask = GetStartBitMask(startBit); int lastWord = GetNumDWords() - 1; if ((GetNumBits() % BITS_PER_INT) != 0) { unsigned int elem = Base()[wordIndex]; elem &= startMask; if (wordIndex == lastWord) { elem &= (GetEndMask()); if (elem) return FirstBitInWord(elem, wordIndex << 5); } else { if (elem) return FirstBitInWord(elem, wordIndex << 5); for (int i = wordIndex + 1; i < lastWord; i++) { elem = Base()[i]; if (elem) return FirstBitInWord(elem, i << 5); } elem = Base()[lastWord] & GetEndMask(); if (elem) return FirstBitInWord(elem, lastWord << 5); } } else { const uint32* RESTRICT pCurElem = Base() + wordIndex; unsigned int elem = *pCurElem; elem &= startMask; do { if (elem) return FirstBitInWord(elem, wordIndex << 5); ++pCurElem; elem = *pCurElem; ++wordIndex; } while (wordIndex <= lastWord); } } return -1; } template inline int CFixedBitVecBase::FindNextSetBit(int startBit) const { if (startBit < NUM_BITS) { int wordIndex = BitVec_Int(startBit); unsigned int startMask = GetStartBitMask(startBit); if ((NUM_BITS % BITS_PER_INT) != 0) { unsigned int elem = Base()[wordIndex]; elem &= startMask; if (wordIndex == NUM_INTS - 1) { elem &= (GetEndMask()); if (elem) return FirstBitInWord(elem, wordIndex << 5); } else { if (elem) return FirstBitInWord(elem, wordIndex << 5); for (int i = wordIndex + 1; i < NUM_INTS - 1; i++) { elem = Base()[i]; if (elem) return FirstBitInWord(elem, i << 5); } elem = Base()[NUM_INTS - 1] & GetEndMask(); if (elem) return FirstBitInWord(elem, (NUM_INTS - 1) << 5); } } else { const uint32* RESTRICT pCurElem = Base() + wordIndex; unsigned int elem = *pCurElem; elem &= startMask; do { if (elem) return FirstBitInWord(elem, wordIndex << 5); ++pCurElem; elem = *pCurElem; ++wordIndex; } while (wordIndex <= NUM_INTS - 1); } } return -1; } template<> FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::And(const CBitVecT& addStr, CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pOperand1 = Base(); const uint32* pOperand2 = addStr.Base(); pDest[0] = pOperand1[0] & pOperand2[0]; pDest[1] = pOperand1[1] & pOperand2[1]; pDest[2] = pOperand1[2] & pOperand2[2]; pDest[3] = pOperand1[3] & pOperand2[3]; pDest[4] = pOperand1[4] & pOperand2[4]; pDest[5] = pOperand1[5] & pOperand2[5]; pDest[6] = pOperand1[6] & pOperand2[6]; pDest[7] = pOperand1[7] & pOperand2[7]; } template<> FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<256> >::IsAllClear(void) const { const uint32* pInts = Base(); return (pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 && pInts[3] == 0 && pInts[4] == 0 && pInts[5] == 0 && pInts[6] == 0 && pInts[7] == 0); } template<> FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::CopyTo(CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pInts = Base(); pDest[0] = pInts[0]; pDest[1] = pInts[1]; pDest[2] = pInts[2]; pDest[3] = pInts[3]; pDest[4] = pInts[4]; pDest[5] = pInts[5]; pDest[6] = pInts[6]; pDest[7] = pInts[7]; } template<> FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::And(const CBitVecT& addStr, CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pOperand1 = Base(); const uint32* pOperand2 = addStr.Base(); pDest[0] = pOperand1[0] & pOperand2[0]; pDest[1] = pOperand1[1] & pOperand2[1]; pDest[2] = pOperand1[2] & pOperand2[2]; pDest[3] = pOperand1[3] & pOperand2[3]; } template<> FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<128> >::IsAllClear(void) const { const uint32* pInts = Base(); return (pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 && pInts[3] == 0); } template<> FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::CopyTo(CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pInts = Base(); pDest[0] = pInts[0]; pDest[1] = pInts[1]; pDest[2] = pInts[2]; pDest[3] = pInts[3]; } template<> inline void CBitVecT< CFixedBitVecBase<96> >::And(const CBitVecT& addStr, CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pOperand1 = Base(); const uint32* pOperand2 = addStr.Base(); pDest[0] = pOperand1[0] & pOperand2[0]; pDest[1] = pOperand1[1] & pOperand2[1]; pDest[2] = pOperand1[2] & pOperand2[2]; } template<> inline bool CBitVecT< CFixedBitVecBase<96> >::IsAllClear(void) const { const uint32* pInts = Base(); return (pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0); } template<> inline void CBitVecT< CFixedBitVecBase<96> >::CopyTo(CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pInts = Base(); pDest[0] = pInts[0]; pDest[1] = pInts[1]; pDest[2] = pInts[2]; } template<> inline void CBitVecT< CFixedBitVecBase<64> >::And(const CBitVecT& addStr, CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pOperand1 = Base(); const uint32* pOperand2 = addStr.Base(); pDest[0] = pOperand1[0] & pOperand2[0]; pDest[1] = pOperand1[1] & pOperand2[1]; } template<> inline bool CBitVecT< CFixedBitVecBase<64> >::IsAllClear(void) const { const uint32* pInts = Base(); return (pInts[0] == 0 && pInts[1] == 0); } template<> inline void CBitVecT< CFixedBitVecBase<64> >::CopyTo(CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pInts = Base(); pDest[0] = pInts[0]; pDest[1] = pInts[1]; } template<> inline void CBitVecT< CFixedBitVecBase<32> >::And(const CBitVecT& addStr, CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pOperand1 = Base(); const uint32* pOperand2 = addStr.Base(); pDest[0] = pOperand1[0] & pOperand2[0]; } template<> inline bool CBitVecT< CFixedBitVecBase<32> >::IsAllClear(void) const { const uint32* pInts = Base(); return (pInts[0] == 0); } template<> inline void CBitVecT< CFixedBitVecBase<32> >::CopyTo(CBitVecT* out) const { uint32* pDest = out->Base(); const uint32* pInts = Base(); pDest[0] = pInts[0]; } template <> inline uint32 CBitVecT< CFixedBitVecBase<32> >::Get(uint32 bitNum) const { return (*Base() & BitVec_Bit(bitNum)); } template <> inline bool CBitVecT< CFixedBitVecBase<32> >::IsBitSet(int bitNum) const { return ((*Base() & BitVec_Bit(bitNum)) != 0); } template <> inline void CBitVecT< CFixedBitVecBase<32> >::Set(int bitNum) { *Base() |= BitVec_Bit(bitNum); } template <> inline void CBitVecT< CFixedBitVecBase<32> >::Clear(int bitNum) { *Base() &= ~BitVec_Bit(bitNum); } template <> inline void CBitVecT< CFixedBitVecBase<32> >::Set(int bitNum, bool bNewVal) { uint32 bitMask = BitVec_Bit(bitNum); if (bNewVal) { *Base() |= bitMask; } else { *Base() &= ~bitMask; } } #include "memdbgon.h" template inline void CVarBitVecBase::Resize(int resizeNumBits, bool bClearAll) { Assert(resizeNumBits >= 0 && ((BITCOUNTTYPE)resizeNumBits == resizeNumBits)); int newIntCount = CalcNumIntsForBits(resizeNumBits); if (newIntCount != GetNumDWords()) { if (Base()) { ReallocInts(newIntCount); if (!bClearAll && resizeNumBits >= GetNumBits()) { Base()[GetNumDWords() - 1] &= GetEndMask(); Plat_FastMemset(Base() + GetNumDWords(), 0, (newIntCount - GetNumDWords()) * sizeof(int)); } } else { AllocInts(newIntCount); bClearAll = true; } m_numInts = newIntCount; } else if (!bClearAll && resizeNumBits >= GetNumBits() && Base()) { Base()[GetNumDWords() - 1] &= GetEndMask(); } if (bClearAll && Base()) { Plat_FastMemset(Base(), 0, newIntCount * sizeof(int)); } m_numBits = resizeNumBits; } template inline void CVarBitVecBase::AllocInts(int numInts) { Assert(!m_pInt); if (numInts == 0) return; if (numInts == 1) { m_pInt = &m_iBitStringStorage; return; } m_pInt = (uint32*)malloc(numInts * sizeof(int)); } template inline void CVarBitVecBase::ReallocInts(int numInts) { Assert(Base()); if (numInts == 0) { FreeInts(); return; } if (m_pInt == &m_iBitStringStorage) { if (numInts != 1) { m_pInt = ((uint32*)malloc(numInts * sizeof(int))); *m_pInt = m_iBitStringStorage; } return; } if (numInts == 1) { m_iBitStringStorage = *m_pInt; free(m_pInt); m_pInt = &m_iBitStringStorage; return; } m_pInt = (uint32*)realloc(m_pInt, numInts * sizeof(int)); } template inline void CVarBitVecBase::FreeInts(void) { if (m_numInts > 1) { free(m_pInt); } m_pInt = NULL; } #include "memdbgoff.h" inline CBitVecAccessor::CBitVecAccessor(uint32* 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 uint32() { return m_pDWords[m_iBit >> 5] & (1 << (m_iBit & 31)); } #endif