[libc++] Make all of <random> depend on <__math/FOO.h> instead of <cmath> (#213084)

Some of `<random>` functionality depends on the system's `math.h` header
instead of `__math/FOO.h`. System's are just undefined symbol to be
linked, but the `__math/FOO.h` are implemented with potentially
constexpr-friendly builtins. Also, some of the functionality seems to be
using `__math::` namespace and some doesn't, seemingly randomly.

This PR fixes such inconsistency, avoids using non-constexpr functions
from the system's `math.h`, and in turn removes obstacles for P3791
`constexpr <random>`.

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
GitOrigin-RevId: ada3786e91ca2058f3ac8255a024c12ae7d263ee
diff --git a/include/__random/binomial_distribution.h b/include/__random/binomial_distribution.h
index e4fe921..abc9d75 100644
--- a/include/__random/binomial_distribution.h
+++ b/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 @@
 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/include/__random/cauchy_distribution.h b/include/__random/cauchy_distribution.h
index 65e8309..ad88b5a 100644
--- a/include/__random/cauchy_distribution.h
+++ b/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 @@
   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/include/__random/clamp_to_integral.h b/include/__random/clamp_to_integral.h
index 9ddf41e..0990ad4 100644
--- a/include/__random/clamp_to_integral.h
+++ b/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 @@
 // 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/include/__random/exponential_distribution.h b/include/__random/exponential_distribution.h
index 17f566e..c029db4 100644
--- a/include/__random/exponential_distribution.h
+++ b/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 _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/include/__random/extreme_value_distribution.h b/include/__random/extreme_value_distribution.h
index e59079b..ce26da1 100644
--- a/include/__random/extreme_value_distribution.h
+++ b/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 _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/include/__random/gamma_distribution.h b/include/__random/gamma_distribution.h
index aa418fd..19185d3 100644
--- a/include/__random/gamma_distribution.h
+++ b/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 @@
       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 @@
       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/include/__random/lognormal_distribution.h b/include/__random/lognormal_distribution.h
index a94918a..da5c644 100644
--- a/include/__random/lognormal_distribution.h
+++ b/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 @@
   // 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/include/__random/normal_distribution.h b/include/__random/normal_distribution.h
index 4ebfd75..999c7cc 100644
--- a/include/__random/normal_distribution.h
+++ b/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 @@
       __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/include/__random/piecewise_linear_distribution.h b/include/__random/piecewise_linear_distribution.h
index ddf6416..fb5be22 100644
--- a/include/__random/piecewise_linear_distribution.h
+++ b/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 @@
     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/include/__random/poisson_distribution.h b/include/__random/poisson_distribution.h
index 118f148..ccb459a 100644
--- a/include/__random/poisson_distribution.h
+++ b/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 @@
     // 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 @@
     __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 @@
     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 @@
           __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 @@
       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 @@
                           __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/include/__random/student_t_distribution.h b/include/__random/student_t_distribution.h
index 1657996..21e2927 100644
--- a/include/__random/student_t_distribution.h
+++ b/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 @@
 _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/include/__random/weibull_distribution.h b/include/__random/weibull_distribution.h
index 333699c..7fb913f 100644
--- a/include/__random/weibull_distribution.h
+++ b/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 @@
   }
   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/include/random b/include/random
index 65121be..69a3608 100644
--- a/include/random
+++ b/include/random
@@ -1729,6 +1729,10 @@
 #  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER >= 17 && _LIBCPP_STD_VER <= 23
 #    include <optional>
 #  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/test/libcxx/transitive_includes/cxx26.csv b/test/libcxx/transitive_includes/cxx26.csv
index caf94dc..87a446b 100644
--- a/test/libcxx/transitive_includes/cxx26.csv
+++ b/test/libcxx/transitive_includes/cxx26.csv
@@ -742,7 +742,6 @@
 queue version
 random cctype
 random climits
-random cmath
 random compare
 random cstdint
 random cstdio