[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
Wed Aug 5 03:25:02 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 1/3] [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" }

>From 46fe2057474124dc0e77deb645e16d877f3d49ed Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Tue, 4 Aug 2026 09:28:34 -0400
Subject: [PATCH 2/3] Move to __cmath instead

---
 libcxx/include/CMakeLists.txt             | 2 +-
 libcxx/include/{__math => __cmath}/lerp.h | 6 +++---
 libcxx/include/cmath                      | 2 +-
 libcxx/include/complex                    | 1 +
 libcxx/include/module.modulemap.in        | 5 ++++-
 5 files changed, 10 insertions(+), 6 deletions(-)
 rename libcxx/include/{__math => __cmath}/lerp.h (95%)

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index f408294fd70e9..ba2716671ab2f 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -294,6 +294,7 @@ set(files
   __chrono/year_month_day.h
   __chrono/year_month_weekday.h
   __chrono/zoned_time.h
+  __cmath/lerp.h
   __compare/common_comparison_category.h
   __compare/compare_partial_order_fallback.h
   __compare/compare_strong_order_fallback.h
@@ -575,7 +576,6 @@ 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/__cmath/lerp.h
similarity index 95%
rename from libcxx/include/__math/lerp.h
rename to libcxx/include/__cmath/lerp.h
index 5973f263c3eb3..4cbbcc570fb83 100644
--- a/libcxx/include/__math/lerp.h
+++ b/libcxx/include/__cmath/lerp.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___MATH_LERP_H
-#define _LIBCPP___MATH_LERP_H
+#ifndef _LIBCPP___CMATH_LERP_H
+#define _LIBCPP___CMATH_LERP_H
 
 #include <__config>
 #include <__type_traits/is_arithmetic.h>
@@ -61,4 +61,4 @@ _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_STD_VER >= 20
 
-#endif // _LIBCPP___MATH_LERP_H
+#endif // _LIBCPP___CMATH_LERP_H
diff --git a/libcxx/include/cmath b/libcxx/include/cmath
index 4367e51eca5ed..8ef7e5d8eb27f 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -320,7 +320,7 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
 #  include <__type_traits/is_floating_point.h>
 #  include <version>
 
-#  include <__math/lerp.h>
+#  include <__cmath/lerp.h>
 #  include <__math/special_functions.h>
 #  include <math.h>
 
diff --git a/libcxx/include/complex b/libcxx/include/complex
index f1ba85eb9624e..b3c21fcf9397a 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -266,6 +266,7 @@ template<class T> complex<T> tanh (const complex<T>&);
 #  include <__tuple/tuple_element.h>
 #  include <__tuple/tuple_size.h>
 #  include <__type_traits/conditional.h>
+#  include <__type_traits/promote.h>
 #  include <__utility/move.h>
 #  include <cmath>
 #  include <version>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 08624eafd3f23..dfb4c8feeac6f 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -19,6 +19,10 @@ module std_config {
 }
 
 module std_core {
+  module cmath {
+    module lerp { header "__cmath/lerp.h" }
+  }
+
   module cstddef {
     module byte         { header "__cstddef/byte.h" }
     module max_align_t  {
@@ -59,7 +63,6 @@ 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" }

>From 77e07d2c5b72d0210331bd70f655acce9f5fbf90 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 5 Aug 2026 06:03:57 -0400
Subject: [PATCH 3/3] Update libcxx/include/complex

Co-authored-by: A. Jiang <de34 at live.cn>
---
 libcxx/include/complex | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libcxx/include/complex b/libcxx/include/complex
index 160df2f195c58..b407bb70156e3 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -266,6 +266,10 @@ template<class T> complex<T> tanh (const complex<T>&);
 #  include <__tuple/tuple_element.h>
 #  include <__tuple/tuple_size.h>
 #  include <__type_traits/conditional.h>
+#  include <__type_traits/is_arithmetic.h>
+#  include <__type_traits/is_floating_point.h>
+#  include <__type_traits/is_integral.h>
+#  include <__type_traits/is_same.h>
 #  include <__type_traits/promote.h>
 #  include <__utility/move.h>
 #  include <cmath>



More information about the libcxx-commits mailing list