Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move _Floating_type_traits-related functions #4615

Merged
merged 3 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions stl/inc/cmath
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#endif // _HAS_CMATH_INTRINSICS

#if _HAS_CXX20
#include <xutility>
#include <type_traits>
#endif // _HAS_CXX20

#pragma pack(push, _CRT_PACKING)
Expand Down Expand Up @@ -1460,8 +1460,13 @@ _NODISCARD constexpr _Ty _Linear_for_lerp(const _Ty _ArgA, const _Ty _ArgB, cons
auto _Abs_smaller = _Float_abs(_Smaller);
auto _Abs_larger = _Float_abs(_Larger);
if (_Abs_larger < _Abs_smaller) {
_STD swap(_Smaller, _Larger);
_STD swap(_Abs_smaller, _Abs_larger);
_Ty _Tmp = _Smaller;
_Smaller = _Larger;
_Larger = _Tmp;

_Tmp = _Abs_smaller;
_Abs_smaller = _Abs_larger;
_Abs_larger = _Tmp;
}

if (_Abs_smaller > 1) {
Expand Down
16 changes: 16 additions & 0 deletions stl/inc/complex
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ struct _C_ldouble_complex {
#define _IM 1

_STD_BEGIN
// TRANSITION, workaround x86 ABI
// On x86 ABI, floating-point by-value arguments and return values are passed in 80-bit x87 registers.
// When the value is a 32-bit or 64-bit signaling NaN, the conversion to/from 80-bit raises FE_INVALID
// and turns it into a quiet NaN. This behavior is undesirable if we want to test for signaling NaNs.
template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_signaling_nan(const _Ty& _Xx) noexcept { // returns true if input is a signaling NaN
using _Traits = _Floating_type_traits<_Ty>;
const auto _Abs_bits = _Float_abs_bits(_Xx);
return _Abs_bits > _Traits::_Shifted_exponent_mask && ((_Abs_bits & _Traits::_Special_nan_mantissa_mask) == 0);
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_inf(const _Ty _Xx) noexcept { // constexpr isinf()
using _Traits = _Floating_type_traits<_Ty>;
return _Float_abs_bits(_Xx) == _Traits::_Shifted_exponent_mask;
}

// implements multi-precision floating-point arithmetic for numerical algorithms
#pragma float_control(precise, on, push)
Expand Down
26 changes: 2 additions & 24 deletions stl/inc/numeric
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@
#include <__msvc_bit_utils.hpp>
#endif // _HAS_CXX17

#if _HAS_CXX20
#include <cfloat>
#endif // _HAS_CXX20

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
Expand Down Expand Up @@ -645,24 +641,6 @@ _NODISCARD constexpr common_type_t<_Mt, _Nt> lcm(const _Mt _Mx, const _Nt _Nx) n
#endif // _HAS_CXX17

#if _HAS_CXX20
template <class _Flt>
constexpr _Flt _Floating_max{};
template <>
inline constexpr float _Floating_max<float> = FLT_MAX;
template <>
inline constexpr double _Floating_max<double> = DBL_MAX;
template <>
inline constexpr long double _Floating_max<long double> = LDBL_MAX;

template <class _Flt>
constexpr _Flt _Floating_min{};
template <>
inline constexpr float _Floating_min<float> = FLT_MIN;
template <>
inline constexpr double _Floating_min<double> = DBL_MIN;
template <>
inline constexpr long double _Floating_min<long double> = LDBL_MIN;

_EXPORT_STD template <class _Ty, enable_if_t<is_arithmetic_v<_Ty> && !is_same_v<remove_cv_t<_Ty>, bool>, int> = 0>
_NODISCARD constexpr _Ty midpoint(const _Ty _Val1, const _Ty _Val2) noexcept {
if constexpr (is_floating_point_v<_Ty>) {
Expand All @@ -681,7 +659,7 @@ _NODISCARD constexpr _Ty midpoint(const _Ty _Val1, const _Ty _Val2) noexcept {
}
}

constexpr _Ty _High_limit = _Floating_max<remove_cv_t<_Ty>> / 2;
constexpr _Ty _High_limit = _Floating_type_traits<remove_cv_t<_Ty>>::_Maximum_value / 2;
const auto _Val1_a = _Float_abs(_Val1);
const auto _Val2_a = _Float_abs(_Val2);
if (_Val1_a <= _High_limit && _Val2_a <= _High_limit) {
Expand All @@ -705,7 +683,7 @@ _NODISCARD constexpr _Ty midpoint(const _Ty _Val1, const _Ty _Val2) noexcept {

// In the default rounding mode this less than one ULP difference will always be rounded away, so under
// /fp:fast we could avoid these tests if we had some means of detecting it in the caller.
constexpr _Ty _Low_limit = _Floating_min<remove_cv_t<_Ty>> * 2;
constexpr _Ty _Low_limit = _Floating_type_traits<remove_cv_t<_Ty>>::_Minimum_value * 2;
if (_Val1_a < _Low_limit) {
return _Val1 + _Val2 / 2;
}
Expand Down
31 changes: 31 additions & 0 deletions stl/inc/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -2443,6 +2443,9 @@ struct _Floating_type_traits<float> {
static constexpr uint32_t _Special_nan_mantissa_mask = 0x00400000u; // 1u << (_Mantissa_bits - 2)
static constexpr uint32_t _Shifted_sign_mask = 0x80000000u; // 1u << _Sign_shift
static constexpr uint32_t _Shifted_exponent_mask = 0x7F800000u; // _Exponent_mask << _Exponent_shift

static constexpr float _Minimum_value = 0x1.000000p-126f; // FLT_MIN
static constexpr float _Maximum_value = 0x1.FFFFFEp+127f; // FLT_MAX
};

template <>
Expand All @@ -2463,6 +2466,9 @@ struct _Floating_type_traits<double> {
static constexpr uint64_t _Special_nan_mantissa_mask = 0x0008000000000000u; // 1ULL << (_Mantissa_bits - 2)
static constexpr uint64_t _Shifted_sign_mask = 0x8000000000000000u; // 1ULL << _Sign_shift
static constexpr uint64_t _Shifted_exponent_mask = 0x7FF0000000000000u; // _Exponent_mask << _Exponent_shift

static constexpr double _Minimum_value = 0x1.0000000000000p-1022; // DBL_MIN
static constexpr double _Maximum_value = 0x1.FFFFFFFFFFFFFp+1023; // DBL_MAX
};

template <>
Expand All @@ -2478,6 +2484,31 @@ _NODISCARD constexpr _To _Bit_cast(const _From& _Val) noexcept {
return __builtin_bit_cast(_To, _Val);
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr auto _Float_abs_bits(const _Ty& _Xx) noexcept {
using _Traits = _Floating_type_traits<_Ty>;
using _Uint_type = typename _Traits::_Uint_type;
const auto _Bits = _Bit_cast<_Uint_type>(_Xx);
return _Bits & ~_Traits::_Shifted_sign_mask;
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr _Ty _Float_abs(const _Ty _Xx) noexcept { // constexpr floating-point abs()
return _Bit_cast<_Ty>(_Float_abs_bits(_Xx));
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_nan(const _Ty _Xx) noexcept { // constexpr isnan()
using _Traits = _Floating_type_traits<_Ty>;
return _Float_abs_bits(_Xx) > _Traits::_Shifted_exponent_mask;
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_finite(const _Ty _Xx) noexcept { // constexpr isfinite()
using _Traits = _Floating_type_traits<_Ty>;
return _Float_abs_bits(_Xx) < _Traits::_Shifted_exponent_mask;
}

template <bool _IsConst, class _Ty>
using _Maybe_const = conditional_t<_IsConst, const _Ty, _Ty>;

Expand Down
50 changes: 0 additions & 50 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -7350,56 +7350,6 @@ struct _CXX17_DEPRECATE_ITERATOR_BASE_CLASS iterator { // base type for iterator
using reference = _Reference;
};

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr auto _Float_abs_bits(const _Ty& _Xx) noexcept {
using _Traits = _Floating_type_traits<_Ty>;
using _Uint_type = typename _Traits::_Uint_type;
const auto _Bits = _Bit_cast<_Uint_type>(_Xx);
return _Bits & ~_Traits::_Shifted_sign_mask;
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr _Ty _Float_abs(const _Ty _Xx) noexcept { // constexpr floating-point abs()
return _Bit_cast<_Ty>(_Float_abs_bits(_Xx));
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr _Ty _Float_copysign(const _Ty _Magnitude, const _Ty _Sign) { // constexpr copysign()
using _Traits = _Floating_type_traits<_Ty>;
using _Uint_type = typename _Traits::_Uint_type;
const auto _Signbit = _Bit_cast<_Uint_type>(_Sign) & _Traits::_Shifted_sign_mask;
return _Bit_cast<_Ty>(_Float_abs_bits(_Magnitude) | _Signbit);
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_nan(const _Ty _Xx) noexcept { // constexpr isnan()
using _Traits = _Floating_type_traits<_Ty>;
return _Float_abs_bits(_Xx) > _Traits::_Shifted_exponent_mask;
}

// TRANSITION, workaround x86 ABI
// On x86 ABI, floating-point by-value arguments and return values are passed in 80-bit x87 registers.
// When the value is a 32-bit or 64-bit signaling NaN, the conversion to/from 80-bit raises FE_INVALID
// and turns it into a quiet NaN. This behavior is undesirable if we want to test for signaling NaNs.
template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_signaling_nan(const _Ty& _Xx) noexcept { // returns true if input is a signaling NaN
using _Traits = _Floating_type_traits<_Ty>;
const auto _Abs_bits = _Float_abs_bits(_Xx);
return _Abs_bits > _Traits::_Shifted_exponent_mask && ((_Abs_bits & _Traits::_Special_nan_mantissa_mask) == 0);
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_inf(const _Ty _Xx) noexcept { // constexpr isinf()
using _Traits = _Floating_type_traits<_Ty>;
return _Float_abs_bits(_Xx) == _Traits::_Shifted_exponent_mask;
}

template <class _Ty, enable_if_t<is_floating_point_v<_Ty>, int> = 0>
_NODISCARD constexpr bool _Is_finite(const _Ty _Xx) noexcept { // constexpr isfinite()
using _Traits = _Floating_type_traits<_Ty>;
return _Float_abs_bits(_Xx) < _Traits::_Shifted_exponent_mask;
}

#if _HAS_CXX17
_EXPORT_STD struct monostate {};
#endif // _HAS_CXX17
Expand Down