constexpr T constexpr_log2(T a, T e) {
return e == T(1) ? a : constexpr_log2(a + T(1), e / T(2));
}
+
+template <typename T>
+constexpr T constexpr_log2_ceil(T l2, T t) {
+ return l2 + T(T(1) << l2 < t ? 1 : 0);
+}
} // namespace detail
template <typename T>
return detail::constexpr_log2(T(0), t);
}
+template <typename T>
+constexpr T constexpr_log2_ceil(T t) {
+ return detail::constexpr_log2_ceil(constexpr_log2(t), t);
+}
+
template <typename T>
constexpr T constexpr_ceil(T t, T round) {
return round == T(0)
EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
}
+TEST_F(ConstexprMathTest, constexpr_log2_ceil_1) {
+ constexpr auto v = 1ull;
+ constexpr auto a = folly::constexpr_log2_ceil(v);
+ EXPECT_EQ(0ull, a);
+ EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}
+
+TEST_F(ConstexprMathTest, constexpr_log2_ceil_2) {
+ constexpr auto v = 2ull;
+ constexpr auto a = folly::constexpr_log2_ceil(v);
+ EXPECT_EQ(1ull, a);
+ EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}
+
+TEST_F(ConstexprMathTest, constexpr_log2_ceil_3) {
+ constexpr auto v = 3ull;
+ constexpr auto a = folly::constexpr_log2_ceil(v);
+ EXPECT_EQ(2ull, a);
+ EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}
+
+TEST_F(ConstexprMathTest, constexpr_log2_ceil_63) {
+ constexpr auto v = 63ull;
+ constexpr auto a = folly::constexpr_log2_ceil(v);
+ EXPECT_EQ(6ull, a);
+ EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}
+
+TEST_F(ConstexprMathTest, constexpr_log2_ceil_64) {
+ constexpr auto v = 64ull;
+ constexpr auto a = folly::constexpr_log2_ceil(v);
+ EXPECT_EQ(6ull, a);
+ EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}
+
TEST_F(ConstexprMathTest, constexpr_ceil) {
{
constexpr auto roundable = 20ull;