[libcxx-commits] [libcxx] [libcxx] Change the return type of pow(complex<float>, int) (PR #128779)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 25 14:11:02 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Omar Hossam (moar55)

<details>
<summary>Changes</summary>

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?

---
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
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;
 }

``````````

</details>


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


More information about the libcxx-commits mailing list