Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Standalone View
libcxx/include/math.h
Show First 20 Lines • Show All 277 Lines • ▼ Show 20 Lines | |||||
long double scalblnl(long double x, long ex); | long double scalblnl(long double x, long ex); | ||||
floating_point scalbn (arithmetic x, int ex); | floating_point scalbn (arithmetic x, int ex); | ||||
float scalbnf(float x, int ex); | float scalbnf(float x, int ex); | ||||
long double scalbnl(long double x, int ex); | long double scalbnl(long double x, int ex); | ||||
floating_point tgamma (arithmetic x); | floating_point tgamma (arithmetic x); | ||||
float tgammaf(float x); | float tgammaf(float x); | ||||
long double tgammal(long double x); | long double tgammal(long double x); | ||||
ldionne: Can you try to:
1. Reformat the existing code in a separate patch
2. Make your change without… | |||||
floating_point trunc (arithmetic x); | floating_point trunc (arithmetic x); | ||||
float truncf(float x); | float truncf(float x); | ||||
long double truncl(long double x); | long double truncl(long double x); | ||||
*/ | */ | ||||
#include <__config> | #include <__config> | ||||
Mingw is failing the clang-tidy test, and only that. Can you please figure out what's wrong and add the missing tests? ldionne: Mingw is failing the `clang-tidy` test, and only that. Can you please figure out what's wrong… | |||||
This should be fixed in D136908. philnik: This should be fixed in D136908. | |||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||||
# pragma GCC system_header | # pragma GCC system_header | ||||
#endif | #endif | ||||
#include_next <math.h> | #include_next <math.h> | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
// We support including .h headers inside 'extern "C"' contexts, so switch | // We support including .h headers inside 'extern "C"' contexts, so switch | ||||
// back to C++ linkage before including these C++ headers. | // back to C++ linkage before including these C++ headers. | ||||
extern "C++" { | extern "C++" { | ||||
#include <__type_traits/promote.h> | #include <__type_traits/promote.h> | ||||
#include <limits> | #include <limits> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <type_traits> | #include <type_traits> | ||||
// signbit | // signbit | ||||
# ifdef signbit | # ifdef signbit | ||||
template <class _A1> | template <class _A1> | ||||
_LIBCPP_HIDE_FROM_ABI bool __libcpp_signbit(_A1 __x) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI bool __libcpp_signbit(_A1 __x) _NOEXCEPT { | ||||
# if __has_builtin(__builtin_signbit) | |||||
return __builtin_signbit(__x); | return __builtin_signbit(__x); | ||||
# else | |||||
return signbit(__x); | |||||
# endif | |||||
} | } | ||||
# undef signbit | # undef signbit | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, bool>::type | inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, bool>::type | ||||
signbit(_A1 __x) _NOEXCEPT { | signbit(_A1 __x) _NOEXCEPT { | ||||
return __libcpp_signbit(__x); | return __libcpp_signbit(__x); | ||||
Show All 38 Lines | |||||
# endif // signbit | # endif // signbit | ||||
// fpclassify | // fpclassify | ||||
# ifdef fpclassify | # ifdef fpclassify | ||||
template <class _A1> | template <class _A1> | ||||
_LIBCPP_HIDE_FROM_ABI int __libcpp_fpclassify(_A1 __x) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI int __libcpp_fpclassify(_A1 __x) _NOEXCEPT { | ||||
# if __has_builtin(__builtin_fpclassify) | |||||
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); | return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); | ||||
# else | |||||
return fpclassify(__x); | |||||
# endif | |||||
} | } | ||||
# undef fpclassify | # undef fpclassify | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, int>::type | inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, int>::type | ||||
fpclassify(_A1 __x) _NOEXCEPT { | fpclassify(_A1 __x) _NOEXCEPT { | ||||
return __libcpp_fpclassify(__x); | return __libcpp_fpclassify(__x); | ||||
Show All 22 Lines | |||||
# endif // fpclassify | # endif // fpclassify | ||||
// isfinite | // isfinite | ||||
# ifdef isfinite | # ifdef isfinite | ||||
template <class _A1> | template <class _A1> | ||||
_LIBCPP_HIDE_FROM_ABI bool __libcpp_isfinite(_A1 __x) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI bool __libcpp_isfinite(_A1 __x) _NOEXCEPT { | ||||
# if __has_builtin(__builtin_isfinite) | |||||
return __builtin_isfinite(__x); | return __builtin_isfinite(__x); | ||||
# else | |||||
return isfinite(__x); | |||||
# endif | |||||
} | } | ||||
# undef isfinite | # undef isfinite | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if< std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, bool>::type | typename std::enable_if< std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, bool>::type | ||||
isfinite(_A1 __x) _NOEXCEPT { | isfinite(_A1 __x) _NOEXCEPT { | ||||
Show All 10 Lines | |||||
# endif // isfinite | # endif // isfinite | ||||
// isinf | // isinf | ||||
# ifdef isinf | # ifdef isinf | ||||
template <class _A1> | template <class _A1> | ||||
_LIBCPP_HIDE_FROM_ABI bool __libcpp_isinf(_A1 __x) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI bool __libcpp_isinf(_A1 __x) _NOEXCEPT { | ||||
# if __has_builtin(__builtin_isinf) | |||||
return __builtin_isinf(__x); | return __builtin_isinf(__x); | ||||
# else | |||||
return isinf(__x); | |||||
# endif | |||||
} | } | ||||
# undef isinf | # undef isinf | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if< std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, bool>::type | typename std::enable_if< std::is_arithmetic<_A1>::value && std::numeric_limits<_A1>::has_infinity, bool>::type | ||||
isinf(_A1 __x) _NOEXCEPT { | isinf(_A1 __x) _NOEXCEPT { | ||||
Show All 18 Lines | |||||
# endif // isinf | # endif // isinf | ||||
// isnan | // isnan | ||||
# ifdef isnan | # ifdef isnan | ||||
template <class _A1> | template <class _A1> | ||||
_LIBCPP_HIDE_FROM_ABI bool __libcpp_isnan(_A1 __x) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI bool __libcpp_isnan(_A1 __x) _NOEXCEPT { | ||||
# if __has_builtin(__builtin_isnan) | |||||
return __builtin_isnan(__x); | return __builtin_isnan(__x); | ||||
# else | |||||
return isnan(__x); | |||||
# endif | |||||
} | } | ||||
# undef isnan | # undef isnan | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, bool>::type | inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, bool>::type | ||||
isnan(_A1 __x) _NOEXCEPT { | isnan(_A1 __x) _NOEXCEPT { | ||||
return __libcpp_isnan(__x); | return __libcpp_isnan(__x); | ||||
Show All 15 Lines | |||||
# endif // isnan | # endif // isnan | ||||
// isnormal | // isnormal | ||||
# ifdef isnormal | # ifdef isnormal | ||||
template <class _A1> | template <class _A1> | ||||
_LIBCPP_HIDE_FROM_ABI bool __libcpp_isnormal(_A1 __x) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI bool __libcpp_isnormal(_A1 __x) _NOEXCEPT { | ||||
# if __has_builtin(__builtin_isnormal) | |||||
return __builtin_isnormal(__x); | return __builtin_isnormal(__x); | ||||
# else | |||||
return isnormal(__x); | |||||
# endif | |||||
} | } | ||||
# undef isnormal | # undef isnormal | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, bool>::type | inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_floating_point<_A1>::value, bool>::type | ||||
isnormal(_A1 __x) _NOEXCEPT { | isnormal(_A1 __x) _NOEXCEPT { | ||||
Those all need to be inline for ODR. ldionne: Those all need to be `inline` for ODR. | |||||
These are templates, so they are implicitly inline. philnik: These are templates, so they are implicitly `inline`. | |||||
return __libcpp_isnormal(__x); | return __libcpp_isnormal(__x); | ||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_integral<_A1>::value, bool>::type | inline _LIBCPP_HIDE_FROM_ABI typename std::enable_if<std::is_integral<_A1>::value, bool>::type | ||||
isnormal(_A1 __x) _NOEXCEPT { | isnormal(_A1 __x) _NOEXCEPT { | ||||
return __x != 0; | return __x != 0; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
# endif // islessequal | # endif // islessequal | ||||
// islessgreater | // islessgreater | ||||
# ifdef islessgreater | # ifdef islessgreater | ||||
template <class _A1, class _A2> | template <class _A1, class _A2> | ||||
_LIBCPP_HIDE_FROM_ABI bool __libcpp_islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI bool __libcpp_islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { | ||||
return islessgreater(__x, __y); | return islessgreater(__x, __y); | ||||
Were'n EricWF: Were'n | |||||
I guess this wasn't planned? philnik: I guess this wasn't planned? | |||||
} | } | ||||
# undef islessgreater | # undef islessgreater | ||||
template <class _A1, class _A2> | template <class _A1, class _A2> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if< std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, bool >::type | typename std::enable_if< std::is_arithmetic<_A1>::value && std::is_arithmetic<_A2>::value, bool >::type | ||||
islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { | islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { | ||||
typedef typename std::__promote<_A1, _A2>::type type; | typedef typename std::__promote<_A1, _A2>::type type; | ||||
return __libcpp_islessgreater((type)__x, (type)__y); | return __libcpp_islessgreater((type)__x, (type)__y); | ||||
} | } | ||||
# endif // islessgreater | # endif // islessgreater | ||||
// isunordered | // isunordered | ||||
# ifdef isunordered | # ifdef isunordered | ||||
template <class _A1, class _A2> | template <class _A1, class _A2> | ||||
You removed __promote here and in a bunch of other places. Can you please do that as a separate patch (including the ones that are trivial, i.e. __promote<T> where T is a floating point). That will make this change easier to validate. ldionne: You removed `__promote` here and in a bunch of other places. Can you please do that as a… | |||||
_LIBCPP_HIDE_FROM_ABI bool __libcpp_isunordered(_A1 __x, _A2 __y) _NOEXCEPT { | _LIBCPP_HIDE_FROM_ABI bool __libcpp_isunordered(_A1 __x, _A2 __y) _NOEXCEPT { | ||||
return isunordered(__x, __y); | return isunordered(__x, __y); | ||||
} | } | ||||
# undef isunordered | # undef isunordered | ||||
template <class _A1, class _A2> | template <class _A1, class _A2> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
▲ Show 20 Lines • Show All 342 Lines • ▼ Show 20 Lines | |||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
cbrt(_A1 __x) _NOEXCEPT {return ::cbrt((double)__x);} | cbrt(_A1 __x) _NOEXCEPT {return ::cbrt((double)__x);} | ||||
// copysign | // copysign | ||||
#if __has_builtin(__builtin_copysignf) | |||||
_LIBCPP_CONSTEXPR | _LIBCPP_CONSTEXPR | ||||
#endif | |||||
inline _LIBCPP_HIDE_FROM_ABI float __libcpp_copysign(float __x, float __y) _NOEXCEPT { | inline _LIBCPP_HIDE_FROM_ABI float __libcpp_copysign(float __x, float __y) _NOEXCEPT { | ||||
#if __has_builtin(__builtin_copysignf) | |||||
return __builtin_copysignf(__x, __y); | return __builtin_copysignf(__x, __y); | ||||
#else | |||||
return ::copysignf(__x, __y); | |||||
#endif | |||||
} | } | ||||
#if __has_builtin(__builtin_copysign) | |||||
_LIBCPP_CONSTEXPR | _LIBCPP_CONSTEXPR | ||||
#endif | |||||
inline _LIBCPP_HIDE_FROM_ABI double __libcpp_copysign(double __x, double __y) _NOEXCEPT { | inline _LIBCPP_HIDE_FROM_ABI double __libcpp_copysign(double __x, double __y) _NOEXCEPT { | ||||
#if __has_builtin(__builtin_copysign) | |||||
return __builtin_copysign(__x, __y); | return __builtin_copysign(__x, __y); | ||||
#else | |||||
return ::copysign(__x, __y); | |||||
#endif | |||||
} | } | ||||
#if __has_builtin(__builtin_copysignl) | |||||
_LIBCPP_CONSTEXPR | _LIBCPP_CONSTEXPR | ||||
#endif | |||||
inline _LIBCPP_HIDE_FROM_ABI long double __libcpp_copysign(long double __x, long double __y) _NOEXCEPT { | inline _LIBCPP_HIDE_FROM_ABI long double __libcpp_copysign(long double __x, long double __y) _NOEXCEPT { | ||||
ldionneUnsubmitted Not Done ReplyInline ActionsCan you make a TODO to clean this up? ldionne: Can you make a TODO to clean this up? | |||||
#if __has_builtin(__builtin_copysignl) | |||||
return __builtin_copysignl(__x, __y); | return __builtin_copysignl(__x, __y); | ||||
#else | |||||
return ::copysignl(__x, __y); | |||||
#endif | |||||
} | } | ||||
template <class _A1, class _A2> | template <class _A1, class _A2> | ||||
#if __has_builtin(__builtin_copysign) | |||||
_LIBCPP_CONSTEXPR | _LIBCPP_CONSTEXPR | ||||
#endif | |||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::__enable_if_t | typename std::__enable_if_t | ||||
< | < | ||||
std::is_arithmetic<_A1>::value && | std::is_arithmetic<_A1>::value && | ||||
std::is_arithmetic<_A2>::value, | std::is_arithmetic<_A2>::value, | ||||
std::__promote<_A1, _A2> | std::__promote<_A1, _A2> | ||||
>::type | >::type | ||||
__libcpp_copysign(_A1 __x, _A2 __y) _NOEXCEPT { | __libcpp_copysign(_A1 __x, _A2 __y) _NOEXCEPT { | ||||
typedef typename std::__promote<_A1, _A2>::type __result_type; | typedef typename std::__promote<_A1, _A2>::type __result_type; | ||||
static_assert((!(std::_IsSame<_A1, __result_type>::value && | static_assert((!(std::_IsSame<_A1, __result_type>::value && | ||||
std::_IsSame<_A2, __result_type>::value)), ""); | std::_IsSame<_A2, __result_type>::value)), ""); | ||||
#if __has_builtin(__builtin_copysign) | |||||
return __builtin_copysign((__result_type)__x, (__result_type)__y); | return __builtin_copysign((__result_type)__x, (__result_type)__y); | ||||
#else | |||||
return ::copysign((__result_type)__x, (__result_type)__y); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { | inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { | ||||
return ::__libcpp_copysign(__x, __y); | return ::__libcpp_copysign(__x, __y); | ||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { | inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { | ||||
return ::__libcpp_copysign(__x, __y); | return ::__libcpp_copysign(__x, __y); | ||||
} | } | ||||
template <class _A1, class _A2> | template <class _A1, class _A2> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::__enable_if_t | typename std::__enable_if_t | ||||
< | < | ||||
std::is_arithmetic<_A1>::value && | std::is_arithmetic<_A1>::value && | ||||
std::is_arithmetic<_A2>::value, | std::is_arithmetic<_A2>::value, | ||||
std::__promote<_A1, _A2> | std::__promote<_A1, _A2> | ||||
>::type | >::type | ||||
copysign(_A1 __x, _A2 __y) _NOEXCEPT { | copysign(_A1 __x, _A2 __y) _NOEXCEPT { | ||||
return ::__libcpp_copysign(__x, __y); | return ::__libcpp_copysign(__x, __y); | ||||
} | } | ||||
// erf | // erf | ||||
inline _LIBCPP_HIDE_FROM_ABI float erf(float __x) _NOEXCEPT {return ::erff(__x);} | inline _LIBCPP_HIDE_FROM_ABI float erf(float __x) _NOEXCEPT {return ::erff(__x);} | ||||
If the C library does not provide copysign(double, double), this is infinite recursion. This is too subtle and the failure mode is terrible, i.e. this should never be a runtime error. Instead, let's do this (per live review just now): #include <type_traits> // in C library float copysignf(float, float); double copysign(double, double); long double copysignl(long double, long double); // in libc++ inline auto copysign(float, float); inline auto copysign(long double, long double); template <class = int> inline auto copysign(double x, double) { return x; } template <class _Tp, class _Up, std::enable_if_t<std::is_arithmetic<_Tp>::value && std::is_arithmetic<_Up>::value, int> = 0> inline auto copysign(_Tp __x, _Up __y); int main() { double d = 0; copysign(d, d); } ldionne: If the C library does not provide `copysign(double, double)`, this is infinite recursion. This… | |||||
Good spotting. EricWF: Good spotting. | |||||
Not Done ReplyInline Actions@philnik Can you please triple check that this is not an issue anymore? I'm approving this but contingent on this not being an issue. This behavior would be really, really not acceptable for users. ldionne: @philnik Can you please triple check that this is not an issue anymore? I'm approving this but… | |||||
inline _LIBCPP_HIDE_FROM_ABI long double erf(long double __x) _NOEXCEPT {return ::erfl(__x);} | inline _LIBCPP_HIDE_FROM_ABI long double erf(long double __x) _NOEXCEPT {return ::erfl(__x);} | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
erf(_A1 __x) _NOEXCEPT {return ::erf((double)__x);} | erf(_A1 __x) _NOEXCEPT {return ::erf((double)__x);} | ||||
// erfc | // erfc | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | static_assert((!(std::_IsSame<_A1, __result_type>::value && | ||||
std::_IsSame<_A2, __result_type>::value)), ""); | std::_IsSame<_A2, __result_type>::value)), ""); | ||||
return ::fdim((__result_type)__x, (__result_type)__y); | return ::fdim((__result_type)__x, (__result_type)__y); | ||||
} | } | ||||
// fma | // fma | ||||
inline _LIBCPP_HIDE_FROM_ABI float fma(float __x, float __y, float __z) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI float fma(float __x, float __y, float __z) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_fmaf) | |||||
return __builtin_fmaf(__x, __y, __z); | return __builtin_fmaf(__x, __y, __z); | ||||
#else | |||||
return ::fmaf(__x, __y, __z); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long double fma(long double __x, long double __y, long double __z) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long double fma(long double __x, long double __y, long double __z) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_fmal) | |||||
return __builtin_fmal(__x, __y, __z); | return __builtin_fmal(__x, __y, __z); | ||||
#else | |||||
return ::fmal(__x, __y, __z); | |||||
#endif | |||||
} | } | ||||
template <class _A1, class _A2, class _A3> | template <class _A1, class _A2, class _A3> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::__enable_if_t | typename std::__enable_if_t | ||||
< | < | ||||
std::is_arithmetic<_A1>::value && | std::is_arithmetic<_A1>::value && | ||||
std::is_arithmetic<_A2>::value && | std::is_arithmetic<_A2>::value && | ||||
std::is_arithmetic<_A3>::value, | std::is_arithmetic<_A3>::value, | ||||
std::__promote<_A1, _A2, _A3> | std::__promote<_A1, _A2, _A3> | ||||
>::type | >::type | ||||
fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT | fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT | ||||
{ | { | ||||
typedef typename std::__promote<_A1, _A2, _A3>::type __result_type; | typedef typename std::__promote<_A1, _A2, _A3>::type __result_type; | ||||
static_assert((!(std::_IsSame<_A1, __result_type>::value && | static_assert((!(std::_IsSame<_A1, __result_type>::value && | ||||
std::_IsSame<_A2, __result_type>::value && | std::_IsSame<_A2, __result_type>::value && | ||||
std::_IsSame<_A3, __result_type>::value)), ""); | std::_IsSame<_A3, __result_type>::value)), ""); | ||||
#if __has_builtin(__builtin_fma) | |||||
return __builtin_fma((__result_type)__x, (__result_type)__y, (__result_type)__z); | return __builtin_fma((__result_type)__x, (__result_type)__y, (__result_type)__z); | ||||
#else | |||||
return ::fma((__result_type)__x, (__result_type)__y, (__result_type)__z); | |||||
#endif | |||||
} | } | ||||
// fmax | // fmax | ||||
inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT {return ::fmaxf(__x, __y);} | inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT {return ::fmaxf(__x, __y);} | ||||
inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT {return ::fmaxl(__x, __y);} | inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT {return ::fmaxl(__x, __y);} | ||||
template <class _A1, class _A2> | template <class _A1, class _A2> | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
lgamma(_A1 __x) _NOEXCEPT {return ::lgamma((double)__x);} | lgamma(_A1 __x) _NOEXCEPT {return ::lgamma((double)__x);} | ||||
// llrint | // llrint | ||||
inline _LIBCPP_HIDE_FROM_ABI long long llrint(float __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long long llrint(float __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_llrintf) | |||||
return __builtin_llrintf(__x); | return __builtin_llrintf(__x); | ||||
#else | |||||
return ::llrintf(__x); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long long llrint(long double __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long long llrint(long double __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_llrintl) | |||||
return __builtin_llrintl(__x); | return __builtin_llrintl(__x); | ||||
#else | |||||
return ::llrintl(__x); | |||||
#endif | |||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, long long>::type | typename std::enable_if<std::is_integral<_A1>::value, long long>::type | ||||
llrint(_A1 __x) _NOEXCEPT | llrint(_A1 __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_llrint) | |||||
return __builtin_llrint((double)__x); | return __builtin_llrint((double)__x); | ||||
#else | |||||
return ::llrint((double)__x); | |||||
#endif | |||||
} | } | ||||
// llround | // llround | ||||
inline _LIBCPP_HIDE_FROM_ABI long long llround(float __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long long llround(float __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_llroundf) | |||||
return __builtin_llroundf(__x); | return __builtin_llroundf(__x); | ||||
#else | |||||
return ::llroundf(__x); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long long llround(long double __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long long llround(long double __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_llroundl) | |||||
return __builtin_llroundl(__x); | return __builtin_llroundl(__x); | ||||
#else | |||||
return ::llroundl(__x); | |||||
#endif | |||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, long long>::type | typename std::enable_if<std::is_integral<_A1>::value, long long>::type | ||||
llround(_A1 __x) _NOEXCEPT | llround(_A1 __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_llround) | |||||
return __builtin_llround((double)__x); | return __builtin_llround((double)__x); | ||||
#else | |||||
return ::llround((double)__x); | |||||
#endif | |||||
} | } | ||||
// log1p | // log1p | ||||
inline _LIBCPP_HIDE_FROM_ABI float log1p(float __x) _NOEXCEPT {return ::log1pf(__x);} | inline _LIBCPP_HIDE_FROM_ABI float log1p(float __x) _NOEXCEPT {return ::log1pf(__x);} | ||||
inline _LIBCPP_HIDE_FROM_ABI long double log1p(long double __x) _NOEXCEPT {return ::log1pl(__x);} | inline _LIBCPP_HIDE_FROM_ABI long double log1p(long double __x) _NOEXCEPT {return ::log1pl(__x);} | ||||
template <class _A1> | template <class _A1> | ||||
Show All 20 Lines | |||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
logb(_A1 __x) _NOEXCEPT {return ::logb((double)__x);} | logb(_A1 __x) _NOEXCEPT {return ::logb((double)__x);} | ||||
// lrint | // lrint | ||||
inline _LIBCPP_HIDE_FROM_ABI long lrint(float __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long lrint(float __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_lrintf) | |||||
return __builtin_lrintf(__x); | return __builtin_lrintf(__x); | ||||
#else | |||||
return ::lrintf(__x); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long lrint(long double __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long lrint(long double __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_lrintl) | |||||
return __builtin_lrintl(__x); | return __builtin_lrintl(__x); | ||||
#else | |||||
return ::lrintl(__x); | |||||
#endif | |||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, long>::type | typename std::enable_if<std::is_integral<_A1>::value, long>::type | ||||
lrint(_A1 __x) _NOEXCEPT | lrint(_A1 __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_lrint) | |||||
return __builtin_lrint((double)__x); | return __builtin_lrint((double)__x); | ||||
#else | |||||
return ::lrint((double)__x); | |||||
#endif | |||||
} | } | ||||
// lround | // lround | ||||
inline _LIBCPP_HIDE_FROM_ABI long lround(float __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long lround(float __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_lroundf) | |||||
return __builtin_lroundf(__x); | return __builtin_lroundf(__x); | ||||
#else | |||||
return ::lroundf(__x); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long lround(long double __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long lround(long double __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_lroundl) | |||||
return __builtin_lroundl(__x); | return __builtin_lroundl(__x); | ||||
#else | |||||
return ::lroundl(__x); | |||||
#endif | |||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, long>::type | typename std::enable_if<std::is_integral<_A1>::value, long>::type | ||||
lround(_A1 __x) _NOEXCEPT | lround(_A1 __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_lround) | |||||
return __builtin_lround((double)__x); | return __builtin_lround((double)__x); | ||||
#else | |||||
return ::lround((double)__x); | |||||
#endif | |||||
} | } | ||||
// nan | // nan | ||||
// nearbyint | // nearbyint | ||||
inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT {return ::nearbyintf(__x);} | inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT {return ::nearbyintf(__x);} | ||||
inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT {return ::nearbyintl(__x);} | inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT {return ::nearbyintl(__x);} | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | static_assert((!(std::_IsSame<_A1, __result_type>::value && | ||||
std::_IsSame<_A2, __result_type>::value)), ""); | std::_IsSame<_A2, __result_type>::value)), ""); | ||||
return ::remquo((__result_type)__x, (__result_type)__y, __z); | return ::remquo((__result_type)__x, (__result_type)__y, __z); | ||||
} | } | ||||
// rint | // rint | ||||
inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_rintf) | |||||
return __builtin_rintf(__x); | return __builtin_rintf(__x); | ||||
#else | |||||
return ::rintf(__x); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_rintl) | |||||
return __builtin_rintl(__x); | return __builtin_rintl(__x); | ||||
#else | |||||
return ::rintl(__x); | |||||
#endif | |||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
rint(_A1 __x) _NOEXCEPT | rint(_A1 __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_rint) | |||||
return __builtin_rint((double)__x); | return __builtin_rint((double)__x); | ||||
#else | |||||
return ::rint((double)__x); | |||||
#endif | |||||
} | } | ||||
// round | // round | ||||
inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_round) | |||||
return __builtin_round(__x); | return __builtin_round(__x); | ||||
#else | |||||
return ::round(__x); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_roundl) | |||||
return __builtin_roundl(__x); | return __builtin_roundl(__x); | ||||
#else | |||||
return ::roundl(__x); | |||||
#endif | |||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
round(_A1 __x) _NOEXCEPT | round(_A1 __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_round) | |||||
return __builtin_round((double)__x); | return __builtin_round((double)__x); | ||||
#else | |||||
return ::round((double)__x); | |||||
#endif | |||||
} | } | ||||
// scalbln | // scalbln | ||||
inline _LIBCPP_HIDE_FROM_ABI float scalbln(float __x, long __y) _NOEXCEPT {return ::scalblnf(__x, __y);} | inline _LIBCPP_HIDE_FROM_ABI float scalbln(float __x, long __y) _NOEXCEPT {return ::scalblnf(__x, __y);} | ||||
inline _LIBCPP_HIDE_FROM_ABI long double scalbln(long double __x, long __y) _NOEXCEPT {return ::scalblnl(__x, __y);} | inline _LIBCPP_HIDE_FROM_ABI long double scalbln(long double __x, long __y) _NOEXCEPT {return ::scalblnl(__x, __y);} | ||||
template <class _A1> | template <class _A1> | ||||
Show All 20 Lines | |||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
tgamma(_A1 __x) _NOEXCEPT {return ::tgamma((double)__x);} | tgamma(_A1 __x) _NOEXCEPT {return ::tgamma((double)__x);} | ||||
// trunc | // trunc | ||||
inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_trunc) | |||||
return __builtin_trunc(__x); | return __builtin_trunc(__x); | ||||
#else | |||||
return ::trunc(__x); | |||||
#endif | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT | inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_truncl) | |||||
return __builtin_truncl(__x); | return __builtin_truncl(__x); | ||||
#else | |||||
return ::truncl(__x); | |||||
#endif | |||||
} | } | ||||
template <class _A1> | template <class _A1> | ||||
inline _LIBCPP_HIDE_FROM_ABI | inline _LIBCPP_HIDE_FROM_ABI | ||||
typename std::enable_if<std::is_integral<_A1>::value, double>::type | typename std::enable_if<std::is_integral<_A1>::value, double>::type | ||||
trunc(_A1 __x) _NOEXCEPT | trunc(_A1 __x) _NOEXCEPT | ||||
{ | { | ||||
#if __has_builtin(__builtin_trunc) | |||||
return __builtin_trunc((double)__x); | return __builtin_trunc((double)__x); | ||||
#else | |||||
return ::trunc((double)__x); | |||||
#endif | |||||
} | } | ||||
} // extern "C++" | } // extern "C++" | ||||
#endif // __cplusplus | #endif // __cplusplus | ||||
#else // _LIBCPP_MATH_H | #else // _LIBCPP_MATH_H | ||||
Show All 13 Lines |
Can you try to:
If that doesn't make the diff any better, nvm we'll review as-is, but I find it tricky to validate in the current state of the diff.