Skip to content
Open
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
20 changes: 20 additions & 0 deletions libcxx/include/complex
Original file line number Diff line number Diff line change
Expand Up @@ -1100,18 +1100,38 @@ inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const com
return std::exp(__y * std::log(__x));
}

# if _LIBCPP_STD_VER >= 26
template <class _Tp, class _Up, __enable_if_t<is_floating_point<_Tp>::value && is_floating_point<_Up>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, conditional_t<is_integral_v<_Up>, double, _Up>>::type>
pow(const complex<_Tp>& __x, const complex<_Up>& __y) {
using _Yp = conditional_t<is_integral_v<_Up>, double, _Up>;
typedef complex<typename __promote<_Tp, _Yp>::type> result_type;
return std::pow(result_type(__x), result_type(__y));
}
# else
template <class _Tp, class _Up, __enable_if_t<is_floating_point<_Tp>::value && is_floating_point<_Up>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type>
pow(const complex<_Tp>& __x, const complex<_Up>& __y) {
typedef complex<typename __promote<_Tp, _Up>::type> result_type;
return std::pow(result_type(__x), result_type(__y));
}
# endif

# if _LIBCPP_STD_VER >= 26
template <class _Tp, class _Up, __enable_if_t<is_floating_point<_Tp>::value && is_arithmetic<_Up>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, conditional_t<is_integral_v<_Up>, double, _Up>>::type>
pow(const complex<_Tp>& __x, const _Up& __y) {
using _Yp = conditional_t<is_integral_v<_Up>, double, _Up>;
typedef complex<typename __promote<_Tp, _Yp>::type> result_type;
return std::pow(result_type(__x), result_type(__y));
}
# else
template <class _Tp, class _Up, __enable_if_t<is_floating_point<_Tp>::value && is_arithmetic<_Up>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const complex<_Tp>& __x, const _Up& __y) {
typedef complex<typename __promote<_Tp, _Up>::type> result_type;
return std::pow(result_type(__x), result_type(__y));
}
# endif

template <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value && is_floating_point<_Up>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const _Tp& __x, const complex<_Up>& __y) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,8 @@ int main(int, char**) {
assert(pow(ctag, std::complex<long double>(1.0l)) == 4);
assert(pow(std::complex<long double>(1.0l), ctag) == 5);

// Make sure LWG4191: P1467 is respected.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC the libcxx/test/libcxx subdirectory is intendedly used for libc++-specific implementation details and extensions. As we're testing implementation of standard requirements, I think it's better not to add cases here.

static_assert(std::is_same_v<decltype(std::pow(std::complex<float>(), int())), std::complex<double>>, "");

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,8 @@ int main(int, char**)
test<long double, float>();
test<long double, double>();

return 0;
// Make sure LWG4191: P1467 is respected.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to change this file either. test<int, float>(), test<unsigned, float>(), and test<long long, float>() should have been sufficient.

static_assert(std::is_same_v<decltype(std::pow(std::complex<float>(), int())), std::complex<double>>, "");

return 0;
}
Loading