From db55f1dda2692c3f778ae783bc7121891c79aec4 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 31 Oct 2022 20:13:02 +0100 Subject: libstdc++-v3: support for extended floating point types The following patch adds 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 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::complex converting ctor, complex::complex converting ctor, complex::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. --- gcc/testsuite/g++.dg/cpp23/ext-floating12.C | 182 ++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp23/ext-floating12.C (limited to 'gcc') 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 +#include + +#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 a01(complex(1.0f, 2.0f)); + complex a02 = complex(1.0f, 2.0f); + complex a03(complex(1.0, 2.0)); + complex a04 = complex(1.0, 2.0); // { dg-error "conversion from 'complex' to non-scalar type 'complex' requested" } + complex a05(complex(1.0L, 2.0L)); + complex a06 = complex(1.0L, 2.0L); // { dg-error "conversion from 'complex' to non-scalar type 'complex' requested" } + complex a07(complex(1.0f32, 2.0f32)); + complex a08 = complex(1.0f32, 2.0f32); + complex a09(complex(1.0f64, 2.0f64)); + complex a10 = complex(1.0f64, 2.0f64); // { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex' requested" } + complex a11(complex(1.0f128, 2.0f128)); + complex a12 = complex(1.0f128, 2.0f128); // { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex' requested" } +#ifdef __STDCPP_FLOAT16_T__ + complex a13(complex(1.0f16, 2.0f16)); + complex a14 = complex(1.0f16, 2.0f16); +#endif +#ifdef __STDCPP_BFLOAT16_T__ + complex a15(complex(1.0bf16, 2.0bf16)); + complex a16 = complex(1.0bf16, 2.0bf16); +#endif + complex b01(complex(1.0f, 2.0f)); + complex b02 = complex(1.0f, 2.0f); + complex b03(complex(1.0, 2.0)); + complex b04 = complex(1.0, 2.0); + complex b05(complex(1.0L, 2.0L)); + complex b06 = complex(1.0L, 2.0L); // { dg-error "conversion from 'complex' to non-scalar type 'complex' requested" } + complex b07(complex(1.0f32, 2.0f32)); + complex b08 = complex(1.0f32, 2.0f32); + complex b09(complex(1.0f64, 2.0f64)); + complex b10 = complex(1.0f64, 2.0f64); + complex b11(complex(1.0f128, 2.0f128)); + complex b12 = complex(1.0f128, 2.0f128); // { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex' requested" } +#ifdef __STDCPP_FLOAT16_T__ + complex b13(complex(1.0f16, 2.0f16)); + complex b14 = complex(1.0f16, 2.0f16); +#endif +#ifdef __STDCPP_BFLOAT16_T__ + complex b15(complex(1.0bf16, 2.0bf16)); + complex b16 = complex(1.0bf16, 2.0bf16); +#endif + complex c01(complex(1.0f, 2.0f)); + complex c02 = complex(1.0f, 2.0f); + complex c03(complex(1.0, 2.0)); + complex c04 = complex(1.0, 2.0); + complex c05(complex(1.0L, 2.0L)); + complex c06 = complex(1.0L, 2.0L); + complex c07(complex(1.0f32, 2.0f32)); + complex c08 = complex(1.0f32, 2.0f32); + complex c09(complex(1.0f64, 2.0f64)); + complex c10 = complex(1.0f64, 2.0f64); + complex c11(complex(1.0f128, 2.0f128)); + complex c12 = complex(1.0f128, 2.0f128); // { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex' requested" } +#ifdef __STDCPP_FLOAT16_T__ + complex c13(complex(1.0f16, 2.0f16)); + complex c14 = complex(1.0f16, 2.0f16); +#endif +#ifdef __STDCPP_BFLOAT16_T__ + complex c15(complex(1.0bf16, 2.0bf16)); + complex c16 = complex(1.0bf16, 2.0bf16); +#endif + complex d01(complex(1.0f, 2.0f)); + complex d02 = complex(1.0f, 2.0f); + complex d03(complex(1.0, 2.0)); + complex d04 = complex(1.0, 2.0); // { dg-error "conversion from 'complex' to non-scalar type 'complex<_Float32>' requested" } + complex d05(complex(1.0L, 2.0L)); + complex d06 = complex(1.0L, 2.0L); // { dg-error "conversion from 'complex' to non-scalar type 'complex<_Float32>' requested" } + complex d07(complex(1.0f32, 2.0f32)); + complex d08 = complex(1.0f32, 2.0f32); + complex d09(complex(1.0f64, 2.0f64)); + complex d10 = complex(1.0f64, 2.0f64); // { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex<_Float32>' requested" } + complex d11(complex(1.0f128, 2.0f128)); + complex d12 = complex(1.0f128, 2.0f128); // { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<_Float32>' requested" } +#ifdef __STDCPP_FLOAT16_T__ + complex d13(complex(1.0f16, 2.0f16)); + complex d14 = complex(1.0f16, 2.0f16); +#endif +#ifdef __STDCPP_BFLOAT16_T__ + complex d15(complex(1.0bf16, 2.0bf16)); + complex d16 = complex(1.0bf16, 2.0bf16); +#endif + complex e01(complex(1.0f, 2.0f)); + complex e02 = complex(1.0f, 2.0f); + complex e03(complex(1.0, 2.0)); + complex e04 = complex(1.0, 2.0); + complex e05(complex(1.0L, 2.0L)); + complex e06 = complex(1.0L, 2.0L); // { dg-error "conversion from 'complex' to non-scalar type 'complex<_Float64>' requested" } + complex e07(complex(1.0f32, 2.0f32)); + complex e08 = complex(1.0f32, 2.0f32); + complex e09(complex(1.0f64, 2.0f64)); + complex e10 = complex(1.0f64, 2.0f64); + complex e11(complex(1.0f128, 2.0f128)); + complex e12 = complex(1.0f128, 2.0f128); // { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<_Float64>' requested" } +#ifdef __STDCPP_FLOAT16_T__ + complex e13(complex(1.0f16, 2.0f16)); + complex e14 = complex(1.0f16, 2.0f16); +#endif +#ifdef __STDCPP_BFLOAT16_T__ + complex e15(complex(1.0bf16, 2.0bf16)); + complex e16 = complex(1.0bf16, 2.0bf16); +#endif + complex f01(complex(1.0f, 2.0f)); + complex f02 = complex(1.0f, 2.0f); + complex f03(complex(1.0, 2.0)); + complex f04 = complex(1.0, 2.0); + complex f05(complex(1.0L, 2.0L)); + complex f06 = complex(1.0L, 2.0L); + complex f07(complex(1.0f32, 2.0f32)); + complex f08 = complex(1.0f32, 2.0f32); + complex f09(complex(1.0f64, 2.0f64)); + complex f10 = complex(1.0f64, 2.0f64); + complex f11(complex(1.0f128, 2.0f128)); + complex f12 = complex(1.0f128, 2.0f128); +#ifdef __STDCPP_FLOAT16_T__ + complex f13(complex(1.0f16, 2.0f16)); + complex f14 = complex(1.0f16, 2.0f16); +#endif +#ifdef __STDCPP_BFLOAT16_T__ + complex f15(complex(1.0bf16, 2.0bf16)); + complex f16 = complex(1.0bf16, 2.0bf16); +#endif +#ifdef __STDCPP_FLOAT16_T__ + complex g01(complex(1.0f, 2.0f)); + complex g02 = complex(1.0f, 2.0f); // { dg-error "conversion from 'complex' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } } + complex g03(complex(1.0, 2.0)); + complex g04 = complex(1.0, 2.0); // { dg-error "conversion from 'complex' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } } + complex g05(complex(1.0L, 2.0L)); + complex g06 = complex(1.0L, 2.0L); // { dg-error "conversion from 'complex' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } } + complex g07(complex(1.0f32, 2.0f32)); + complex g08 = complex(1.0f32, 2.0f32); // { dg-error "conversion from 'complex<_Float32>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } } + complex g09(complex(1.0f64, 2.0f64)); + complex g10 = complex(1.0f64, 2.0f64); // { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } } + complex g11(complex(1.0f128, 2.0f128)); + complex g12 = complex(1.0f128, 2.0f128); // { dg-error "conversion from 'complex<_Float128>' to non-scalar type 'complex<_Float16>' requested" "" { target float16 } } + complex g13(complex(1.0f16, 2.0f16)); + complex g14 = complex(1.0f16, 2.0f16); +#ifdef __STDCPP_BFLOAT16_T__ + complex g15(complex(1.0bf16, 2.0bf16)); + complex g16 = complex(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 h01(complex(1.0f, 2.0f)); + complex h02 = complex(1.0f, 2.0f); // { dg-error "conversion from 'complex' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } } + complex h03(complex(1.0, 2.0)); + complex h04 = complex(1.0, 2.0); // { dg-error "conversion from 'complex' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } } + complex h05(complex(1.0L, 2.0L)); + complex h06 = complex(1.0L, 2.0L); // { dg-error "conversion from 'complex' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } } + complex h07(complex(1.0f32, 2.0f32)); + complex h08 = complex(1.0f32, 2.0f32); // { dg-error "conversion from 'complex<_Float32>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } } + complex h09(complex(1.0f64, 2.0f64)); + complex h10 = complex(1.0f64, 2.0f64); // { dg-error "conversion from 'complex<_Float64>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target bfloat16 } } + complex h11(complex(1.0f128, 2.0f128)); + complex h12 = complex(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 h13(complex(1.0f16, 2.0f16)); + complex h14 = complex(1.0f16, 2.0f16); // { dg-error "conversion from 'complex<_Float16>' to non-scalar type 'complex<\[^\n\r]*>' requested" "" { target { float16 && bfloat16 } } } +#endif + complex h15(complex(1.0bf16, 2.0bf16)); + complex h16 = complex(1.0bf16, 2.0bf16); +#endif +} -- cgit v1.1