зеркало из https://github.com/microsoft/STL.git
<complex>: Fix the pow(complex, arithmetic) overload set (#1299)
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
This commit is contained in:
Родитель
bb05875900
Коммит
d05f8ecbb2
|
@ -1853,65 +1853,22 @@ _NODISCARD complex<_Upgrade_to_double<_Ty>> proj(_Ty _Left) {
|
|||
// FUNCTION TEMPLATE pow
|
||||
template <class _Ty1, class _Ty2>
|
||||
_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const complex<_Ty1>& _Left, const complex<_Ty2>& _Right) {
|
||||
using type = complex<_Common_float_type_t<_Ty1, _Ty2>>;
|
||||
return _STD pow(type(_Left), type(_Right));
|
||||
using _Type = complex<_Common_float_type_t<_Ty1, _Ty2>>;
|
||||
return _STD pow(_Type(_Left), _Type(_Right));
|
||||
}
|
||||
|
||||
template <class _Ty1, class _Ty2, enable_if_t<!is_integral_v<_Ty2>, int> = 0>
|
||||
template <class _Ty1, class _Ty2, enable_if_t<is_arithmetic_v<_Ty2>, int> = 0>
|
||||
_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const complex<_Ty1>& _Left, const _Ty2& _Right) {
|
||||
using type = complex<_Common_float_type_t<_Ty1, _Ty2>>;
|
||||
return _STD pow(type(_Left), type(_Right));
|
||||
using _Promoted = _Common_float_type_t<_Ty1, _Ty2>;
|
||||
using _Type = complex<_Promoted>;
|
||||
return _STD pow(_Type(_Left), _Type(static_cast<_Promoted>(_Right)));
|
||||
}
|
||||
|
||||
template <class _Ty1, class _Ty2, enable_if_t<!is_integral_v<_Ty1> && is_integral_v<_Ty2>, int> = 0>
|
||||
_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const complex<_Ty1>& _Left, const _Ty2 _Right) {
|
||||
using type = complex<_Common_float_type_t<_Ty1, _Ty2>>;
|
||||
|
||||
type _Tmp = _Left;
|
||||
auto _Count = static_cast<make_unsigned_t<_Ty2>>(_Right);
|
||||
|
||||
if (_Right < 0) {
|
||||
_Count = 0 - _Count; // safe negation as unsigned
|
||||
}
|
||||
|
||||
for (type _Zv(1);; _Tmp *= _Tmp) { // fold in _Left ^ (2 ^ _Count) as needed
|
||||
if ((_Count & 1) != 0) {
|
||||
_Zv *= _Tmp;
|
||||
}
|
||||
|
||||
if ((_Count >>= 1) == 0) {
|
||||
return _Right < 0 ? type(1) / _Zv : _Zv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Ty1, class _Ty2, enable_if_t<is_integral_v<_Ty1> && is_integral_v<_Ty2>, int> = 0>
|
||||
_NODISCARD complex<_Ty1> pow(const complex<_Ty1>& _Left, _Ty2 _Right) {
|
||||
// raise Gaussian integer to an integer power
|
||||
using type = complex<_Ty1>;
|
||||
|
||||
type _Ans = type(1, 0);
|
||||
|
||||
if (_Right < 0) {
|
||||
_Ans = type(0, 0); // ignore 1/type(0, 0) error
|
||||
} else if (0 < _Right) { // raise to a positive power
|
||||
for (type _Factor = _Left;; _Factor *= _Factor) { // fold in _Left^(2^N))
|
||||
if ((_Right & 1) != 0) {
|
||||
_Ans *= _Factor;
|
||||
}
|
||||
|
||||
if ((_Right >>= 1) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _Ans;
|
||||
}
|
||||
|
||||
template <class _Ty1, class _Ty2>
|
||||
template <class _Ty1, class _Ty2, enable_if_t<is_arithmetic_v<_Ty1>, int> = 0>
|
||||
_NODISCARD complex<_Common_float_type_t<_Ty1, _Ty2>> pow(const _Ty1& _Left, const complex<_Ty2>& _Right) {
|
||||
using type = complex<_Common_float_type_t<_Ty1, _Ty2>>;
|
||||
return _STD pow(type(_Left), type(_Right));
|
||||
using _Promoted = _Common_float_type_t<_Ty1, _Ty2>;
|
||||
using _Type = complex<_Promoted>;
|
||||
return _STD pow(_Type(static_cast<_Promoted>(_Left)), _Type(_Right));
|
||||
}
|
||||
|
||||
// FUNCTION TEMPLATE operator>>
|
||||
|
|
|
@ -530,9 +530,6 @@ std/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp FAIL
|
|||
# GH-1004 <regex>: Error C2664 in std::regex_traits::transform
|
||||
std/re/re.traits/transform.pass.cpp FAIL
|
||||
|
||||
# GH-1260 <complex>: pow, incorrect type conversion
|
||||
std/numerics/complex.number/cmplx.over/pow.pass.cpp FAIL
|
||||
|
||||
# GH-1295 <array>: array<const T, 0> allows fill() and swap()
|
||||
std/containers/sequences/array/array.fill/fill.fail.cpp FAIL
|
||||
std/containers/sequences/array/array.swap/swap.fail.cpp FAIL
|
||||
|
@ -752,6 +749,7 @@ std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp F
|
|||
|
||||
# Tests emit warning C4244: 'argument': conversion from 'T' to 'const std::complex<double>::_Ty', possible loss of data
|
||||
std/numerics/complex.number/cmplx.over/conj.pass.cpp:0 FAIL
|
||||
std/numerics/complex.number/cmplx.over/pow.pass.cpp:0 FAIL
|
||||
std/numerics/complex.number/cmplx.over/proj.pass.cpp:0 FAIL
|
||||
|
||||
# Assertion failed: std::abs(skew - x_skew) < 0.01
|
||||
|
|
|
@ -530,9 +530,6 @@ input.output\file.streams\fstreams\filebuf.virtuals\underflow.pass.cpp
|
|||
# GH-1004 <regex>: Error C2664 in std::regex_traits::transform
|
||||
re\re.traits\transform.pass.cpp
|
||||
|
||||
# GH-1260 <complex>: pow, incorrect type conversion
|
||||
numerics\complex.number\cmplx.over\pow.pass.cpp
|
||||
|
||||
# GH-1295 <array>: array<const T, 0> allows fill() and swap()
|
||||
containers\sequences\array\array.fill\fill.fail.cpp
|
||||
containers\sequences\array\array.swap\swap.fail.cpp
|
||||
|
@ -752,6 +749,7 @@ iterators\predef.iterators\insert.iterators\insert.iterator\types.pass.cpp
|
|||
|
||||
# Tests emit warning C4244: 'argument': conversion from 'T' to 'const std::complex<double>::_Ty', possible loss of data
|
||||
numerics\complex.number\cmplx.over\conj.pass.cpp
|
||||
numerics\complex.number\cmplx.over\pow.pass.cpp
|
||||
numerics\complex.number\cmplx.over\proj.pass.cpp
|
||||
|
||||
# Assertion failed: std::abs(skew - x_skew) < 0.01
|
||||
|
|
Загрузка…
Ссылка в новой задаче