return countTrailingZeros(Val, ZB_Undefined);
}
+/// \brief Create a bitmask with the N right-most bits set to 1, and all other
+/// bits set to 0. Only unsigned types are allowed.
+template <typename T> T maskTrailingOnes(unsigned N) {
+ static_assert(std::is_unsigned<T>::value, "Invalid type!");
+ const unsigned Bits = CHAR_BIT * sizeof(T);
+ assert(N <= Bits && "Invalid bit index");
+ return -T(N != 0) & (T(-1) >> (Bits - N));
+}
+
+/// \brief Create a bitmask with the N left-most bits set to 1, and all other
+/// bits set to 0. Only unsigned types are allowed.
+template <typename T> T maskLeadingOnes(unsigned N) {
+ return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
+}
+
/// \brief Get the index of the last set bit starting from the least
/// significant bit.
///
}
}
+TEST(MathExtras, onesMask) {
+ EXPECT_EQ(0U, maskLeadingOnes<uint8_t>(0));
+ EXPECT_EQ(0U, maskTrailingOnes<uint8_t>(0));
+ EXPECT_EQ(0U, maskLeadingOnes<uint16_t>(0));
+ EXPECT_EQ(0U, maskTrailingOnes<uint16_t>(0));
+ EXPECT_EQ(0U, maskLeadingOnes<uint32_t>(0));
+ EXPECT_EQ(0U, maskTrailingOnes<uint32_t>(0));
+ EXPECT_EQ(0U, maskLeadingOnes<uint64_t>(0));
+ EXPECT_EQ(0U, maskTrailingOnes<uint64_t>(0));
+
+ EXPECT_EQ(0x00000003U, maskTrailingOnes<uint32_t>(2U));
+ EXPECT_EQ(0xC0000000U, maskLeadingOnes<uint32_t>(2U));
+
+ EXPECT_EQ(0x000007FFU, maskTrailingOnes<uint32_t>(11U));
+ EXPECT_EQ(0xFFE00000U, maskLeadingOnes<uint32_t>(11U));
+
+ EXPECT_EQ(0xFFFFFFFFU, maskTrailingOnes<uint32_t>(32U));
+ EXPECT_EQ(0xFFFFFFFFU, maskLeadingOnes<uint32_t>(32U));
+}
+
TEST(MathExtras, findFirstSet) {
uint8_t Z8 = 0;
uint16_t Z16 = 0;