Commit 2180558b authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook Github Bot

Implement extractFirstSet

Summary: This can be useful to iterate bitmasks that are ORs of power-of-2 enum flags.

Reviewed By: yfeldblum

Differential Revision: D15245333

fbshipit-source-id: 661e0bdbe4468b693e37fda12e513202a3b3ed17
parent 42925695
......@@ -26,6 +26,10 @@
* 1-based. 0 = no bits are set (x == 0)
* for x != 0, findLastSet(x) == 1 + floor(log2(x))
*
* extractFirstSet(x) [constexpr]
* extract first (least significant) bit set in a value of an integral
* type, 0 = no bits are set (x == 0)
*
* nextPowTwo(x) [constexpr]
* Finds the next power of two >= x.
*
......@@ -146,6 +150,18 @@ inline constexpr unsigned int findLastSet(T const v) {
// clang-format on
}
/// extractFirstSet
///
/// Return a value where all the bits but the least significant are cleared.
template <typename T>
inline constexpr T extractFirstSet(T const v) {
static_assert(std::is_integral<T>::value, "non-integral type");
static_assert(std::is_unsigned<T>::value, "signed type");
static_assert(!std::is_same<T, bool>::value, "bool type");
return v & -v;
}
/// popcount
///
/// Returns the number of bits which are set.
......
......@@ -65,6 +65,17 @@ void testFLS() {
}
}
template <class UINT>
void testEFS() {
EXPECT_EQ(0, extractFirstSet(static_cast<UINT>(0)));
size_t bits = std::numeric_limits<UINT>::digits;
for (size_t i = 0; i < bits; i++) {
UINT lsb = static_cast<UINT>(1) << i;
UINT v = (static_cast<UINT>(1) << (bits - 1)) | lsb;
EXPECT_EQ(lsb, extractFirstSet(v));
}
}
} // namespace
TEST(Bits, FindFirstSet) {
......@@ -95,6 +106,14 @@ TEST(Bits, FindLastSet) {
testFLS<unsigned long long>();
}
TEST(Bits, ExtractFirstSet) {
testEFS<unsigned char>();
testEFS<unsigned short>();
testEFS<unsigned int>();
testEFS<unsigned long>();
testEFS<unsigned long long>();
}
TEST(Bits, nextPowTwoClz) {
EXPECT_EQ(1, nextPowTwo(0u));
EXPECT_EQ(1, nextPowTwo(1u));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment