constexpr_pow v2018.01.01.00
authorYedidya Feldblum <yfeldblum@fb.com>
Sun, 31 Dec 2017 00:08:32 +0000 (16:08 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sun, 31 Dec 2017 00:25:31 +0000 (16:25 -0800)
Summary:
[Folly] `constexpr_pow`.

The power function. Initially, supports nonnegative integers only.

Reviewed By: spalamarchuk

Differential Revision: D6646376

fbshipit-source-id: 33a5a45f496b6f3be52d0cd7e3a5f2cd7edb3026

folly/ConstexprMath.h
folly/test/ConstexprMathTest.cpp

index a15f098c5421b3d13168529ab1f7822276185b58..871b19433d6cc6f0ab89386b3f7f6cb5a65abec5 100644 (file)
@@ -113,6 +113,11 @@ template <typename T>
 constexpr T constexpr_log2_ceil_(T l2, T t) {
   return l2 + T(T(1) << l2 < t ? 1 : 0);
 }
+
+template <typename T>
+constexpr T constexpr_square_(T t) {
+  return t * t;
+}
 } // namespace detail
 
 template <typename T>
@@ -132,4 +137,13 @@ constexpr T constexpr_ceil(T t, T round) {
       : ((t + (t < T(0) ? T(0) : round - T(1))) / round) * round;
 }
 
+template <typename T>
+constexpr T constexpr_pow(T base, std::size_t exp) {
+  return exp == 0
+      ? T(1)
+      : exp == 1 ? base
+                 : detail::constexpr_square_(constexpr_pow(base, exp / 2)) *
+              (exp % 2 ? base : T(1));
+}
+
 } // namespace folly
index a0f9b102331c7fa2ccb31d0debb71f0b1d999f20..fb5956e22e04d4f2fd2dce8f49e1c2e4d7ac9e63 100644 (file)
@@ -178,3 +178,18 @@ TEST_F(ConstexprMathTest, constexpr_ceil) {
     EXPECT_EQ(-20ll, rounded);
   }
 }
+
+TEST_F(ConstexprMathTest, constexpr_pow) {
+  {
+    constexpr auto a = folly::constexpr_pow(uint64_t(0), 15);
+    EXPECT_EQ(0, a);
+  }
+  {
+    constexpr auto a = folly::constexpr_pow(uint64_t(15), 0);
+    EXPECT_EQ(1, a);
+  }
+  {
+    constexpr auto a = folly::constexpr_pow(uint64_t(2), 6);
+    EXPECT_EQ(64, a);
+  }
+}