On Fri, 21 Oct 2022 at 16:58, Jakub Jelinek <ja...@redhat.com> wrote:
>
> 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  <ja...@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())) { }

Do these casts to _Tp do anything? The _M_real and _M_imag members are
already of type _Tp and we're using () initialization not {} so
there's no narrowing concern. _M_real(__z.real()) is already an
explicit conversion from decltype(__z.real()) to decltype(_M_real) so
the extra _Tp is redundant.

I think the diff between C++23 and older standards would be smaller
done like this:

      ///  Converting constructor.
      template<typename _Up>
#if __cplusplus > 202002L
       explicit(!requires(_Up __u) { _Tp{__u}; })
#endif
        _GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z)
       : _M_real(__z.real()), _M_imag(__z.imag()) { }


This also means the constructor body is always defined on the same
line, which avoids warnings from ld.gold's -Wodr-violations which IIRC
is based on simple heuristics like the line where the function is
defined.

Otherwise this looks great. If the above alternative works, please use
that, but OK for trunk either way (once all the other patches it
depends on are in).

Reply via email to