[libcxx-commits] [libcxx] [libc++] Make all `__random/HEADER.h` depend on `<__math/FOO.h>` instead of `<cmath>` and use `__math::` namespace instead `std::` (PR #213084)

Hana Dusíková via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jul 31 04:59:27 PDT 2026


https://github.com/hanickadot updated https://github.com/llvm/llvm-project/pull/213084

>From bebce74a9bb5fc7c9c3140eca71153d07b240a2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= <hanicka at hanicka.net>
Date: Thu, 30 Jul 2026 22:45:38 +0200
Subject: [PATCH] [libc++] make all `__random/HEADER.h` depend on
 <__math/FOO.h> instead of <cmath> and use `__math::` namespace

---
 .../include/__random/binomial_distribution.h  |  9 +++---
 libcxx/include/__random/cauchy_distribution.h |  4 +--
 libcxx/include/__random/clamp_to_integral.h   | 15 +++++----
 .../__random/exponential_distribution.h       |  4 +--
 .../__random/extreme_value_distribution.h     |  4 +--
 libcxx/include/__random/gamma_distribution.h  | 15 +++++----
 .../include/__random/lognormal_distribution.h |  6 ++--
 libcxx/include/__random/normal_distribution.h |  5 +--
 .../__random/piecewise_linear_distribution.h  |  5 +--
 .../include/__random/poisson_distribution.h   | 31 +++++++++++--------
 .../include/__random/student_t_distribution.h |  4 +--
 .../include/__random/weibull_distribution.h   |  4 +--
 libcxx/include/random                         |  5 +++
 .../test/libcxx/transitive_includes/cxx26.csv |  1 -
 14 files changed, 65 insertions(+), 47 deletions(-)

diff --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h
index e4fe92143741a..abc9d7556f628 100644
--- a/libcxx/include/__random/binomial_distribution.h
+++ b/libcxx/include/__random/binomial_distribution.h
@@ -10,10 +10,11 @@
 #define _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/exponential_functions.h>
 #include <__math/gamma.h>
+#include <__math/logarithms.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
-#include <cmath>
 #include <iosfwd>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -102,9 +103,9 @@ template <class _IntType>
 binomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p) : __t_(__t), __p_(__p) {
   if (0 < __p_ && __p_ < 1) {
     __r0_ = static_cast<result_type>((__t_ + 1) * __p_);
-    __pr_ =
-        std::exp(__math::__lgamma_r(__t_ + 1.) - __math::__lgamma_r(__r0_ + 1.) -
-                 __math::__lgamma_r(__t_ - __r0_ + 1.) + __r0_ * std::log(__p_) + (__t_ - __r0_) * std::log(1 - __p_));
+    __pr_ = __math::exp(
+        __math::__lgamma_r(__t_ + 1.) - __math::__lgamma_r(__r0_ + 1.) - __math::__lgamma_r(__t_ - __r0_ + 1.) +
+        __r0_ * __math::log(__p_) + (__t_ - __r0_) * __math::log(1 - __p_));
     __odds_ratio_ = __p_ / (1 - __p_);
   }
 }
diff --git a/libcxx/include/__random/cauchy_distribution.h b/libcxx/include/__random/cauchy_distribution.h
index 65e83095c5445..ad88b5a2c5828 100644
--- a/libcxx/include/__random/cauchy_distribution.h
+++ b/libcxx/include/__random/cauchy_distribution.h
@@ -10,9 +10,9 @@
 #define _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/trigonometric_functions.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -100,7 +100,7 @@ inline _RealType cauchy_distribution<_RealType>::operator()(_URNG& __g, const pa
   static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
   uniform_real_distribution<result_type> __gen;
   // purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite
-  return __p.a() + __p.b() * std::tan(3.1415926535897932384626433832795 * __gen(__g));
+  return __p.a() + __p.b() * __math::tan(3.1415926535897932384626433832795 * __gen(__g));
 }
 
 template <class _CharT, class _Traits, class _RT>
diff --git a/libcxx/include/__random/clamp_to_integral.h b/libcxx/include/__random/clamp_to_integral.h
index 9ddf41e0a39a2..0990ad43a1249 100644
--- a/libcxx/include/__random/clamp_to_integral.h
+++ b/libcxx/include/__random/clamp_to_integral.h
@@ -10,7 +10,9 @@
 #define _LIBCPP___RANDOM_CLAMP_TO_INTEGRAL_H
 
 #include <__config>
-#include <cmath>
+#include <__math/rounding_functions.h>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_integral.h>
 #include <limits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -42,12 +44,13 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _IntT __max_representable_int_for_float(
 // The behavior is undefined if `__r` is NaN.
 template <class _IntT, class _RealT>
 _LIBCPP_HIDE_FROM_ABI _IntT __clamp_to_integral(_RealT __r) _NOEXCEPT {
-  using _Lim            = numeric_limits<_IntT>;
+  using _IntLim         = numeric_limits<_IntT>;
+  using _RealLim        = numeric_limits<_RealT>;
   const _IntT __max_val = std::__max_representable_int_for_float<_IntT, _RealT>();
-  if (__r >= ::nextafter(static_cast<_RealT>(__max_val), INFINITY)) {
-    return _Lim::max();
-  } else if (__r <= _Lim::lowest()) {
-    return _Lim::min();
+  if (__r >= __math::nextafter(static_cast<_RealT>(__max_val), _RealLim::infinity())) {
+    return _IntLim::max();
+  } else if (__r <= _IntLim::lowest()) {
+    return _IntLim::min();
   }
   return static_cast<_IntT>(__r);
 }
diff --git a/libcxx/include/__random/exponential_distribution.h b/libcxx/include/__random/exponential_distribution.h
index 17f566ec6a2f8..c029db44d8962 100644
--- a/libcxx/include/__random/exponential_distribution.h
+++ b/libcxx/include/__random/exponential_distribution.h
@@ -10,10 +10,10 @@
 #define _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/logarithms.h>
 #include <__random/generate_canonical.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -96,7 +96,7 @@ template <class _RealType>
 template <class _URNG>
 _RealType exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) {
   static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
-  return -std::log(result_type(1) - std::generate_canonical<result_type, numeric_limits<result_type>::digits>(__g)) /
+  return -__math::log(result_type(1) - std::generate_canonical<result_type, numeric_limits<result_type>::digits>(__g)) /
          __p.lambda();
 }
 
diff --git a/libcxx/include/__random/extreme_value_distribution.h b/libcxx/include/__random/extreme_value_distribution.h
index e59079b7d6c22..ce26da1c60d9c 100644
--- a/libcxx/include/__random/extreme_value_distribution.h
+++ b/libcxx/include/__random/extreme_value_distribution.h
@@ -10,9 +10,9 @@
 #define _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/logarithms.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -100,7 +100,7 @@ template <class _RealType>
 template <class _URNG>
 _RealType extreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) {
   static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
-  return __p.a() - __p.b() * std::log(-std::log(1 - uniform_real_distribution<result_type>()(__g)));
+  return __p.a() - __p.b() * __math::log(-__math::log(1 - uniform_real_distribution<result_type>()(__g)));
 }
 
 template <class _CharT, class _Traits, class _RT>
diff --git a/libcxx/include/__random/gamma_distribution.h b/libcxx/include/__random/gamma_distribution.h
index aa418fd66702e..19185d34f698f 100644
--- a/libcxx/include/__random/gamma_distribution.h
+++ b/libcxx/include/__random/gamma_distribution.h
@@ -10,10 +10,13 @@
 #define _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/exponential_functions.h>
+#include <__math/gamma.h>
+#include <__math/logarithms.h>
+#include <__math/roots.h>
 #include <__random/exponential_distribution.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -114,13 +117,13 @@ _RealType gamma_distribution<_RealType>::operator()(_URNG& __g, const param_type
       const result_type __v = __gen(__g);
       const result_type __w = __u * (1 - __u);
       if (__w != 0) {
-        const result_type __y = std::sqrt(__c / __w) * (__u - result_type(0.5));
+        const result_type __y = __math::sqrt(__c / __w) * (__u - result_type(0.5));
         __x                   = __b + __y;
         if (__x >= 0) {
           const result_type __z = 64 * __w * __w * __w * __v * __v;
           if (__z <= 1 - 2 * __y * __y / __x)
             break;
-          if (std::log(__z) <= 2 * (__b * std::log(__x / __b) - __y))
+          if (__math::log(__z) <= 2 * (__b * __math::log(__x / __b) - __y))
             break;
         }
       }
@@ -131,12 +134,12 @@ _RealType gamma_distribution<_RealType>::operator()(_URNG& __g, const param_type
       const result_type __u  = __gen(__g);
       const result_type __es = __egen(__g);
       if (__u <= 1 - __a) {
-        __x = std::pow(__u, 1 / __a);
+        __x = __math::pow(__u, 1 / __a);
         if (__x <= __es)
           break;
       } else {
-        const result_type __e = -std::log((1 - __u) / __a);
-        __x                   = std::pow(1 - __a + __a * __e, 1 / __a);
+        const result_type __e = -__math::log((1 - __u) / __a);
+        __x                   = __math::pow(1 - __a + __a * __e, 1 / __a);
         if (__x <= __e + __es)
           break;
       }
diff --git a/libcxx/include/__random/lognormal_distribution.h b/libcxx/include/__random/lognormal_distribution.h
index a94918a6a6a44..da5c64418fc52 100644
--- a/libcxx/include/__random/lognormal_distribution.h
+++ b/libcxx/include/__random/lognormal_distribution.h
@@ -10,9 +10,9 @@
 #define _LIBCPP___RANDOM_LOGNORMAL_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/exponential_functions.h>
 #include <__random/is_valid.h>
 #include <__random/normal_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -69,13 +69,13 @@ class lognormal_distribution {
   // generating functions
   template <class _URNG>
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g) {
-    return std::exp(__nd_(__g));
+    return __math::exp(__nd_(__g));
   }
 
   template <class _URNG>
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p) {
     typename normal_distribution<result_type>::param_type __pn(__p.m(), __p.s());
-    return std::exp(__nd_(__g, __pn));
+    return __math::exp(__nd_(__g, __pn));
   }
 
   // property functions
diff --git a/libcxx/include/__random/normal_distribution.h b/libcxx/include/__random/normal_distribution.h
index 4ebfd750a5f8a..999c7cc72a4a0 100644
--- a/libcxx/include/__random/normal_distribution.h
+++ b/libcxx/include/__random/normal_distribution.h
@@ -10,9 +10,10 @@
 #define _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/logarithms.h>
+#include <__math/roots.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -123,7 +124,7 @@ _RealType normal_distribution<_RealType>::operator()(_URNG& __g, const param_typ
       __v = __uni(__g);
       __s = __u * __u + __v * __v;
     } while (__s > 1 || __s == 0);
-    result_type __fp = std::sqrt(-2 * std::log(__s) / __s);
+    result_type __fp = __math::sqrt(-2 * __math::log(__s) / __s);
     __v_             = __v * __fp;
     __v_hot_         = true;
     __up             = __u * __fp;
diff --git a/libcxx/include/__random/piecewise_linear_distribution.h b/libcxx/include/__random/piecewise_linear_distribution.h
index ddf6416704395..fb5be22c73e5d 100644
--- a/libcxx/include/__random/piecewise_linear_distribution.h
+++ b/libcxx/include/__random/piecewise_linear_distribution.h
@@ -14,11 +14,11 @@
 #include <__config>
 #include <__cstddef/ptrdiff_t.h>
 #include <__iterator/back_insert_iterator.h>
+#include <__math/roots.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
 #include <__vector/comparison.h>
 #include <__vector/vector.h>
-#include <cmath>
 #include <initializer_list>
 #include <iosfwd>
 
@@ -257,7 +257,8 @@ _RealType piecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const
     return __u / __dk + __bk;
   const result_type __bk1    = __p.__b_[__k + 1];
   const result_type __deltab = __bk1 - __bk;
-  return (__bk * __dk1 - __bk1 * __dk + std::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) / __deltad;
+  return (__bk * __dk1 - __bk1 * __dk + __math::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) /
+         __deltad;
 }
 
 template <class _CharT, class _Traits, class _RT>
diff --git a/libcxx/include/__random/poisson_distribution.h b/libcxx/include/__random/poisson_distribution.h
index 118f148e9b6da..ccb459a92747b 100644
--- a/libcxx/include/__random/poisson_distribution.h
+++ b/libcxx/include/__random/poisson_distribution.h
@@ -10,12 +10,17 @@
 #define _LIBCPP___RANDOM_POISSON_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/abs.h>
+#include <__math/exponential_functions.h>
+#include <__math/logarithms.h>
+#include <__math/roots.h>
+#include <__math/rounding_functions.h>
+#include <__math/traits.h>
 #include <__random/clamp_to_integral.h>
 #include <__random/exponential_distribution.h>
 #include <__random/is_valid.h>
 #include <__random/normal_distribution.h>
 #include <__random/uniform_real_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -107,11 +112,11 @@ poisson_distribution<_IntType>::param_type::param_type(double __mean)
     // According to the standard `inf` is a valid input, but it causes the
     // distribution to hang, so we replace it with the maximum representable
     // mean.
-    : __mean_(isinf(__mean) ? numeric_limits<double>::max() : __mean) {
+    : __mean_(__math::isinf(__mean) ? numeric_limits<double>::max() : __mean) {
   if (__mean_ < 10) {
     __s_     = 0;
     __d_     = 0;
-    __l_     = std::exp(-__mean_);
+    __l_     = __math::exp(-__mean_);
     __omega_ = 0;
     __c3_    = 0;
     __c2_    = 0;
@@ -119,9 +124,9 @@ poisson_distribution<_IntType>::param_type::param_type(double __mean)
     __c0_    = 0;
     __c_     = 0;
   } else {
-    __s_        = std::sqrt(__mean_);
+    __s_        = __math::sqrt(__mean_);
     __d_        = 6 * __mean_ * __mean_;
-    __l_        = std::trunc(__mean_ - 1.1484);
+    __l_        = __math::trunc(__mean_ - 1.1484);
     __omega_    = .3989423 / __s_;
     double __b1 = .4166667E-1 / __mean_;
     double __b2 = .3 * __b1 * __b1;
@@ -148,7 +153,7 @@ _IntType poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_t
     double __g = __pr.__mean_ + __pr.__s_ * normal_distribution<double>()(__urng);
     double __u;
     if (__g > 0) {
-      __tx = std::trunc(__g);
+      __tx = __math::trunc(__g);
       if (__tx >= __pr.__l_)
         return std::__clamp_to_integral<result_type>(__tx);
       __difmuk = __pr.__mean_ - __tx;
@@ -167,7 +172,7 @@ _IntType poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_t
           __u += __u - 1;
           __t = 1.8 + (__u < 0 ? -__e : __e);
         } while (__t <= -.6744);
-        __tx             = std::trunc(__pr.__mean_ + __pr.__s_ * __t);
+        __tx             = __math::trunc(__pr.__mean_ + __pr.__s_ * __t);
         __difmuk         = __pr.__mean_ - __tx;
         __using_exp_dist = true;
       }
@@ -176,13 +181,13 @@ _IntType poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_t
       if (__tx < 10 && __tx >= 0) {
         const double __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
         __px                 = -__pr.__mean_;
-        __py                 = std::pow(__pr.__mean_, (double)__tx) / __fac[static_cast<int>(__tx)];
+        __py                 = __math::pow(__pr.__mean_, (double)__tx) / __fac[static_cast<int>(__tx)];
       } else {
         double __del = .8333333E-1 / __tx;
         __del -= 4.8 * __del * __del * __del;
         double __v = __difmuk / __tx;
-        if (std::abs(__v) > 0.25)
-          __px = __tx * std::log(1 + __v) - __difmuk - __del;
+        if (__math::abs(__v) > 0.25)
+          __px = __tx * __math::log(1 + __v) - __difmuk - __del;
         else
           __px = __tx * __v * __v *
                      (((((((.1250060 * __v + -.1384794) * __v + .1421878) * __v + -.1661269) * __v + .2000118) * __v +
@@ -192,17 +197,17 @@ _IntType poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_t
                           __v +
                       -.5) -
                  __del;
-        __py = .3989423 / std::sqrt(__tx);
+        __py = .3989423 / __math::sqrt(__tx);
       }
       double __r  = (0.5 - __difmuk) / __pr.__s_;
       double __r2 = __r * __r;
       double __fx = -0.5 * __r2;
       double __fy = __pr.__omega_ * (((__pr.__c3_ * __r2 + __pr.__c2_) * __r2 + __pr.__c1_) * __r2 + __pr.__c0_);
       if (__using_exp_dist) {
-        if (__pr.__c_ * std::abs(__u) <= __py * std::exp(__px + __e) - __fy * std::exp(__fx + __e))
+        if (__pr.__c_ * __math::abs(__u) <= __py * __math::exp(__px + __e) - __fy * __math::exp(__fx + __e))
           break;
       } else {
-        if (__fy - __u * __fy <= __py * std::exp(__px - __fx))
+        if (__fy - __u * __fy <= __py * __math::exp(__px - __fx))
           break;
       }
     }
diff --git a/libcxx/include/__random/student_t_distribution.h b/libcxx/include/__random/student_t_distribution.h
index 16579962ce925..21e29278af39b 100644
--- a/libcxx/include/__random/student_t_distribution.h
+++ b/libcxx/include/__random/student_t_distribution.h
@@ -10,10 +10,10 @@
 #define _LIBCPP___RANDOM_STUDENT_T_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/roots.h>
 #include <__random/gamma_distribution.h>
 #include <__random/is_valid.h>
 #include <__random/normal_distribution.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -96,7 +96,7 @@ template <class _URNG>
 _RealType student_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) {
   static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
   gamma_distribution<result_type> __gd(__p.n() * .5, 2);
-  return __nd_(__g) * std::sqrt(__p.n() / __gd(__g));
+  return __nd_(__g) * __math::sqrt(__p.n() / __gd(__g));
 }
 
 template <class _CharT, class _Traits, class _RT>
diff --git a/libcxx/include/__random/weibull_distribution.h b/libcxx/include/__random/weibull_distribution.h
index 333699cac1be4..7fb913f9bf705 100644
--- a/libcxx/include/__random/weibull_distribution.h
+++ b/libcxx/include/__random/weibull_distribution.h
@@ -10,9 +10,9 @@
 #define _LIBCPP___RANDOM_WEIBULL_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/exponential_functions.h>
 #include <__random/exponential_distribution.h>
 #include <__random/is_valid.h>
-#include <cmath>
 #include <iosfwd>
 #include <limits>
 
@@ -75,7 +75,7 @@ class weibull_distribution {
   }
   template <class _URNG>
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p) {
-    return __p.b() * std::pow(exponential_distribution<result_type>()(__g), 1 / __p.a());
+    return __p.b() * __math::pow(exponential_distribution<result_type>()(__g), 1 / __p.a());
   }
 
   // property functions
diff --git a/libcxx/include/random b/libcxx/include/random
index 05decfc69c923..8738bfc5d0fdb 100644
--- a/libcxx/include/random
+++ b/libcxx/include/random
@@ -1741,6 +1741,11 @@ class piecewise_linear_distribution
 #    include <type_traits>
 #    include <vector>
 #  endif
+
+#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
+#    include <cmath>
+#  endif
+
 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
 
 #endif // _LIBCPP_RANDOM
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index 9b047ca3d97db..fc736188b008d 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -753,7 +753,6 @@ queue vector
 queue version
 random cctype
 random climits
-random cmath
 random compare
 random cstdint
 random cstdio



More information about the libcxx-commits mailing list