constexpr_log2
authorYedidya Feldblum <yfeldblum@fb.com>
Wed, 30 Aug 2017 18:39:43 +0000 (11:39 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 30 Aug 2017 18:54:45 +0000 (11:54 -0700)
Summary:
[Folly] `constexpr_log2`.

Useful for anything that needs to compute log2 at compile time.

Reviewed By: eduardo-elizondo

Differential Revision: D5734727

fbshipit-source-id: 8eab7991eea2104570eecd8e84ede6160bb0b549

folly/portability/Constexpr.h
folly/portability/test/ConstexprTest.cpp

index 0b5c5a1a59b80ad7bcd9be3342e5bd885add6fbe..a7620918bf5519eed75eeb0c56407f3c46516018 100644 (file)
@@ -81,6 +81,11 @@ constexpr auto constexpr_abs(T t)
   return detail::constexpr_abs_helper<T>::go(t);
 }
 
+template <typename T>
+constexpr T constexpr_log2(T t) {
+  return t == T(1) ? T(0) : T(1) + constexpr_log2(t / T(2));
+}
+
 namespace detail {
 
 template <typename Char>
index bb4b8beeeb5108ec37999220ba97660d7d65a3df..d2f6dbe3a17390865d773b2b7535fd330a02dcb3 100644 (file)
@@ -71,3 +71,24 @@ TEST_F(ConstexprTest, constexpr_abs_double_negative) {
   EXPECT_EQ(17.5, a);
   EXPECT_TRUE((std::is_same<const double, decltype(a)>::value));
 }
+
+TEST_F(ConstexprTest, constexpr_log2_1) {
+  constexpr auto v = 1ull;
+  constexpr auto a = folly::constexpr_log2(v);
+  EXPECT_EQ(0ull, a);
+  EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}
+
+TEST_F(ConstexprTest, constexpr_log2_2) {
+  constexpr auto v = 2ull;
+  constexpr auto a = folly::constexpr_log2(v);
+  EXPECT_EQ(1ull, a);
+  EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}
+
+TEST_F(ConstexprTest, constexpr_log2_64) {
+  constexpr auto v = 64ull;
+  constexpr auto a = folly::constexpr_log2(v);
+  EXPECT_EQ(6ull, a);
+  EXPECT_TRUE((std::is_same<decltype(v), decltype(a)>::value));
+}