public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Jonathan Wakely <jwakely@redhat.com>
Cc: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org
Subject: [PATCH] libstdc++-v3: <complex> support for extended floating point types
Date: Fri, 21 Oct 2022 17:58:19 +0200	[thread overview]
Message-ID: <Y1LBm4u+R3Ka28Dj@tucnak> (raw)

Hi!

The following patch adds <complex> support for extended floating point
types.
C++23 removes the float/double/long double specializations from the spec
and instead adds explicit(bool) specifier on the converting constructor.
The patch uses that for converting constructor of the base template as well
as the float/double/long double specializations's converting constructors
(e.g. so that it handles convertion construction also from complex of extended
floating point types).  Copy ctor was already defaulted as the spec now
requires.
The patch also adds partial specialization for the _Float{16,32,64,128}
and __gnu_cxx::__bfloat16_t types because the base template doesn't use
__complex__ but a pair of floating point values.
This patch is on top of
https://gcc.gnu.org/pipermail/libstdc++/2022-October/054849.html
(and if
https://gcc.gnu.org/pipermail/libstdc++/2022-October/054862.html
is also applied, then
https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603665.html                                                                                                                    
https://gcc.gnu.org/pipermail/gcc-patches/2022-October/604080.html                                                                                                                    
https://gcc.gnu.org/pipermail/gcc-patches/2022-October/604134.html
are needed as well).
The g++.dg/cpp23/ testcase verifies explicit(bool) works correctly.

Tested on x86_64-linux, ok for trunk?

2022-10-21  Jakub Jelinek  <jakub@redhat.com>

gcc/testsuite/
	* g++.dg/cpp23/ext-floating12.C: New test.
libstdc++-v3/
	* include/std/complex (complex::complex converting ctor): For C++23
	use explicit specifier with constant expression and explicitly cast
	both parts to _Tp.
	(__complex_abs, __complex_arg, __complex_cos, __complex_cosh,
	__complex_exp, __complex_log, __complex_sin, __complex_sinh,
	__complex_sqrt, __complex_tan, __complex_tanh, __complex_pow): Add
	__complex__ _Float{16,32,64,128} and __complex__ decltype(0.0bf16)
	overloads.
	(complex<float>::complex converting ctor,
	complex<double>::complex converting ctor,
	complex<long double>::complex converting ctor): For C++23 implement
	as template with explicit specifier with constant expression
	and explicit casts.
	(__complex_type): New template.
	(complex): New partial specialization for types with extended floating
	point types.
	(__complex_acos, __complex_asin, __complex_atan, __complex_acosh,
	__complex_asinh, __complex_atanh): Add __complex__ _Float{16,32,64,128}
	and __complex__ decltype(0.0bf16) overloads.
	(__complex_proj): Likewise.  Add template for complex of extended
	floating point types.
	* include/bits/cpp_type_traits.h (__is_floating): Specialize for
	_Float{16,32,64,128} and __gnu_cxx::__bfloat16_t.
	* testsuite/26_numerics/complex/ext_c++23.cc: New test.

--- libstdc++-v3/include/std/complex.jj	2022-10-21 08:55:43.037675332 +0200
+++ libstdc++-v3/include/std/complex	2022-10-21 17:05:36.802243229 +0200
@@ -142,8 +142,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       ///  Converting constructor.
       template<typename _Up>
+#if __cplusplus > 202002L
+	explicit(!requires(_Up __u) { _Tp{__u}; })
+	constexpr complex(const complex<_Up>& __z)
+	: _M_real(_Tp(__z.real())), _M_imag(_Tp(__z.imag())) { }
+#else
         _GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z)
 	: _M_real(__z.real()), _M_imag(__z.imag()) { }
+#endif
 
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -1077,6 +1083,264 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	                 : std::pow(complex<_Tp>(__x), __y);
     }
 
+#if _GLIBCXX_USE_C99_COMPLEX
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float16
+  __complex_abs(__complex__ _Float16 __z)
+  { return _Float16(__builtin_cabsf(__z)); }
+
+  inline _Float16
+  __complex_arg(__complex__ _Float16 __z)
+  { return _Float16(__builtin_cargf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_cos(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_ccosf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_cosh(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_ccoshf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_exp(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_cexpf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_log(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_clogf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_sin(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_csinf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_sinh(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_csinhf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_sqrt(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_csqrtf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_tan(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_ctanf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_tanh(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_ctanhf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_pow(__complex__ _Float16 __x, __complex__ _Float16 __y)
+  { return static_cast<__complex__ _Float16>(__builtin_cpowf(__x, __y)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float32
+  __complex_abs(__complex__ _Float32 __z) { return __builtin_cabsf(__z); }
+
+  inline _Float32
+  __complex_arg(__complex__ _Float32 __z) { return __builtin_cargf(__z); }
+
+  inline __complex__ _Float32
+  __complex_cos(__complex__ _Float32 __z) { return __builtin_ccosf(__z); }
+
+  inline __complex__ _Float32
+  __complex_cosh(__complex__ _Float32 __z) { return __builtin_ccoshf(__z); }
+
+  inline __complex__ _Float32
+  __complex_exp(__complex__ _Float32 __z) { return __builtin_cexpf(__z); }
+
+  inline __complex__ _Float32
+  __complex_log(__complex__ _Float32 __z) { return __builtin_clogf(__z); }
+
+  inline __complex__ _Float32
+  __complex_sin(__complex__ _Float32 __z) { return __builtin_csinf(__z); }
+
+  inline __complex__ _Float32
+  __complex_sinh(__complex__ _Float32 __z) { return __builtin_csinhf(__z); }
+
+  inline __complex__ _Float32
+  __complex_sqrt(__complex__ _Float32 __z) { return __builtin_csqrtf(__z); }
+
+  inline __complex__ _Float32
+  __complex_tan(__complex__ _Float32 __z) { return __builtin_ctanf(__z); }
+
+  inline __complex__ _Float32
+  __complex_tanh(__complex__ _Float32 __z) { return __builtin_ctanhf(__z); }
+
+  inline __complex__ _Float32
+  __complex_pow(__complex__ _Float32 __x, __complex__ _Float32 __y)
+  { return __builtin_cpowf(__x, __y); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline _Float64
+  __complex_abs(__complex__ _Float64 __z) { return __builtin_cabs(__z); }
+
+  inline _Float64
+  __complex_arg(__complex__ _Float64 __z) { return __builtin_carg(__z); }
+
+  inline __complex__ _Float64
+  __complex_cos(__complex__ _Float64 __z) { return __builtin_ccos(__z); }
+
+  inline __complex__ _Float64
+  __complex_cosh(__complex__ _Float64 __z) { return __builtin_ccosh(__z); }
+
+  inline __complex__ _Float64
+  __complex_exp(__complex__ _Float64 __z) { return __builtin_cexp(__z); }
+
+  inline __complex__ _Float64
+  __complex_log(__complex__ _Float64 __z) { return __builtin_clog(__z); }
+
+  inline __complex__ _Float64
+  __complex_sin(__complex__ _Float64 __z) { return __builtin_csin(__z); }
+
+  inline __complex__ _Float64
+  __complex_sinh(__complex__ _Float64 __z) { return __builtin_csinh(__z); }
+
+  inline __complex__ _Float64
+  __complex_sqrt(__complex__ _Float64 __z) { return __builtin_csqrt(__z); }
+
+  inline __complex__ _Float64
+  __complex_tan(__complex__ _Float64 __z) { return __builtin_ctan(__z); }
+
+  inline __complex__ _Float64
+  __complex_tanh(__complex__ _Float64 __z) { return __builtin_ctanh(__z); }
+
+  inline __complex__ _Float64
+  __complex_pow(__complex__ _Float64 __x, __complex__ _Float64 __y)
+  { return __builtin_cpow(__x, __y); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  inline _Float128
+  __complex_abs(__complex__ _Float128 __z) { return __builtin_cabsl(__z); }
+
+  inline _Float128
+  __complex_arg(__complex__ _Float128 __z) { return __builtin_cargl(__z); }
+
+  inline __complex__ _Float128
+  __complex_cos(__complex__ _Float128 __z) { return __builtin_ccosl(__z); }
+
+  inline __complex__ _Float128
+  __complex_cosh(__complex__ _Float128 __z) { return __builtin_ccoshl(__z); }
+
+  inline __complex__ _Float128
+  __complex_exp(__complex__ _Float128 __z) { return __builtin_cexpl(__z); }
+
+  inline __complex__ _Float128
+  __complex_log(__complex__ _Float128 __z) { return __builtin_clogl(__z); }
+
+  inline __complex__ _Float128
+  __complex_sin(__complex__ _Float128 __z) { return __builtin_csinl(__z); }
+
+  inline __complex__ _Float128
+  __complex_sinh(__complex__ _Float128 __z) { return __builtin_csinhl(__z); }
+
+  inline __complex__ _Float128
+  __complex_sqrt(__complex__ _Float128 __z) { return __builtin_csqrtl(__z); }
+
+  inline __complex__ _Float128
+  __complex_tan(__complex__ _Float128 __z) { return __builtin_ctanl(__z); }
+
+  inline __complex__ _Float128
+  __complex_tanh(__complex__ _Float128 __z) { return __builtin_ctanhl(__z); }
+
+  inline __complex__ _Float128
+  __complex_pow(__complex__ _Float128 __x, __complex__ _Float128 __y)
+  { return __builtin_cpowl(__x, __y); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  inline _Float128
+  __complex_abs(__complex__ _Float128 __z) { return __builtin_cabsf128(__z); }
+
+  inline _Float128
+  __complex_arg(__complex__ _Float128 __z) { return __builtin_cargf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_cos(__complex__ _Float128 __z) { return __builtin_ccosf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_cosh(__complex__ _Float128 __z) { return __builtin_ccoshf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_exp(__complex__ _Float128 __z) { return __builtin_cexpf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_log(__complex__ _Float128 __z) { return __builtin_clogf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_sin(__complex__ _Float128 __z) { return __builtin_csinf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_sinh(__complex__ _Float128 __z) { return __builtin_csinhf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_sqrt(__complex__ _Float128 __z) { return __builtin_csqrtf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_tan(__complex__ _Float128 __z) { return __builtin_ctanf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_tanh(__complex__ _Float128 __z) { return __builtin_ctanhf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_pow(__complex__ _Float128 __x, __complex__ _Float128 __y)
+  { return __builtin_cpowf128(__x, __y); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __gnu_cxx::__bfloat16_t
+  __complex_abs(__complex__ decltype(0.0bf16) __z)
+  { return __gnu_cxx::__bfloat16_t(__builtin_cabsf(__z)); }
+
+  inline __gnu_cxx::__bfloat16_t
+  __complex_arg(__complex__ decltype(0.0bf16) __z)
+  { return __gnu_cxx::__bfloat16_t(__builtin_cargf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_cos(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_ccosf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_cosh(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_ccoshf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_exp(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_cexpf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_log(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_clogf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_sin(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_csinf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_sinh(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_csinhf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_sqrt(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_csqrtf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_tan(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_ctanf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_tanh(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_ctanhf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_pow(__complex__ decltype(0.0bf16) __x,
+		__complex__ decltype(0.0bf16) __y)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_cpowf(__x,
+								      __y)); }
+#endif
+#endif
+
   /// 26.2.3  complex specializations
   /// complex<float> specialization
   template<>
@@ -1098,8 +1362,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 #endif
 
+#if __cplusplus > 202002L
+      template<typename _Up>
+	explicit(!requires(_Up __u) { value_type{__u}; })
+	constexpr complex(const complex<_Up>& __z)
+	: _M_value{ value_type(__z.real()), value_type(__z.imag()) } { }
+#else
       explicit _GLIBCXX_CONSTEXPR complex(const complex<double>&);
       explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&);
+#endif
 
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -1244,10 +1515,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 #endif
 
+#if __cplusplus > 202002L
+      template<typename _Up>
+	explicit(!requires(_Up __u) { value_type{__u}; })
+	constexpr complex(const complex<_Up>& __z)
+	: _M_value{ value_type(__z.real()), value_type(__z.imag()) } { }
+#else
       _GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
       : _M_value(__z.__rep()) { }
 
       explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&);
+#endif
 
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -1391,11 +1669,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 #endif
 
+#if __cplusplus > 202002L
+      template<typename _Up>
+	explicit(!requires(_Up __u) { value_type{__u}; })
+	constexpr complex(const complex<_Up>& __z)
+	: _M_value{ value_type(__z.real()), value_type(__z.imag()) } { }
+#else
       _GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
       : _M_value(__z.__rep()) { }
 
       _GLIBCXX_CONSTEXPR complex(const complex<double>& __z)
       : _M_value(__z.__rep()) { }
+#endif
 
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -1517,6 +1802,161 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _ComplexT _M_value;
     };
 
+#if __cplusplus > 202002L
+  template<typename _Tp>
+    struct __complex_type
+    { };
+
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct __complex_type<_Float16>
+    { typedef __complex__ _Float16 type; };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct __complex_type<_Float32>
+    { typedef __complex__ _Float32 type; };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct __complex_type<_Float64>
+    { typedef __complex__ _Float64 type; };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct __complex_type<_Float128>
+    { typedef __complex__ _Float128 type; };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct __complex_type<__gnu_cxx::__bfloat16_t>
+    { typedef __complex__ decltype(0.0bf16) type; };
+#endif
+
+  template<typename _Tp>
+    requires(__complex_type<_Tp>::type)
+    class complex<_Tp>
+    {
+    public:
+      typedef _Tp value_type;
+      typedef std::__complex_type<_Tp>::type _ComplexT;
+
+      constexpr complex(_ComplexT __z) : _M_value(__z) { }
+
+      constexpr complex(_Tp __r = _Tp(), _Tp __i = _Tp())
+      : _M_value{ __r, __i } { }
+
+      template<typename _Up>
+	explicit(!requires(_Up __u) { value_type{__u}; })
+	constexpr complex(const complex<_Up>& __z)
+	: _M_value{ value_type(__z.real()), value_type(__z.imag()) } { }
+
+      constexpr _Tp
+      real() const { return __real__ _M_value; }
+
+      constexpr _Tp
+      imag() const { return __imag__ _M_value; }
+
+      constexpr void
+      real(_Tp __val) { __real__ _M_value = __val; }
+
+      constexpr void
+      imag(_Tp __val) { __imag__ _M_value = __val; }
+
+      constexpr complex&
+      operator=(_Tp __f)
+      {
+	_M_value = __f;
+	return *this;
+      }
+
+      constexpr complex&
+      operator+=(_Tp __f)
+      {
+	_M_value += __f;
+	return *this;
+      }
+
+      constexpr complex&
+      operator-=(_Tp __f)
+      {
+	_M_value -= __f;
+	return *this;
+      }
+
+      constexpr complex&
+      operator*=(_Tp __f)
+      {
+	_M_value *= __f;
+	return *this;
+      }
+
+      constexpr complex&
+      operator/=(_Tp __f)
+      {
+	_M_value /= __f;
+	return *this;
+      }
+
+      // Let the compiler synthesize the copy and assignment
+      // operator.  It always does a pretty good job.
+      constexpr complex& operator=(const complex&) = default;
+
+      template<typename _Up>
+	constexpr complex&
+	operator=(const complex<_Up>&  __z)
+	{
+	  __real__ _M_value = __z.real();
+	  __imag__ _M_value = __z.imag();
+	  return *this;
+	}
+
+      template<typename _Up>
+	constexpr complex&
+	operator+=(const complex<_Up>& __z)
+	{
+	  _M_value += __z.__rep();
+	  return *this;
+	}
+
+      template<class _Up>
+	constexpr complex&
+	operator-=(const complex<_Up>& __z)
+	{
+	  _M_value -= __z.__rep();
+	  return *this;
+	}
+
+      template<class _Up>
+	constexpr complex&
+	operator*=(const complex<_Up>& __z)
+	{
+	  const _ComplexT __t = __z.__rep();
+	  _M_value *= __t;
+	  return *this;
+	}
+
+      template<class _Up>
+	constexpr complex&
+	operator/=(const complex<_Up>& __z)
+	{
+	  const _ComplexT __t = __z.__rep();
+	  _M_value /= __t;
+	  return *this;
+	}
+
+      constexpr _ComplexT __rep() const { return _M_value; }
+
+    private:
+      _ComplexT _M_value;
+    };
+#endif
+
+#if __cplusplus <= 202002L
   // These bits have to be at the end of this file, so that the
   // specializations have all been defined.
   inline _GLIBCXX_CONSTEXPR
@@ -1530,6 +1970,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   inline _GLIBCXX_CONSTEXPR
   complex<double>::complex(const complex<long double>& __z)
   : _M_value(__z.__rep()) { }
+#endif
 
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.
@@ -1809,6 +2250,162 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __complex_atanh(__z); }
 #endif
 
+#if _GLIBCXX_USE_C99_COMPLEX_TR1
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __complex__ _Float16
+  __complex_acos(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_cacosf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_asin(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_casinf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_atan(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_catanf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_acosh(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_cacoshf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_asinh(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_casinhf(__z)); }
+
+  inline __complex__ _Float16
+  __complex_atanh(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_catanhf(__z)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __complex__ _Float32
+  __complex_acos(__complex__ _Float32 __z)
+  { return __builtin_cacosf(__z); }
+
+  inline __complex__ _Float32
+  __complex_asin(__complex__ _Float32 __z)
+  { return __builtin_casinf(__z); }
+
+  inline __complex__ _Float32
+  __complex_atan(__complex__ _Float32 __z)
+  { return __builtin_catanf(__z); }
+
+  inline __complex__ _Float32
+  __complex_acosh(__complex__ _Float32 __z)
+  { return __builtin_cacoshf(__z); }
+
+  inline __complex__ _Float32
+  __complex_asinh(__complex__ _Float32 __z)
+  { return __builtin_casinhf(__z); }
+
+  inline __complex__ _Float32
+  __complex_atanh(__complex__ _Float32 __z)
+  { return __builtin_catanhf(__z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline __complex__ _Float64
+  __complex_acos(__complex__ _Float64 __z)
+  { return __builtin_cacos(__z); }
+
+  inline __complex__ _Float64
+  __complex_asin(__complex__ _Float64 __z)
+  { return __builtin_casin(__z); }
+
+  inline __complex__ _Float64
+  __complex_atan(__complex__ _Float64 __z)
+  { return __builtin_catan(__z); }
+
+  inline __complex__ _Float64
+  __complex_acosh(__complex__ _Float64 __z)
+  { return __builtin_cacosh(__z); }
+
+  inline __complex__ _Float64
+  __complex_asinh(__complex__ _Float64 __z)
+  { return __builtin_casinh(__z); }
+
+  inline __complex__ _Float64
+  __complex_atanh(__complex__ _Float64 __z)
+  { return __builtin_catanh(__z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  inline __complex__ _Float128
+  __complex_acos(__complex__ _Float128 __z)
+  { return __builtin_cacosl(__z); }
+
+  inline __complex__ _Float128
+  __complex_asin(__complex__ _Float128 __z)
+  { return __builtin_casinl(__z); }
+
+  inline __complex__ _Float128
+  __complex_atan(__complex__ _Float128 __z)
+  { return __builtin_catanl(__z); }
+
+  inline __complex__ _Float128
+  __complex_acosh(__complex__ _Float128 __z)
+  { return __builtin_cacoshl(__z); }
+
+  inline __complex__ _Float128
+  __complex_asinh(__complex__ _Float128 __z)
+  { return __builtin_casinhl(__z); }
+
+  inline __complex__ _Float128
+  __complex_atanh(__complex__ _Float128 __z)
+  { return __builtin_catanhl(__z); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  inline __complex__ _Float128
+  __complex_acos(__complex__ _Float128 __z)
+  { return __builtin_cacosf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_asin(__complex__ _Float128 __z)
+  { return __builtin_casinf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_atan(__complex__ _Float128 __z)
+  { return __builtin_catanf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_acosh(__complex__ _Float128 __z)
+  { return __builtin_cacoshf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_asinh(__complex__ _Float128 __z)
+  { return __builtin_casinhf128(__z); }
+
+  inline __complex__ _Float128
+  __complex_atanh(__complex__ _Float128 __z)
+  { return __builtin_catanhf128(__z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __complex__ decltype(0.0bf16)
+  __complex_acos(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_cacosf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_asin(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_casinf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_atan(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_catanf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_acosh(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_cacoshf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_asinh(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_casinhf(__z)); }
+
+  inline __complex__ decltype(0.0bf16)
+  __complex_atanh(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_catanhf(__z)); }
+#endif
+#endif
+
   template<typename _Tp>
     inline _Tp
     /// fabs(__z) [8.1.8].
@@ -1897,6 +2494,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   inline complex<long double>
   __complex_proj(const complex<long double>& __z)
   { return __builtin_cprojl(__z.__rep()); }
+
+#if __cplusplus > 202002L
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __complex__ _Float16
+  __complex_proj(__complex__ _Float16 __z)
+  { return static_cast<__complex__ _Float16>(__builtin_cprojf(__z)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __complex__ _Float32
+  __complex_proj(__complex__ _Float32 __z)
+  { return __builtin_cprojf(__z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline __complex__ _Float64
+  __complex_proj(__complex__ _Float64 __z)
+  { return __builtin_cproj(__z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  inline __complex__ _Float128
+  __complex_proj(__complex__ _Float128 __z)
+  { return __builtin_cprojl(__z); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  inline __complex__ _Float128
+  __complex_proj(__complex__ _Float128 __z)
+  { return __builtin_cprojf128(__z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __complex__ decltype(0.0bf16)
+  __complex_proj(__complex__ decltype(0.0bf16) __z)
+  { return static_cast<__complex__ decltype(0.0bf16)>(__builtin_cprojf(__z)); }
+#endif
+
+  template<typename _Tp>
+    requires(__complex_type<_Tp>::type)
+    inline complex<_Tp>
+    __complex_proj(const complex<_Tp>& __z)
+    { return __complex_proj(__z.__rep()); }
+#endif
+
 #elif defined _GLIBCXX_USE_C99_MATH_TR1
   inline complex<float>
   __complex_proj(const complex<float>& __z)
--- libstdc++-v3/include/bits/cpp_type_traits.h.jj	2022-01-11 23:11:24.144265506 +0100
+++ libstdc++-v3/include/bits/cpp_type_traits.h	2022-10-21 11:06:07.059777783 +0200
@@ -315,6 +315,51 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
       typedef __true_type __type;
     };
 
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct __is_floating<_Float16>
+    {
+      enum { __value = 1 };
+      typedef __true_type __type;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct __is_floating<_Float32>
+    {
+      enum { __value = 1 };
+      typedef __true_type __type;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct __is_floating<_Float64>
+    {
+      enum { __value = 1 };
+      typedef __true_type __type;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct __is_floating<_Float128>
+    {
+      enum { __value = 1 };
+      typedef __true_type __type;
+    };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct __is_floating<__gnu_cxx::__bfloat16_t>
+    {
+      enum { __value = 1 };
+      typedef __true_type __type;
+    };
+#endif
+
   //
   // Pointer types
   //
--- libstdc++-v3/testsuite/26_numerics/complex/ext_c++23.cc.jj	2022-10-21 16:24:24.337657605 +0200
+++ libstdc++-v3/testsuite/26_numerics/complex/ext_c++23.cc	2022-10-21 17:20:47.300853616 +0200
@@ -0,0 +1,89 @@
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2b" }
+// { dg-do link { target c++23 } }
+
+#include <stdfloat>
+#include <complex>
+
+template <typename T>
+__attribute__((__noipa__)) void
+test_functions(T *p, std::complex<T> *q)
+{
+  p[0] = std::abs(q[0]);
+  p[1] = std::arg(q[1]);
+  q[2] = std::cos(q[2]);
+  q[3] = std::cosh(q[3]);
+  q[4] = std::exp(q[4]);
+  q[5] = std::log(q[5]);
+  q[6] = std::sin(q[6]);
+  q[7] = std::sinh(q[7]);
+  q[8] = std::sqrt(q[8]);
+  q[9] = std::tan(q[9]);
+  q[10] = std::tanh(q[10]);
+  q[11] = std::pow(q[11], q[19]);
+  q[12] = std::acos(q[12]);
+  q[13] = std::asin(q[13]);
+  q[14] = std::atan(q[14]);
+  q[15] = std::acosh(q[15]);
+  q[16] = std::asinh(q[16]);
+  q[17] = std::atanh(q[17]);
+  q[18] = std::proj(q[18]);
+}
+
+int
+main()
+{
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::float16_t p[2] = {};
+    std::complex<std::float16_t> q[20] = {};
+    test_functions(p, q);
+  }
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::float32_t p[2] = {};
+    std::complex<std::float32_t> q[20] = {};
+    test_functions(p, q);
+  }
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  {
+    std::float64_t p[2] = {};
+    std::complex<std::float64_t> q[20] = {};
+    test_functions(p, q);
+  }
+#endif
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  {
+    std::float128_t p[2] = {};
+    std::complex<std::float128_t> q[20] = {};
+    test_functions(p, q);
+  }
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::bfloat16_t p[2] = {};
+    std::complex<std::bfloat16_t> q[20] = {};
+    test_functions(p, q);
+  }
+#endif
+}
--- gcc/testsuite/g++.dg/cpp23/ext-floating12.C.jj	2022-10-21 15:12:38.119671632 +0200
+++ gcc/testsuite/g++.dg/cpp23/ext-floating12.C	2022-10-21 16:13:27.021501628 +0200
@@ -0,0 +1,182 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do compile { target { c++23 && { i?86-*-linux* x86_64-*-linux* } } } }
+// { dg-options "" }
+
+#include <complex>
+#include <stdfloat>
+
+#if !defined(__STDCPP_FLOAT32_T__) \
+    || !defined(__STDCPP_FLOAT64_T__) || !defined(__STDCPP_FLOAT128_T__) \
+    || __FLT_MAX_EXP__ != __FLT32_MAX_EXP__ || __FLT_MANT_DIG__ != __FLT32_MANT_DIG__ \
+    || __DBL_MAX_EXP__ != __FLT64_MAX_EXP__ || __DBL_MANT_DIG__ != __FLT64_MANT_DIG__ \
+    || __LDBL_MAX_EXP__ != __FLT128_MAX_EXP__ || __LDBL_MANT_DIG__ >= __FLT128_MANT_DIG__ \
+    || !defined(__SIZEOF_FLOAT128__)
+#error Unexpected set of floating point types
+#endif
+
+using namespace std;
+
+int
+main()
+{
+  complex<float> a01(complex<float>(1.0f, 2.0f));
+  complex<float> a02 = complex<float>(1.0f, 2.0f);
+  complex<float> a03(complex<double>(1.0, 2.0));
+  complex<float> a04 = complex<double>(1.0, 2.0);			// { dg-error "conversion from 'complex<double>' to non-scalar type 'complex<float>' requested" }
+  complex<float> a05(complex<long double>(1.0L, 2.0L));
+  complex<float> a06 = complex<long double>(1.0L, 2.0L);		// { dg-error "conversion from 'complex<long double>' to non-scalar type 'complex<float>' requested" }
+  complex<float> a07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<float> a08 = complex<float32_t>(1.0f32, 2.0f32);
+  complex<float> a09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<float> a10 = complex<float64_t>(1.0f64, 2.0f64);		// { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex<float>' requested" }
+  complex<float> a11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<float> a12 = complex<float128_t>(1.0f128, 2.0f128);		// { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<float>' requested" }
+#ifdef __STDCPP_FLOAT16_T__
+  complex<float> a13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<float> a14 = complex<float16_t>(1.0f16, 2.0f16);
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<float> a15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<float> a16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);
+#endif
+  complex<double> b01(complex<float>(1.0f, 2.0f));
+  complex<double> b02 = complex<float>(1.0f, 2.0f);
+  complex<double> b03(complex<double>(1.0, 2.0));
+  complex<double> b04 = complex<double>(1.0, 2.0);
+  complex<double> b05(complex<long double>(1.0L, 2.0L));
+  complex<double> b06 = complex<long double>(1.0L, 2.0L);		// { dg-error "conversion from 'complex<long double>' to non-scalar type 'complex<double>' requested" }
+  complex<double> b07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<double> b08 = complex<float32_t>(1.0f32, 2.0f32);
+  complex<double> b09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<double> b10 = complex<float64_t>(1.0f64, 2.0f64);
+  complex<double> b11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<double> b12 = complex<float128_t>(1.0f128, 2.0f128);		// { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<double>' requested" }
+#ifdef __STDCPP_FLOAT16_T__
+  complex<double> b13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<double> b14 = complex<float16_t>(1.0f16, 2.0f16);
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<double> b15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<double> b16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);
+#endif
+  complex<long double> c01(complex<float>(1.0f, 2.0f));
+  complex<long double> c02 = complex<float>(1.0f, 2.0f);
+  complex<long double> c03(complex<double>(1.0, 2.0));
+  complex<long double> c04 = complex<double>(1.0, 2.0);
+  complex<long double> c05(complex<long double>(1.0L, 2.0L));
+  complex<long double> c06 = complex<long double>(1.0L, 2.0L);
+  complex<long double> c07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<long double> c08 = complex<float32_t>(1.0f32, 2.0f32);
+  complex<long double> c09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<long double> c10 = complex<float64_t>(1.0f64, 2.0f64);
+  complex<long double> c11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<long double> c12 = complex<float128_t>(1.0f128, 2.0f128);	// { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<long double>' requested" }
+#ifdef __STDCPP_FLOAT16_T__
+  complex<long double> c13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<long double> c14 = complex<float16_t>(1.0f16, 2.0f16);
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<long double> c15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<long double> c16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);
+#endif
+  complex<float32_t> d01(complex<float>(1.0f, 2.0f));
+  complex<float32_t> d02 = complex<float>(1.0f, 2.0f);
+  complex<float32_t> d03(complex<double>(1.0, 2.0));
+  complex<float32_t> d04 = complex<double>(1.0, 2.0);			// { dg-error "conversion from 'complex<double>' to non-scalar type 'complex<_Float32>' requested" }
+  complex<float32_t> d05(complex<long double>(1.0L, 2.0L));
+  complex<float32_t> d06 = complex<long double>(1.0L, 2.0L);		// { dg-error "conversion from 'complex<long double>' to non-scalar type 'complex<_Float32>' requested" }
+  complex<float32_t> d07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<float32_t> d08 = complex<float32_t>(1.0f32, 2.0f32);
+  complex<float32_t> d09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<float32_t> d10 = complex<float64_t>(1.0f64, 2.0f64);		// { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex<_Float32>' requested" }
+  complex<float32_t> d11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<float32_t> d12 = complex<float128_t>(1.0f128, 2.0f128);	// { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<_Float32>' requested" }
+#ifdef __STDCPP_FLOAT16_T__
+  complex<float32_t> d13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<float32_t> d14 = complex<float16_t>(1.0f16, 2.0f16);
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<float32_t> d15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<float32_t> d16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);
+#endif
+  complex<float64_t> e01(complex<float>(1.0f, 2.0f));
+  complex<float64_t> e02 = complex<float>(1.0f, 2.0f);
+  complex<float64_t> e03(complex<double>(1.0, 2.0));
+  complex<float64_t> e04 = complex<double>(1.0, 2.0);
+  complex<float64_t> e05(complex<long double>(1.0L, 2.0L));
+  complex<float64_t> e06 = complex<long double>(1.0L, 2.0L);		// { dg-error "conversion from 'complex<long double>' to non-scalar type 'complex<_Float64>' requested" }
+  complex<float64_t> e07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<float64_t> e08 = complex<float32_t>(1.0f32, 2.0f32);
+  complex<float64_t> e09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<float64_t> e10 = complex<float64_t>(1.0f64, 2.0f64);
+  complex<float64_t> e11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<float64_t> e12 = complex<float128_t>(1.0f128, 2.0f128);	// { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<_Float64>' requested" }
+#ifdef __STDCPP_FLOAT16_T__
+  complex<float64_t> e13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<float64_t> e14 = complex<float16_t>(1.0f16, 2.0f16);
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<float64_t> e15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<float64_t> e16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);
+#endif
+  complex<float128_t> f01(complex<float>(1.0f, 2.0f));
+  complex<float128_t> f02 = complex<float>(1.0f, 2.0f);
+  complex<float128_t> f03(complex<double>(1.0, 2.0));
+  complex<float128_t> f04 = complex<double>(1.0, 2.0);
+  complex<float128_t> f05(complex<long double>(1.0L, 2.0L));
+  complex<float128_t> f06 = complex<long double>(1.0L, 2.0L);
+  complex<float128_t> f07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<float128_t> f08 = complex<float32_t>(1.0f32, 2.0f32);
+  complex<float128_t> f09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<float128_t> f10 = complex<float64_t>(1.0f64, 2.0f64);
+  complex<float128_t> f11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<float128_t> f12 = complex<float128_t>(1.0f128, 2.0f128);
+#ifdef __STDCPP_FLOAT16_T__
+  complex<float128_t> f13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<float128_t> f14 = complex<float16_t>(1.0f16, 2.0f16);
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<float128_t> f15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<float128_t> f16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);
+#endif
+#ifdef __STDCPP_FLOAT16_T__
+  complex<float16_t> g01(complex<float>(1.0f, 2.0f));
+  complex<float16_t> g02 = complex<float>(1.0f, 2.0f);			// { dg-error "conversion from 'complex<float>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } }
+  complex<float16_t> g03(complex<double>(1.0, 2.0));
+  complex<float16_t> g04 = complex<double>(1.0, 2.0);			// { dg-error "conversion from 'complex<double>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } }
+  complex<float16_t> g05(complex<long double>(1.0L, 2.0L));
+  complex<float16_t> g06 = complex<long double>(1.0L, 2.0L);		// { dg-error "conversion from 'complex<long double>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } }
+  complex<float16_t> g07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<float16_t> g08 = complex<float32_t>(1.0f32, 2.0f32);		// { dg-error "conversion from 'complex<_Float32>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } }
+  complex<float16_t> g09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<float16_t> g10 = complex<float64_t>(1.0f64, 2.0f64);		// { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } }
+  complex<float16_t> g11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<float16_t> g12 = complex<float128_t>(1.0f128, 2.0f128);	// { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } }
+  complex<float16_t> g13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<float16_t> g14 = complex<float16_t>(1.0f16, 2.0f16);
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<float16_t> g15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<float16_t> g16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);	// { dg-error "conversion from 'complex<\[^\n\r]*>' to non-scalar type 'complex<_Float16>' requested" "" { target { float16 && bfloat16 } } }
+#endif
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  complex<bfloat16_t> h01(complex<float>(1.0f, 2.0f));
+  complex<bfloat16_t> h02 = complex<float>(1.0f, 2.0f);			// { dg-error "conversion from 'complex<float>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } }
+  complex<bfloat16_t> h03(complex<double>(1.0, 2.0));
+  complex<bfloat16_t> h04 = complex<double>(1.0, 2.0);			// { dg-error "conversion from 'complex<double>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } }
+  complex<bfloat16_t> h05(complex<long double>(1.0L, 2.0L));
+  complex<bfloat16_t> h06 = complex<long double>(1.0L, 2.0L);		// { dg-error "conversion from 'complex<long double>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } }
+  complex<bfloat16_t> h07(complex<float32_t>(1.0f32, 2.0f32));
+  complex<bfloat16_t> h08 = complex<float32_t>(1.0f32, 2.0f32);		// { dg-error "conversion from 'complex<_Float32>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } }
+  complex<bfloat16_t> h09(complex<float64_t>(1.0f64, 2.0f64));
+  complex<bfloat16_t> h10 = complex<float64_t>(1.0f64, 2.0f64);		// { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } }
+  complex<bfloat16_t> h11(complex<float128_t>(1.0f128, 2.0f128));
+  complex<bfloat16_t> h12 = complex<float128_t>(1.0f128, 2.0f128);	// { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } }
+#ifdef __STDCPP_FLOAT16_T__
+  complex<bfloat16_t> h13(complex<float16_t>(1.0f16, 2.0f16));
+  complex<bfloat16_t> h14 = complex<float16_t>(1.0f16, 2.0f16);		// { dg-error "conversion from 'complex<_Float16>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target { float16 && bfloat16 } } }
+#endif
+  complex<bfloat16_t> h15(complex<bfloat16_t>(1.0bf16, 2.0bf16));
+  complex<bfloat16_t> h16 = complex<bfloat16_t>(1.0bf16, 2.0bf16);
+#endif
+}

	Jakub


             reply	other threads:[~2022-10-21 15:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-21 15:58 Jakub Jelinek [this message]
2022-10-31 10:26 ` Jonathan Wakely
2022-10-31 16:57   ` Jakub Jelinek
2022-10-31 17:04     ` Jonathan Wakely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y1LBm4u+R3Ka28Dj@tucnak \
    --to=jakub@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jwakely@redhat.com \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).