#ifndef BITHACKS_H #define BITHACKS_H #ifdef _MSC_VER # include #endif namespace bithacks { typedef unsigned int uint32; typedef int int32; // floor to next power of 2 inline uint32 flp2(uint32 x) { x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return x - (x >> 1); } // ceil to next power of 2 inline uint32 clp2(uint32 x) { --x; x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return x + 1; } inline uint32 popcnt(uint32 x) { x -= ((x >> 1) & 0x55555555); x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); x = (((x >> 4) + x) & 0x0f0f0f0f); x += (x >> 8); x += (x >> 16); return x & 0x0000003f; } inline uint32 ctz(uint32 x) { #ifdef __GNUC__ return __builtin_ctz(x); #elif defined(_MSC_VER) && defined(_M_IX86) unsigned long r = 0; _BitScanForward(&r, x); return r; #else return popcnt((x & -x) - 1); #endif } inline unsigned int clz(uint32 x) { #ifdef __GNUC__ return __builtin_clz(x); #elif defined(_MSC_VER) && defined(_M_IX86) unsigned long r = 0; _BitScanReverse(&r, x); return r; #else x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return 32 - popcnt(x); #endif } } // end namespace bithacks #endif