-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libcxx] Change the return type of pow(complex<float>, int) #128779
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-libcxx Author: Omar Hossam (moar55) ChangesThis addresses #127866. Full diff: https://github.com/llvm/llvm-project/pull/128779.diff 3 Files Affected:
diff --git a/libcxx/include/complex b/libcxx/include/complex
index df18159595b34..0871ded7f5707 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -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) {
diff --git a/libcxx/test/libcxx/numerics/complex.number/cmplx.over.pow.pass.cpp b/libcxx/test/libcxx/numerics/complex.number/cmplx.over.pow.pass.cpp
index 8c1b3a17c669f..76f2224be37e0 100644
--- a/libcxx/test/libcxx/numerics/complex.number/cmplx.over.pow.pass.cpp
+++ b/libcxx/test/libcxx/numerics/complex.number/cmplx.over.pow.pass.cpp
@@ -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.
+ static_assert(std::is_same_v<decltype(std::pow(std::complex<float>(), int())), std::complex<double>>, "");
+
return 0;
}
diff --git a/libcxx/test/std/numerics/complex.number/cmplx.over/pow.pass.cpp b/libcxx/test/std/numerics/complex.number/cmplx.over/pow.pass.cpp
index 54a6cba9c0011..7a9ca6719a20c 100644
--- a/libcxx/test/std/numerics/complex.number/cmplx.over/pow.pass.cpp
+++ b/libcxx/test/std/numerics/complex.number/cmplx.over/pow.pass.cpp
@@ -101,6 +101,9 @@ int main(int, char**)
test<long double, float>();
test<long double, double>();
+
+ // Make sure LWG4191: P1467 is respected.
+ static_assert(std::is_same_v<decltype(std::pow(std::complex<float>(), int())), std::complex<double>>, "");
return 0;
}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
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 test files, because LWG4191 just reverts a mistaken change in C++23. The current pre-C++23 test coverages are sufficient.
However, I have no idea how to continue as we haven't implemented P1467R9.
@@ -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. |
There was a problem hiding this comment.
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.
@@ -102,5 +102,8 @@ int main(int, char**) | |||
test<long double, float>(); | |||
test<long double, double>(); | |||
|
|||
return 0; | |||
// Make sure LWG4191: P1467 is respected. |
There was a problem hiding this comment.
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.
This addresses #127866.
This is just a first attempt, as I am not sure about a few things...
Should I add a test in
libcxx
as well?I also added this logic to
pow(complex<T>, complex<U>)
, because the amendment of the proposal talks about this as well. Does that make sense to you?