#ifndef CHESSY_BITOPERATIONS_H #define CHESSY_BITOPERATIONS_H #include #ifdef _MSC_VER #include #include #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