Skip to content

[libc++] Simplify __promote #136101

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

Merged
merged 1 commit into from
May 8, 2025
Merged

[libc++] Simplify __promote #136101

merged 1 commit into from
May 8, 2025

Conversation

philnik777
Copy link
Contributor

@philnik777 philnik777 commented Apr 17, 2025

This avoids instantiating an extra class for every variant __promote is used in.

Copy link

github-actions bot commented Apr 17, 2025

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

@ldionne ldionne marked this pull request as ready for review May 7, 2025 14:59
@ldionne ldionne requested a review from a team as a code owner May 7, 2025 14:59
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label May 7, 2025
@llvmbot
Copy link
Member

llvmbot commented May 7, 2025

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

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

15 Files Affected:

  • (modified) libcxx/include/__math/copysign.h (+1-1)
  • (modified) libcxx/include/__math/exponential_functions.h (+2-2)
  • (modified) libcxx/include/__math/fdim.h (+2-2)
  • (modified) libcxx/include/__math/fma.h (+2-2)
  • (modified) libcxx/include/__math/hypot.h (+4-4)
  • (modified) libcxx/include/__math/inverse_trigonometric_functions.h (+2-2)
  • (modified) libcxx/include/__math/min_max.h (+4-4)
  • (modified) libcxx/include/__math/modulo.h (+2-2)
  • (modified) libcxx/include/__math/remainder.h (+4-4)
  • (modified) libcxx/include/__math/rounding_functions.h (+2-2)
  • (modified) libcxx/include/__math/traits.h (+6-6)
  • (modified) libcxx/include/__type_traits/promote.h (+14-21)
  • (modified) libcxx/include/cmath (+3-5)
  • (modified) libcxx/include/complex (+6-7)
  • (modified) libcxx/test/libcxx/numerics/complex.number/cmplx.over.pow.pass.cpp (+3-3)
diff --git a/libcxx/include/__math/copysign.h b/libcxx/include/__math/copysign.h
index c3ca6a3b0370b..4c297cb0894e9 100644
--- a/libcxx/include/__math/copysign.h
+++ b/libcxx/include/__math/copysign.h
@@ -33,7 +33,7 @@ namespace __math {
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type copysign(_A1 __x, _A2 __y) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> copysign(_A1 __x, _A2 __y) _NOEXCEPT {
   return ::__builtin_copysign(__x, __y);
 }
 
diff --git a/libcxx/include/__math/exponential_functions.h b/libcxx/include/__math/exponential_functions.h
index 109c3349970f6..09930b7819e23 100644
--- a/libcxx/include/__math/exponential_functions.h
+++ b/libcxx/include/__math/exponential_functions.h
@@ -158,8 +158,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double pow(long double __x, long double __y) _
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type pow(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> pow(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::pow((__result_type)__x, (__result_type)__y);
 }
diff --git a/libcxx/include/__math/fdim.h b/libcxx/include/__math/fdim.h
index dc1b4ecc07dce..a1081c7bde3d3 100644
--- a/libcxx/include/__math/fdim.h
+++ b/libcxx/include/__math/fdim.h
@@ -35,8 +35,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double fdim(long double __x, long double __y)
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fdim(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> fdim(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::fdim((__result_type)__x, (__result_type)__y);
 }
diff --git a/libcxx/include/__math/fma.h b/libcxx/include/__math/fma.h
index 6ba7a5a2d26d6..b972d85b89cb3 100644
--- a/libcxx/include/__math/fma.h
+++ b/libcxx/include/__math/fma.h
@@ -40,8 +40,8 @@ template <class _A1,
           class _A2,
           class _A3,
           __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value && is_arithmetic<_A3>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2, _A3>::type fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2, _A3>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2, _A3> fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2, _A3>;
   static_assert(
       !(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value && _IsSame<_A3, __result_type>::value),
       "");
diff --git a/libcxx/include/__math/hypot.h b/libcxx/include/__math/hypot.h
index b2bf8e11c8ec2..8e8c35b4a41c8 100644
--- a/libcxx/include/__math/hypot.h
+++ b/libcxx/include/__math/hypot.h
@@ -43,8 +43,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double hypot(long double __x, long double __y)
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type hypot(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> hypot(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::hypot((__result_type)__x, (__result_type)__y);
 }
@@ -91,8 +91,8 @@ template <class _A1,
           class _A2,
           class _A3,
           std::enable_if_t< is_arithmetic_v<_A1> && is_arithmetic_v<_A2> && is_arithmetic_v<_A3>, int> = 0 >
-_LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2, _A3>::type hypot(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2, _A3>::type;
+_LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2, _A3> hypot(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2, _A3>;
   static_assert(!(
       std::is_same_v<_A1, __result_type> && std::is_same_v<_A2, __result_type> && std::is_same_v<_A3, __result_type>));
   return __math::__hypot(
diff --git a/libcxx/include/__math/inverse_trigonometric_functions.h b/libcxx/include/__math/inverse_trigonometric_functions.h
index cd98b46a6aab8..409500278e7a9 100644
--- a/libcxx/include/__math/inverse_trigonometric_functions.h
+++ b/libcxx/include/__math/inverse_trigonometric_functions.h
@@ -86,8 +86,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double atan2(long double __y, long double __x)
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type atan2(_A1 __y, _A2 __x) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> atan2(_A1 __y, _A2 __x) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::atan2((__result_type)__y, (__result_type)__x);
 }
diff --git a/libcxx/include/__math/min_max.h b/libcxx/include/__math/min_max.h
index db900c849e722..1ddbb557d1e8f 100644
--- a/libcxx/include/__math/min_max.h
+++ b/libcxx/include/__math/min_max.h
@@ -39,8 +39,8 @@ template <class = int>
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmax(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> fmax(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::fmax((__result_type)__x, (__result_type)__y);
 }
@@ -61,8 +61,8 @@ template <class = int>
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmin(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> fmin(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::fmin((__result_type)__x, (__result_type)__y);
 }
diff --git a/libcxx/include/__math/modulo.h b/libcxx/include/__math/modulo.h
index c8ea506f37d75..71405abb6b9b8 100644
--- a/libcxx/include/__math/modulo.h
+++ b/libcxx/include/__math/modulo.h
@@ -37,8 +37,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double fmod(long double __x, long double __y)
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmod(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> fmod(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::fmod((__result_type)__x, (__result_type)__y);
 }
diff --git a/libcxx/include/__math/remainder.h b/libcxx/include/__math/remainder.h
index 0adb7f3af5de2..39fb76af6bdec 100644
--- a/libcxx/include/__math/remainder.h
+++ b/libcxx/include/__math/remainder.h
@@ -37,8 +37,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double remainder(long double __x, long double
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type remainder(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> remainder(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::remainder((__result_type)__x, (__result_type)__y);
 }
@@ -59,8 +59,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double remquo(long double __x, long double __y
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type remquo(_A1 __x, _A2 __y, int* __z) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> remquo(_A1 __x, _A2 __y, int* __z) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::remquo((__result_type)__x, (__result_type)__y, __z);
 }
diff --git a/libcxx/include/__math/rounding_functions.h b/libcxx/include/__math/rounding_functions.h
index 474f585a62f15..aadeb395fa2eb 100644
--- a/libcxx/include/__math/rounding_functions.h
+++ b/libcxx/include/__math/rounding_functions.h
@@ -158,8 +158,8 @@ inline _LIBCPP_HIDE_FROM_ABI long double nextafter(long double __x, long double
 }
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type nextafter(_A1 __x, _A2 __y) _NOEXCEPT {
-  using __result_type = typename __promote<_A1, _A2>::type;
+inline _LIBCPP_HIDE_FROM_ABI __promote_t<_A1, _A2> nextafter(_A1 __x, _A2 __y) _NOEXCEPT {
+  using __result_type = __promote_t<_A1, _A2>;
   static_assert(!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value), "");
   return __math::nextafter((__result_type)__x, (__result_type)__y);
 }
diff --git a/libcxx/include/__math/traits.h b/libcxx/include/__math/traits.h
index 550eb393e2d4f..4a6e58c6da8ad 100644
--- a/libcxx/include/__math/traits.h
+++ b/libcxx/include/__math/traits.h
@@ -145,7 +145,7 @@ template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT {
-  using type = typename __promote<_A1, _A2>::type;
+  using type = __promote_t<_A1, _A2>;
   return __builtin_isgreater((type)__x, (type)__y);
 }
 
@@ -153,7 +153,7 @@ template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_ar
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT {
-  using type = typename __promote<_A1, _A2>::type;
+  using type = __promote_t<_A1, _A2>;
   return __builtin_isgreaterequal((type)__x, (type)__y);
 }
 
@@ -161,7 +161,7 @@ template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_ar
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT {
-  using type = typename __promote<_A1, _A2>::type;
+  using type = __promote_t<_A1, _A2>;
   return __builtin_isless((type)__x, (type)__y);
 }
 
@@ -169,7 +169,7 @@ template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_ar
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT {
-  using type = typename __promote<_A1, _A2>::type;
+  using type = __promote_t<_A1, _A2>;
   return __builtin_islessequal((type)__x, (type)__y);
 }
 
@@ -177,7 +177,7 @@ template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_ar
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT {
-  using type = typename __promote<_A1, _A2>::type;
+  using type = __promote_t<_A1, _A2>;
   return __builtin_islessgreater((type)__x, (type)__y);
 }
 
@@ -185,7 +185,7 @@ template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_ar
 
 template <class _A1, class _A2, __enable_if_t<is_arithmetic<_A1>::value && is_arithmetic<_A2>::value, int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT {
-  using type = typename __promote<_A1, _A2>::type;
+  using type = __promote_t<_A1, _A2>;
   return __builtin_isunordered((type)__x, (type)__y);
 }
 
diff --git a/libcxx/include/__type_traits/promote.h b/libcxx/include/__type_traits/promote.h
index b449a749004ab..499081aead863 100644
--- a/libcxx/include/__type_traits/promote.h
+++ b/libcxx/include/__type_traits/promote.h
@@ -10,8 +10,6 @@
 #define _LIBCPP___TYPE_TRAITS_PROMOTE_H
 
 #include <__config>
-#include <__type_traits/integral_constant.h>
-#include <__type_traits/is_arithmetic.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -19,28 +17,23 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class... _Args>
-class __promote {
-  static_assert((is_arithmetic<_Args>::value && ...));
-
-  static float __test(float);
-  static double __test(char);
-  static double __test(int);
-  static double __test(unsigned);
-  static double __test(long);
-  static double __test(unsigned long);
-  static double __test(long long);
-  static double __test(unsigned long long);
+float __promote_impl(float);
+double __promote_impl(char);
+double __promote_impl(int);
+double __promote_impl(unsigned);
+double __promote_impl(long);
+double __promote_impl(unsigned long);
+double __promote_impl(long long);
+double __promote_impl(unsigned long long);
 #if _LIBCPP_HAS_INT128
-  static double __test(__int128_t);
-  static double __test(__uint128_t);
+double __promote_impl(__int128_t);
+double __promote_impl(__uint128_t);
 #endif
-  static double __test(double);
-  static long double __test(long double);
+double __promote_impl(double);
+long double __promote_impl(long double);
 
-public:
-  using type = decltype((__test(_Args()) + ...));
-};
+template <class... _Args>
+using __promote_t _LIBCPP_NODEBUG = decltype((std::__promote_impl(_Args()) + ...));
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/cmath b/libcxx/include/cmath
index 9cf044d4d023b..bee743f702d01 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -599,11 +599,9 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr long double lerp(long double __a, long do
 }
 
 template <class _A1, class _A2, class _A3>
-inline _LIBCPP_HIDE_FROM_ABI constexpr
-    typename enable_if_t< is_arithmetic<_A1>::value && is_arithmetic<_A2>::value && is_arithmetic<_A3>::value,
-                          __promote<_A1, _A2, _A3> >::type
-    lerp(_A1 __a, _A2 __b, _A3 __t) noexcept {
-  typedef typename __promote<_A1, _A2, _A3>::type __result_type;
+  requires(is_arithmetic_v<_A1> && is_arithmetic_v<_A2> && is_arithmetic_v<_A3>)
+_LIBCPP_HIDE_FROM_ABI inline constexpr __promote_t<_A1, _A2, _A3> lerp(_A1 __a, _A2 __b, _A3 __t) noexcept {
+  using __result_type = __promote_t<_A1, _A2, _A3>;
   static_assert(!(
       _IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value && _IsSame<_A3, __result_type>::value));
   return std::__lerp((__result_type)__a, (__result_type)__b, (__result_type)__t);
diff --git a/libcxx/include/complex b/libcxx/include/complex
index fda75796ffa67..e9baec04d9465 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -1101,21 +1101,20 @@ inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const com
 }
 
 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;
+inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> > pow(const complex<_Tp>& __x, const complex<_Up>& __y) {
+  typedef complex<__promote_t<_Tp, _Up> > result_type;
   return std::pow(result_type(__x), result_type(__y));
 }
 
 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;
+inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> > pow(const complex<_Tp>& __x, const _Up& __y) {
+  typedef complex<__promote_t<_Tp, _Up> > result_type;
   return std::pow(result_type(__x), result_type(__y));
 }
 
 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) {
-  typedef complex<typename __promote<_Tp, _Up>::type> result_type;
+inline _LIBCPP_HIDE_FROM_ABI complex<__promote_t<_Tp, _Up> > pow(const _Tp& __x, const complex<_Up>& __y) {
+  typedef complex<__promote_t<_Tp, _Up> > result_type;
   return std::pow(result_type(__x), result_type(__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..d87e259cefe39 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
@@ -10,9 +10,9 @@
 
 // XFAIL: FROZEN-CXX03-HEADERS-FIXME
 
-//  template<class T, class U> complex<__promote<T, U>::type> pow(const complex<T>&, const U&);
-//  template<class T, class U> complex<__promote<T, U>::type> pow(const complex<T>&, const complex<U>&);
-//  template<class T, class U> complex<__promote<T, U>::type> pow(const T&, const complex<U>&);
+//  template<class T, class U> complex<__promote_t<T, U>> pow(const complex<T>&, const U&);
+//  template<class T, class U> complex<__promote_t<T, U>> pow(const complex<T>&, const complex<U>&);
+//  template<class T, class U> complex<__promote_t<T, U>> pow(const T&, const complex<U>&);
 
 // Test that these additional overloads are free from catching std::complex<non-floating-point>,
 // which is expected by several 3rd party libraries, see https://github.com/llvm/llvm-project/issues/109858.

@ldionne ldionne merged commit 948bffa into llvm:main May 8, 2025
84 checks passed
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