[libc++] Avoid including <cmath> in <compare> (#80418)

This reduces the time to include `<compare>` from 84ms to 36ms.
This commit is contained in:
Nikolas Klauser 2024-02-08 19:23:10 +01:00 committed by GitHub
parent d272d944de
commit 1b5f691619
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 21 additions and 17 deletions

View File

@ -13,11 +13,14 @@
#include <__compare/compare_three_way.h> #include <__compare/compare_three_way.h>
#include <__compare/ordering.h> #include <__compare/ordering.h>
#include <__config> #include <__config>
#include <__math/exponential_functions.h>
#include <__math/traits.h>
#include <__type_traits/conditional.h> #include <__type_traits/conditional.h>
#include <__type_traits/decay.h> #include <__type_traits/decay.h>
#include <__type_traits/is_floating_point.h>
#include <__type_traits/is_same.h>
#include <__utility/forward.h> #include <__utility/forward.h>
#include <__utility/priority_tag.h> #include <__utility/priority_tag.h>
#include <cmath>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
@ -66,27 +69,27 @@ struct __fn {
return strong_ordering::greater; return strong_ordering::greater;
} else if (__t == __u) { } else if (__t == __u) {
if constexpr (numeric_limits<_Dp>::radix == 2) { if constexpr (numeric_limits<_Dp>::radix == 2) {
return std::signbit(__u) <=> std::signbit(__t); return __math::signbit(__u) <=> __math::signbit(__t);
} else { } else {
// This is bullet 3 of the IEEE754 algorithm, relevant // This is bullet 3 of the IEEE754 algorithm, relevant
// only for decimal floating-point; // only for decimal floating-point;
// see https://stackoverflow.com/questions/69068075/ // see https://stackoverflow.com/questions/69068075/
if (__t == 0 || std::isinf(__t)) { if (__t == 0 || __math::isinf(__t)) {
return std::signbit(__u) <=> std::signbit(__t); return __math::signbit(__u) <=> __math::signbit(__t);
} else { } else {
int __texp, __uexp; int __texp, __uexp;
(void)std::frexp(__t, &__texp); (void)__math::frexp(__t, &__texp);
(void)std::frexp(__u, &__uexp); (void)__math::frexp(__u, &__uexp);
return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp);
} }
} }
} else { } else {
// They're unordered, so one of them must be a NAN. // They're unordered, so one of them must be a NAN.
// The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN.
bool __t_is_nan = std::isnan(__t); bool __t_is_nan = __math::isnan(__t);
bool __u_is_nan = std::isnan(__u); bool __u_is_nan = __math::isnan(__u);
bool __t_is_negative = std::signbit(__t); bool __t_is_negative = __math::signbit(__t);
bool __u_is_negative = std::signbit(__u); bool __u_is_negative = __math::signbit(__u);
using _IntType = using _IntType =
conditional_t< sizeof(__t) == sizeof(int32_t), conditional_t< sizeof(__t) == sizeof(int32_t),
int32_t, int32_t,

View File

@ -13,10 +13,12 @@
#include <__compare/ordering.h> #include <__compare/ordering.h>
#include <__compare/strong_order.h> #include <__compare/strong_order.h>
#include <__config> #include <__config>
#include <__math/traits.h>
#include <__type_traits/decay.h> #include <__type_traits/decay.h>
#include <__type_traits/is_floating_point.h>
#include <__type_traits/is_same.h>
#include <__utility/forward.h> #include <__utility/forward.h>
#include <__utility/priority_tag.h> #include <__utility/priority_tag.h>
#include <cmath>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header # pragma GCC system_header
@ -51,10 +53,10 @@ struct __fn {
return weak_ordering::greater; return weak_ordering::greater;
} else { } else {
// Otherwise, at least one of them is a NaN. // Otherwise, at least one of them is a NaN.
bool __t_is_nan = std::isnan(__t); bool __t_is_nan = __math::isnan(__t);
bool __u_is_nan = std::isnan(__u); bool __u_is_nan = __math::isnan(__u);
bool __t_is_negative = std::signbit(__t); bool __t_is_negative = __math::signbit(__t);
bool __u_is_negative = std::signbit(__u); bool __u_is_negative = __math::signbit(__u);
if (__t_is_nan && __u_is_nan) { if (__t_is_nan && __u_is_nan) {
return (__u_is_negative <=> __t_is_negative); return (__u_is_negative <=> __t_is_negative);
} else if (__t_is_nan) { } else if (__t_is_nan) {

View File

@ -162,6 +162,7 @@ namespace std {
#endif #endif
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <cmath>
# include <type_traits> # include <type_traits>
#endif #endif

View File

@ -105,7 +105,6 @@ codecvt string
codecvt tuple codecvt tuple
codecvt typeinfo codecvt typeinfo
codecvt version codecvt version
compare cmath
compare cstddef compare cstddef
compare cstdint compare cstdint
compare limits compare limits

1 algorithm climits
105 codecvt tuple
106 codecvt typeinfo
107 codecvt version
compare cmath
108 compare cstddef
109 compare cstdint
110 compare limits

View File

@ -105,7 +105,6 @@ codecvt string
codecvt tuple codecvt tuple
codecvt typeinfo codecvt typeinfo
codecvt version codecvt version
compare cmath
compare cstddef compare cstddef
compare cstdint compare cstdint
compare limits compare limits

1 algorithm climits
105 codecvt tuple
106 codecvt typeinfo
107 codecvt version
compare cmath
108 compare cstddef
109 compare cstdint
110 compare limits