Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 10 additions & 53 deletions stl/inc/complex
Original file line number Diff line number Diff line change
Expand Up @@ -1845,65 +1845,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>>
Expand Down
4 changes: 1 addition & 3 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down