Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1630 lines
42 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #ifndef BITVEC_H
  7. #define BITVEC_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include <limits.h>
  12. #include "tier0/dbg.h"
  13. #include "tier0/basetypes.h"
  14. #include "tier1/strtools.h"
  15. class CBitVecAccessor
  16. {
  17. public:
  18. CBitVecAccessor(uint32 *pDWords, int iBit);
  19. void operator=(int val);
  20. operator uint32();
  21. private:
  22. uint32 *m_pDWords;
  23. int m_iBit;
  24. };
  25. //-----------------------------------------------------------------------------
  26. // Support functions
  27. //-----------------------------------------------------------------------------
  28. #define LOG2_BITS_PER_INT 5
  29. #define BITS_PER_INT 32
  30. #if _WIN32 && !defined(_X360)
  31. #include <intrin.h>
  32. #pragma intrinsic(_BitScanForward)
  33. #endif
  34. inline int FirstBitInWord( unsigned int elem, int offset )
  35. {
  36. #if _WIN32
  37. if ( !elem )
  38. return -1;
  39. #if defined( _X360 )
  40. // this implements CountTrailingZeros() / BitScanForward()
  41. unsigned int mask = elem-1;
  42. unsigned int comp = ~elem;
  43. elem = mask & comp;
  44. return (32 - _CountLeadingZeros(elem)) + offset;
  45. #else
  46. unsigned long out;
  47. _BitScanForward(&out, elem);
  48. return out + offset;
  49. #endif
  50. #else
  51. static unsigned firstBitLUT[256] =
  52. {
  53. 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,
  54. 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,
  55. 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,
  56. 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,
  57. 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,
  58. 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,
  59. 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
  60. };
  61. unsigned elemByte;
  62. elemByte = (elem & 0xFF);
  63. if ( elemByte )
  64. return offset + firstBitLUT[elemByte];
  65. elem >>= 8;
  66. offset += 8;
  67. elemByte = (elem & 0xFF);
  68. if ( elemByte )
  69. return offset + firstBitLUT[elemByte];
  70. elem >>= 8;
  71. offset += 8;
  72. elemByte = (elem & 0xFF);
  73. if ( elemByte )
  74. return offset + firstBitLUT[elemByte];
  75. elem >>= 8;
  76. offset += 8;
  77. elemByte = (elem & 0xFF);
  78. if ( elemByte )
  79. return offset + firstBitLUT[elemByte];
  80. return -1;
  81. #endif
  82. }
  83. //-------------------------------------
  84. inline unsigned GetEndMask( int numBits )
  85. {
  86. static unsigned bitStringEndMasks[] =
  87. {
  88. 0xffffffff,
  89. 0x00000001,
  90. 0x00000003,
  91. 0x00000007,
  92. 0x0000000f,
  93. 0x0000001f,
  94. 0x0000003f,
  95. 0x0000007f,
  96. 0x000000ff,
  97. 0x000001ff,
  98. 0x000003ff,
  99. 0x000007ff,
  100. 0x00000fff,
  101. 0x00001fff,
  102. 0x00003fff,
  103. 0x00007fff,
  104. 0x0000ffff,
  105. 0x0001ffff,
  106. 0x0003ffff,
  107. 0x0007ffff,
  108. 0x000fffff,
  109. 0x001fffff,
  110. 0x003fffff,
  111. 0x007fffff,
  112. 0x00ffffff,
  113. 0x01ffffff,
  114. 0x03ffffff,
  115. 0x07ffffff,
  116. 0x0fffffff,
  117. 0x1fffffff,
  118. 0x3fffffff,
  119. 0x7fffffff,
  120. };
  121. return bitStringEndMasks[numBits % BITS_PER_INT];
  122. }
  123. inline int GetBitForBitnum( int bitNum )
  124. {
  125. static int bitsForBitnum[] =
  126. {
  127. ( 1 << 0 ),
  128. ( 1 << 1 ),
  129. ( 1 << 2 ),
  130. ( 1 << 3 ),
  131. ( 1 << 4 ),
  132. ( 1 << 5 ),
  133. ( 1 << 6 ),
  134. ( 1 << 7 ),
  135. ( 1 << 8 ),
  136. ( 1 << 9 ),
  137. ( 1 << 10 ),
  138. ( 1 << 11 ),
  139. ( 1 << 12 ),
  140. ( 1 << 13 ),
  141. ( 1 << 14 ),
  142. ( 1 << 15 ),
  143. ( 1 << 16 ),
  144. ( 1 << 17 ),
  145. ( 1 << 18 ),
  146. ( 1 << 19 ),
  147. ( 1 << 20 ),
  148. ( 1 << 21 ),
  149. ( 1 << 22 ),
  150. ( 1 << 23 ),
  151. ( 1 << 24 ),
  152. ( 1 << 25 ),
  153. ( 1 << 26 ),
  154. ( 1 << 27 ),
  155. ( 1 << 28 ),
  156. ( 1 << 29 ),
  157. ( 1 << 30 ),
  158. ( 1 << 31 ),
  159. };
  160. return bitsForBitnum[ (bitNum) & (BITS_PER_INT-1) ];
  161. }
  162. inline int GetBitForBitnumByte( int bitNum )
  163. {
  164. static int bitsForBitnum[] =
  165. {
  166. ( 1 << 0 ),
  167. ( 1 << 1 ),
  168. ( 1 << 2 ),
  169. ( 1 << 3 ),
  170. ( 1 << 4 ),
  171. ( 1 << 5 ),
  172. ( 1 << 6 ),
  173. ( 1 << 7 ),
  174. };
  175. return bitsForBitnum[ bitNum & 7 ];
  176. }
  177. inline int CalcNumIntsForBits( int numBits ) { return (numBits + (BITS_PER_INT-1)) / BITS_PER_INT; }
  178. // http://bits.stephan-brumme.com/PopulationCount.html
  179. // http://graphics.stanford.edu/~seander/bithacks.html#PopulationCountSetParallel
  180. inline uint PopulationCount( uint32 v )
  181. {
  182. uint32 const w = v - ((v >> 1) & 0x55555555);
  183. uint32 const x = (w & 0x33333333) + ((w >> 2) & 0x33333333);
  184. return ((x + (x >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
  185. }
  186. inline uint PopulationCount( uint64 v )
  187. {
  188. uint64 const w = v - ((v >> 1) & 0x5555555555555555ull);
  189. uint64 const x = (w & 0x3333333333333333ull) + ((w >> 2) & 0x3333333333333333ull);
  190. return ( ( x + ( x >> 4 ) & 0x0F0F0F0F0F0F0F0Full ) * 0x0101010101010101ull ) >> 56; // [Sergiy] I'm not sure if it's faster to multiply here to reduce the bit sum further first, so feel free to optimize, please
  191. }
  192. inline uint PopulationCount( uint16 v )
  193. {
  194. uint16 const w = v - ((v >> 1) & 0x5555);
  195. uint16 const x = (w & 0x3333) + ((w >> 2) & 0x3333);
  196. return ( ( x + ( x >> 4 ) & 0x0F0F) * 0x101 ) >> 8;
  197. }
  198. inline uint PopulationCount( uint8 v )
  199. {
  200. uint8 const w = v - ( ( v >> 1 ) & 0x55);
  201. uint8 const x = ( w & 0x33 ) + ( ( w >> 2 ) & 0x33 );
  202. return x + ( x >> 4 ) & 0x0F;
  203. }
  204. #ifdef _X360
  205. #define BitVec_Bit( bitNum ) GetBitForBitnum( bitNum )
  206. #define BitVec_BitInByte( bitNum ) GetBitForBitnumByte( bitNum )
  207. #else
  208. #define BitVec_Bit( bitNum ) ( 1 << ( (bitNum) & (BITS_PER_INT-1) ) )
  209. #define BitVec_BitInByte( bitNum ) ( 1 << ( (bitNum) & 7 ) )
  210. #endif
  211. #define BitVec_Int( bitNum ) ( (bitNum) >> LOG2_BITS_PER_INT )
  212. //-----------------------------------------------------------------------------
  213. // template CBitVecT
  214. //
  215. // Defines the operations relevant to any bit array. Simply requires a base
  216. // class that implements GetNumBits(), Base(), GetNumDWords() & ValidateOperand()
  217. //
  218. // CVarBitVec and CBitVec<int> are the actual classes generally used
  219. // by clients
  220. //
  221. template <class BASE_OPS>
  222. class CBitVecT : public BASE_OPS
  223. {
  224. public:
  225. CBitVecT();
  226. explicit CBitVecT(int numBits); // Must be initialized with the number of bits
  227. void Init(int val = 0);
  228. // Access the bits like an array.
  229. CBitVecAccessor operator[](int i);
  230. uint32 operator[]( int i )const;
  231. // Do NOT override bitwise operators (see note in header)
  232. void And(const CBitVecT &andStr, CBitVecT *out) const;
  233. void Or(const CBitVecT &orStr, CBitVecT *out) const;
  234. void Xor(const CBitVecT &orStr, CBitVecT *out) const;
  235. void Not(CBitVecT *out) const;
  236. void CopyTo(CBitVecT *out) const;
  237. void Copy( const CBitVecT<BASE_OPS> &other, int nBits=-1 );
  238. bool Compare( const CBitVecT<BASE_OPS> &other, int nBits=-1 ) const;
  239. bool IsAllClear(void) const; // Are all bits zero?
  240. bool IsAllSet(void) const; // Are all bits one?
  241. uint32 Get( uint32 bitNum ) const;
  242. bool IsBitSet( int bitNum ) const;
  243. void Set( int bitNum );
  244. void Set( int bitNum, bool bNewVal );
  245. void Clear(int bitNum);
  246. bool TestAndSet(int bitNum);
  247. void Set( uint32 offset, uint32 mask );
  248. void Clear( uint32 offset, uint32 mask );
  249. uint32 Get( uint32 offset, uint32 mask );
  250. void SetAll(void); // Sets all bits
  251. void ClearAll(void); // Clears all bits
  252. uint32 GetDWord(int i) const;
  253. void SetDWord(int i, uint32 val);
  254. uint PopulationCount()const;
  255. CBitVecT<BASE_OPS>& operator=(const CBitVecT<BASE_OPS> &other) { other.CopyTo( this ); return *this; }
  256. bool operator==(const CBitVecT<BASE_OPS> &other) { return Compare( other ); }
  257. bool operator!=(const CBitVecT<BASE_OPS> &other) { return !operator==( other ); }
  258. static void GetOffsetMaskForBit( uint32 bitNum, uint32 *pOffset, uint32 *pMask ) { *pOffset = BitVec_Int( bitNum ); *pMask = BitVec_Bit( bitNum ); }
  259. };
  260. //-----------------------------------------------------------------------------
  261. // class CVarBitVecBase
  262. //
  263. // Defines the operations necessary for a variable sized bit array
  264. template <typename BITCOUNTTYPE>
  265. class CVarBitVecBase
  266. {
  267. public:
  268. bool IsFixedSize() const { return false; }
  269. int GetNumBits(void) const { return m_numBits; }
  270. void Resize( int numBits, bool bClearAll = false ); // resizes bit array
  271. int GetNumDWords() const { return m_numInts; }
  272. uint32 *Base() { return m_pInt; }
  273. const uint32 *Base() const { return m_pInt; }
  274. void Attach( uint32 *pBits, int numBits );
  275. bool Detach( uint32 **ppBits, int *pNumBits );
  276. int FindNextSetBit(int iStartBit) const; // returns -1 if no set bit was found
  277. protected:
  278. CVarBitVecBase();
  279. explicit CVarBitVecBase(int numBits);
  280. CVarBitVecBase( const CVarBitVecBase<BITCOUNTTYPE> &from );
  281. CVarBitVecBase &operator=( const CVarBitVecBase<BITCOUNTTYPE> &from );
  282. ~CVarBitVecBase(void);
  283. void ValidateOperand( const CVarBitVecBase<BITCOUNTTYPE> &operand ) const { Assert(GetNumBits() == operand.GetNumBits()); }
  284. unsigned GetEndMask() const { return ::GetEndMask( GetNumBits() ); }
  285. private:
  286. BITCOUNTTYPE m_numBits; // Number of bits in the bitstring
  287. BITCOUNTTYPE m_numInts; // Number of ints to needed to store bitstring
  288. uint32 m_iBitStringStorage; // If the bit string fits in one int, it goes here
  289. uint32 * m_pInt; // Array of ints containing the bitstring
  290. void AllocInts( int numInts ); // Free the allocated bits
  291. void ReallocInts( int numInts );
  292. void FreeInts( void ); // Free the allocated bits
  293. };
  294. //-----------------------------------------------------------------------------
  295. // class CFixedBitVecBase
  296. //
  297. // Defines the operations necessary for a fixed sized bit array.
  298. //
  299. template <int bits> struct BitCountToEndMask_t { };
  300. template <> struct BitCountToEndMask_t< 0> { enum { MASK = 0xffffffff }; };
  301. template <> struct BitCountToEndMask_t< 1> { enum { MASK = 0x00000001 }; };
  302. template <> struct BitCountToEndMask_t< 2> { enum { MASK = 0x00000003 }; };
  303. template <> struct BitCountToEndMask_t< 3> { enum { MASK = 0x00000007 }; };
  304. template <> struct BitCountToEndMask_t< 4> { enum { MASK = 0x0000000f }; };
  305. template <> struct BitCountToEndMask_t< 5> { enum { MASK = 0x0000001f }; };
  306. template <> struct BitCountToEndMask_t< 6> { enum { MASK = 0x0000003f }; };
  307. template <> struct BitCountToEndMask_t< 7> { enum { MASK = 0x0000007f }; };
  308. template <> struct BitCountToEndMask_t< 8> { enum { MASK = 0x000000ff }; };
  309. template <> struct BitCountToEndMask_t< 9> { enum { MASK = 0x000001ff }; };
  310. template <> struct BitCountToEndMask_t<10> { enum { MASK = 0x000003ff }; };
  311. template <> struct BitCountToEndMask_t<11> { enum { MASK = 0x000007ff }; };
  312. template <> struct BitCountToEndMask_t<12> { enum { MASK = 0x00000fff }; };
  313. template <> struct BitCountToEndMask_t<13> { enum { MASK = 0x00001fff }; };
  314. template <> struct BitCountToEndMask_t<14> { enum { MASK = 0x00003fff }; };
  315. template <> struct BitCountToEndMask_t<15> { enum { MASK = 0x00007fff }; };
  316. template <> struct BitCountToEndMask_t<16> { enum { MASK = 0x0000ffff }; };
  317. template <> struct BitCountToEndMask_t<17> { enum { MASK = 0x0001ffff }; };
  318. template <> struct BitCountToEndMask_t<18> { enum { MASK = 0x0003ffff }; };
  319. template <> struct BitCountToEndMask_t<19> { enum { MASK = 0x0007ffff }; };
  320. template <> struct BitCountToEndMask_t<20> { enum { MASK = 0x000fffff }; };
  321. template <> struct BitCountToEndMask_t<21> { enum { MASK = 0x001fffff }; };
  322. template <> struct BitCountToEndMask_t<22> { enum { MASK = 0x003fffff }; };
  323. template <> struct BitCountToEndMask_t<23> { enum { MASK = 0x007fffff }; };
  324. template <> struct BitCountToEndMask_t<24> { enum { MASK = 0x00ffffff }; };
  325. template <> struct BitCountToEndMask_t<25> { enum { MASK = 0x01ffffff }; };
  326. template <> struct BitCountToEndMask_t<26> { enum { MASK = 0x03ffffff }; };
  327. template <> struct BitCountToEndMask_t<27> { enum { MASK = 0x07ffffff }; };
  328. template <> struct BitCountToEndMask_t<28> { enum { MASK = 0x0fffffff }; };
  329. template <> struct BitCountToEndMask_t<29> { enum { MASK = 0x1fffffff }; };
  330. template <> struct BitCountToEndMask_t<30> { enum { MASK = 0x3fffffff }; };
  331. template <> struct BitCountToEndMask_t<31> { enum { MASK = 0x7fffffff }; };
  332. //-------------------------------------
  333. template <int NUM_BITS>
  334. class CFixedBitVecBase
  335. {
  336. public:
  337. bool IsFixedSize() const { return true; }
  338. int GetNumBits(void) const { return NUM_BITS; }
  339. void Resize( int numBits, bool bClearAll = false ) { Assert(numBits == NUM_BITS); if ( bClearAll ) Plat_FastMemset( m_Ints, 0, NUM_INTS * sizeof(uint32) ); }// for syntatic consistency (for when using templates)
  340. int GetNumDWords() const { return NUM_INTS; }
  341. uint32 * Base() { return m_Ints; }
  342. const uint32 * Base() const { return m_Ints; }
  343. int FindNextSetBit(int iStartBit) const; // returns -1 if no set bit was found
  344. protected:
  345. CFixedBitVecBase() {}
  346. explicit CFixedBitVecBase(int numBits)
  347. {
  348. // doesn't make sense, really. Supported to simplify templates & allow easy replacement of variable
  349. Assert( numBits == NUM_BITS );
  350. }
  351. void ValidateOperand( const CFixedBitVecBase<NUM_BITS> &operand ) const { } // no need, compiler does so statically
  352. public: // for test code
  353. unsigned GetEndMask() const { return static_cast<unsigned>( BitCountToEndMask_t<NUM_BITS % BITS_PER_INT>::MASK ); }
  354. private:
  355. enum
  356. {
  357. NUM_INTS = (NUM_BITS + (BITS_PER_INT-1)) / BITS_PER_INT
  358. };
  359. uint32 m_Ints[(NUM_BITS + (BITS_PER_INT-1)) / BITS_PER_INT];
  360. };
  361. //-----------------------------------------------------------------------------
  362. //
  363. // The actual classes used
  364. //
  365. // inheritance instead of typedef to allow forward declarations
  366. template< class CountType = unsigned short >
  367. class CVarBitVecT : public CBitVecT< CVarBitVecBase< CountType > >
  368. {
  369. public:
  370. CVarBitVecT()
  371. {
  372. }
  373. explicit CVarBitVecT(int numBits)
  374. : CBitVecT<CVarBitVecBase< CountType > >(numBits)
  375. {
  376. }
  377. };
  378. class CVarBitVec : public CVarBitVecT<unsigned short>
  379. {
  380. public:
  381. CVarBitVec() : CVarBitVecT<unsigned short>() {}
  382. explicit CVarBitVec( int nBitCount ) : CVarBitVecT<unsigned short>(nBitCount) {}
  383. };
  384. class CLargeVarBitVec : public CBitVecT< CVarBitVecBase<int> >
  385. {
  386. public:
  387. CLargeVarBitVec()
  388. {
  389. }
  390. explicit CLargeVarBitVec(int numBits)
  391. : CBitVecT< CVarBitVecBase<int> >(numBits)
  392. {
  393. }
  394. };
  395. //-----------------------------------------------------------------------------
  396. template < int NUM_BITS >
  397. class CBitVec : public CBitVecT< CFixedBitVecBase<NUM_BITS> >
  398. {
  399. public:
  400. CBitVec()
  401. {
  402. }
  403. explicit CBitVec(int numBits)
  404. : CBitVecT< CFixedBitVecBase<NUM_BITS> >(numBits)
  405. {
  406. }
  407. };
  408. //-----------------------------------------------------------------------------
  409. typedef CBitVec<32> CDWordBitVec;
  410. //-----------------------------------------------------------------------------
  411. template <typename BITCOUNTTYPE>
  412. inline CVarBitVecBase<BITCOUNTTYPE>::CVarBitVecBase()
  413. {
  414. Plat_FastMemset( this, 0, sizeof( *this ) );
  415. }
  416. //-----------------------------------------------------------------------------
  417. template <typename BITCOUNTTYPE>
  418. inline CVarBitVecBase<BITCOUNTTYPE>::CVarBitVecBase(int numBits)
  419. {
  420. Assert( numBits );
  421. m_numBits = numBits;
  422. // Figure out how many ints are needed
  423. m_numInts = CalcNumIntsForBits( numBits );
  424. m_pInt = NULL;
  425. AllocInts( m_numInts );
  426. }
  427. //-----------------------------------------------------------------------------
  428. template <typename BITCOUNTTYPE>
  429. inline CVarBitVecBase<BITCOUNTTYPE>::CVarBitVecBase( const CVarBitVecBase<BITCOUNTTYPE> &from )
  430. {
  431. if ( from.m_numInts )
  432. {
  433. m_numBits = from.m_numBits;
  434. m_numInts = from.m_numInts;
  435. m_pInt = NULL;
  436. AllocInts( m_numInts );
  437. memcpy( m_pInt, from.m_pInt, m_numInts * sizeof(int) );
  438. }
  439. else
  440. memset( this, 0, sizeof( *this ) );
  441. }
  442. //-----------------------------------------------------------------------------
  443. template <typename BITCOUNTTYPE>
  444. inline CVarBitVecBase<BITCOUNTTYPE> &CVarBitVecBase<BITCOUNTTYPE>::operator=( const CVarBitVecBase<BITCOUNTTYPE> &from )
  445. {
  446. Resize( from.GetNumBits() );
  447. if ( m_pInt )
  448. memcpy( m_pInt, from.m_pInt, m_numInts * sizeof(int) );
  449. return (*this);
  450. }
  451. //-----------------------------------------------------------------------------
  452. // Purpose: Destructor
  453. // Input :
  454. // Output :
  455. //-----------------------------------------------------------------------------
  456. template <typename BITCOUNTTYPE>
  457. inline CVarBitVecBase<BITCOUNTTYPE>::~CVarBitVecBase(void)
  458. {
  459. FreeInts();
  460. }
  461. //-----------------------------------------------------------------------------
  462. template <typename BITCOUNTTYPE>
  463. inline void CVarBitVecBase<BITCOUNTTYPE>::Attach( uint32 *pBits, int numBits )
  464. {
  465. FreeInts();
  466. m_numBits = numBits;
  467. m_numInts = CalcNumIntsForBits( numBits );
  468. if ( m_numInts > 1 )
  469. {
  470. m_pInt = pBits;
  471. }
  472. else
  473. {
  474. m_iBitStringStorage = *pBits;
  475. m_pInt = &m_iBitStringStorage;
  476. free( pBits );
  477. }
  478. }
  479. //-----------------------------------------------------------------------------
  480. template <typename BITCOUNTTYPE>
  481. inline bool CVarBitVecBase<BITCOUNTTYPE>::Detach( uint32 **ppBits, int *pNumBits )
  482. {
  483. if ( !m_numBits )
  484. {
  485. return false;
  486. }
  487. *pNumBits = m_numBits;
  488. if ( m_numInts > 1 )
  489. {
  490. *ppBits = m_pInt;
  491. }
  492. else
  493. {
  494. *ppBits = (uint32 *)malloc( sizeof(uint32) );
  495. **ppBits = m_iBitStringStorage;
  496. free( m_pInt );
  497. }
  498. memset( this, 0, sizeof( *this ) );
  499. return true;
  500. }
  501. //-----------------------------------------------------------------------------
  502. template <class BASE_OPS>
  503. inline CBitVecT<BASE_OPS>::CBitVecT()
  504. {
  505. // undef this is ints are not 4 bytes
  506. // generate a compile error if sizeof(int) is not 4 (HACK: can't use the preprocessor so use the compiler)
  507. COMPILE_TIME_ASSERT( sizeof(int)==4 );
  508. // Initialize bitstring by clearing all bits
  509. ClearAll();
  510. }
  511. //-----------------------------------------------------------------------------
  512. template <class BASE_OPS>
  513. inline CBitVecT<BASE_OPS>::CBitVecT(int numBits)
  514. : BASE_OPS( numBits )
  515. {
  516. // undef this is ints are not 4 bytes
  517. // generate a compile error if sizeof(int) is not 4 (HACK: can't use the preprocessor so use the compiler)
  518. COMPILE_TIME_ASSERT( sizeof(int)==4 );
  519. // Initialize bitstring by clearing all bits
  520. ClearAll();
  521. }
  522. //-----------------------------------------------------------------------------
  523. template <class BASE_OPS>
  524. inline CBitVecAccessor CBitVecT<BASE_OPS>::operator[](int i)
  525. {
  526. Assert(i >= 0 && i < this->GetNumBits());
  527. return CBitVecAccessor(this->Base(), i);
  528. }
  529. template <class BASE_OPS>
  530. inline uint32 CBitVecT<BASE_OPS>::operator[]( int i )const
  531. {
  532. Assert( i >= 0 && i < this->GetNumBits() );
  533. return this->Base()[ i >> 5 ] & ( 1 << ( i & 31 ) );
  534. }
  535. //-----------------------------------------------------------------------------
  536. template <class BASE_OPS>
  537. inline void CBitVecT<BASE_OPS>::Init( int val )
  538. {
  539. if ( this->Base() )
  540. Plat_FastMemset( this->Base(), ( val ) ? 0xff : 0, this->GetNumDWords() * sizeof(int) );
  541. }
  542. //-----------------------------------------------------------------------------
  543. template <class BASE_OPS>
  544. inline uint32 CBitVecT<BASE_OPS>::Get( uint32 bitNum ) const
  545. {
  546. Assert( bitNum < (uint32)this->GetNumBits() );
  547. const uint32 *pInt = this->Base() + BitVec_Int( bitNum );
  548. return ( *pInt & BitVec_Bit( bitNum ) );
  549. }
  550. //-----------------------------------------------------------------------------
  551. template <class BASE_OPS>
  552. inline bool CBitVecT<BASE_OPS>::IsBitSet( int bitNum ) const
  553. {
  554. Assert( bitNum >= 0 && bitNum < this->GetNumBits() );
  555. const uint32 *pInt = this->Base() + BitVec_Int( bitNum );
  556. return ( ( *pInt & BitVec_Bit( bitNum ) ) != 0 );
  557. }
  558. //-----------------------------------------------------------------------------
  559. template <class BASE_OPS>
  560. inline void CBitVecT<BASE_OPS>::Set( int bitNum )
  561. {
  562. Assert( bitNum >= 0 && bitNum < this->GetNumBits() );
  563. uint32 *pInt = this->Base() + BitVec_Int( bitNum );
  564. *pInt |= BitVec_Bit( bitNum );
  565. }
  566. //-----------------------------------------------------------------------------
  567. template <class BASE_OPS>
  568. inline bool CBitVecT<BASE_OPS>::TestAndSet(int bitNum)
  569. {
  570. Assert( bitNum >= 0 && bitNum < this->GetNumBits() );
  571. uint32 bitVecBit = BitVec_Bit( bitNum );
  572. uint32 *pInt = this->Base() + BitVec_Int( bitNum );
  573. bool bResult = ( ( *pInt & bitVecBit) != 0 );
  574. *pInt |= bitVecBit;
  575. return bResult;
  576. }
  577. //-----------------------------------------------------------------------------
  578. template <class BASE_OPS>
  579. inline void CBitVecT<BASE_OPS>::Clear(int bitNum)
  580. {
  581. Assert( bitNum >= 0 && bitNum < this->GetNumBits() );
  582. uint32 *pInt = this->Base() + BitVec_Int( bitNum );
  583. *pInt &= ~BitVec_Bit( bitNum );
  584. }
  585. //-----------------------------------------------------------------------------
  586. template <class BASE_OPS>
  587. inline void CBitVecT<BASE_OPS>::Set( int bitNum, bool bNewVal )
  588. {
  589. uint32 *pInt = this->Base() + BitVec_Int( bitNum );
  590. uint32 bitMask = BitVec_Bit( bitNum );
  591. if ( bNewVal )
  592. {
  593. *pInt |= bitMask;
  594. }
  595. else
  596. {
  597. *pInt &= ~bitMask;
  598. }
  599. }
  600. //-----------------------------------------------------------------------------
  601. template <class BASE_OPS>
  602. inline void CBitVecT<BASE_OPS>::Set( uint32 offset, uint32 mask )
  603. {
  604. uint32 *pInt = this->Base() + offset;
  605. *pInt |= mask;
  606. }
  607. //-----------------------------------------------------------------------------
  608. template <class BASE_OPS>
  609. inline void CBitVecT<BASE_OPS>::Clear( uint32 offset, uint32 mask )
  610. {
  611. uint32 *pInt = this->Base() + offset;
  612. *pInt &= ~mask;
  613. }
  614. //-----------------------------------------------------------------------------
  615. template <class BASE_OPS>
  616. inline uint32 CBitVecT<BASE_OPS>::Get( uint32 offset, uint32 mask )
  617. {
  618. uint32 *pInt = this->Base() + offset;
  619. return ( *pInt & mask );
  620. }
  621. //-----------------------------------------------------------------------------
  622. // Purpose:
  623. // Input :
  624. // Output :
  625. //-----------------------------------------------------------------------------
  626. template <class BASE_OPS>
  627. inline void CBitVecT<BASE_OPS>::And(const CBitVecT &addStr, CBitVecT *out) const
  628. {
  629. ValidateOperand( addStr );
  630. ValidateOperand( *out );
  631. uint32 * pDest = out->Base();
  632. const uint32 *pOperand1 = this->Base();
  633. const uint32 *pOperand2 = addStr.Base();
  634. for (int i = this->GetNumDWords() - 1; i >= 0 ; --i)
  635. {
  636. pDest[i] = pOperand1[i] & pOperand2[i];
  637. }
  638. }
  639. //-----------------------------------------------------------------------------
  640. // Purpose:
  641. // Input :
  642. // Output :
  643. //-----------------------------------------------------------------------------
  644. template <class BASE_OPS>
  645. inline void CBitVecT<BASE_OPS>::Or(const CBitVecT &orStr, CBitVecT *out) const
  646. {
  647. ValidateOperand( orStr );
  648. ValidateOperand( *out );
  649. uint32 * pDest = out->Base();
  650. const uint32 *pOperand1 = this->Base();
  651. const uint32 *pOperand2 = orStr.Base();
  652. for (int i = this->GetNumDWords() - 1; i >= 0; --i)
  653. {
  654. pDest[i] = pOperand1[i] | pOperand2[i];
  655. }
  656. }
  657. //-----------------------------------------------------------------------------
  658. // Purpose:
  659. // Input :
  660. // Output :
  661. //-----------------------------------------------------------------------------
  662. template <class BASE_OPS>
  663. inline void CBitVecT<BASE_OPS>::Xor(const CBitVecT &xorStr, CBitVecT *out) const
  664. {
  665. uint32 * pDest = out->Base();
  666. const uint32 *pOperand1 = this->Base();
  667. const uint32 *pOperand2 = xorStr.Base();
  668. for (int i = this->GetNumDWords() - 1; i >= 0; --i)
  669. {
  670. pDest[i] = pOperand1[i] ^ pOperand2[i];
  671. }
  672. }
  673. //-----------------------------------------------------------------------------
  674. // Purpose:
  675. // Input :
  676. // Output :
  677. //-----------------------------------------------------------------------------
  678. template <class BASE_OPS>
  679. inline void CBitVecT<BASE_OPS>::Not(CBitVecT *out) const
  680. {
  681. this->ValidateOperand( *out );
  682. uint32 * pDest = out->Base();
  683. const uint32 *pOperand = this->Base();
  684. for (int i = this->GetNumDWords() - 1; i >= 0; --i)
  685. {
  686. pDest[i] = ~(pOperand[i]);
  687. }
  688. }
  689. //-----------------------------------------------------------------------------
  690. // Purpose: Copy a bit string
  691. // Input :
  692. // Output :
  693. //-----------------------------------------------------------------------------
  694. template <class BASE_OPS>
  695. inline void CBitVecT<BASE_OPS>::CopyTo(CBitVecT *out) const
  696. {
  697. out->Resize( this->GetNumBits() );
  698. this->ValidateOperand( *out );
  699. Assert( out != this );
  700. memcpy( out->Base(), this->Base(), this->GetNumDWords() * sizeof( int ) );
  701. }
  702. //-----------------------------------------------------------------------------
  703. // Purpose: Are all bits zero?
  704. // Input :
  705. // Output :
  706. //-----------------------------------------------------------------------------
  707. template <class BASE_OPS>
  708. inline bool CBitVecT<BASE_OPS>::IsAllClear(void) const
  709. {
  710. // Number of available bits may be more than the number
  711. // actually used, so make sure to mask out unused bits
  712. // before testing for zero
  713. (const_cast<CBitVecT *>(this))->Base()[this->GetNumDWords()-1] &= CBitVecT<BASE_OPS>::GetEndMask(); // external semantics of const retained
  714. for (int i = this->GetNumDWords() - 1; i >= 0; --i)
  715. {
  716. if ( this->Base()[i] !=0 )
  717. {
  718. return false;
  719. }
  720. }
  721. return true;
  722. }
  723. //-----------------------------------------------------------------------------
  724. // Purpose: Are all bits set?
  725. // Input :
  726. // Output :
  727. //-----------------------------------------------------------------------------
  728. template <class BASE_OPS>
  729. inline bool CBitVecT<BASE_OPS>::IsAllSet(void) const
  730. {
  731. // Number of available bits may be more than the number
  732. // actually used, so make sure to mask out unused bits
  733. // before testing for set bits
  734. (const_cast<CBitVecT *>(this))->Base()[this->GetNumDWords()-1] |= ~CBitVecT<BASE_OPS>::GetEndMask(); // external semantics of const retained
  735. for (int i = this->GetNumDWords() - 1; i >= 0; --i)
  736. {
  737. if ( this->Base()[i] != ~0 )
  738. {
  739. return false;
  740. }
  741. }
  742. return true;
  743. }
  744. //-----------------------------------------------------------------------------
  745. // Purpose: Sets all bits
  746. // Input :
  747. // Output :
  748. //-----------------------------------------------------------------------------
  749. template <class BASE_OPS>
  750. inline void CBitVecT<BASE_OPS>::SetAll(void)
  751. {
  752. if ( this->Base() )
  753. Plat_FastMemset( this->Base(), 0xff, this->GetNumDWords() * sizeof(int) );
  754. }
  755. //-----------------------------------------------------------------------------
  756. // Purpose: Clears all bits
  757. // Input :
  758. // Output :
  759. //-----------------------------------------------------------------------------
  760. template <class BASE_OPS>
  761. inline void CBitVecT<BASE_OPS>::ClearAll(void)
  762. {
  763. if ( this->Base() )
  764. Plat_FastMemset( this->Base(), 0, this->GetNumDWords() * sizeof(int) );
  765. }
  766. //-----------------------------------------------------------------------------
  767. template <class BASE_OPS>
  768. inline void CBitVecT<BASE_OPS>::Copy( const CBitVecT<BASE_OPS> &other, int nBits )
  769. {
  770. if ( nBits == - 1 )
  771. {
  772. nBits = other.GetNumBits();
  773. }
  774. this->Resize( nBits );
  775. this->ValidateOperand( other );
  776. Assert( &other != this );
  777. memcpy( this->Base(), other.Base(), this->GetNumDWords() * sizeof( uint32 ) );
  778. }
  779. //-----------------------------------------------------------------------------
  780. template <class BASE_OPS>
  781. inline bool CBitVecT<BASE_OPS>::Compare( const CBitVecT<BASE_OPS> &other, int nBits ) const
  782. {
  783. if ( nBits == - 1 )
  784. {
  785. if ( other.GetNumBits() != this->GetNumBits() )
  786. {
  787. return false;
  788. }
  789. nBits = other.GetNumBits();
  790. }
  791. if ( nBits > other.GetNumBits() || nBits > this->GetNumBits() )
  792. {
  793. return false;
  794. }
  795. (const_cast<CBitVecT *>(this))->Base()[this->GetNumDWords()-1] &= CBitVecT<BASE_OPS>::GetEndMask(); // external semantics of const retained
  796. (const_cast<CBitVecT *>(&other))->Base()[this->GetNumDWords()-1] &= other.CBitVecT<BASE_OPS>::GetEndMask(); // external semantics of const retained
  797. int nBytes = PAD_NUMBER( nBits, 8 ) >> 3;
  798. return ( memcmp( this->Base(), other.Base(), nBytes ) == 0 );
  799. }
  800. //-----------------------------------------------------------------------------
  801. template <class BASE_OPS>
  802. inline uint32 CBitVecT<BASE_OPS>::GetDWord(int i) const
  803. {
  804. Assert(i >= 0 && i < this->GetNumDWords());
  805. return this->Base()[i];
  806. }
  807. //-----------------------------------------------------------------------------
  808. template <class BASE_OPS>
  809. inline void CBitVecT<BASE_OPS>::SetDWord(int i, uint32 val)
  810. {
  811. Assert(i >= 0 && i < this->GetNumDWords());
  812. this->Base()[i] = val;
  813. }
  814. //-----------------------------------------------------------------------------
  815. template <class BASE_OPS>
  816. inline uint32 CBitVecT<BASE_OPS>::PopulationCount() const
  817. {
  818. int nDwordCount = this->GetNumDWords();
  819. const uint32 *pBase = this->Base();
  820. uint32 nCount = 0;
  821. for( int i = 0; i < nDwordCount; ++i )
  822. {
  823. nCount += ::PopulationCount( pBase[i] );
  824. }
  825. return nCount;
  826. }
  827. //-----------------------------------------------------------------------------
  828. inline unsigned GetStartBitMask( int startBit )
  829. {
  830. static unsigned int g_StartMask[32] =
  831. {
  832. 0xffffffff,
  833. 0xfffffffe,
  834. 0xfffffffc,
  835. 0xfffffff8,
  836. 0xfffffff0,
  837. 0xffffffe0,
  838. 0xffffffc0,
  839. 0xffffff80,
  840. 0xffffff00,
  841. 0xfffffe00,
  842. 0xfffffc00,
  843. 0xfffff800,
  844. 0xfffff000,
  845. 0xffffe000,
  846. 0xffffc000,
  847. 0xffff8000,
  848. 0xffff0000,
  849. 0xfffe0000,
  850. 0xfffc0000,
  851. 0xfff80000,
  852. 0xfff00000,
  853. 0xffe00000,
  854. 0xffc00000,
  855. 0xff800000,
  856. 0xff000000,
  857. 0xfe000000,
  858. 0xfc000000,
  859. 0xf8000000,
  860. 0xf0000000,
  861. 0xe0000000,
  862. 0xc0000000,
  863. 0x80000000,
  864. };
  865. return g_StartMask[ startBit & 31 ];
  866. }
  867. #ifdef _X360
  868. #define BitVec_Bit( bitNum ) GetBitForBitnum( bitNum )
  869. #define BitVec_BitInByte( bitNum ) GetBitForBitnumByte( bitNum )
  870. #else
  871. #define BitVec_Bit( bitNum ) ( 1 << ( (bitNum) & (BITS_PER_INT-1) ) )
  872. #define BitVec_BitInByte( bitNum ) ( 1 << ( (bitNum) & 7 ) )
  873. #endif
  874. #define BitVec_Int( bitNum ) ( (bitNum) >> LOG2_BITS_PER_INT )
  875. inline bool BitVec_IsBitSet( const uint32 *pBase, int nBitNum )
  876. {
  877. const uint32 *pInt = pBase + BitVec_Int( nBitNum );
  878. return ( ( *pInt & BitVec_Bit( nBitNum ) ) != 0 );
  879. }
  880. inline void Bitvec_Set( uint32 *pBits, int nBitNum )
  881. {
  882. uint32 *pInt = pBits + BitVec_Int( nBitNum );
  883. *pInt |= BitVec_Bit( nBitNum );
  884. }
  885. inline void Bitvec_Unset( uint32 *pBits, int nBitNum )
  886. {
  887. uint32 *pInt = pBits + BitVec_Int( nBitNum );
  888. *pInt &= ~BitVec_Bit( nBitNum );
  889. }
  890. inline bool BitVec_TestAndSetBit( uint32 *pBase, int nBitNum )
  891. {
  892. uint32 *pInt = pBase + BitVec_Int( nBitNum );
  893. uint32 nBits = *pInt;
  894. uint32 nSetMask = BitVec_Bit( nBitNum );
  895. *pInt = nBits | nSetMask;
  896. return ( nBits & nSetMask ) ? true : false;
  897. }
  898. inline void BitVec_ClearAll( uint32 *pDst, int nDWords, uint32 nEndMask )
  899. {
  900. if ( nDWords > 1 )
  901. {
  902. V_memset( pDst, 0, ( nDWords - 1 ) * sizeof( uint32 ) );
  903. }
  904. pDst[ nDWords - 1 ] &= ~nEndMask;
  905. }
  906. inline void BitVec_ClearAll( uint32 *pDst, int nDWords )
  907. {
  908. V_memset( pDst, 0, nDWords * sizeof( uint32 ) );
  909. }
  910. inline void BitVec_SetAll( uint32 *pDst, int nDWords, uint32 nEndMask )
  911. {
  912. if ( nDWords > 1 )
  913. {
  914. V_memset( pDst, 0xff, ( nDWords - 1 ) * sizeof( uint32 ) );
  915. }
  916. pDst[ nDWords - 1 ] |= nEndMask;
  917. }
  918. inline void BitVec_SetAll( uint32 *pDst, int nDWords )
  919. {
  920. V_memset( pDst, 0xff, nDWords * sizeof( uint32 ) );
  921. }
  922. inline void BitVec_Or( uint32 *pDst, const uint32 *pSrc, int nDWords, uint32 nEndMask )
  923. {
  924. uint32 *pEnd = pDst + nDWords - 1;
  925. for ( ; pDst < pEnd; ++pSrc, ++pDst )
  926. {
  927. *pDst = *pDst | *pSrc;
  928. }
  929. *pDst = *pDst | ( *pSrc & nEndMask );
  930. }
  931. inline void BitVec_Or( uint32 *pDst, const uint32 *pSrc, int nDWords )
  932. {
  933. uint32 *pEnd = pDst + nDWords;
  934. for ( ; pDst < pEnd; ++pSrc, ++pDst )
  935. {
  936. *pDst = *pDst | *pSrc;
  937. }
  938. }
  939. inline void BitVec_AndNot( uint32 *pDst, const uint32 *pSrc, const uint32 *pAndNot, int nDWords )
  940. {
  941. uint32 *pEnd = pDst + nDWords;
  942. for ( ; pDst < pEnd; ++pSrc, ++pDst, ++pAndNot )
  943. {
  944. *pDst = *pSrc & ~( *pAndNot );
  945. }
  946. }
  947. inline bool BitVec_IsAnySet( const uint32 *pDst, int nDWords )
  948. {
  949. const uint32 *pEnd = pDst + nDWords;
  950. for ( ; pDst < pEnd; ++pDst )
  951. {
  952. if ( *pDst != 0 )
  953. return true;
  954. }
  955. return false;
  956. }
  957. inline int BitVec_CountNewBits( const uint32 *pOld, const uint32 *pNew, int nDWords, uint32 nEndMask )
  958. {
  959. // NOTE - this assumes that any unused bits are unchanged between pOld and pNew
  960. int nNewBits = 0;
  961. const uint32 *pEnd = pNew + nDWords - 1;
  962. for ( ; pNew < pEnd; ++pOld, ++pNew )
  963. {
  964. uint32 diff = *pNew & ~*pOld;
  965. nNewBits += PopulationCount( diff );
  966. }
  967. nNewBits += PopulationCount( ( *pNew & ~*pOld ) & nEndMask );
  968. return nNewBits;
  969. }
  970. template <typename BITCOUNTTYPE>
  971. inline int CVarBitVecBase<BITCOUNTTYPE>::FindNextSetBit( int startBit ) const
  972. {
  973. if ( startBit < GetNumBits() )
  974. {
  975. int wordIndex = BitVec_Int(startBit);
  976. unsigned int startMask = GetStartBitMask( startBit );
  977. int lastWord = GetNumDWords()-1;
  978. // handle non dword lengths
  979. if ( (GetNumBits() % BITS_PER_INT) != 0 )
  980. {
  981. unsigned int elem = Base()[wordIndex];
  982. elem &= startMask;
  983. if ( wordIndex == lastWord)
  984. {
  985. elem &= (GetEndMask());
  986. // there's a bit remaining in this word
  987. if ( elem )
  988. return FirstBitInWord(elem, wordIndex << 5);
  989. }
  990. else
  991. {
  992. // there's a bit remaining in this word
  993. if ( elem )
  994. return FirstBitInWord(elem, wordIndex << 5);
  995. // iterate the words
  996. for ( int i = wordIndex+1; i < lastWord; i++ )
  997. {
  998. elem = Base()[i];
  999. if ( elem )
  1000. return FirstBitInWord(elem, i << 5);
  1001. }
  1002. elem = Base()[lastWord] & GetEndMask();
  1003. if ( elem )
  1004. return FirstBitInWord(elem, lastWord << 5);
  1005. }
  1006. }
  1007. else
  1008. {
  1009. const uint32 * RESTRICT pCurElem = Base() + wordIndex;
  1010. unsigned int elem = *pCurElem;
  1011. elem &= startMask;
  1012. do
  1013. {
  1014. if ( elem )
  1015. return FirstBitInWord(elem, wordIndex << 5);
  1016. ++pCurElem;
  1017. elem = *pCurElem;
  1018. ++wordIndex;
  1019. } while( wordIndex <= lastWord );
  1020. }
  1021. }
  1022. return -1;
  1023. }
  1024. template <int NUM_BITS>
  1025. inline int CFixedBitVecBase<NUM_BITS>::FindNextSetBit( int startBit ) const
  1026. {
  1027. if ( startBit < NUM_BITS )
  1028. {
  1029. int wordIndex = BitVec_Int(startBit);
  1030. unsigned int startMask = GetStartBitMask( startBit );
  1031. // handle non dword lengths
  1032. if ( (NUM_BITS % BITS_PER_INT) != 0 )
  1033. {
  1034. unsigned int elem = Base()[wordIndex];
  1035. elem &= startMask;
  1036. if ( wordIndex == NUM_INTS-1)
  1037. {
  1038. elem &= (GetEndMask());
  1039. // there's a bit remaining in this word
  1040. if ( elem )
  1041. return FirstBitInWord(elem, wordIndex << 5);
  1042. }
  1043. else
  1044. {
  1045. // there's a bit remaining in this word
  1046. if ( elem )
  1047. return FirstBitInWord(elem, wordIndex << 5);
  1048. // iterate the words
  1049. for ( int i = wordIndex+1; i < NUM_INTS-1; i++ )
  1050. {
  1051. elem = Base()[i];
  1052. if ( elem )
  1053. return FirstBitInWord(elem, i << 5);
  1054. }
  1055. elem = Base()[NUM_INTS-1] & GetEndMask();
  1056. if ( elem )
  1057. return FirstBitInWord(elem, (NUM_INTS-1) << 5);
  1058. }
  1059. }
  1060. else
  1061. {
  1062. const uint32 * RESTRICT pCurElem = Base() + wordIndex;
  1063. unsigned int elem = *pCurElem;
  1064. elem &= startMask;
  1065. do
  1066. {
  1067. if ( elem )
  1068. return FirstBitInWord(elem, wordIndex << 5);
  1069. ++pCurElem;
  1070. elem = *pCurElem;
  1071. ++wordIndex;
  1072. } while( wordIndex <= NUM_INTS-1);
  1073. }
  1074. }
  1075. return -1;
  1076. }
  1077. //-----------------------------------------------------------------------------
  1078. // Unrolled loops for some common sizes
  1079. template<>
  1080. FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::And(const CBitVecT &addStr, CBitVecT *out) const
  1081. {
  1082. uint32 * pDest = out->Base();
  1083. const uint32 *pOperand1 = Base();
  1084. const uint32 *pOperand2 = addStr.Base();
  1085. pDest[0] = pOperand1[0] & pOperand2[0];
  1086. pDest[1] = pOperand1[1] & pOperand2[1];
  1087. pDest[2] = pOperand1[2] & pOperand2[2];
  1088. pDest[3] = pOperand1[3] & pOperand2[3];
  1089. pDest[4] = pOperand1[4] & pOperand2[4];
  1090. pDest[5] = pOperand1[5] & pOperand2[5];
  1091. pDest[6] = pOperand1[6] & pOperand2[6];
  1092. pDest[7] = pOperand1[7] & pOperand2[7];
  1093. }
  1094. template<>
  1095. FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<256> >::IsAllClear(void) const
  1096. {
  1097. const uint32 *pInts = Base();
  1098. 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 );
  1099. }
  1100. template<>
  1101. FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::CopyTo(CBitVecT *out) const
  1102. {
  1103. uint32 * pDest = out->Base();
  1104. const uint32 *pInts = Base();
  1105. pDest[0] = pInts[0];
  1106. pDest[1] = pInts[1];
  1107. pDest[2] = pInts[2];
  1108. pDest[3] = pInts[3];
  1109. pDest[4] = pInts[4];
  1110. pDest[5] = pInts[5];
  1111. pDest[6] = pInts[6];
  1112. pDest[7] = pInts[7];
  1113. }
  1114. template<>
  1115. FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::And(const CBitVecT &addStr, CBitVecT *out) const
  1116. {
  1117. uint32 * pDest = out->Base();
  1118. const uint32 *pOperand1 = Base();
  1119. const uint32 *pOperand2 = addStr.Base();
  1120. pDest[0] = pOperand1[0] & pOperand2[0];
  1121. pDest[1] = pOperand1[1] & pOperand2[1];
  1122. pDest[2] = pOperand1[2] & pOperand2[2];
  1123. pDest[3] = pOperand1[3] & pOperand2[3];
  1124. }
  1125. template<>
  1126. FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<128> >::IsAllClear(void) const
  1127. {
  1128. const uint32 *pInts = Base();
  1129. return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 && pInts[3] == 0 );
  1130. }
  1131. template<>
  1132. FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::CopyTo(CBitVecT *out) const
  1133. {
  1134. uint32 * pDest = out->Base();
  1135. const uint32 *pInts = Base();
  1136. pDest[0] = pInts[0];
  1137. pDest[1] = pInts[1];
  1138. pDest[2] = pInts[2];
  1139. pDest[3] = pInts[3];
  1140. }
  1141. template<>
  1142. inline void CBitVecT< CFixedBitVecBase<96> >::And(const CBitVecT &addStr, CBitVecT *out) const
  1143. {
  1144. uint32 * pDest = out->Base();
  1145. const uint32 *pOperand1 = Base();
  1146. const uint32 *pOperand2 = addStr.Base();
  1147. pDest[0] = pOperand1[0] & pOperand2[0];
  1148. pDest[1] = pOperand1[1] & pOperand2[1];
  1149. pDest[2] = pOperand1[2] & pOperand2[2];
  1150. }
  1151. template<>
  1152. inline bool CBitVecT< CFixedBitVecBase<96> >::IsAllClear(void) const
  1153. {
  1154. const uint32 *pInts = Base();
  1155. return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 );
  1156. }
  1157. template<>
  1158. inline void CBitVecT< CFixedBitVecBase<96> >::CopyTo(CBitVecT *out) const
  1159. {
  1160. uint32 * pDest = out->Base();
  1161. const uint32 *pInts = Base();
  1162. pDest[0] = pInts[0];
  1163. pDest[1] = pInts[1];
  1164. pDest[2] = pInts[2];
  1165. }
  1166. template<>
  1167. inline void CBitVecT< CFixedBitVecBase<64> >::And(const CBitVecT &addStr, CBitVecT *out) const
  1168. {
  1169. uint32 * pDest = out->Base();
  1170. const uint32 *pOperand1 = Base();
  1171. const uint32 *pOperand2 = addStr.Base();
  1172. pDest[0] = pOperand1[0] & pOperand2[0];
  1173. pDest[1] = pOperand1[1] & pOperand2[1];
  1174. }
  1175. template<>
  1176. inline bool CBitVecT< CFixedBitVecBase<64> >::IsAllClear(void) const
  1177. {
  1178. const uint32 *pInts = Base();
  1179. return ( pInts[0] == 0 && pInts[1] == 0 );
  1180. }
  1181. template<>
  1182. inline void CBitVecT< CFixedBitVecBase<64> >::CopyTo(CBitVecT *out) const
  1183. {
  1184. uint32 * pDest = out->Base();
  1185. const uint32 *pInts = Base();
  1186. pDest[0] = pInts[0];
  1187. pDest[1] = pInts[1];
  1188. }
  1189. template<>
  1190. inline void CBitVecT< CFixedBitVecBase<32> >::And(const CBitVecT &addStr, CBitVecT *out) const
  1191. {
  1192. uint32 * pDest = out->Base();
  1193. const uint32 *pOperand1 = Base();
  1194. const uint32 *pOperand2 = addStr.Base();
  1195. pDest[0] = pOperand1[0] & pOperand2[0];
  1196. }
  1197. template<>
  1198. inline bool CBitVecT< CFixedBitVecBase<32> >::IsAllClear(void) const
  1199. {
  1200. const uint32 *pInts = Base();
  1201. return ( pInts[0] == 0 );
  1202. }
  1203. template<>
  1204. inline void CBitVecT< CFixedBitVecBase<32> >::CopyTo(CBitVecT *out) const
  1205. {
  1206. uint32 * pDest = out->Base();
  1207. const uint32 *pInts = Base();
  1208. pDest[0] = pInts[0];
  1209. }
  1210. //-----------------------------------------------------------------------------
  1211. template <>
  1212. inline uint32 CBitVecT< CFixedBitVecBase<32> >::Get( uint32 bitNum ) const
  1213. {
  1214. return ( *Base() & BitVec_Bit( bitNum ) );
  1215. }
  1216. //-----------------------------------------------------------------------------
  1217. template <>
  1218. inline bool CBitVecT< CFixedBitVecBase<32> >::IsBitSet( int bitNum ) const
  1219. {
  1220. return ( ( *Base() & BitVec_Bit( bitNum ) ) != 0 );
  1221. }
  1222. //-----------------------------------------------------------------------------
  1223. template <>
  1224. inline void CBitVecT< CFixedBitVecBase<32> >::Set( int bitNum )
  1225. {
  1226. *Base() |= BitVec_Bit( bitNum );
  1227. }
  1228. //-----------------------------------------------------------------------------
  1229. template <>
  1230. inline void CBitVecT< CFixedBitVecBase<32> >::Clear(int bitNum)
  1231. {
  1232. *Base() &= ~BitVec_Bit( bitNum );
  1233. }
  1234. //-----------------------------------------------------------------------------
  1235. template <>
  1236. inline void CBitVecT< CFixedBitVecBase<32> >::Set( int bitNum, bool bNewVal )
  1237. {
  1238. uint32 bitMask = BitVec_Bit( bitNum );
  1239. if ( bNewVal )
  1240. {
  1241. *Base() |= bitMask;
  1242. }
  1243. else
  1244. {
  1245. *Base() &= ~bitMask;
  1246. }
  1247. }
  1248. //-----------------------------------------------------------------------------
  1249. #include "tier0/memdbgon.h"
  1250. //-----------------------------------------------------------------------------
  1251. // Purpose: Resizes the bit string to a new number of bits
  1252. // Input : resizeNumBits -
  1253. //-----------------------------------------------------------------------------
  1254. template <typename BITCOUNTTYPE>
  1255. inline void CVarBitVecBase<BITCOUNTTYPE>::Resize( int resizeNumBits, bool bClearAll )
  1256. {
  1257. Assert( resizeNumBits >= 0 && ((BITCOUNTTYPE)resizeNumBits == resizeNumBits) );
  1258. int newIntCount = CalcNumIntsForBits( resizeNumBits );
  1259. if ( newIntCount != GetNumDWords() )
  1260. {
  1261. if ( Base() )
  1262. {
  1263. ReallocInts( newIntCount );
  1264. if ( !bClearAll && resizeNumBits >= GetNumBits() )
  1265. {
  1266. Base()[GetNumDWords() - 1] &= GetEndMask();
  1267. Plat_FastMemset( Base() + GetNumDWords(), 0, (newIntCount - GetNumDWords()) * sizeof(int) );
  1268. }
  1269. }
  1270. else
  1271. {
  1272. // Figure out how many ints are needed
  1273. AllocInts( newIntCount );
  1274. // Initialize bitstring by clearing all bits
  1275. bClearAll = true;
  1276. }
  1277. m_numInts = newIntCount;
  1278. }
  1279. else if ( !bClearAll && resizeNumBits >= GetNumBits() && Base() )
  1280. {
  1281. Base()[GetNumDWords() - 1] &= GetEndMask();
  1282. }
  1283. if ( bClearAll && Base() )
  1284. {
  1285. Plat_FastMemset( Base(), 0, newIntCount * sizeof(int) );
  1286. }
  1287. // store the new size and end mask
  1288. m_numBits = resizeNumBits;
  1289. }
  1290. //-----------------------------------------------------------------------------
  1291. // Purpose: Allocate the storage for the ints
  1292. // Input : numInts -
  1293. //-----------------------------------------------------------------------------
  1294. template <typename BITCOUNTTYPE>
  1295. inline void CVarBitVecBase<BITCOUNTTYPE>::AllocInts( int numInts )
  1296. {
  1297. Assert( !m_pInt );
  1298. if ( numInts == 0 )
  1299. return;
  1300. if ( numInts == 1 )
  1301. {
  1302. m_pInt = &m_iBitStringStorage;
  1303. return;
  1304. }
  1305. m_pInt = (uint32 *)malloc( numInts * sizeof(int) );
  1306. }
  1307. //-----------------------------------------------------------------------------
  1308. // Purpose: Reallocate the storage for the ints
  1309. // Input : numInts -
  1310. //-----------------------------------------------------------------------------
  1311. template <typename BITCOUNTTYPE>
  1312. inline void CVarBitVecBase<BITCOUNTTYPE>::ReallocInts( int numInts )
  1313. {
  1314. Assert( Base() );
  1315. if ( numInts == 0)
  1316. {
  1317. FreeInts();
  1318. return;
  1319. }
  1320. if ( m_pInt == &m_iBitStringStorage )
  1321. {
  1322. if ( numInts != 1 )
  1323. {
  1324. m_pInt = ((uint32 *)malloc( numInts * sizeof(int) ));
  1325. *m_pInt = m_iBitStringStorage;
  1326. }
  1327. return;
  1328. }
  1329. if ( numInts == 1 )
  1330. {
  1331. m_iBitStringStorage = *m_pInt;
  1332. free( m_pInt );
  1333. m_pInt = &m_iBitStringStorage;
  1334. return;
  1335. }
  1336. m_pInt = (uint32 *)realloc( m_pInt, numInts * sizeof(int) );
  1337. }
  1338. //-----------------------------------------------------------------------------
  1339. // Purpose: Free storage allocated with AllocInts
  1340. //-----------------------------------------------------------------------------
  1341. template <typename BITCOUNTTYPE>
  1342. inline void CVarBitVecBase<BITCOUNTTYPE>::FreeInts( void )
  1343. {
  1344. if ( m_numInts > 1 )
  1345. {
  1346. free( m_pInt );
  1347. }
  1348. m_pInt = NULL;
  1349. }
  1350. #include "tier0/memdbgoff.h"
  1351. // ------------------------------------------------------------------------ //
  1352. // CBitVecAccessor inlines.
  1353. // ------------------------------------------------------------------------ //
  1354. inline CBitVecAccessor::CBitVecAccessor(uint32 *pDWords, int iBit)
  1355. {
  1356. m_pDWords = pDWords;
  1357. m_iBit = iBit;
  1358. }
  1359. inline void CBitVecAccessor::operator=(int val)
  1360. {
  1361. if(val)
  1362. m_pDWords[m_iBit >> 5] |= (1 << (m_iBit & 31));
  1363. else
  1364. m_pDWords[m_iBit >> 5] &= ~(unsigned long)(1 << (m_iBit & 31));
  1365. }
  1366. inline CBitVecAccessor::operator uint32()
  1367. {
  1368. return m_pDWords[m_iBit >> 5] & (1 << (m_iBit & 31));
  1369. }
  1370. //=============================================================================
  1371. #endif // BITVEC_H