[libcxx-commits] [PATCH] D116295: [libc++] Add missing templated version of `std::lerp`

Arthur O'Dwyer via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sun Dec 26 19:20:05 PST 2021


Quuxplusone created this revision.
Quuxplusone added reviewers: libc++, mclow.lists, ldionne, Mordante.
Quuxplusone added a project: libc++.
Quuxplusone requested review of this revision.
Herald added a subscriber: libcxx-commits.
Herald added 1 blocking reviewer(s): libc++.

Fixes https://github.com/llvm/llvm-project/issues/50806

The new implementation and new tests are both copy-pasted from `hypot(a,b,c)`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116295

Files:
  libcxx/include/cmath
  libcxx/test/std/numerics/c.math/cmath.pass.cpp


Index: libcxx/test/std/numerics/c.math/cmath.pass.cpp
===================================================================
--- libcxx/test/std/numerics/c.math/cmath.pass.cpp
+++ libcxx/test/std/numerics/c.math/cmath.pass.cpp
@@ -82,6 +82,7 @@
 Ambiguous hypot(Ambiguous, Ambiguous){ return Ambiguous(); }
 Ambiguous hypot(Ambiguous, Ambiguous, Ambiguous){ return Ambiguous(); }
 Ambiguous ilogb(Ambiguous){ return Ambiguous(); }
+Ambiguous lerp(Ambiguous, Ambiguous, Ambiguous){ return Ambiguous(); }
 Ambiguous lgamma(Ambiguous){ return Ambiguous(); }
 Ambiguous llrint(Ambiguous){ return Ambiguous(); }
 Ambiguous llround(Ambiguous){ return Ambiguous(); }
@@ -1137,7 +1138,6 @@
     static_assert((std::is_same<decltype(std::hypot((float)0, (bool)0, (float)0)), double>::value), "");
     static_assert((std::is_same<decltype(std::hypot((float)0, (unsigned short)0, (double)0)), double>::value), "");
     static_assert((std::is_same<decltype(std::hypot((float)0, (int)0, (long double)0)), long double>::value), "");
-    static_assert((std::is_same<decltype(std::hypot((float)0, (unsigned int)0)), double>::value), "");
     static_assert((std::is_same<decltype(std::hypot((float)0, (double)0, (long)0)), double>::value), "");
     static_assert((std::is_same<decltype(std::hypot((float)0, (long double)0, (unsigned long)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::hypot((float)0, (int)0, (long long)0)), double>::value), "");
@@ -1174,6 +1174,31 @@
     assert(std::ilogb(1) == 0);
 }
 
+void test_lerp()
+{
+#if TEST_STD_VER > 17
+    static_assert((std::is_same<decltype(std::lerp((float)0, (float)0, (float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (bool)0, (float)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (unsigned short)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (int)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (double)0, (long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (long double)0, (unsigned long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (int)0, (long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (int)0, (unsigned long long)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (double)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (long double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (float)0, (double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (float)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((float)0, (double)0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(std::lerp((int)0, (int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(lerp(Ambiguous(), Ambiguous(), Ambiguous())), Ambiguous>::value), "");
+
+    assert(std::lerp(2, 3, 1) == 3);
+    assert(std::lerp(1, 3, 0.5) == 2);
+    assert(std::lerp(0, 4.0, 0) == 0);
+#endif
+}
+
 void test_lgamma()
 {
     static_assert((std::is_same<decltype(std::lgamma((float)0)), float>::value), "");
@@ -1607,6 +1632,7 @@
     test_fmin();
     test_hypot();
     test_ilogb();
+    test_lerp();
     test_lgamma();
     test_llrint();
     test_llround();
Index: libcxx/include/cmath
===================================================================
--- libcxx/include/cmath
+++ libcxx/include/cmath
@@ -636,6 +636,23 @@
 constexpr long double
 lerp(long double __a, long double __b, long double __t) _NOEXCEPT { return __lerp(__a, __b, __t); }
 
+template <class _A1, class _A2, class _A3>
+inline _LIBCPP_HIDE_FROM_ABI
+typename enable_if_t
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value &&
+    is_arithmetic<_A3>::value,
+    __promote<_A1, _A2, _A3>
+>::type
+lerp(_A1 __a, _A2 __b, _A3 __t) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2, _A3>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                     is_same<_A2, __result_type>::value &&
+                     is_same<_A3, __result_type>::value)), "");
+    return __lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
+}
 #endif // _LIBCPP_STD_VER > 17
 
 _LIBCPP_END_NAMESPACE_STD


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D116295.396258.patch
Type: text/x-patch
Size: 4626 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211227/79b2a2ad/attachment.bin>


More information about the libcxx-commits mailing list