[libcxx-commits] [libcxx] [libc++] Move lerp to its own header instead of <cmath> (PR #213111)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jul 31 10:28:04 PDT 2026


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/213111

>From c1c216899752ce409b95258a9d74508f9514d304 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 30 Jul 2026 15:22:39 -0400
Subject: [PATCH] [libc++] Move lerp to its own header instead of <cmath>

This moves <cmath> towards an umbrella header.
---
 libcxx/include/CMakeLists.txt      |  1 +
 libcxx/include/__math/lerp.h       | 64 ++++++++++++++++++++++++++++++
 libcxx/include/cmath               | 41 +------------------
 libcxx/include/module.modulemap.in |  1 +
 4 files changed, 67 insertions(+), 40 deletions(-)
 create mode 100644 libcxx/include/__math/lerp.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 5034d5f6fe95b..f408294fd70e9 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -575,6 +575,7 @@ set(files
   __math/hypot.h
   __math/inverse_hyperbolic_functions.h
   __math/inverse_trigonometric_functions.h
+  __math/lerp.h
   __math/logarithms.h
   __math/min_max.h
   __math/modulo.h
diff --git a/libcxx/include/__math/lerp.h b/libcxx/include/__math/lerp.h
new file mode 100644
index 0000000000000..5973f263c3eb3
--- /dev/null
+++ b/libcxx/include/__math/lerp.h
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MATH_LERP_H
+#define _LIBCPP___MATH_LERP_H
+
+#include <__config>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/promote.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <typename _Fp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Fp __lerp(_Fp __a, _Fp __b, _Fp __t) noexcept {
+  if ((__a <= 0 && __b >= 0) || (__a >= 0 && __b <= 0))
+    return __t * __b + (1 - __t) * __a;
+
+  if (__t == 1)
+    return __b;
+  const _Fp __x = __a + __t * (__b - __a);
+  if ((__t > 1) == (__b > __a))
+    return __b < __x ? __x : __b;
+  else
+    return __x < __b ? __x : __b;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr float lerp(float __a, float __b, float __t) _NOEXCEPT {
+  return __lerp(__a, __b, __t);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr double lerp(double __a, double __b, double __t) _NOEXCEPT {
+  return __lerp(__a, __b, __t);
+}
+
+_LIBCPP_HIDE_FROM_ABI inline 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>
+  requires(is_arithmetic_v<_A1> && is_arithmetic_v<_A2> && is_arithmetic_v<_A3>)
+_LIBCPP_HIDE_FROM_ABI inline constexpr __promote_t<_A1, _A2, _A3> lerp(_A1 __a, _A2 __b, _A3 __t) noexcept {
+  using __result_type = __promote_t<_A1, _A2, _A3>;
+  static_assert(!(
+      _IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value && _IsSame<_A3, __result_type>::value));
+  return std::__lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___MATH_LERP_H
diff --git a/libcxx/include/cmath b/libcxx/include/cmath
index 27698a09fd75f..22402f0546a2e 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -318,15 +318,13 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
 #  include <__config>
 #  include <__math/hypot.h>
 #  include <__type_traits/enable_if.h>
-#  include <__type_traits/is_arithmetic.h>
 #  include <__type_traits/is_constant_evaluated.h>
 #  include <__type_traits/is_floating_point.h>
-#  include <__type_traits/is_same.h>
-#  include <__type_traits/promote.h>
 #  include <__type_traits/remove_cv.h>
 #  include <limits>
 #  include <version>
 
+#  include <__math/lerp.h>
 #  include <__math/special_functions.h>
 #  include <math.h>
 
@@ -571,43 +569,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __constexpr_isinf(_A1 __lcpp_x) _NO
   return std::isinf(__lcpp_x);
 }
 
-#  if _LIBCPP_STD_VER >= 20
-template <typename _Fp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Fp __lerp(_Fp __a, _Fp __b, _Fp __t) noexcept {
-  if ((__a <= 0 && __b >= 0) || (__a >= 0 && __b <= 0))
-    return __t * __b + (1 - __t) * __a;
-
-  if (__t == 1)
-    return __b;
-  const _Fp __x = __a + __t * (__b - __a);
-  if ((__t > 1) == (__b > __a))
-    return __b < __x ? __x : __b;
-  else
-    return __x < __b ? __x : __b;
-}
-
-_LIBCPP_HIDE_FROM_ABI inline constexpr float lerp(float __a, float __b, float __t) _NOEXCEPT {
-  return __lerp(__a, __b, __t);
-}
-
-_LIBCPP_HIDE_FROM_ABI inline constexpr double lerp(double __a, double __b, double __t) _NOEXCEPT {
-  return __lerp(__a, __b, __t);
-}
-
-_LIBCPP_HIDE_FROM_ABI inline 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>
-  requires(is_arithmetic_v<_A1> && is_arithmetic_v<_A2> && is_arithmetic_v<_A3>)
-_LIBCPP_HIDE_FROM_ABI inline constexpr __promote_t<_A1, _A2, _A3> lerp(_A1 __a, _A2 __b, _A3 __t) noexcept {
-  using __result_type = __promote_t<_A1, _A2, _A3>;
-  static_assert(!(
-      _IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value && _IsSame<_A3, __result_type>::value));
-  return std::__lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
-}
-#  endif // _LIBCPP_STD_VER >= 20
-
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 6b491e4e2589f..08624eafd3f23 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -59,6 +59,7 @@ module std_core {
     module hypot                            { header "__math/hypot.h" }
     module inverse_hyperbolic_functions     { header "__math/inverse_hyperbolic_functions.h" }
     module inverse_trigonometric_functions  { header "__math/inverse_trigonometric_functions.h" }
+    module lerp                             { header "__math/lerp.h" }
     module logarithms                       { header "__math/logarithms.h" }
     module min_max                          { header "__math/min_max.h" }
     module modulo                           { header "__math/modulo.h" }



More information about the libcxx-commits mailing list