BitOperations.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #ifndef CHESSY_BITOPERATIONS_H
  2. #define CHESSY_BITOPERATIONS_H
  3. #include <cinttypes>
  4. #ifdef _MSC_VER
  5. #include <intrin.h>
  6. #include <stdlib.h>
  7. #endif
  8. namespace chessy
  9. {
  10. using U64 = uint64_t;
  11. using U32 = uint32_t;
  12. using U16 = uint16_t;
  13. using U8 = uint8_t;
  14. /*!
  15. * reverses the byte order of a 64-bit integer
  16. */
  17. inline U64 byteswap(U64 x)
  18. {
  19. #if __GNUC__ > 4 && __GNUC_MINOR__ >= 3
  20. return __builtin_bswap64(x);
  21. #elif defined(_MSC_VER)
  22. return _byteswap_uint64(x);
  23. #else
  24. return (x << 56) |
  25. ((x & 0xFF00) << 40) |
  26. ((x & 0xFF0000) << 24) |
  27. ((x & 0xFF000000) << 8) |
  28. ((x & 0xFF00000000) >> 8) |
  29. ((x & 0xFF0000000000) >> 24) |
  30. ((x & 0xFF000000000000) >> 40) |
  31. (x >> 56);
  32. #endif
  33. }
  34. /*!
  35. * counts the trailing zeroes on a 64 bit integer
  36. */
  37. inline int trailingZeroes(U64 x) {
  38. #if __GNUC__ > 4 && 0
  39. return __builtin_ctzll(x)
  40. #elif defined(_MSC_VER)
  41. unsigned long out;
  42. if (_BitScanForward64(&out, x))
  43. return out;
  44. else
  45. return 0;
  46. #else
  47. for (int i = 0; i < 64; i++)
  48. if (x & (1ULL << i))
  49. return i;
  50. return 0;
  51. #endif
  52. }
  53. /*!
  54. * counts the leading zeroes on a 64 bit integer
  55. */
  56. inline int leadingZeroes(U64 x) {
  57. #if __GNUC__ > 4
  58. return __builtin_clzll(x);
  59. #elif defined(_MSC_VER) && defined(_M_X64)
  60. return __lzcnt64(x);
  61. #else
  62. for (int i = 0; i < 64; i++)
  63. if (x & (1ULL << (63 - i)))
  64. return i;
  65. return 0;
  66. #endif
  67. }
  68. inline int popcount(U64 x) {
  69. #if __GNUC__ > 4
  70. return __builtin_popcount(x);
  71. #elif defined(_MSC_VER) && defined(_M_X64)
  72. return _mm_popcnt_u64(x);
  73. #else
  74. int result = 0;
  75. for (int i = 0; i < 64; i++)
  76. if (x & (1ULL << i))
  77. result++;
  78. return result;
  79. #endif
  80. }
  81. }
  82. #endif // CHESSY_BITOPERATIONS_H