Commit cb47018e authored by Mohamad Gebai's avatar Mohamad Gebai Committed by Facebook GitHub Bot

Add strict versions of prevPowTwo() and nextPowTwo()

Summary: Returns the previous/next power of two that are strictly smaller/greater than the parameter.

Reviewed By: yfeldblum, Gownta

Differential Revision: D21920224

fbshipit-source-id: be919063379e5b231cc69d743128fcaeb0ea9f39
parent c94ebed8
......@@ -33,6 +33,9 @@
* nextPowTwo(x) [constexpr]
* Finds the next power of two >= x.
*
* strictNextPowTwo(x) [constexpr]
* Finds the next power of two > x.
*
* isPowTwo(x) [constexpr]
* return true iff x is a power of two
*
......@@ -208,6 +211,18 @@ inline constexpr bool isPowTwo(T const v) {
return (v != 0) && !(v & (v - 1));
}
template <class T>
inline constexpr T strictNextPowTwo(T const v) {
static_assert(std::is_unsigned<T>::value, "signed type");
return nextPowTwo(T(v + 1));
}
template <class T>
inline constexpr T strictPrevPowTwo(T const v) {
static_assert(std::is_unsigned<T>::value, "signed type");
return v > 1 ? prevPowTwo(T(v - 1)) : T(0);
}
/**
* Endianness detection and manipulation primitives.
*/
......
......@@ -137,6 +137,29 @@ TEST(Bits, nextPowTwoClz) {
EXPECT_EQ(1ull << 63, nextPowTwo((1ull << 62) + 1));
}
TEST(Bits, strictNextPowTwoClz) {
EXPECT_EQ(1, strictNextPowTwo(0u));
EXPECT_EQ(2, strictNextPowTwo(1u));
EXPECT_EQ(4, strictNextPowTwo(2u));
EXPECT_EQ(4, strictNextPowTwo(3u));
EXPECT_EQ(8, strictNextPowTwo(4u));
EXPECT_EQ(8, strictNextPowTwo(5u));
EXPECT_EQ(8, strictNextPowTwo(6u));
EXPECT_EQ(8, strictNextPowTwo(7u));
EXPECT_EQ(16, strictNextPowTwo(8u));
EXPECT_EQ(16, strictNextPowTwo(9u));
EXPECT_EQ(16, strictNextPowTwo(13u));
EXPECT_EQ(32, strictNextPowTwo(16u));
EXPECT_EQ(512, strictNextPowTwo(510u));
EXPECT_EQ(512, strictNextPowTwo(511u));
EXPECT_EQ(1024, strictNextPowTwo(512u));
EXPECT_EQ(1024, strictNextPowTwo(513u));
EXPECT_EQ(1024, strictNextPowTwo(777u));
EXPECT_EQ(1ul << 31, strictNextPowTwo((1ul << 31) - 1));
EXPECT_EQ(1ull << 32, strictNextPowTwo((1ull << 32) - 1));
EXPECT_EQ(1ull << 63, strictNextPowTwo((1ull << 62) + 1));
}
TEST(Bits, prevPowTwoClz) {
EXPECT_EQ(0, prevPowTwo(0u));
EXPECT_EQ(1, prevPowTwo(1u));
......@@ -160,6 +183,29 @@ TEST(Bits, prevPowTwoClz) {
EXPECT_EQ(1ull << 62, prevPowTwo((1ull << 62) + 1));
}
TEST(Bits, strictPrevPowTwoClz) {
EXPECT_EQ(0, strictPrevPowTwo(0u));
EXPECT_EQ(0, strictPrevPowTwo(1u));
EXPECT_EQ(1, strictPrevPowTwo(2u));
EXPECT_EQ(2, strictPrevPowTwo(3u));
EXPECT_EQ(2, strictPrevPowTwo(4u));
EXPECT_EQ(4, strictPrevPowTwo(5u));
EXPECT_EQ(4, strictPrevPowTwo(6u));
EXPECT_EQ(4, strictPrevPowTwo(7u));
EXPECT_EQ(4, strictPrevPowTwo(8u));
EXPECT_EQ(8, strictPrevPowTwo(9u));
EXPECT_EQ(8, strictPrevPowTwo(13u));
EXPECT_EQ(8, strictPrevPowTwo(16u));
EXPECT_EQ(256, strictPrevPowTwo(510u));
EXPECT_EQ(256, strictPrevPowTwo(511u));
EXPECT_EQ(256, strictPrevPowTwo(512u));
EXPECT_EQ(512, strictPrevPowTwo(513u));
EXPECT_EQ(512, strictPrevPowTwo(777u));
EXPECT_EQ(1ul << 30, strictPrevPowTwo((1ul << 31) - 1));
EXPECT_EQ(1ull << 31, strictPrevPowTwo((1ull << 32) - 1));
EXPECT_EQ(1ull << 62, strictPrevPowTwo((1ull << 62) + 1));
}
TEST(Bits, isPowTwo) {
EXPECT_FALSE(isPowTwo(0u));
EXPECT_TRUE(isPowTwo(1ul));
......
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