mirror of https://github.com/AxioDL/zeus.git
Proper SFINAE usage on PopCount
This commit is contained in:
parent
eb2968304b
commit
286d098ecb
|
@ -94,21 +94,28 @@ float fastSinF(float val);
|
||||||
int floorPowerOfTwo(int x);
|
int floorPowerOfTwo(int x);
|
||||||
int ceilingPowerOfTwo(int x);
|
int ceilingPowerOfTwo(int x);
|
||||||
|
|
||||||
template <class T>
|
template <typename U>
|
||||||
inline int PopCount(T x)
|
typename std::enable_if<!std::is_enum<U>::value && std::is_integral<U>::value, int>::type
|
||||||
|
PopCount(U x)
|
||||||
{
|
{
|
||||||
using U = std::make_unsigned_t<std::conditional_t<std::is_enum<T>::value, std::underlying_type_t<T>, T>>;
|
|
||||||
U cx = U(x);
|
|
||||||
const U m1 = U(0x5555555555555555); //binary: 0101...
|
const U m1 = U(0x5555555555555555); //binary: 0101...
|
||||||
const U m2 = U(0x3333333333333333); //binary: 00110011..
|
const U m2 = U(0x3333333333333333); //binary: 00110011..
|
||||||
const U m4 = U(0x0f0f0f0f0f0f0f0f); //binary: 4 zeros, 4 ones ...
|
const U m4 = U(0x0f0f0f0f0f0f0f0f); //binary: 4 zeros, 4 ones ...
|
||||||
const U h01 = U(0x0101010101010101); //the sum of 256 to the power of 0,1,2,3...
|
const U h01 = U(0x0101010101010101); //the sum of 256 to the power of 0,1,2,3...
|
||||||
|
|
||||||
cx -= (cx >> 1) & m1; //put count of each 2 bits into those 2 bits
|
x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
|
||||||
cx = (cx & m2) + ((cx >> 2) & m2); //put count of each 4 bits into those 4 bits
|
x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
|
||||||
cx = (cx + (cx >> 4)) & m4; //put count of each 8 bits into those 8 bits
|
x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
|
||||||
return (cx * h01) >> ((sizeof(U)-1)*8); //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
|
return (x * h01) >> ((sizeof(U)-1)*8); //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename E>
|
||||||
|
typename std::enable_if<std::is_enum<E>::value, int>::type
|
||||||
|
PopCount(E e)
|
||||||
|
{
|
||||||
|
return PopCount(static_cast<typename std::underlying_type<E>::type>(e));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MATH_HPP
|
#endif // MATH_HPP
|
||||||
|
|
Loading…
Reference in New Issue