2014-12-15 21:04:08 +00:00
|
|
|
// This file is under the public domain.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include "CommonTypes.h"
|
|
|
|
|
|
|
|
// Helper functions:
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <intrin.h>
|
|
|
|
template <typename T>
|
2017-01-26 18:34:21 +00:00
|
|
|
inline int CountSetBits(T v) {
|
2014-12-15 21:04:08 +00:00
|
|
|
// from https://graphics.stanford.edu/~seander/bithacks.html
|
|
|
|
// GCC has this built in, but MSVC's intrinsic will only emit the actual
|
|
|
|
// POPCNT instruction, which we're not depending on
|
|
|
|
v = v - ((v >> 1) & (T)~(T)0/3);
|
|
|
|
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);
|
|
|
|
v = (v + (v >> 4)) & (T)~(T)0/255*15;
|
|
|
|
return (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8;
|
|
|
|
}
|
2017-01-26 18:34:21 +00:00
|
|
|
inline int LeastSignificantSetBit(u32 val)
|
2014-12-15 21:04:08 +00:00
|
|
|
{
|
|
|
|
unsigned long index;
|
|
|
|
_BitScanForward(&index, val);
|
|
|
|
return (int)index;
|
|
|
|
}
|
|
|
|
#ifdef _M_X64
|
2017-01-26 18:34:21 +00:00
|
|
|
inline int LeastSignificantSetBit(u64 val)
|
2014-12-15 21:04:08 +00:00
|
|
|
{
|
|
|
|
unsigned long index;
|
|
|
|
_BitScanForward64(&index, val);
|
|
|
|
return (int)index;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#else
|
2017-01-26 18:34:21 +00:00
|
|
|
inline int CountSetBits(u32 val) { return __builtin_popcount(val); }
|
|
|
|
inline int CountSetBits(u64 val) { return __builtin_popcountll(val); }
|
|
|
|
inline int LeastSignificantSetBit(u32 val) { return __builtin_ctz(val); }
|
|
|
|
inline int LeastSignificantSetBit(u64 val) { return __builtin_ctzll(val); }
|
2014-12-15 21:04:08 +00:00
|
|
|
#endif
|