diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-10-31 20:13:02 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-10-31 20:15:27 +0100 |
commit | db55f1dda2692c3f778ae783bc7121891c79aec4 (patch) | |
tree | 8d52dbc318c855b5cce71dc41d11a39bc825e2bf /gcc | |
parent | 8422861bddc7c4fd202cd59c8487d4bc6b807dc3 (diff) | |
download | gcc-db55f1dda2692c3f778ae783bc7121891c79aec4.zip gcc-db55f1dda2692c3f778ae783bc7121891c79aec4.tar.gz gcc-db55f1dda2692c3f778ae783bc7121891c79aec4.tar.bz2 |
libstdc++-v3: <complex> support for extended floating point types
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.
The g++.dg/cpp23/ testcase verifies explicit(bool) works correctly.
2022-10-31 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. 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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp23/ext-floating12.C | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating12.C b/gcc/testsuite/g++.dg/cpp23/ext-floating12.C new file mode 100644 index 0000000..77ee4c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/ext-floating12.C @@ -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 +} |