[libcxx-commits] [libcxx] 004ebe2 - [libc++] Add missing templated version of `std::lerp`.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 7 06:56:00 PST 2022


Author: Arthur O'Dwyer
Date: 2022-01-07T09:55:33-05:00
New Revision: 004ebe22f857aedb1cceb3097db95bdab28d3fba

URL: https://github.com/llvm/llvm-project/commit/004ebe22f857aedb1cceb3097db95bdab28d3fba
DIFF: https://github.com/llvm/llvm-project/commit/004ebe22f857aedb1cceb3097db95bdab28d3fba.diff

LOG: [libc++] Add missing templated version of `std::lerp`.

Fixes #50806.

Differential Revision: https://reviews.llvm.org/D116295

Added: 
    libcxx/test/std/numerics/c.math/lerp.pass.cpp

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

Removed: 
    libcxx/test/std/numerics/c.math/c.math.lerp/c.math.lerp.pass.cpp


################################################################################
diff  --git a/libcxx/include/cmath b/libcxx/include/cmath
index b5c332c81ad6b..d8fb0c0d759a0 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -636,6 +636,23 @@ lerp(double __a, double __b, double __t)                _NOEXCEPT { return __ler
 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
+constexpr 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(!(_IsSame<_A1, __result_type>::value &&
+                    _IsSame<_A2, __result_type>::value &&
+                    _IsSame<_A3, __result_type>::value));
+    return __lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
+}
 #endif // _LIBCPP_STD_VER > 17
 
 _LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/test/std/numerics/c.math/cmath.pass.cpp b/libcxx/test/std/numerics/c.math/cmath.pass.cpp
index 3d739f52ec75e..10c06fa28d704 100644
--- a/libcxx/test/std/numerics/c.math/cmath.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/cmath.pass.cpp
@@ -82,6 +82,7 @@ Ambiguous fmin(Ambiguous, Ambiguous){ return Ambiguous(); }
 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(); }
@@ -110,43 +111,37 @@ std::false_type has_abs_imp(...);
 template <class T>
 struct has_abs : decltype(has_abs_imp<T>(0)) {};
 
-void test_abs() {
+void test_abs()
+{
+    // See also "abs.pass.cpp"
+
 #ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wabsolute-value"
 #endif
-  static_assert((std::is_same<decltype(std::abs((float)0)), float>::value), "");
-  static_assert((std::is_same<decltype(std::abs((double)0)), double>::value), "");
-  static_assert(
-      (std::is_same<decltype(std::abs((long double)0)), long double>::value), "");
-  static_assert((std::is_same<decltype(std::abs((int)0)), int>::value), "");
-  static_assert((std::is_same<decltype(std::abs((long)0)), long>::value), "");
-  static_assert((std::is_same<decltype(std::abs((long long)0)), long long>::value),
-                "");
-  static_assert((std::is_same<decltype(std::abs((unsigned char)0)), int>::value),
-                "");
-  static_assert((std::is_same<decltype(std::abs((unsigned short)0)), int>::value),
-                "");
-  static_assert((std::is_same<decltype(std::abs((signed char)0)), int>::value),
-                "");
-  static_assert((std::is_same<decltype(std::abs((short)0)), int>::value),
-                "");
-  static_assert((std::is_same<decltype(std::abs((unsigned char)0)), int>::value),
-                "");
-  static_assert((std::is_same<decltype(std::abs((char)0)), int>::value),
-                "");
-  static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value), "");
-
-  static_assert(!has_abs<unsigned>::value, "");
-  static_assert(!has_abs<unsigned long>::value, "");
-  static_assert(!has_abs<unsigned long long>::value, "");
-  static_assert(!has_abs<size_t>::value, "");
-
+    static_assert((std::is_same<decltype(std::abs((float)0)), float>::value), "");
+    static_assert((std::is_same<decltype(std::abs((double)0)), double>::value), "");
+    static_assert((std::is_same<decltype(std::abs((long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(std::abs((int)0)), int>::value), "");
+    static_assert((std::is_same<decltype(std::abs((long)0)), long>::value), "");
+    static_assert((std::is_same<decltype(std::abs((long long)0)), long long>::value), "");
+    static_assert((std::is_same<decltype(std::abs((unsigned char)0)), int>::value), "");
+    static_assert((std::is_same<decltype(std::abs((unsigned short)0)), int>::value), "");
+    static_assert((std::is_same<decltype(std::abs((signed char)0)), int>::value), "");
+    static_assert((std::is_same<decltype(std::abs((short)0)), int>::value), "");
+    static_assert((std::is_same<decltype(std::abs((unsigned char)0)), int>::value), "");
+    static_assert((std::is_same<decltype(std::abs((char)0)), int>::value), "");
+    static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value), "");
+
+    static_assert(!has_abs<unsigned>::value, "");
+    static_assert(!has_abs<unsigned long>::value, "");
+    static_assert(!has_abs<unsigned long long>::value, "");
+    static_assert(!has_abs<size_t>::value, "");
 #ifdef __clang__
 #pragma clang diagnostic pop
 #endif
 
-  assert(std::abs(-1.) == 1);
+    assert(std::abs(-1.) == 1);
 }
 
 
@@ -1173,6 +1168,36 @@ void test_ilogb()
     assert(std::ilogb(1) == 0);
 }
 
+void test_lerp()
+{
+    // See also "lerp.pass.cpp"
+
+#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);
+    static_assert(std::lerp(2, 3, 1) == 3);
+    static_assert(std::lerp(1, 3, 0.5) == 2);
+    static_assert(std::lerp(0, 4.0, 0) == 0);
+#endif
+}
+
 void test_lgamma()
 {
     static_assert((std::is_same<decltype(std::lgamma((float)0)), float>::value), "");
@@ -1606,6 +1631,7 @@ int main(int, char**)
     test_fmin();
     test_hypot();
     test_ilogb();
+    test_lerp();
     test_lgamma();
     test_llrint();
     test_llround();

diff  --git a/libcxx/test/std/numerics/c.math/c.math.lerp/c.math.lerp.pass.cpp b/libcxx/test/std/numerics/c.math/lerp.pass.cpp
similarity index 100%
rename from libcxx/test/std/numerics/c.math/c.math.lerp/c.math.lerp.pass.cpp
rename to libcxx/test/std/numerics/c.math/lerp.pass.cpp


        


More information about the libcxx-commits mailing list