Skip to content
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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

moar55
Copy link
Contributor

@moar55 moar55 commented Feb 25, 2025

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?

@moar55 moar55 requested a review from a team as a code owner February 25, 2025 22:10
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Feb 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 25, 2025

@llvm/pr-subscribers-libcxx

Author: Omar Hossam (moar55)

Changes

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&lt;T&gt;, complex&lt;U&gt;), because the amendment of the proposal talks about this as well. Does that make sense to you?


Full diff: https://github.com/llvm/llvm-project/pull/128779.diff

3 Files Affected:

  • (modified) libcxx/include/complex (+20)
  • (modified) libcxx/test/libcxx/numerics/complex.number/cmplx.over.pow.pass.cpp (+3)
  • (modified) libcxx/test/std/numerics/complex.number/cmplx.over/pow.pass.cpp (+3)
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;
 }

Copy link

github-actions bot commented Feb 25, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@frederick-vs-ja frederick-vs-ja left a 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.
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.

@@ -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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants