1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #ifndef CHESSY_BITOPERATIONS_H
- #define CHESSY_BITOPERATIONS_H
- #include <cinttypes>
- #ifdef _MSC_VER
- #include <intrin.h>
- #include <stdlib.h>
- #endif
- namespace chessy
- {
- using U64 = uint64_t;
- using U32 = uint32_t;
- using U16 = uint16_t;
- using U8 = uint8_t;
- /*!
- * reverses the byte order of a 64-bit integer
- */
- inline U64 byteswap(U64 x)
- {
- #if __GNUC__ > 4 && __GNUC_MINOR__ >= 3
- return __builtin_bswap64(x);
- #elif defined(_MSC_VER)
- return _byteswap_uint64(x);
- #else
- return (x << 56) |
- ((x & 0xFF00) << 40) |
- ((x & 0xFF0000) << 24) |
- ((x & 0xFF000000) << 8) |
- ((x & 0xFF00000000) >> 8) |
- ((x & 0xFF0000000000) >> 24) |
- ((x & 0xFF000000000000) >> 40) |
- (x >> 56);
- #endif
- }
- /*!
- * counts the trailing zeroes on a 64 bit integer
- */
- inline int trailingZeroes(U64 x) {
- #if __GNUC__ > 4 && 0
- return __builtin_ctzll(x)
- #elif defined(_MSC_VER)
- unsigned long out;
- if (_BitScanForward64(&out, x))
- return out;
- else
- return 0;
- #else
- for (int i = 0; i < 64; i++)
- if (x & (1ULL << i))
- return i;
- return 0;
- #endif
- }
- /*!
- * counts the leading zeroes on a 64 bit integer
- */
- inline int leadingZeroes(U64 x) {
- #if __GNUC__ > 4
- return __builtin_clzll(x);
- #elif defined(_MSC_VER) && defined(_M_X64)
- return __lzcnt64(x);
- #else
- for (int i = 0; i < 64; i++)
- if (x & (1ULL << (63 - i)))
- return i;
- return 0;
- #endif
- }
- inline int popcount(U64 x) {
- #if __GNUC__ > 4
- return __builtin_popcount(x);
- #elif defined(_MSC_VER) && defined(_M_X64)
- return _mm_popcnt_u64(x);
- #else
- int result = 0;
- for (int i = 0; i < 64; i++)
- if (x & (1ULL << i))
- result++;
- return result;
- #endif
- }
- }
- #endif // CHESSY_BITOPERATIONS_H
|