diff --git a/stl/inc/complex b/stl/inc/complex index ce60701b76..4cbee83eba 100644 --- a/stl/inc/complex +++ b/stl/inc/complex @@ -243,7 +243,7 @@ namespace _Math_algorithms { // TRANSITION: CRT log1p can be inaccurate for tiny inputs under directed rounding modes template - _NODISCARD _Ty _Logp1(const _Ty _Xval) { // returns log(1 + _Xval) + _NODISCARD _Ty _Logp1(const _Ty _Xval) noexcept { // returns log(1 + _Xval) static_assert(is_floating_point_v<_Ty>, "_Ty must be floating-point"); if (_Is_nan(_Xval)) { // NaN @@ -496,41 +496,42 @@ class _Ctraits { public: using _Ty = long double; - static constexpr _Ty _Flt_eps() { // get epsilon + static constexpr _Ty _Flt_eps() noexcept { // get epsilon return numeric_limits::epsilon(); } - static constexpr _Ty _Flt_max() { + static constexpr _Ty _Flt_max() noexcept { return (numeric_limits::max)(); } - static constexpr _Ty _Flt_norm_min() { + static constexpr _Ty _Flt_norm_min() noexcept { return (numeric_limits::min)(); } - static _Ty _Abs(_Ty _Left) { + static _Ty _Abs(_Ty _Left) noexcept { // testing _Left < 0 would be incorrect when _Left is -0.0 return _CSTD fabsl(_Left); } - static _Ty _Cosh(_Ty _Left, _Ty _Right) { // return cosh(_Left) * _Right + static _Ty _Cosh(_Ty _Left, _Ty _Right) noexcept { // return cosh(_Left) * _Right return _CSTD _LCosh(_Left, _Right); } - static _Ty _Copysign(_Ty _Magnitude, _Ty _Sign) { + static _Ty _Copysign(_Ty _Magnitude, _Ty _Sign) noexcept { // testing _Sign < 0 would be incorrect when _Sign is -0.0 return _CSTD copysignl(_Magnitude, _Sign); } - static short _Exp(_Ty* _Pleft, _Ty _Right, short _Exponent) { // compute exp(*_Pleft) * _Right * 2 ^ _Exponent + static short _Exp(_Ty* _Pleft, _Ty _Right, short _Exponent) noexcept { + // compute exp(*_Pleft) * _Right * 2 ^ _Exponent return _CSTD _LExp(_Pleft, _Right, _Exponent); } - static constexpr _Ty _Infv() { // return infinity + static constexpr _Ty _Infv() noexcept { // return infinity return numeric_limits::infinity(); } - static bool _Isinf(_Ty _Left) { // test for infinity + static bool _Isinf(_Ty _Left) noexcept { // test for infinity #if defined(__LDBL_DIG__) && __LDBL_DIG__ == 18 return _CSTD _LDtest(&_Left) == _INFCODE; #else // ^^^ 80-bit long double (not supported by MSVC in general, see GH-1316) / 64-bit long double vvv @@ -539,7 +540,7 @@ public: #endif // ^^^ 64-bit long double ^^^ } - static _CONSTEXPR20 bool _Isnan(_Ty _Left) { + static _CONSTEXPR20 bool _Isnan(_Ty _Left) noexcept { #if defined(__LDBL_DIG__) && __LDBL_DIG__ == 18 return _CSTD _LDtest(&_Left) == _NANCODE; #else // ^^^ 80-bit long double (not supported by MSVC in general, see GH-1316) / 64-bit long double vvv @@ -548,20 +549,20 @@ public: #endif // ^^^ 64-bit long double ^^^ } - static constexpr _Ty _Nanv() { // return NaN + static constexpr _Ty _Nanv() noexcept { // return NaN return numeric_limits::quiet_NaN(); } - static bool _Signbit(_Ty _Left) { + static bool _Signbit(_Ty _Left) noexcept { // testing _Left < 0 would be incorrect when _Left is -0.0 return (_STD signbit)(_Left); } - static _Ty _Sinh(_Ty _Left, _Ty _Right) { // return sinh(_Left) * _Right + static _Ty _Sinh(_Ty _Left, _Ty _Right) noexcept { // return sinh(_Left) * _Right return _CSTD _LSinh(_Left, _Right); } - static _Ty asinh(_Ty _Left) { + static _Ty asinh(_Ty _Left) noexcept { if (_Left == 0 || _Isnan(_Left) || _Isinf(_Left)) { return _Left; } @@ -582,27 +583,27 @@ public: return _Copysign(_Ans, _Old_left); } - static _Ty atan2(_Ty _Yval, _Ty _Xval) { // return atan(_Yval / _Xval) + static _Ty atan2(_Ty _Yval, _Ty _Xval) noexcept { // return atan(_Yval / _Xval) return _CSTD atan2l(_Yval, _Xval); } - static _Ty cos(_Ty _Left) { + static _Ty cos(_Ty _Left) noexcept { return _CSTD cosl(_Left); } - static _Ty exp(_Ty _Left) { + static _Ty exp(_Ty _Left) noexcept { return _CSTD expl(_Left); } - static _Ty ldexp(_Ty _Left, int _Exponent) { // return _Left * 2 ^ _Exponent + static _Ty ldexp(_Ty _Left, int _Exponent) noexcept { // return _Left * 2 ^ _Exponent return _CSTD ldexpl(_Left, _Exponent); } - static _Ty log(_Ty _Left) { + static _Ty log(_Ty _Left) noexcept { return _CSTD logl(_Left); } - static _Ty log1p(_Ty _Left) { // return log(1 + _Left) + static _Ty log1p(_Ty _Left) noexcept { // return log(1 + _Left) if (_Left < -1) { return _Nanv(); } else if (_Left == 0) { @@ -613,23 +614,23 @@ public: } } - static _Ty pow(_Ty _Left, _Ty _Right) { + static _Ty pow(_Ty _Left, _Ty _Right) noexcept { return _CSTD powl(_Left, _Right); } - static _Ty sin(_Ty _Left) { + static _Ty sin(_Ty _Left) noexcept { return _CSTD sinl(_Left); } - static _Ty sqrt(_Ty _Left) { + static _Ty sqrt(_Ty _Left) noexcept { return _CSTD sqrtl(_Left); } - static _Ty tan(_Ty _Left) { + static _Ty tan(_Ty _Left) noexcept { return _CSTD tanl(_Left); } - static _Ty hypot(_Ty _Left, _Ty _Right) { + static _Ty hypot(_Ty _Left, _Ty _Right) noexcept { return _CSTD hypotl(_Left, _Right); } }; @@ -639,64 +640,65 @@ class _Ctraits { public: using _Ty = double; - static constexpr _Ty _Flt_eps() { // get epsilon + static constexpr _Ty _Flt_eps() noexcept { // get epsilon return numeric_limits::epsilon(); } - static constexpr _Ty _Flt_max() { + static constexpr _Ty _Flt_max() noexcept { return (numeric_limits::max)(); } - static constexpr _Ty _Flt_norm_min() { + static constexpr _Ty _Flt_norm_min() noexcept { return (numeric_limits::min)(); } - static _Ty _Abs(_Ty _Left) { + static _Ty _Abs(_Ty _Left) noexcept { // testing _Left < 0 would be incorrect when _Left is -0.0 return _CSTD fabs(_Left); } - static _Ty _Cosh(_Ty _Left, _Ty _Right) { // return cosh(_Left) * _Right + static _Ty _Cosh(_Ty _Left, _Ty _Right) noexcept { // return cosh(_Left) * _Right return _CSTD _Cosh(_Left, _Right); } - static _Ty _Copysign(_Ty _Magnitude, _Ty _Sign) { + static _Ty _Copysign(_Ty _Magnitude, _Ty _Sign) noexcept { // testing _Sign < 0 would be incorrect when _Sign is -0.0 return _CSTD copysign(_Magnitude, _Sign); } - static short _Exp(_Ty* _Pleft, _Ty _Right, short _Exponent) { // compute exp(*_Pleft) * _Right * 2 ^ _Exponent + static short _Exp(_Ty* _Pleft, _Ty _Right, short _Exponent) noexcept { + // compute exp(*_Pleft) * _Right * 2 ^ _Exponent return _CSTD _Exp(_Pleft, _Right, _Exponent); } - static constexpr _Ty _Infv() { // return infinity + static constexpr _Ty _Infv() noexcept { // return infinity return numeric_limits::infinity(); } - static bool _Isinf(_Ty _Left) { // test for infinity + static bool _Isinf(_Ty _Left) noexcept { // test for infinity const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffffffffffU) == 0x7ff0000000000000U; } - static _CONSTEXPR20 bool _Isnan(_Ty _Left) { + static _CONSTEXPR20 bool _Isnan(_Ty _Left) noexcept { const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffffffffffU) > 0x7ff0000000000000U; } - static constexpr _Ty _Nanv() { // return NaN + static constexpr _Ty _Nanv() noexcept { // return NaN return numeric_limits::quiet_NaN(); } - static bool _Signbit(_Ty _Left) { + static bool _Signbit(_Ty _Left) noexcept { // testing _Left < 0 would be incorrect when _Left is -0.0 return (_STD signbit)(_Left); } - static _Ty _Sinh(_Ty _Left, _Ty _Right) { // return sinh(_Left) * _Right + static _Ty _Sinh(_Ty _Left, _Ty _Right) noexcept { // return sinh(_Left) * _Right return _CSTD _Sinh(_Left, _Right); } - static _Ty asinh(_Ty _Left) { + static _Ty asinh(_Ty _Left) noexcept { if (_Isnan(_Left) || _Isinf(_Left) || _Left == 0) { return _Left; } else { // _Left finite nonzero @@ -716,27 +718,27 @@ public: } } - static _Ty atan2(_Ty _Yval, _Ty _Xval) { // return atan(_Yval / _Xval) + static _Ty atan2(_Ty _Yval, _Ty _Xval) noexcept { // return atan(_Yval / _Xval) return _CSTD atan2(_Yval, _Xval); } - static _Ty cos(_Ty _Left) { + static _Ty cos(_Ty _Left) noexcept { return _CSTD cos(_Left); } - static _Ty exp(_Ty _Left) { + static _Ty exp(_Ty _Left) noexcept { return _CSTD exp(_Left); } - static _Ty ldexp(_Ty _Left, int _Exponent) { // return _Left * 2 ^ _Exponent + static _Ty ldexp(_Ty _Left, int _Exponent) noexcept { // return _Left * 2 ^ _Exponent return _CSTD ldexp(_Left, _Exponent); } - static _Ty log(_Ty _Left) { + static _Ty log(_Ty _Left) noexcept { return _CSTD log(_Left); } - static _Ty log1p(_Ty _Left) { // return log(1 + _Left) + static _Ty log1p(_Ty _Left) noexcept { // return log(1 + _Left) if (_Isnan(_Left) || _Left == 0 || (_Isinf(_Left) && 0 < _Left)) { return _Left; } else if (_Left < -1) { @@ -751,23 +753,23 @@ public: } } - static _Ty pow(_Ty _Left, _Ty _Right) { + static _Ty pow(_Ty _Left, _Ty _Right) noexcept { return _CSTD pow(_Left, _Right); } - static _Ty sin(_Ty _Left) { + static _Ty sin(_Ty _Left) noexcept { return _CSTD sin(_Left); } - static _Ty sqrt(_Ty _Left) { + static _Ty sqrt(_Ty _Left) noexcept { return _CSTD sqrt(_Left); } - static _Ty tan(_Ty _Left) { + static _Ty tan(_Ty _Left) noexcept { return _CSTD tan(_Left); } - static _Ty hypot(_Ty _Left, _Ty _Right) { + static _Ty hypot(_Ty _Left, _Ty _Right) noexcept { return _CSTD hypot(_Left, _Right); } }; @@ -777,64 +779,65 @@ class _Ctraits { public: using _Ty = float; - static constexpr _Ty _Flt_eps() { // get epsilon + static constexpr _Ty _Flt_eps() noexcept { // get epsilon return numeric_limits::epsilon(); } - static constexpr _Ty _Flt_max() { + static constexpr _Ty _Flt_max() noexcept { return (numeric_limits::max)(); } - static constexpr _Ty _Flt_norm_min() { + static constexpr _Ty _Flt_norm_min() noexcept { return (numeric_limits::min)(); } - static _Ty _Abs(_Ty _Left) { + static _Ty _Abs(_Ty _Left) noexcept { // testing _Left < 0 would be incorrect when _Left is -0.0 return _CSTD fabsf(_Left); } - static _Ty _Cosh(_Ty _Left, _Ty _Right) { // return cosh(_Left) * _Right + static _Ty _Cosh(_Ty _Left, _Ty _Right) noexcept { // return cosh(_Left) * _Right return _CSTD _FCosh(_Left, _Right); } - static _Ty _Copysign(_Ty _Magnitude, _Ty _Sign) { + static _Ty _Copysign(_Ty _Magnitude, _Ty _Sign) noexcept { // testing _Sign < 0 would be incorrect when _Sign is -0.0 return _CSTD copysignf(_Magnitude, _Sign); } - static short _Exp(_Ty* _Pleft, _Ty _Right, short _Exponent) { // compute exp(*_Pleft) * _Right * 2 ^ _Exponent + static short _Exp(_Ty* _Pleft, _Ty _Right, short _Exponent) noexcept { + // compute exp(*_Pleft) * _Right * 2 ^ _Exponent return _CSTD _FExp(_Pleft, _Right, _Exponent); } - static constexpr _Ty _Infv() { // return infinity + static constexpr _Ty _Infv() noexcept { // return infinity return numeric_limits::infinity(); } - static bool _Isinf(_Ty _Left) { // test for infinity + static bool _Isinf(_Ty _Left) noexcept { // test for infinity const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffU) == 0x7f800000U; } - static _CONSTEXPR20 bool _Isnan(_Ty _Left) { + static _CONSTEXPR20 bool _Isnan(_Ty _Left) noexcept { const auto _Uint = _Bit_cast(_Left); return (_Uint & 0x7fffffffU) > 0x7f800000U; } - static constexpr _Ty _Nanv() { // return NaN + static constexpr _Ty _Nanv() noexcept { // return NaN return numeric_limits::quiet_NaN(); } - static bool _Signbit(_Ty _Left) { + static bool _Signbit(_Ty _Left) noexcept { // testing _Left < 0 would be incorrect when _Left is -0.0 return (_STD signbit)(_Left); } - static _Ty _Sinh(_Ty _Left, _Ty _Right) { // return sinh(_Left) * _Right + static _Ty _Sinh(_Ty _Left, _Ty _Right) noexcept { // return sinh(_Left) * _Right return _CSTD _FSinh(_Left, _Right); } - static _Ty asinh(_Ty _Left) { + static _Ty asinh(_Ty _Left) noexcept { if (_Left == 0 || _Isnan(_Left) || _Isinf(_Left)) { return _Left; } @@ -855,27 +858,27 @@ public: return _Copysign(_Ans, _Old_left); } - static _Ty atan2(_Ty _Yval, _Ty _Xval) { // return atan(_Yval / _Xval) + static _Ty atan2(_Ty _Yval, _Ty _Xval) noexcept { // return atan(_Yval / _Xval) return _CSTD atan2f(_Yval, _Xval); } - static _Ty cos(_Ty _Left) { + static _Ty cos(_Ty _Left) noexcept { return _CSTD cosf(_Left); } - static _Ty exp(_Ty _Left) { + static _Ty exp(_Ty _Left) noexcept { return _CSTD expf(_Left); } - static _Ty ldexp(_Ty _Left, int _Exponent) { // return _Left * 2 ^ _Exponent + static _Ty ldexp(_Ty _Left, int _Exponent) noexcept { // return _Left * 2 ^ _Exponent return _CSTD ldexpf(_Left, _Exponent); } - static _Ty log(_Ty _Left) { + static _Ty log(_Ty _Left) noexcept { return _CSTD logf(_Left); } - static _Ty log1p(_Ty _Left) { // return log(1 + _Left) + static _Ty log1p(_Ty _Left) noexcept { // return log(1 + _Left) if (_Left < -1) { return _Nanv(); } else if (_Left == 0) { @@ -886,27 +889,30 @@ public: } } - static _Ty pow(_Ty _Left, _Ty _Right) { + static _Ty pow(_Ty _Left, _Ty _Right) noexcept { return _CSTD powf(_Left, _Right); } - static _Ty sin(_Ty _Left) { + static _Ty sin(_Ty _Left) noexcept { return _CSTD sinf(_Left); } - static _Ty sqrt(_Ty _Left) { + static _Ty sqrt(_Ty _Left) noexcept { return _CSTD sqrtf(_Left); } - static _Ty tan(_Ty _Left) { + static _Ty tan(_Ty _Left) noexcept { return _CSTD tanf(_Left); } - static _Ty hypot(_Ty _Left, _Ty _Right) { + static _Ty hypot(_Ty _Left, _Ty _Right) noexcept { return _CSTD hypotf(_Left, _Right); } }; +template +_INLINE_VAR constexpr bool _Is_unqual_fp = _Is_any_of_v<_Ty, float, double, long double>; + template struct _Complex_value { enum { _Re = 0, _Im = 1 }; @@ -915,43 +921,52 @@ struct _Complex_value { template class _Complex_base : public _Valbase { +private: + static constexpr bool _Is_for_standard_complex = _Is_any_of_v<_Complex_base, _Complex_base, + _Complex_base, _Complex_base>; + public: using _Myctraits = _Ctraits<_Ty>; using value_type = _Ty; - constexpr _Complex_base(const _Ty& _Realval, const _Ty& _Imagval) : _Valbase{{_Realval, _Imagval}} {} + constexpr _Complex_base(const _Ty& _Realval, const _Ty& _Imagval) noexcept(_Is_for_standard_complex) + : _Valbase{{_Realval, _Imagval}} {} - _CONSTEXPR20 void real(const _Ty& _Right) { // set real component + _CONSTEXPR20 void real(const _Ty& _Right) noexcept(_Is_for_standard_complex) /* strengthened */ { + // set real component this->_Val[_RE] = _Right; } - _CONSTEXPR20 void imag(const _Ty& _Right) { // set imaginary component + _CONSTEXPR20 void imag(const _Ty& _Right) noexcept(_Is_for_standard_complex) /* strengthened */ { + // set imaginary component this->_Val[_IM] = _Right; } - _NODISCARD constexpr _Ty real() const { // return real component + _NODISCARD constexpr _Ty real() const noexcept(_Is_for_standard_complex) /* strengthened */ { + // return real component return this->_Val[_RE]; } - _NODISCARD constexpr _Ty imag() const { // return imaginary component + _NODISCARD constexpr _Ty imag() const noexcept(_Is_for_standard_complex) /* strengthened */ { + // return imaginary component return this->_Val[_IM]; } protected: template - _CONSTEXPR20 void _Add(const complex<_Other>& _Right) { + _CONSTEXPR20 void _Add(const complex<_Other>& _Right) noexcept(_Is_for_standard_complex&& _Is_unqual_fp<_Other>) { this->_Val[_RE] = this->_Val[_RE] + static_cast<_Ty>(_Right.real()); this->_Val[_IM] = this->_Val[_IM] + static_cast<_Ty>(_Right.imag()); } template - _CONSTEXPR20 void _Sub(const complex<_Other>& _Right) { + _CONSTEXPR20 void _Sub(const complex<_Other>& _Right) noexcept(_Is_for_standard_complex&& _Is_unqual_fp<_Other>) { this->_Val[_RE] = this->_Val[_RE] - static_cast<_Ty>(_Right.real()); this->_Val[_IM] = this->_Val[_IM] - static_cast<_Ty>(_Right.imag()); } template - _CONSTEXPR20 void _Mul(const complex<_Other>& _Right) { + _CONSTEXPR20 void _Mul(const complex<_Other>& _Right) noexcept(_Is_for_standard_complex&& _Is_unqual_fp<_Other>) { _Ty _Rightreal = static_cast<_Ty>(_Right.real()); _Ty _Rightimag = static_cast<_Ty>(_Right.imag()); @@ -961,7 +976,7 @@ protected: } template - _CONSTEXPR20 void _Div(const complex<_Other>& _Right) { + _CONSTEXPR20 void _Div(const complex<_Other>& _Right) noexcept(_Is_for_standard_complex&& _Is_unqual_fp<_Other>) { using _Myctraits = _Ctraits<_Ty>; _Ty _Rightreal = static_cast<_Ty>(_Right.real()); @@ -1007,87 +1022,87 @@ class complex : public _Complex_base { public: using _Ty = float; - constexpr explicit complex(const complex&); // defined below - constexpr explicit complex(const complex&); // defined below + constexpr explicit complex(const complex&) noexcept; // strengthened, defined below + constexpr explicit complex(const complex&) noexcept; // strengthened, defined below - constexpr complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0) + constexpr complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0) noexcept // strengthened : _Complex_base(_Realval, _Imagval) {} - _CONSTEXPR20 complex& operator=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Right; _Val[_IM] = 0; return *this; } - _CONSTEXPR20 complex& operator+=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator+=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] + _Right; return *this; } - _CONSTEXPR20 complex& operator-=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator-=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] - _Right; return *this; } - _CONSTEXPR20 complex& operator*=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator*=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] * _Right; _Val[_IM] = _Val[_IM] * _Right; return *this; } - _CONSTEXPR20 complex& operator/=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator/=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] / _Right; _Val[_IM] = _Val[_IM] / _Right; return *this; } - _CONSTEXPR20 complex& operator+=(const complex& _Right) { + _CONSTEXPR20 complex& operator+=(const complex& _Right) noexcept /* strengthened */ { this->_Add(_Right); return *this; } - _CONSTEXPR20 complex& operator-=(const complex& _Right) { + _CONSTEXPR20 complex& operator-=(const complex& _Right) noexcept /* strengthened */ { this->_Sub(_Right); return *this; } - _CONSTEXPR20 complex& operator*=(const complex& _Right) { + _CONSTEXPR20 complex& operator*=(const complex& _Right) noexcept /* strengthened */ { this->_Mul(_Right); return *this; } - _CONSTEXPR20 complex& operator/=(const complex& _Right) { + _CONSTEXPR20 complex& operator/=(const complex& _Right) noexcept /* strengthened */ { this->_Div(_Right); return *this; } template - _CONSTEXPR20 complex& operator=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { _Val[_RE] = static_cast<_Ty>(_Right._Val[_RE]); _Val[_IM] = static_cast<_Ty>(_Right._Val[_IM]); return *this; } template - _CONSTEXPR20 complex& operator+=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator+=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Add(_Right); return *this; } template - _CONSTEXPR20 complex& operator-=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator-=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Sub(_Right); return *this; } template - _CONSTEXPR20 complex& operator*=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator*=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Mul(_Right); return *this; } template - _CONSTEXPR20 complex& operator/=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator/=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Div(_Right); return *this; } @@ -1098,87 +1113,87 @@ class complex : public _Complex_base { public: using _Ty = double; - constexpr complex(const complex&); // defined below - constexpr explicit complex(const complex&); // defined below + constexpr complex(const complex&) noexcept; // strengthened, defined below + constexpr explicit complex(const complex&) noexcept; // strengthened, defined below - constexpr complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0) + constexpr complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0) noexcept // strengthened : _Complex_base(_Realval, _Imagval) {} - _CONSTEXPR20 complex& operator=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Right; _Val[_IM] = 0; return *this; } - _CONSTEXPR20 complex& operator+=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator+=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] + _Right; return *this; } - _CONSTEXPR20 complex& operator-=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator-=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] - _Right; return *this; } - _CONSTEXPR20 complex& operator*=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator*=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] * _Right; _Val[_IM] = _Val[_IM] * _Right; return *this; } - _CONSTEXPR20 complex& operator/=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator/=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] / _Right; _Val[_IM] = _Val[_IM] / _Right; return *this; } - _CONSTEXPR20 complex& operator+=(const complex& _Right) { + _CONSTEXPR20 complex& operator+=(const complex& _Right) noexcept /* strengthened */ { this->_Add(_Right); return *this; } - _CONSTEXPR20 complex& operator-=(const complex& _Right) { + _CONSTEXPR20 complex& operator-=(const complex& _Right) noexcept /* strengthened */ { this->_Sub(_Right); return *this; } - _CONSTEXPR20 complex& operator*=(const complex& _Right) { + _CONSTEXPR20 complex& operator*=(const complex& _Right) noexcept /* strengthened */ { this->_Mul(_Right); return *this; } - _CONSTEXPR20 complex& operator/=(const complex& _Right) { + _CONSTEXPR20 complex& operator/=(const complex& _Right) noexcept /* strengthened */ { this->_Div(_Right); return *this; } template - _CONSTEXPR20 complex& operator=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { _Val[_RE] = static_cast<_Ty>(_Right._Val[_RE]); _Val[_IM] = static_cast<_Ty>(_Right._Val[_IM]); return *this; } template - _CONSTEXPR20 complex& operator+=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator+=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Add(_Right); return *this; } template - _CONSTEXPR20 complex& operator-=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator-=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Sub(_Right); return *this; } template - _CONSTEXPR20 complex& operator*=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator*=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Mul(_Right); return *this; } template - _CONSTEXPR20 complex& operator/=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator/=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Div(_Right); return *this; } @@ -1189,108 +1204,108 @@ class complex : public _Complex_base public: using _Ty = long double; - constexpr complex(const complex&); // defined below - constexpr complex(const complex&); // defined below + constexpr complex(const complex&) noexcept; // strengthened, defined below + constexpr complex(const complex&) noexcept; // strengthened, defined below - constexpr complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0) + constexpr complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0) noexcept // strengthened : _Complex_base(_Realval, _Imagval) {} - _CONSTEXPR20 complex& operator=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Right; _Val[_IM] = 0; return *this; } - _CONSTEXPR20 complex& operator+=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator+=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] + _Right; return *this; } - _CONSTEXPR20 complex& operator-=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator-=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] - _Right; return *this; } - _CONSTEXPR20 complex& operator*=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator*=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] * _Right; _Val[_IM] = _Val[_IM] * _Right; return *this; } - _CONSTEXPR20 complex& operator/=(const _Ty& _Right) { + _CONSTEXPR20 complex& operator/=(const _Ty& _Right) noexcept /* strengthened */ { _Val[_RE] = _Val[_RE] / _Right; _Val[_IM] = _Val[_IM] / _Right; return *this; } - _CONSTEXPR20 complex& operator+=(const complex& _Right) { + _CONSTEXPR20 complex& operator+=(const complex& _Right) noexcept /* strengthened */ { this->_Add(_Right); return *this; } - _CONSTEXPR20 complex& operator-=(const complex& _Right) { + _CONSTEXPR20 complex& operator-=(const complex& _Right) noexcept /* strengthened */ { this->_Sub(_Right); return *this; } - _CONSTEXPR20 complex& operator*=(const complex& _Right) { + _CONSTEXPR20 complex& operator*=(const complex& _Right) noexcept /* strengthened */ { this->_Mul(_Right); return *this; } - _CONSTEXPR20 complex& operator/=(const complex& _Right) { + _CONSTEXPR20 complex& operator/=(const complex& _Right) noexcept /* strengthened */ { this->_Div(_Right); return *this; } template - _CONSTEXPR20 complex& operator=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { _Val[_RE] = static_cast<_Ty>(_Right._Val[_RE]); _Val[_IM] = static_cast<_Ty>(_Right._Val[_IM]); return *this; } template - _CONSTEXPR20 complex& operator+=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator+=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Add(_Right); return *this; } template - _CONSTEXPR20 complex& operator-=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator-=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Sub(_Right); return *this; } template - _CONSTEXPR20 complex& operator*=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator*=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Mul(_Right); return *this; } template - _CONSTEXPR20 complex& operator/=(const complex<_Other>& _Right) { + _CONSTEXPR20 complex& operator/=(const complex<_Other>& _Right) noexcept(_Is_unqual_fp<_Other>) /* strengthened */ { this->_Div(_Right); return *this; } }; -constexpr complex::complex(const complex& _Right) +constexpr complex::complex(const complex& _Right) noexcept // strengthened : _Complex_base(static_cast<_Ty>(_Right.real()), static_cast<_Ty>(_Right.imag())) {} -constexpr complex::complex(const complex& _Right) +constexpr complex::complex(const complex& _Right) noexcept // strengthened : _Complex_base(static_cast<_Ty>(_Right.real()), static_cast<_Ty>(_Right.imag())) {} -constexpr complex::complex(const complex& _Right) +constexpr complex::complex(const complex& _Right) noexcept // strengthened : _Complex_base(_Right.real(), _Right.imag()) {} -constexpr complex::complex(const complex& _Right) +constexpr complex::complex(const complex& _Right) noexcept // strengthened : _Complex_base(static_cast<_Ty>(_Right.real()), static_cast<_Ty>(_Right.imag())) {} -constexpr complex::complex(const complex& _Right) +constexpr complex::complex(const complex& _Right) noexcept // strengthened : _Complex_base(_Right.real(), _Right.imag()) {} -constexpr complex::complex(const complex& _Right) +constexpr complex::complex(const complex& _Right) noexcept // strengthened : _Complex_base(_Right.real(), _Right.imag()) {} _EXPORT_STD template @@ -1386,151 +1401,171 @@ public: }; _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const complex<_Ty>& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const complex<_Ty>& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp += _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const complex<_Ty>& _Left, const _Ty& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const complex<_Ty>& _Left, const _Ty& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp += _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const _Ty& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const _Ty& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Right); _Tmp += _Left; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const complex<_Ty>& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const complex<_Ty>& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp -= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const complex<_Ty>& _Left, const _Ty& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const complex<_Ty>& _Left, const _Ty& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp -= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const _Ty& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const _Ty& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp -= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator*(const complex<_Ty>& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator*(const complex<_Ty>& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp *= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator*(const complex<_Ty>& _Left, const _Ty& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator*(const complex<_Ty>& _Left, const _Ty& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp *= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator*(const _Ty& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator*(const _Ty& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Right); _Tmp *= _Left; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator/(const complex<_Ty>& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator/(const complex<_Ty>& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp /= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator/(const complex<_Ty>& _Left, const _Ty& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator/(const complex<_Ty>& _Left, const _Ty& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp /= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator/(const _Ty& _Left, const complex<_Ty>& _Right) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator/(const _Ty& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Tmp(_Left); _Tmp /= _Right; return _Tmp; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const complex<_Ty>& _Left) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const complex<_Ty>& _Left) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return _Left; } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const complex<_Ty>& _Left) { +_NODISCARD _CONSTEXPR20 complex<_Ty> operator-(const complex<_Ty>& _Left) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return complex<_Ty>(-_Left.real(), -_Left.imag()); } _EXPORT_STD template -_NODISCARD constexpr bool operator==(const complex<_Ty>& _Left, const complex<_Ty>& _Right) { +_NODISCARD constexpr bool operator==(const complex<_Ty>& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return _Left.real() == _Right.real() && _Left.imag() == _Right.imag(); } _EXPORT_STD template -_NODISCARD constexpr bool operator==(const complex<_Ty>& _Left, const _Ty& _Right) { +_NODISCARD constexpr bool operator==(const complex<_Ty>& _Left, const _Ty& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return _Left.real() == _Right && _Left.imag() == 0; } #if !_HAS_CXX20 template -_NODISCARD constexpr bool operator==(const _Ty& _Left, const complex<_Ty>& _Right) { +_NODISCARD constexpr bool operator==(const _Ty& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return _Left == _Right.real() && 0 == _Right.imag(); } template -_NODISCARD constexpr bool operator!=(const complex<_Ty>& _Left, const complex<_Ty>& _Right) { +_NODISCARD constexpr bool operator!=(const complex<_Ty>& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return !(_Left == _Right); } template -_NODISCARD constexpr bool operator!=(const complex<_Ty>& _Left, const _Ty& _Right) { +_NODISCARD constexpr bool operator!=(const complex<_Ty>& _Left, const _Ty& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return !(_Left == _Right); } template -_NODISCARD constexpr bool operator!=(const _Ty& _Left, const complex<_Ty>& _Right) { +_NODISCARD constexpr bool operator!=(const _Ty& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { return !(_Left == _Right); } #endif // !_HAS_CXX20 _EXPORT_STD template -_NODISCARD constexpr _Ty imag(const complex<_Ty>& _Left) { +_NODISCARD constexpr _Ty imag(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return _Left.imag(); } _EXPORT_STD template -_NODISCARD constexpr _Ty real(const complex<_Ty>& _Left) { +_NODISCARD constexpr _Ty real(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return _Left.real(); } _EXPORT_STD template -_NODISCARD complex<_Ty> sqrt(const complex<_Ty>& _Left); +_NODISCARD complex<_Ty> sqrt(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */; _EXPORT_STD template -_NODISCARD _Ty abs(const complex<_Ty>& _Left) { +_NODISCARD _Ty abs(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return _Ctraits<_Ty>::hypot(_Left.real(), _Left.imag()); } _EXPORT_STD template -_NODISCARD complex<_Ty> acos(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> acos(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { const _Ty _Arcbig = static_cast<_Ty>(0.25) * _Ctraits<_Ty>::sqrt(_Ctraits<_Ty>::_Flt_max()); constexpr _Ty _Pi_val = static_cast<_Ty>(3.1415926535897932384626433832795029L); @@ -1597,7 +1632,7 @@ _NODISCARD complex<_Ty> acos(const complex<_Ty>& _Left) { } _EXPORT_STD template -_NODISCARD complex<_Ty> acosh(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> acosh(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { const _Ty _Arcbig = static_cast<_Ty>(0.25) * _Ctraits<_Ty>::sqrt(_Ctraits<_Ty>::_Flt_max()); constexpr _Ty _Pi_val = static_cast<_Ty>(3.1415926535897932384626433832795029L); @@ -1667,7 +1702,7 @@ _NODISCARD complex<_Ty> acosh(const complex<_Ty>& _Left) { } _EXPORT_STD template -_NODISCARD complex<_Ty> asinh(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> asinh(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { const _Ty _Arcbig = static_cast<_Ty>(0.25) * _Ctraits<_Ty>::sqrt(_Ctraits<_Ty>::_Flt_max()); constexpr _Ty _Pi_val = static_cast<_Ty>(3.1415926535897932384626433832795029L); @@ -1732,14 +1767,14 @@ _NODISCARD complex<_Ty> asinh(const complex<_Ty>& _Left) { } _EXPORT_STD template -_NODISCARD complex<_Ty> asin(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> asin(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Asinh = _STD asinh(complex<_Ty>(-imag(_Left), real(_Left))); return complex<_Ty>(imag(_Asinh), -real(_Asinh)); } _EXPORT_STD template -_NODISCARD complex<_Ty> atanh(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> atanh(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { const _Ty _Arcbig = static_cast<_Ty>(0.25) * _Ctraits<_Ty>::sqrt(_Ctraits<_Ty>::_Flt_max()); constexpr _Ty _Piby2 = static_cast<_Ty>(1.5707963267948966192313216916397514L); @@ -1791,20 +1826,21 @@ _NODISCARD complex<_Ty> atanh(const complex<_Ty>& _Left) { } _EXPORT_STD template -_NODISCARD complex<_Ty> atan(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> atan(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Atanh = _STD atanh(complex<_Ty>(-imag(_Left), real(_Left))); return complex<_Ty>(imag(_Atanh), -real(_Atanh)); } _EXPORT_STD template -_NODISCARD complex<_Ty> cosh(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> cosh(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return complex<_Ty>(_Ctraits<_Ty>::_Cosh(real(_Left), _Ctraits<_Ty>::cos(imag(_Left))), _Ctraits<_Ty>::_Sinh(real(_Left), _Ctraits<_Ty>::sin(imag(_Left)))); } template -_NODISCARD complex<_Ty> _Polar_positive_nan_inf_zero_rho(const _Ty& _Rho, const _Ty& _Theta) { // _Rho is +NaN/+Inf/+0 +_NODISCARD complex<_Ty> _Polar_positive_nan_inf_zero_rho(const _Ty& _Rho, const _Ty& _Theta) noexcept( + _Is_unqual_fp<_Ty>) { // _Rho is +NaN/+Inf/+0 if (_Ctraits<_Ty>::_Isnan(_Theta) || _Ctraits<_Ty>::_Isinf(_Theta)) { // _Theta is NaN/Inf if (_Ctraits<_Ty>::_Isinf(_Rho)) { return complex<_Ty>(_Rho, _Ctraits<_Ty>::sin(_Theta)); // (Inf, NaN/Inf) @@ -1820,7 +1856,7 @@ _NODISCARD complex<_Ty> _Polar_positive_nan_inf_zero_rho(const _Ty& _Rho, const } _EXPORT_STD template -_NODISCARD complex<_Ty> exp(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> exp(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { const _Ty _Log_rho = _STD real(_Left); const _Ty _Theta = _STD imag(_Left); @@ -1846,7 +1882,7 @@ _NODISCARD complex<_Ty> exp(const complex<_Ty>& _Left) { } template -_Ty _Fabs(const complex<_Ty>& _Left, int* _Pexp) { +_Ty _Fabs(const complex<_Ty>& _Left, int* _Pexp) noexcept(_Is_unqual_fp<_Ty>) { // Used by sqrt(), return magnitude and scale factor. // Returns a non-zero even integer in *_Pexp when _Left is finite and non-zero. // Returns 0 in *_Pexp when _Left is zero, infinity, or NaN. @@ -1921,14 +1957,14 @@ _NODISCARD inline float _Log_abs(const complex& _Left) noexcept { } _EXPORT_STD template -_NODISCARD complex<_Ty> log(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> log(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { const _Ty _Log_abs_v = _Log_abs(_Left); // get logarithm of magnitude const _Ty _Theta = _Ctraits<_Ty>::atan2(_STD imag(_Left), _STD real(_Left)); // get phase return complex<_Ty>(_Log_abs_v, _Theta); } template -complex<_Ty> _Pow(const _Ty& _Left, const _Ty& _Right) { +complex<_Ty> _Pow(const _Ty& _Left, const _Ty& _Right) noexcept(_Is_unqual_fp<_Ty>) { if (0 <= _Left) { return complex<_Ty>(_Ctraits<_Ty>::pow(_Left, _Right), _Ctraits<_Ty>::_Copysign(_Ty{0}, _Right)); } else { @@ -1937,7 +1973,8 @@ complex<_Ty> _Pow(const _Ty& _Left, const _Ty& _Right) { } _EXPORT_STD template -_NODISCARD complex<_Ty> pow(const complex<_Ty>& _Left, const _Ty& _Right) { +_NODISCARD complex<_Ty> pow(const complex<_Ty>& _Left, const _Ty& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { if (imag(_Left) == 0) { if (_Ctraits<_Ty>::_Signbit(imag(_Left))) { return conj(_Pow(real(_Left), _Right)); @@ -1950,7 +1987,8 @@ _NODISCARD complex<_Ty> pow(const complex<_Ty>& _Left, const _Ty& _Right) { } _EXPORT_STD template -_NODISCARD complex<_Ty> pow(const _Ty& _Left, const complex<_Ty>& _Right) { +_NODISCARD complex<_Ty> pow(const _Ty& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { if (imag(_Right) == 0) { return _Pow(_Left, real(_Right)); } else if (0 < _Left) { @@ -1961,7 +1999,8 @@ _NODISCARD complex<_Ty> pow(const _Ty& _Left, const complex<_Ty>& _Right) { } _EXPORT_STD template -_NODISCARD complex<_Ty> pow(const complex<_Ty>& _Left, const complex<_Ty>& _Right) { +_NODISCARD complex<_Ty> pow(const complex<_Ty>& _Left, const complex<_Ty>& _Right) noexcept( + _Is_unqual_fp<_Ty>) /* strengthened */ { if (imag(_Right) == 0) { return pow(_Left, real(_Right)); } else if (imag(_Left) == 0 && 0 < real(_Left)) { @@ -1972,13 +2011,13 @@ _NODISCARD complex<_Ty> pow(const complex<_Ty>& _Left, const complex<_Ty>& _Righ } _EXPORT_STD template -_NODISCARD complex<_Ty> sinh(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> sinh(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return complex<_Ty>(_Ctraits<_Ty>::_Sinh(real(_Left), _Ctraits<_Ty>::cos(imag(_Left))), _Ctraits<_Ty>::_Cosh(real(_Left), _Ctraits<_Ty>::sin(imag(_Left)))); } _EXPORT_STD template -_NODISCARD complex<_Ty> sqrt(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> sqrt(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { int _Leftexp; _Ty _Rho = _Fabs(_Left, &_Leftexp); // get magnitude and scale factor @@ -2022,7 +2061,7 @@ _NODISCARD complex<_Ty> sqrt(const complex<_Ty>& _Left) { } _EXPORT_STD template -_NODISCARD complex<_Ty> tanh(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> tanh(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { _Ty _Tv = _Ctraits<_Ty>::tan(imag(_Left)); _Ty _Sv = _Ctraits<_Ty>::_Sinh(real(_Left), _Ty{1}); _Ty _Bv = _Sv * (_Ty{1} + _Tv * _Tv); @@ -2044,17 +2083,20 @@ _NODISCARD complex<_Ty> tanh(const complex<_Ty>& _Left) { } _EXPORT_STD template -_NODISCARD _Ty arg(const complex<_Ty>& _Left) { // return phase angle of complex as real +_NODISCARD _Ty arg(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { + // return phase angle of complex as real return _Ctraits<_Ty>::atan2(imag(_Left), real(_Left)); } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 complex<_Ty> conj(const complex<_Ty>& _Left) { // return complex conjugate +_NODISCARD _CONSTEXPR20 complex<_Ty> conj(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { + // return complex conjugate return complex<_Ty>(real(_Left), -imag(_Left)); } _EXPORT_STD template -_NODISCARD complex<_Ty> proj(const complex<_Ty>& _Left) { // return complex projection +_NODISCARD complex<_Ty> proj(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { + // return complex projection if (_Ctraits<_Ty>::_Isinf(real(_Left)) || _Ctraits<_Ty>::_Isinf(imag(_Left))) { const _Ty _Imag = _Ctraits<_Ty>::_Copysign(_Ty{0}, imag(_Left)); return complex<_Ty>(_Ctraits<_Ty>::_Infv(), _Imag); @@ -2064,23 +2106,25 @@ _NODISCARD complex<_Ty> proj(const complex<_Ty>& _Left) { // return complex proj } _EXPORT_STD template -_NODISCARD complex<_Ty> cos(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> cos(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return complex<_Ty>(_Ctraits<_Ty>::_Cosh(imag(_Left), _Ctraits<_Ty>::cos(real(_Left))), -_Ctraits<_Ty>::_Sinh(imag(_Left), _Ctraits<_Ty>::sin(real(_Left)))); } _EXPORT_STD template -_NODISCARD complex<_Ty> log10(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> log10(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return log(_Left) * static_cast<_Ty>(0.43429448190325182765112891891660508L); } _EXPORT_STD template -_NODISCARD _CONSTEXPR20 _Ty norm(const complex<_Ty>& _Left) { // return squared magnitude +_NODISCARD _CONSTEXPR20 _Ty norm(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { + // return squared magnitude return real(_Left) * real(_Left) + imag(_Left) * imag(_Left); } _EXPORT_STD template -_NODISCARD complex<_Ty> polar(const _Ty& _Rho, const _Ty& _Theta) { // return _Rho * exp(i * _Theta) as complex +_NODISCARD complex<_Ty> polar(const _Ty& _Rho, const _Ty& _Theta) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { + // return _Rho * exp(i * _Theta) as complex if (!_Ctraits<_Ty>::_Isnan(_Rho) && !_Ctraits<_Ty>::_Isinf(_Rho) && _Rho != _Ty{0}) { // _Rho is finite non-zero return complex<_Ty>(_Rho * _Ctraits<_Ty>::cos(_Theta), _Rho * _Ctraits<_Ty>::sin(_Theta)); } @@ -2094,18 +2138,19 @@ _NODISCARD complex<_Ty> polar(const _Ty& _Rho, const _Ty& _Theta) { // return _R } _EXPORT_STD template -_NODISCARD complex<_Ty> polar(const _Ty& _Rho) { // return _Rho * exp(i * 0) as complex +_NODISCARD complex<_Ty> polar(const _Ty& _Rho) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { + // return _Rho * exp(i * 0) as complex return complex<_Ty>(_Rho, _Ty{0}); } _EXPORT_STD template -_NODISCARD complex<_Ty> sin(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> sin(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { return complex<_Ty>(_Ctraits<_Ty>::_Cosh(imag(_Left), _Ctraits<_Ty>::sin(real(_Left))), _Ctraits<_Ty>::_Sinh(imag(_Left), _Ctraits<_Ty>::cos(real(_Left)))); } _EXPORT_STD template -_NODISCARD complex<_Ty> tan(const complex<_Ty>& _Left) { +_NODISCARD complex<_Ty> tan(const complex<_Ty>& _Left) noexcept(_Is_unqual_fp<_Ty>) /* strengthened */ { complex<_Ty> _Zv(tanh(complex<_Ty>(-imag(_Left), real(_Left)))); return complex<_Ty>(imag(_Zv), -real(_Zv)); } @@ -2114,7 +2159,7 @@ template using _Upgrade_to_double = conditional_t, double, _Ty>; _EXPORT_STD template , int> = 0> -_NODISCARD _Upgrade_to_double<_Ty> arg(_Ty _Left) { +_NODISCARD _Upgrade_to_double<_Ty> arg(_Ty _Left) noexcept /* strengthened */ { using _Upgraded = _Upgrade_to_double<_Ty>; const auto _Val = static_cast<_Upgraded>(_Left); @@ -2122,12 +2167,12 @@ _NODISCARD _Upgrade_to_double<_Ty> arg(_Ty _Left) { } _EXPORT_STD template , int> = 0> -_NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> imag(_Ty) { +_NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> imag(_Ty) noexcept /* strengthened */ { return 0; } _EXPORT_STD template , int> = 0> -_NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> real(_Ty _Left) { +_NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> real(_Ty _Left) noexcept /* strengthened */ { using _Upgraded = _Upgrade_to_double<_Ty>; const auto _Val = static_cast<_Upgraded>(_Left); @@ -2135,7 +2180,7 @@ _NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> real(_Ty _Left) { } _EXPORT_STD template , int> = 0> -_NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> norm(_Ty _Left) { +_NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> norm(_Ty _Left) noexcept /* strengthened */ { using _Upgraded = _Upgrade_to_double<_Ty>; const auto _Val = static_cast<_Upgraded>(_Left); @@ -2143,7 +2188,7 @@ _NODISCARD _CONSTEXPR20 _Upgrade_to_double<_Ty> norm(_Ty _Left) { } _EXPORT_STD template , int> = 0> -_NODISCARD _CONSTEXPR20 complex<_Upgrade_to_double<_Ty>> conj(_Ty _Left) { +_NODISCARD _CONSTEXPR20 complex<_Upgrade_to_double<_Ty>> conj(_Ty _Left) noexcept /* strengthened */ { using _Upgraded = _Upgrade_to_double<_Ty>; const auto _Val = static_cast<_Upgraded>(_Left); @@ -2151,7 +2196,7 @@ _NODISCARD _CONSTEXPR20 complex<_Upgrade_to_double<_Ty>> conj(_Ty _Left) { } _EXPORT_STD template , int> = 0> -_NODISCARD complex<_Upgrade_to_double<_Ty>> proj(_Ty _Left) { +_NODISCARD complex<_Upgrade_to_double<_Ty>> proj(_Ty _Left) noexcept /* strengthened */ { using _Upgraded = _Upgrade_to_double<_Ty>; const auto _Val = static_cast<_Upgraded>(_Left); @@ -2165,20 +2210,23 @@ _NODISCARD complex<_Upgrade_to_double<_Ty>> proj(_Ty _Left) { } _EXPORT_STD template -_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const complex<_Ty1>& _Left, const complex<_Ty2>& _Right) { +_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const complex<_Ty1>& _Left, + const complex<_Ty2>& _Right) noexcept(_Is_unqual_fp<_Ty1>&& _Is_unqual_fp<_Ty2>) /* strengthened */ { using _Type = complex<_Common_float_type_t<_Ty1, _Ty2>>; return _STD pow(_Type(_Left), _Type(_Right)); } _EXPORT_STD template , int> = 0> -_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const complex<_Ty1>& _Left, const _Ty2& _Right) { +_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const complex<_Ty1>& _Left, const _Ty2& _Right) noexcept( + _Is_unqual_fp<_Ty1>) /* strengthened */ { using _Promoted = _Common_float_type_t<_Ty1, _Ty2>; using _Type = complex<_Promoted>; return _STD pow(_Type(_Left), _Type(static_cast<_Promoted>(_Right))); } _EXPORT_STD template , int> = 0> -_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const _Ty1& _Left, const complex<_Ty2>& _Right) { +_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const _Ty1& _Left, const complex<_Ty2>& _Right) noexcept( + _Is_unqual_fp<_Ty2>) /* strengthened */ { using _Promoted = _Common_float_type_t<_Ty1, _Ty2>; using _Type = complex<_Promoted>; return _STD pow(_Type(static_cast<_Promoted>(_Left)), _Type(_Right)); @@ -2229,27 +2277,31 @@ basic_ostream<_Elem, _Tr>& operator<<(basic_ostream<_Elem, _Tr>& _Ostr, const co inline namespace literals { inline namespace complex_literals { - _EXPORT_STD _NODISCARD constexpr complex operator""il(long double _Val) { + _EXPORT_STD _NODISCARD constexpr complex operator""il(long double _Val) noexcept + /* strengthened */ { return complex(0.0L, static_cast(_Val)); } - _EXPORT_STD _NODISCARD constexpr complex operator""il(unsigned long long _Val) { + _EXPORT_STD _NODISCARD constexpr complex operator""il(unsigned long long _Val) noexcept + /* strengthened */ { return complex(0.0L, static_cast(_Val)); } - _EXPORT_STD _NODISCARD constexpr complex operator""i(long double _Val) { + _EXPORT_STD _NODISCARD constexpr complex operator""i(long double _Val) noexcept /* strengthened */ { return complex(0.0, static_cast(_Val)); } - _EXPORT_STD _NODISCARD constexpr complex operator""i(unsigned long long _Val) { + _EXPORT_STD _NODISCARD constexpr complex operator""i(unsigned long long _Val) noexcept + /* strengthened */ { return complex(0.0, static_cast(_Val)); } - _EXPORT_STD _NODISCARD constexpr complex operator""if(long double _Val) { + _EXPORT_STD _NODISCARD constexpr complex operator""if(long double _Val) noexcept /* strengthened */ { return complex(0.0f, static_cast(_Val)); } - _EXPORT_STD _NODISCARD constexpr complex operator""if(unsigned long long _Val) { + _EXPORT_STD _NODISCARD constexpr complex operator""if(unsigned long long _Val) noexcept + /* strengthened */ { return complex(0.0f, static_cast(_Val)); } } // namespace complex_literals diff --git a/stl/inc/xutility b/stl/inc/xutility index 60ea3b5a3e..f938e825d5 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -7113,7 +7113,7 @@ struct _CXX17_DEPRECATE_ITERATOR_BASE_CLASS iterator { // base type for iterator }; template , int> = 0> -_NODISCARD constexpr auto _Float_abs_bits(const _Ty& _Xx) { +_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); @@ -7121,7 +7121,7 @@ _NODISCARD constexpr auto _Float_abs_bits(const _Ty& _Xx) { } template , int> = 0> -_NODISCARD constexpr _Ty _Float_abs(const _Ty _Xx) { // constexpr floating-point abs() +_NODISCARD constexpr _Ty _Float_abs(const _Ty _Xx) noexcept { // constexpr floating-point abs() return _Bit_cast<_Ty>(_Float_abs_bits(_Xx)); } @@ -7134,7 +7134,7 @@ _NODISCARD constexpr _Ty _Float_copysign(const _Ty _Magnitude, const _Ty _Sign) } template , int> = 0> -_NODISCARD constexpr bool _Is_nan(const _Ty _Xx) { // constexpr isnan() +_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; } @@ -7144,20 +7144,20 @@ _NODISCARD constexpr bool _Is_nan(const _Ty _Xx) { // constexpr isnan() // 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 , int> = 0> -_NODISCARD constexpr bool _Is_signaling_nan(const _Ty& _Xx) { // returns true if input is a signaling NaN +_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 , int> = 0> -_NODISCARD constexpr bool _Is_inf(const _Ty _Xx) { // constexpr isinf() +_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 , int> = 0> -_NODISCARD constexpr bool _Is_finite(const _Ty _Xx) { // constexpr isfinite() +_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; } diff --git a/stl/inc/ymath.h b/stl/inc/ymath.h index 789ef75a5a..af88d52443 100644 --- a/stl/inc/ymath.h +++ b/stl/inc/ymath.h @@ -21,18 +21,18 @@ _EXTERN_C_UNLESS_PURE #define _INFCODE 1 #define _NANCODE 2 -_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Cosh(double, double); -_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Sinh(double, double); -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Exp(double*, double, short); - -_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FCosh(float, float); -_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FSinh(float, float); -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FExp(float*, float, short); - -_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LCosh(long double, long double); -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LDtest(long double*); -_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LSinh(long double, long double); -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LExp(long double*, long double, short); +_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Cosh(double, double) noexcept; +_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Sinh(double, double) noexcept; +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Exp(double*, double, short) noexcept; + +_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FCosh(float, float) noexcept; +_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FSinh(float, float) noexcept; +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FExp(float*, float, short) noexcept; + +_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LCosh(long double, long double) noexcept; +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LDtest(long double*) noexcept; +_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LSinh(long double, long double) noexcept; +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LExp(long double*, long double, short) noexcept; _END_EXTERN_C_UNLESS_PURE diff --git a/stl/src/xcosh.cpp b/stl/src/xcosh.cpp index 22448633e3..f890f5fbc5 100644 --- a/stl/src/xcosh.cpp +++ b/stl/src/xcosh.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Cosh(double x, double y) { // compute y * cosh(x), |y| <= 1 +_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Cosh(double x, double y) noexcept { // compute y * cosh(x), |y| <= 1 switch (_Dtest(&x)) { // test for special codes case _NANCODE: case _INFCODE: diff --git a/stl/src/xdint.cpp b/stl/src/xdint.cpp index 677f8d597b..9c138b8c85 100644 --- a/stl/src/xdint.cpp +++ b/stl/src/xdint.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _Dint(double* px, short xexp) { // test and drop (scaled) fraction bits +short _Dint(double* px, short xexp) noexcept { // test and drop (scaled) fraction bits const auto ps = reinterpret_cast<_Dval*>(px); short xchar = (ps->_Sh[_D0] & _DMASK) >> _DOFF; diff --git a/stl/src/xdnorm.cpp b/stl/src/xdnorm.cpp index 73c3e0e17c..0737e21339 100644 --- a/stl/src/xdnorm.cpp +++ b/stl/src/xdnorm.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _Dnorm(_Dval* ps) { // normalize double fraction +short _Dnorm(_Dval* ps) noexcept { // normalize double fraction short xchar = 1; unsigned short sign = static_cast(ps->_Sh[_D0] & _DSIGN); diff --git a/stl/src/xdscale.cpp b/stl/src/xdscale.cpp index 2530b4922b..84ab360f9d 100644 --- a/stl/src/xdscale.cpp +++ b/stl/src/xdscale.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _Dscale(double* px, long lexp) { // scale *px by 2^xexp with checking +short _Dscale(double* px, long lexp) noexcept { // scale *px by 2^xexp with checking const auto ps = reinterpret_cast<_Dval*>(px); short xchar = static_cast((ps->_Sh[_D0] & _DMASK) >> _DOFF); diff --git a/stl/src/xdtest.cpp b/stl/src/xdtest.cpp index b5ec78c2ba..d9f7c95a03 100644 --- a/stl/src/xdtest.cpp +++ b/stl/src/xdtest.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double* px) { // categorize *px +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double* px) noexcept { // categorize *px const auto ps = reinterpret_cast<_Dval*>(px); if ((ps->_Sh[_D0] & _DMASK) == _DMAX << _DOFF) { @@ -20,7 +20,7 @@ _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double* px) { // categorize * } } -unsigned short* _Pmsw(double* px) { // get pointer to msw +unsigned short* _Pmsw(double* px) noexcept { // get pointer to msw return &reinterpret_cast<_Dval*>(px)->_Sh[_D0]; } diff --git a/stl/src/xdunscal.cpp b/stl/src/xdunscal.cpp index eb17a0f1bd..21db5d67d7 100644 --- a/stl/src/xdunscal.cpp +++ b/stl/src/xdunscal.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _Dunscale(short* pex, double* px) { // separate *px to 1/2 <= |frac| < 1 and 2^*pex +short _Dunscale(short* pex, double* px) noexcept { // separate *px to 1/2 <= |frac| < 1 and 2^*pex const auto ps = reinterpret_cast<_Dval*>(px); short xchar = (ps->_Sh[_D0] & _DMASK) >> _DOFF; diff --git a/stl/src/xexp.cpp b/stl/src/xexp.cpp index d9c53d96be..8d20f0976d 100644 --- a/stl/src/xexp.cpp +++ b/stl/src/xexp.cpp @@ -16,7 +16,7 @@ static const double hugexp = HUGE_EXP; static const double invln2 = 1.4426950408889634073599246810018921; _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Exp( - double* px, double y, short eoff) { // compute y * e^(*px), (*px) finite, |y| not huge + double* px, double y, short eoff) noexcept { // compute y * e^(*px), (*px) finite, |y| not huge if (y == 0.0) { // zero *px = y; return 0; diff --git a/stl/src/xfcosh.cpp b/stl/src/xfcosh.cpp index 1cc24bedaa..f1c3ab3c3c 100644 --- a/stl/src/xfcosh.cpp +++ b/stl/src/xfcosh.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FCosh(float x, float y) { // compute y * cosh(x), |y| <= 1 +_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FCosh(float x, float y) noexcept { // compute y * cosh(x), |y| <= 1 switch (_FDtest(&x)) { // test for special codes case _NANCODE: case _INFCODE: diff --git a/stl/src/xfdint.cpp b/stl/src/xfdint.cpp index d9966ff287..3436de551a 100644 --- a/stl/src/xfdint.cpp +++ b/stl/src/xfdint.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _FDint(float* px, short xexp) { // test and drop (scaled) fraction bits +short _FDint(float* px, short xexp) noexcept { // test and drop (scaled) fraction bits const auto ps = reinterpret_cast<_Fval*>(px); short xchar = (ps->_Sh[_F0] & _FMASK) >> _FOFF; diff --git a/stl/src/xfdnorm.cpp b/stl/src/xfdnorm.cpp index 46f7e287eb..4ac5e671a0 100644 --- a/stl/src/xfdnorm.cpp +++ b/stl/src/xfdnorm.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _FDnorm(_Fval* ps) { // normalize float fraction +short _FDnorm(_Fval* ps) noexcept { // normalize float fraction short xchar = 1; unsigned short sign = static_cast(ps->_Sh[_F0] & _FSIGN); diff --git a/stl/src/xfdscale.cpp b/stl/src/xfdscale.cpp index e7a5c84e06..d530f6efa5 100644 --- a/stl/src/xfdscale.cpp +++ b/stl/src/xfdscale.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _FDscale(float* px, long lexp) { // scale *px by 2^xexp with checking +short _FDscale(float* px, long lexp) noexcept { // scale *px by 2^xexp with checking const auto ps = reinterpret_cast<_Fval*>(px); short xchar = static_cast((ps->_Sh[_F0] & _FMASK) >> _FOFF); diff --git a/stl/src/xfdtest.cpp b/stl/src/xfdtest.cpp index 2970d0ba02..39dd51ea80 100644 --- a/stl/src/xfdtest.cpp +++ b/stl/src/xfdtest.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float* px) { // categorize *px +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float* px) noexcept { // categorize *px const auto ps = reinterpret_cast<_Fval*>(px); if ((ps->_Sh[_F0] & _FMASK) == _FMAX << _FOFF) { @@ -19,7 +19,7 @@ _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float* px) { // categorize * } } -unsigned short* _FPmsw(float* px) { // get pointer to msw +unsigned short* _FPmsw(float* px) noexcept { // get pointer to msw return &reinterpret_cast<_Fval*>(px)->_Sh[_F0]; } diff --git a/stl/src/xfdunsca.cpp b/stl/src/xfdunsca.cpp index 1cea6634f0..1e5b13927e 100644 --- a/stl/src/xfdunsca.cpp +++ b/stl/src/xfdunsca.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _FDunscale(short* pex, float* px) { // separate *px to 1/2 <= |frac| < 1 and 2^*pex +short _FDunscale(short* pex, float* px) noexcept { // separate *px to 1/2 <= |frac| < 1 and 2^*pex const auto ps = reinterpret_cast<_Fval*>(px); short xchar = (ps->_Sh[_F0] & _FMASK) >> _FOFF; diff --git a/stl/src/xferaise.cpp b/stl/src/xferaise.cpp index a36a55a98b..7f6e4ed072 100644 --- a/stl/src/xferaise.cpp +++ b/stl/src/xferaise.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -void __CLRCALL_PURE_OR_CDECL _Feraise(int except) { // report floating-point exception +void __CLRCALL_PURE_OR_CDECL _Feraise(int except) noexcept { // report floating-point exception if ((except & (_FE_DIVBYZERO | _FE_INVALID)) != 0) { errno = EDOM; } else if ((except & (_FE_UNDERFLOW | _FE_OVERFLOW)) != 0) { diff --git a/stl/src/xfexp.cpp b/stl/src/xfexp.cpp index 221138a978..64dbe51e10 100644 --- a/stl/src/xfexp.cpp +++ b/stl/src/xfexp.cpp @@ -15,7 +15,7 @@ static const float hugexp = FHUGE_EXP; static const float invln2 = 1.4426950408889634073599246810018921F; _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FExp( - float* px, float y, short eoff) { // compute y * e^(*px), (*px) finite, |y| not huge + float* px, float y, short eoff) noexcept { // compute y * e^(*px), (*px) finite, |y| not huge if (y == 0.0F) { // zero *px = y; return 0; diff --git a/stl/src/xfsinh.cpp b/stl/src/xfsinh.cpp index 763ff1feb2..5f9e82aba0 100644 --- a/stl/src/xfsinh.cpp +++ b/stl/src/xfsinh.cpp @@ -10,7 +10,7 @@ _EXTERN_C_UNLESS_PURE // coefficients static const float p[] = {0.00020400F, 0.00832983F, 0.16666737F, 0.99999998F}; -_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FSinh(float x, float y) { // compute y * sinh(x), |y| <= 1 +_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _FSinh(float x, float y) noexcept { // compute y * sinh(x), |y| <= 1 short neg; switch (_FDtest(&x)) { // test for special codes diff --git a/stl/src/xlcosh.cpp b/stl/src/xlcosh.cpp index 4bc577658b..253960a3c5 100644 --- a/stl/src/xlcosh.cpp +++ b/stl/src/xlcosh.cpp @@ -8,7 +8,7 @@ _EXTERN_C_UNLESS_PURE _CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LCosh( - long double x, long double y) { // compute y * cosh(x), |y| <= 1 + long double x, long double y) noexcept { // compute y * cosh(x), |y| <= 1 switch (_LDtest(&x)) { // test for special codes case _NANCODE: case _INFCODE: diff --git a/stl/src/xldint.cpp b/stl/src/xldint.cpp index 45747c55d1..50c5d0e6cc 100644 --- a/stl/src/xldint.cpp +++ b/stl/src/xldint.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _LDint(long double* px, short xexp) { // test and drop (scaled) fraction bits -- 64-bit +short _LDint(long double* px, short xexp) noexcept { // test and drop (scaled) fraction bits -- 64-bit return _Dint(reinterpret_cast(px), xexp); } diff --git a/stl/src/xldscale.cpp b/stl/src/xldscale.cpp index 5bc6456b34..81f2e2c681 100644 --- a/stl/src/xldscale.cpp +++ b/stl/src/xldscale.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _LDscale(long double* px, long lexp) { // scale *px by 2^lexp with checking -- 64-bit +short _LDscale(long double* px, long lexp) noexcept { // scale *px by 2^lexp with checking -- 64-bit return _Dscale(reinterpret_cast(px), lexp); } diff --git a/stl/src/xldtest.cpp b/stl/src/xldtest.cpp index d8ed76d884..fa40339dad 100644 --- a/stl/src/xldtest.cpp +++ b/stl/src/xldtest.cpp @@ -7,11 +7,11 @@ _EXTERN_C_UNLESS_PURE -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LDtest(long double* px) { // categorize *px -- 64-bit +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LDtest(long double* px) noexcept { // categorize *px -- 64-bit return _Dtest(reinterpret_cast(px)); } -unsigned short* _LPmsw(long double* px) { // get pointer to msw +unsigned short* _LPmsw(long double* px) noexcept { // get pointer to msw return &reinterpret_cast<_Lval*>(px)->_Sh[_L0]; } diff --git a/stl/src/xldunsca.cpp b/stl/src/xldunsca.cpp index 5f4d8d6b2a..09af32bac2 100644 --- a/stl/src/xldunsca.cpp +++ b/stl/src/xldunsca.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -short _LDunscale(short* pex, long double* px) { // separate *px to 1/2 <= |frac| < 1 and 2^*pex -- 64-bit +short _LDunscale(short* pex, long double* px) noexcept { // separate *px to 1/2 <= |frac| < 1 and 2^*pex -- 64-bit return _Dunscale(pex, reinterpret_cast(px)); } diff --git a/stl/src/xlexp.cpp b/stl/src/xlexp.cpp index ed58e41653..d016fb0c60 100644 --- a/stl/src/xlexp.cpp +++ b/stl/src/xlexp.cpp @@ -17,7 +17,7 @@ static const long double hugexp = LHUGE_EXP; static const long double invln2 = 1.4426950408889634073599246810018921L; _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _LExp( - long double* px, long double y, short eoff) { // compute y * e^(*px), (*px) finite, |y| not huge + long double* px, long double y, short eoff) noexcept { // compute y * e^(*px), (*px) finite, |y| not huge if (y == 0.0L) { // zero *px = y; return 0; diff --git a/stl/src/xlpoly.cpp b/stl/src/xlpoly.cpp index 43b4747c11..ce1e35503e 100644 --- a/stl/src/xlpoly.cpp +++ b/stl/src/xlpoly.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -long double _LPoly(long double x, const long double* tab, int n) { // compute polynomial +long double _LPoly(long double x, const long double* tab, int n) noexcept { // compute polynomial long double y; for (y = *tab; 0 <= --n;) { diff --git a/stl/src/xlsinh.cpp b/stl/src/xlsinh.cpp index 6fdb37ecb4..3a57f8f0e4 100644 --- a/stl/src/xlsinh.cpp +++ b/stl/src/xlsinh.cpp @@ -16,7 +16,7 @@ static constexpr long double p[] = {0.0000000000000028486835L, 0.000000000000764 static constexpr size_t NP = std::size(p) - 1; -_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LSinh(long double x, long double y) { +_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _LSinh(long double x, long double y) noexcept { // compute y * sinh(x), |y| <= 1 short neg; diff --git a/stl/src/xmath.hpp b/stl/src/xmath.hpp index eafcb9cef1..e7f441d5cc 100644 --- a/stl/src/xmath.hpp +++ b/stl/src/xmath.hpp @@ -55,7 +55,7 @@ _EXTERN_C_UNLESS_PURE -void __CLRCALL_PURE_OR_CDECL _Feraise(int); +void __CLRCALL_PURE_OR_CDECL _Feraise(int) noexcept; union _Dconst { // pun float types as integer array unsigned short _Word[8]; // TRANSITION, ABI: Twice as large as necessary. @@ -64,7 +64,7 @@ union _Dconst { // pun float types as integer array long double _Long_double; }; -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double*); +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double*) noexcept; extern _CRTIMP2_PURE _Dconst _Denorm; extern _CRTIMP2_PURE _Dconst _Hugeval; @@ -72,7 +72,7 @@ extern _CRTIMP2_PURE _Dconst _Inf; extern _CRTIMP2_PURE _Dconst _Nan; extern _CRTIMP2_PURE _Dconst _Snan; -_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float*); +_CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _FDtest(float*) noexcept; extern _CRTIMP2_PURE _Dconst _FDenorm; extern _CRTIMP2_PURE _Dconst _FInf; @@ -84,16 +84,16 @@ extern _CRTIMP2_PURE _Dconst _LInf; extern _CRTIMP2_PURE _Dconst _LNan; extern _CRTIMP2_PURE _Dconst _LSnan; -int _Stopfx(const char**, char**); +int _Stopfx(const char**, char**) noexcept; _In_range_(0, maxsig) int _Stoflt( - const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; _In_range_(0, maxsig) int _Stoxflt( - const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const char*, const char*, char**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; int _WStopfx(const wchar_t**, wchar_t**); _In_range_(0, maxsig) int _WStoflt( - const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; _In_range_(0, maxsig) int _WStoxflt( - const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig); + const wchar_t*, const wchar_t*, wchar_t**, _Out_writes_(maxsig) long[], _In_range_(1, 4) int maxsig) noexcept; // double declarations union _Dval { // pun floating type as integer array @@ -101,28 +101,28 @@ union _Dval { // pun floating type as integer array double _Val; }; -unsigned short* _Pmsw(double*); +unsigned short* _Pmsw(double*) noexcept; -short _Dint(double*, short); -short _Dnorm(_Dval*); -short _Dscale(double*, long); -short _Dunscale(short*, double*); +short _Dint(double*, short) noexcept; +short _Dnorm(_Dval*) noexcept; +short _Dscale(double*, long) noexcept; +short _Dunscale(short*, double*) noexcept; -double _Poly(double, const double*, int); +double _Poly(double, const double*, int) noexcept; extern const _Dconst _Eps; extern const _Dconst _Rteps; extern const double _Xbig; -double _Xp_getw(const double*, int); -double* _Xp_setn(double*, int, long); -double* _Xp_setw(double*, int, double); -double* _Xp_addh(double*, int, double); -double* _Xp_mulh(double*, int, double); -double* _Xp_movx(double*, int, const double*); -double* _Xp_addx(double*, int, const double*, int); -double* _Xp_ldexpx(double*, int, int); -double* _Xp_mulx(double*, int, const double*, int, double*); +double _Xp_getw(const double*, int) noexcept; +double* _Xp_setn(double*, int, long) noexcept; +double* _Xp_setw(double*, int, double) noexcept; +double* _Xp_addh(double*, int, double) noexcept; +double* _Xp_mulh(double*, int, double) noexcept; +double* _Xp_movx(double*, int, const double*) noexcept; +double* _Xp_addx(double*, int, const double*, int) noexcept; +double* _Xp_ldexpx(double*, int, int) noexcept; +double* _Xp_mulx(double*, int, const double*, int, double*) noexcept; // float declarations union _Fval { // pun floating type as integer array @@ -130,28 +130,26 @@ union _Fval { // pun floating type as integer array float _Val; }; -unsigned short* _FPmsw(float*); +unsigned short* _FPmsw(float*) noexcept; -short _FDint(float*, short); -short _FDnorm(_Fval*); -short _FDscale(float*, long); -short _FDunscale(short*, float*); - -float _FPoly(float, const float*, int); +short _FDint(float*, short) noexcept; +short _FDnorm(_Fval*) noexcept; +short _FDscale(float*, long) noexcept; +short _FDunscale(short*, float*) noexcept; extern const _Dconst _FEps; extern const _Dconst _FRteps; extern const float _FXbig; -float _FXp_getw(const float*, int); -float* _FXp_setn(float*, int, long); -float* _FXp_setw(float*, int, float); -float* _FXp_addh(float*, int, float); -float* _FXp_mulh(float*, int, float); -float* _FXp_movx(float*, int, const float*); -float* _FXp_addx(float*, int, const float*, int); -float* _FXp_ldexpx(float*, int, int); -float* _FXp_mulx(float*, int, const float*, int, float*); +float _FXp_getw(const float*, int) noexcept; +float* _FXp_setn(float*, int, long) noexcept; +float* _FXp_setw(float*, int, float) noexcept; +float* _FXp_addh(float*, int, float) noexcept; +float* _FXp_mulh(float*, int, float) noexcept; +float* _FXp_movx(float*, int, const float*) noexcept; +float* _FXp_addx(float*, int, const float*, int) noexcept; +float* _FXp_ldexpx(float*, int, int) noexcept; +float* _FXp_mulx(float*, int, const float*, int, float*) noexcept; // long double declarations union _Lval { // pun floating type as integer array @@ -159,27 +157,26 @@ union _Lval { // pun floating type as integer array long double _Val; }; -unsigned short* _LPmsw(long double*); +unsigned short* _LPmsw(long double*) noexcept; -short _LDint(long double*, short); -short _LDnorm(_Lval*); -short _LDscale(long double*, long); -short _LDunscale(short*, long double*); -long double _LPoly(long double, const long double*, int); +short _LDint(long double*, short) noexcept; +short _LDscale(long double*, long) noexcept; +short _LDunscale(short*, long double*) noexcept; +long double _LPoly(long double, const long double*, int) noexcept; extern const _Dconst _LEps; extern const _Dconst _LRteps; extern const long double _LXbig; -long double _LXp_getw(const long double*, int); -long double* _LXp_setn(long double*, int, long); -long double* _LXp_setw(long double*, int, long double); -long double* _LXp_addh(long double*, int, long double); -long double* _LXp_mulh(long double*, int, long double); -long double* _LXp_movx(long double*, int, const long double*); -long double* _LXp_addx(long double*, int, const long double*, int); -long double* _LXp_ldexpx(long double*, int, int); -long double* _LXp_mulx(long double*, int, const long double*, int, long double*); +long double _LXp_getw(const long double*, int) noexcept; +long double* _LXp_setn(long double*, int, long) noexcept; +long double* _LXp_setw(long double*, int, long double) noexcept; +long double* _LXp_addh(long double*, int, long double) noexcept; +long double* _LXp_mulh(long double*, int, long double) noexcept; +long double* _LXp_movx(long double*, int, const long double*) noexcept; +long double* _LXp_addx(long double*, int, const long double*, int) noexcept; +long double* _LXp_ldexpx(long double*, int, int) noexcept; +long double* _LXp_mulx(long double*, int, const long double*, int, long double*) noexcept; _END_EXTERN_C_UNLESS_PURE diff --git a/stl/src/xpoly.cpp b/stl/src/xpoly.cpp index 763cf0526c..c6005089f0 100644 --- a/stl/src/xpoly.cpp +++ b/stl/src/xpoly.cpp @@ -7,7 +7,7 @@ _EXTERN_C_UNLESS_PURE -double _Poly(double x, const double* tab, int n) { // compute polynomial +double _Poly(double x, const double* tab, int n) noexcept { // compute polynomial double y; for (y = *tab; 0 <= --n;) { diff --git a/stl/src/xsinh.cpp b/stl/src/xsinh.cpp index 3d6d96b435..e5d22f6983 100644 --- a/stl/src/xsinh.cpp +++ b/stl/src/xsinh.cpp @@ -15,7 +15,7 @@ static constexpr double p[] = {0.0000000001632881, 0.0000000250483893, 0.0000027 static constexpr size_t NP = std::size(p) - 1; -_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Sinh(double x, double y) { // compute y * sinh(x), |y| <= 1 +_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _Sinh(double x, double y) noexcept { // compute y * sinh(x), |y| <= 1 short neg; switch (_Dtest(&x)) { // test for special codes diff --git a/stl/src/xstoflt.cpp b/stl/src/xstoflt.cpp index 3a9b6adf21..4322cc1a7d 100644 --- a/stl/src/xstoflt.cpp +++ b/stl/src/xstoflt.cpp @@ -15,8 +15,8 @@ constexpr int _Base = 10; // decimal constexpr int _Ndig = 9; // decimal digits per long word constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -_In_range_(0, maxsig) int _Stoflt( - const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { +_In_range_(0, maxsig) int _Stoflt(const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], + _In_range_(1, 4) int maxsig) noexcept { // convert string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen diff --git a/stl/src/xstopfx.cpp b/stl/src/xstopfx.cpp index fc5928205e..6218ac39ba 100644 --- a/stl/src/xstopfx.cpp +++ b/stl/src/xstopfx.cpp @@ -9,7 +9,7 @@ _EXTERN_C_UNLESS_PURE -int _Stopfx(const char** ps, char** endptr) { // parse prefix of floating-point field +int _Stopfx(const char** ps, char** endptr) noexcept { // parse prefix of floating-point field const char* s = *ps; int code = 0; diff --git a/stl/src/xstoxflt.cpp b/stl/src/xstoxflt.cpp index 196ba95d85..a898f16b58 100644 --- a/stl/src/xstoxflt.cpp +++ b/stl/src/xstoxflt.cpp @@ -16,8 +16,8 @@ constexpr int _Base = 16; // hexadecimal constexpr int _Ndig = 7; // hexadecimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep -_In_range_(0, maxsig) int _Stoxflt( - const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { +_In_range_(0, maxsig) int _Stoxflt(const char* s0, const char* s, char** endptr, _Out_writes_(maxsig) long lo[], + _In_range_(1, 4) int maxsig) noexcept { // convert string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen diff --git a/stl/src/xwstoflt.cpp b/stl/src/xwstoflt.cpp index 0da23a067d..ea12f36b94 100644 --- a/stl/src/xwstoflt.cpp +++ b/stl/src/xwstoflt.cpp @@ -16,7 +16,7 @@ constexpr int _Ndig = 9; // decimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep _In_range_(0, maxsig) int _WStoflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, - _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) noexcept { // convert wide string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen diff --git a/stl/src/xwstoxfl.cpp b/stl/src/xwstoxfl.cpp index 5ed68f104b..9ca5c4b803 100644 --- a/stl/src/xwstoxfl.cpp +++ b/stl/src/xwstoxfl.cpp @@ -17,7 +17,7 @@ constexpr int _Ndig = 7; // hexadecimal digits per long element constexpr int _Maxsig = 5 * _Ndig; // maximum significant digits to keep _In_range_(0, maxsig) int _WStoxflt(const wchar_t* s0, const wchar_t* s, wchar_t** endptr, - _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) { + _Out_writes_(maxsig) long lo[], _In_range_(1, 4) int maxsig) noexcept { // convert wide string to array of long plus exponent char buf[_Maxsig + 1]; // worst case, with room for rounding digit int nsig = 0; // number of significant digits seen diff --git a/stl/src/xxxprec.hpp b/stl/src/xxxprec.hpp index dc3a4491b4..5f17437e26 100644 --- a/stl/src/xxxprec.hpp +++ b/stl/src/xxxprec.hpp @@ -39,7 +39,7 @@ static void printit(const char* s, FTYPE* p, int n) { // print xp array } #endif // 0 -FTYPE FNAME(Xp_getw)(const FTYPE* p, int n) { // get total value +FTYPE FNAME(Xp_getw)(const FTYPE* p, int n) noexcept { // get total value if (n == 0) { return FLIT(0.0); } else if (n == 1 || p[0] == FLIT(0.0) || p[1] == FLIT(0.0)) { @@ -62,7 +62,7 @@ FTYPE FNAME(Xp_getw)(const FTYPE* p, int n) { // get total value } } -FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) { // load a full-precision value +FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) noexcept { // load a full-precision value FTYPE x0 = x; short errx; short xexp; @@ -111,7 +111,7 @@ FTYPE* FNAME(Xp_setw)(FTYPE* p, int n, FTYPE x) { // load a full-precision value return p; } -FTYPE* FNAME(Xp_addh)(FTYPE* p, int n, FTYPE x0) { // add a half-precision value +FTYPE* FNAME(Xp_addh)(FTYPE* p, int n, FTYPE x0) noexcept { // add a half-precision value FTYPE xscaled = x0; short errx; short xexp; @@ -219,7 +219,7 @@ FTYPE* FNAME(Xp_addh)(FTYPE* p, int n, FTYPE x0) { // add a half-precision value return p; } -FTYPE* FNAME(Xp_mulh)(FTYPE* p, int n, FTYPE x0) { // multiply by a half-precision value +FTYPE* FNAME(Xp_mulh)(FTYPE* p, int n, FTYPE x0) noexcept { // multiply by a half-precision value short errx; int j; int k; @@ -280,7 +280,7 @@ FTYPE* FNAME(Xp_mulh)(FTYPE* p, int n, FTYPE x0) { // multiply by a half-precisi return p; } -FTYPE* FNAME(Xp_setn)(FTYPE* p, int n, long x) { // load a long integer +FTYPE* FNAME(Xp_setn)(FTYPE* p, int n, long x) noexcept { // load a long integer #if FBITS == 53 FNAME(Xp_setw)(p, n, static_cast(x)); @@ -295,12 +295,12 @@ FTYPE* FNAME(Xp_setn)(FTYPE* p, int n, long x) { // load a long integer return p; } -FTYPE* FNAME(Xp_movx)(FTYPE* p, int n, const FTYPE* q) { // copy an extended precision value +FTYPE* FNAME(Xp_movx)(FTYPE* p, int n, const FTYPE* q) noexcept { // copy an extended precision value memcpy(p, q, n * sizeof(FTYPE)); return p; } -FTYPE* FNAME(Xp_addx)(FTYPE* p, int n, const FTYPE* q, int m) { // add an extended precision value +FTYPE* FNAME(Xp_addx)(FTYPE* p, int n, const FTYPE* q, int m) noexcept { // add an extended precision value int k; for (k = 0; k < m && q[k] != FLIT(0.0); ++k) { @@ -310,7 +310,7 @@ FTYPE* FNAME(Xp_addx)(FTYPE* p, int n, const FTYPE* q, int m) { // add an extend return p; } -FTYPE* FNAME(Xp_ldexpx)(FTYPE* p, int n, int m) { // scale an extended precision value +FTYPE* FNAME(Xp_ldexpx)(FTYPE* p, int n, int m) noexcept { // scale an extended precision value int k; for (k = 0; k < n; ++k) { p[k] = static_cast(FFUN(ldexp)(p[k], m)); @@ -322,7 +322,7 @@ FTYPE* FNAME(Xp_ldexpx)(FTYPE* p, int n, int m) { // scale an extended precision return p; } -FTYPE* FNAME(Xp_mulx)(FTYPE* p, int n, const FTYPE* q, int m, FTYPE* ptemp2) { +FTYPE* FNAME(Xp_mulx)(FTYPE* p, int n, const FTYPE* q, int m, FTYPE* ptemp2) noexcept { // multiply by an extended precision value (needs 2 * n temp) if (n != 0 && m != 0) { if (q[0] == FLIT(0.0) || q[1] == FLIT(0.0)) { diff --git a/tests/std/tests/Dev10_555491_complex_linker_errors/test.cpp b/tests/std/tests/Dev10_555491_complex_linker_errors/test.cpp index 7c0efffbf0..83718ca15c 100644 --- a/tests/std/tests/Dev10_555491_complex_linker_errors/test.cpp +++ b/tests/std/tests/Dev10_555491_complex_linker_errors/test.cpp @@ -188,6 +188,117 @@ void test_gh_2728() { } } +template +void test_strengthened_exception_specification() { + STATIC_ASSERT(is_nothrow_default_constructible_v>); + + STATIC_ASSERT(is_nothrow_constructible_v, const F&>); + STATIC_ASSERT(is_nothrow_constructible_v, F>); + + STATIC_ASSERT(is_nothrow_constructible_v, const F&, const F&>); + STATIC_ASSERT(is_nothrow_constructible_v, const F&, F>); + STATIC_ASSERT(is_nothrow_constructible_v, F, const F&>); + STATIC_ASSERT(is_nothrow_constructible_v, F, F>); + + STATIC_ASSERT(is_nothrow_assignable_v&, const F&>); + STATIC_ASSERT(is_nothrow_assignable_v&, F>); + + complex c{}; + F f{}; + + STATIC_ASSERT(noexcept(c.real())); + STATIC_ASSERT(noexcept(c.real(f))); + STATIC_ASSERT(noexcept(c.imag())); + STATIC_ASSERT(noexcept(c.imag(f))); + + STATIC_ASSERT(noexcept(+c)); + STATIC_ASSERT(noexcept(-c)); + + STATIC_ASSERT(noexcept(c + c)); + STATIC_ASSERT(noexcept(c + f)); + STATIC_ASSERT(noexcept(f + c)); + STATIC_ASSERT(noexcept(c += c)); + STATIC_ASSERT(noexcept(c += f)); + + STATIC_ASSERT(noexcept(c - c)); + STATIC_ASSERT(noexcept(c - f)); + STATIC_ASSERT(noexcept(f - c)); + STATIC_ASSERT(noexcept(c -= c)); + STATIC_ASSERT(noexcept(c -= f)); + + STATIC_ASSERT(noexcept(c * c)); + STATIC_ASSERT(noexcept(c * f)); + STATIC_ASSERT(noexcept(f * c)); + STATIC_ASSERT(noexcept(c *= c)); + STATIC_ASSERT(noexcept(c *= f)); + + STATIC_ASSERT(noexcept(c / c)); + STATIC_ASSERT(noexcept(c / f)); + STATIC_ASSERT(noexcept(f / c)); + STATIC_ASSERT(noexcept(c /= c)); + STATIC_ASSERT(noexcept(c /= f)); + + STATIC_ASSERT(noexcept(c == c)); + STATIC_ASSERT(noexcept(c == f)); + STATIC_ASSERT(noexcept(f == c)); + + STATIC_ASSERT(noexcept(c != c)); + STATIC_ASSERT(noexcept(c != f)); + STATIC_ASSERT(noexcept(f != c)); + + STATIC_ASSERT(noexcept(real(c))); + STATIC_ASSERT(noexcept(imag(c))); + STATIC_ASSERT(noexcept(abs(c))); + STATIC_ASSERT(noexcept(arg(c))); + STATIC_ASSERT(noexcept(norm(c))); + STATIC_ASSERT(noexcept(conj(c))); + STATIC_ASSERT(noexcept(proj(c))); + + STATIC_ASSERT(noexcept(polar(f))); + STATIC_ASSERT(noexcept(polar(f, f))); + + STATIC_ASSERT(noexcept(acos(c))); + STATIC_ASSERT(noexcept(asin(c))); + STATIC_ASSERT(noexcept(atan(c))); + STATIC_ASSERT(noexcept(acosh(c))); + STATIC_ASSERT(noexcept(asinh(c))); + STATIC_ASSERT(noexcept(atanh(c))); + STATIC_ASSERT(noexcept(cos(c))); + STATIC_ASSERT(noexcept(cosh(c))); + STATIC_ASSERT(noexcept(exp(c))); + STATIC_ASSERT(noexcept(log(c))); + STATIC_ASSERT(noexcept(log10(c))); + STATIC_ASSERT(noexcept(sin(c))); + STATIC_ASSERT(noexcept(sinh(c))); + STATIC_ASSERT(noexcept(sqrt(c))); + STATIC_ASSERT(noexcept(tan(c))); + STATIC_ASSERT(noexcept(tanh(c))); + + STATIC_ASSERT(noexcept(pow(c, c))); + STATIC_ASSERT(noexcept(pow(c, f))); + STATIC_ASSERT(noexcept(pow(f, c))); +} + +template +void test_strengthened_exception_specification_2() { + STATIC_ASSERT(is_nothrow_constructible_v, const complex&>); + STATIC_ASSERT(is_nothrow_constructible_v, complex>); + + STATIC_ASSERT(is_nothrow_assignable_v&, const complex&>); + STATIC_ASSERT(is_nothrow_assignable_v&, complex>); + + complex c1{}; + complex c2{}; + + STATIC_ASSERT(noexcept(c1 += c2)); + STATIC_ASSERT(noexcept(c1 -= c2)); + STATIC_ASSERT(noexcept(c1 *= c2)); + STATIC_ASSERT(noexcept(c1 /= c2)); + + STATIC_ASSERT(noexcept(pow(c1, c2))); + STATIC_ASSERT(noexcept(pow(F1{}, c2))); +} + int main() { complex f(1, 2); @@ -293,7 +404,32 @@ int main() { test_gh_2728(); - // Also test N4928 [complex.numbers.general]/2: + // Also test strengthened exception specifications + test_strengthened_exception_specification(); + test_strengthened_exception_specification(); + test_strengthened_exception_specification(); + + STATIC_ASSERT(noexcept(0if)); // strengthened + STATIC_ASSERT(noexcept(0.0if)); // strengthened + STATIC_ASSERT(noexcept(0i)); // strengthened + STATIC_ASSERT(noexcept(0.0i)); // strengthened + STATIC_ASSERT(noexcept(0il)); // strengthened + STATIC_ASSERT(noexcept(0.0il)); // strengthened + + test_strengthened_exception_specification_2(); + test_strengthened_exception_specification_2(); + test_strengthened_exception_specification_2(); + test_strengthened_exception_specification_2(); + test_strengthened_exception_specification_2(); + test_strengthened_exception_specification_2(); + +#if _HAS_CXX20 + STATIC_ASSERT(is_nothrow_convertible_v, complex>); // strengthened + STATIC_ASSERT(is_nothrow_convertible_v, complex>); // strengthened + STATIC_ASSERT(is_nothrow_convertible_v, complex>); // strengthened +#endif // _HAS_CXX20 + + // Also test N4950 [complex.numbers.general]/2: // "Specializations of complex for cv-unqualified floating-point types are trivially-copyable literal types" STATIC_ASSERT(is_trivially_copyable_v>); STATIC_ASSERT(is_trivially_copyable_v>);