constexpr_clamp
authorYedidya Feldblum <yfeldblum@fb.com>
Sat, 4 Nov 2017 22:34:00 +0000 (15:34 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sat, 4 Nov 2017 22:35:38 +0000 (15:35 -0700)
Summary:
[Folly] `constexpr_clamp`.

Like `std::clamp` (C++17).

Reviewed By: Orvid

Differential Revision: D6236825

fbshipit-source-id: 0f6c5dc9a955b148021ee6ed3e86201b53ae090c

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

index 150acca33ee73119bbefe64d97dbb9cc9a85285a..7e14195c5009eabda1b0c9dc8fe2c878c5f5b79d 100644 (file)
@@ -44,6 +44,22 @@ constexpr T constexpr_min(T a, T b, Ts... ts) {
   return b < a ? constexpr_min(b, ts...) : constexpr_min(a, ts...);
 }
 
+template <typename T, typename Less>
+constexpr T const&
+constexpr_clamp(T const& v, T const& lo, T const& hi, Less less) {
+  return less(v, lo) ? lo : less(hi, v) ? hi : v;
+}
+
+template <typename T>
+constexpr T const& constexpr_clamp(T const& v, T const& lo, T const& hi) {
+  struct Less {
+    constexpr bool operator()(T const& a, T const& b) const {
+      return a < b;
+    }
+  };
+  return constexpr_clamp(v, lo, hi, Less{});
+}
+
 namespace detail {
 
 template <typename T, typename = void>
index 6c0c71f9c9a2f277b22dcc6a6853b81cf6684c00..1d732b7ac9078263386935256615d3035c127bae 100644 (file)
@@ -41,6 +41,18 @@ TEST_F(ConstexprMathTest, constexpr_max) {
   EXPECT_TRUE((std::is_same<const uint16_t, decltype(a)>::value));
 }
 
+TEST_F(ConstexprMathTest, constexpr_clamp) {
+  constexpr auto lo = uint16_t(3);
+  constexpr auto hi = uint16_t(7);
+  constexpr auto x = folly::constexpr_clamp(uint16_t(2), lo, hi);
+  constexpr auto y = folly::constexpr_clamp(uint16_t(5), lo, hi);
+  constexpr auto z = folly::constexpr_clamp(uint16_t(8), lo, hi);
+  EXPECT_EQ(3, x);
+  EXPECT_EQ(5, y);
+  EXPECT_EQ(7, z);
+  EXPECT_TRUE((std::is_same<const uint16_t, decltype(y)>::value));
+}
+
 TEST_F(ConstexprMathTest, constexpr_abs_unsigned) {
   constexpr auto v = uint32_t(17);
   constexpr auto a = folly::constexpr_abs(v);