Bitvec.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #pragma once
  2. #include "Platform.h"
  3. #include <vector>
  4. //-----------------------------------------------------------------------------
  5. void printbits ( const void * blob, int len );
  6. void printhex32 ( const void * blob, int len );
  7. void printbytes ( const void * blob, int len );
  8. void printbytes2 ( const void * blob, int len );
  9. uint32_t popcount ( uint32_t v );
  10. uint32_t parity ( uint32_t v );
  11. uint32_t getbit ( const void * blob, int len, uint32_t bit );
  12. uint32_t getbit_wrap ( const void * blob, int len, uint32_t bit );
  13. void setbit ( void * blob, int len, uint32_t bit );
  14. void setbit ( void * blob, int len, uint32_t bit, uint32_t val );
  15. void clearbit ( void * blob, int len, uint32_t bit );
  16. void flipbit ( void * blob, int len, uint32_t bit );
  17. int countbits ( uint32_t v );
  18. int countbits ( std::vector<uint32_t> & v );
  19. int countbits ( const void * blob, int len );
  20. void invert ( std::vector<uint32_t> & v );
  21. //----------
  22. template< typename T >
  23. inline uint32_t getbit ( T & blob, uint32_t bit )
  24. {
  25. return getbit(&blob,sizeof(blob),bit);
  26. }
  27. template<> inline uint32_t getbit ( uint32_t & blob, uint32_t bit ) { return (blob >> (bit & 31)) & 1; }
  28. template<> inline uint32_t getbit ( uint64_t & blob, uint32_t bit ) { return (blob >> (bit & 63)) & 1; }
  29. //----------
  30. template< typename T >
  31. inline void setbit ( T & blob, uint32_t bit )
  32. {
  33. return setbit(&blob,sizeof(blob),bit);
  34. }
  35. template<> inline void setbit ( uint32_t & blob, uint32_t bit ) { blob |= uint32_t(1) << (bit & 31); }
  36. template<> inline void setbit ( uint64_t & blob, uint32_t bit ) { blob |= uint64_t(1) << (bit & 63); }
  37. //----------
  38. template< typename T >
  39. inline void flipbit ( T & blob, uint32_t bit )
  40. {
  41. flipbit(&blob,sizeof(blob),bit);
  42. }
  43. template<> inline void flipbit ( uint32_t & blob, uint32_t bit ) { bit &= 31; blob ^= (uint32_t(1) << bit); }
  44. template<> inline void flipbit ( uint64_t & blob, uint32_t bit ) { bit &= 63; blob ^= (uint64_t(1) << bit); }
  45. //-----------------------------------------------------------------------------
  46. // Left and right shift of blobs. The shift(N) versions work on chunks of N
  47. // bits at a time (faster)
  48. void lshift1 ( void * blob, int len, int c );
  49. void lshift8 ( void * blob, int len, int c );
  50. void lshift32 ( void * blob, int len, int c );
  51. void rshift1 ( void * blob, int len, int c );
  52. void rshift8 ( void * blob, int len, int c );
  53. void rshift32 ( void * blob, int len, int c );
  54. inline void lshift ( void * blob, int len, int c )
  55. {
  56. if((len & 3) == 0)
  57. {
  58. lshift32(blob,len,c);
  59. }
  60. else
  61. {
  62. lshift8(blob,len,c);
  63. }
  64. }
  65. inline void rshift ( void * blob, int len, int c )
  66. {
  67. if((len & 3) == 0)
  68. {
  69. rshift32(blob,len,c);
  70. }
  71. else
  72. {
  73. rshift8(blob,len,c);
  74. }
  75. }
  76. template < typename T >
  77. inline void lshift ( T & blob, int c )
  78. {
  79. if((sizeof(T) & 3) == 0)
  80. {
  81. lshift32(&blob,sizeof(T),c);
  82. }
  83. else
  84. {
  85. lshift8(&blob,sizeof(T),c);
  86. }
  87. }
  88. template < typename T >
  89. inline void rshift ( T & blob, int c )
  90. {
  91. if((sizeof(T) & 3) == 0)
  92. {
  93. lshift32(&blob,sizeof(T),c);
  94. }
  95. else
  96. {
  97. lshift8(&blob,sizeof(T),c);
  98. }
  99. }
  100. template<> inline void lshift ( uint32_t & blob, int c ) { blob <<= c; }
  101. template<> inline void lshift ( uint64_t & blob, int c ) { blob <<= c; }
  102. template<> inline void rshift ( uint32_t & blob, int c ) { blob >>= c; }
  103. template<> inline void rshift ( uint64_t & blob, int c ) { blob >>= c; }
  104. //-----------------------------------------------------------------------------
  105. // Left and right rotate of blobs. The rot(N) versions work on chunks of N
  106. // bits at a time (faster)
  107. void lrot1 ( void * blob, int len, int c );
  108. void lrot8 ( void * blob, int len, int c );
  109. void lrot32 ( void * blob, int len, int c );
  110. void rrot1 ( void * blob, int len, int c );
  111. void rrot8 ( void * blob, int len, int c );
  112. void rrot32 ( void * blob, int len, int c );
  113. inline void lrot ( void * blob, int len, int c )
  114. {
  115. if((len & 3) == 0)
  116. {
  117. return lrot32(blob,len,c);
  118. }
  119. else
  120. {
  121. return lrot8(blob,len,c);
  122. }
  123. }
  124. inline void rrot ( void * blob, int len, int c )
  125. {
  126. if((len & 3) == 0)
  127. {
  128. return rrot32(blob,len,c);
  129. }
  130. else
  131. {
  132. return rrot8(blob,len,c);
  133. }
  134. }
  135. template < typename T >
  136. inline void lrot ( T & blob, int c )
  137. {
  138. if((sizeof(T) & 3) == 0)
  139. {
  140. return lrot32(&blob,sizeof(T),c);
  141. }
  142. else
  143. {
  144. return lrot8(&blob,sizeof(T),c);
  145. }
  146. }
  147. template < typename T >
  148. inline void rrot ( T & blob, int c )
  149. {
  150. if((sizeof(T) & 3) == 0)
  151. {
  152. return rrot32(&blob,sizeof(T),c);
  153. }
  154. else
  155. {
  156. return rrot8(&blob,sizeof(T),c);
  157. }
  158. }
  159. template<> inline void lrot ( uint32_t & blob, int c ) { blob = ROTL32(blob,c); }
  160. template<> inline void lrot ( uint64_t & blob, int c ) { blob = ROTL64(blob,c); }
  161. template<> inline void rrot ( uint32_t & blob, int c ) { blob = ROTR32(blob,c); }
  162. template<> inline void rrot ( uint64_t & blob, int c ) { blob = ROTR64(blob,c); }
  163. //-----------------------------------------------------------------------------
  164. // Bit-windowing functions - select some N-bit subset of the input blob
  165. uint32_t window1 ( void * blob, int len, int start, int count );
  166. uint32_t window8 ( void * blob, int len, int start, int count );
  167. uint32_t window32 ( void * blob, int len, int start, int count );
  168. inline uint32_t window ( void * blob, int len, int start, int count )
  169. {
  170. if(len & 3)
  171. {
  172. return window8(blob,len,start,count);
  173. }
  174. else
  175. {
  176. return window32(blob,len,start,count);
  177. }
  178. }
  179. template < typename T >
  180. inline uint32_t window ( T & blob, int start, int count )
  181. {
  182. if((sizeof(T) & 3) == 0)
  183. {
  184. return window32(&blob,sizeof(T),start,count);
  185. }
  186. else
  187. {
  188. return window8(&blob,sizeof(T),start,count);
  189. }
  190. }
  191. template<>
  192. inline uint32_t window ( uint32_t & blob, int start, int count )
  193. {
  194. return ROTR32(blob,start) & ((1<<count)-1);
  195. }
  196. template<>
  197. inline uint32_t window ( uint64_t & blob, int start, int count )
  198. {
  199. return (uint32_t)ROTR64(blob,start) & ((1<<count)-1);
  200. }
  201. //-----------------------------------------------------------------------------