return -(-x & -align);
}
-// count trailing zeros.
-// NOTE: the builtin is nondeterministic on 0 input
-template<class T>
- inline typename std::enable_if<
- (std::is_integral<T>::value &&
- sizeof(T) <= sizeof(unsigned)),
- unsigned>::type ctz(T v) {
- if (v == 0)
- return sizeof(v) * 8;
- return __builtin_ctz(v);
-}
-
-template<class T>
- inline typename std::enable_if<
- (std::is_integral<T>::value &&
- sizeof(T) > sizeof(unsigned int) &&
- sizeof(T) <= sizeof(unsigned long)),
- unsigned>::type ctz(T v) {
- if (v == 0)
- return sizeof(v) * 8;
- return __builtin_ctzl(v);
-}
-
-template<class T>
- inline typename std::enable_if<
- (std::is_integral<T>::value &&
- sizeof(T) > sizeof(unsigned long) &&
- sizeof(T) <= sizeof(unsigned long long)),
- unsigned>::type ctz(T v) {
- if (v == 0)
- return sizeof(v) * 8;
- return __builtin_ctzll(v);
-}
-
// count bits (set + any 0's that follow)
template<std::integral T>
unsigned cbits(T v) {
ASSERT_EQ(64u, cbits(0xffffffffffffffff));
}
-TEST(intarith, ctz) {
- ASSERT_EQ(32u, ctz(0));
- ASSERT_EQ(0u, ctz(1));
- ASSERT_EQ(1u, ctz(2));
- ASSERT_EQ(0u, ctz(3));
- ASSERT_EQ(2u, ctz(4));
- ASSERT_EQ(64u, ctz(UINT64_C(0)));
- ASSERT_EQ(0u, ctz(UINT64_C(1)));
- ASSERT_EQ(1u, ctz(UINT64_C(2)));
- ASSERT_EQ(0u, ctz(UINT64_C(3)));
- ASSERT_EQ(2u, ctz(UINT64_C(4)));
- ASSERT_EQ(8u, ctz(0x100));
- ASSERT_EQ(8u, ctz(UINT64_C(0x100)));
- ASSERT_EQ(0u, ctz(0xffffffff));
- ASSERT_EQ(0u, ctz(UINT32_C(0xffffffff)));
- ASSERT_EQ(0u, ctz(UINT64_C(0xffffffff)));
- ASSERT_EQ(20u, ctz(UINT64_C(0xffffffff00000)));
- ASSERT_EQ(48u, ctz(UINT64_C(0xff000000000000)));
-}
-
TEST(intarith, p2family) {
ASSERT_EQ(1024, p2align(1200, 1024));
ASSERT_EQ(1024, p2align(1024, 1024));