Team Fortress 2 Source Code as on 22/4/2020
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.

1446 lines
38 KiB

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