[PATCH, libstdc++] Implement P0415 More constexpr for std::complex.

Jonathan Wakely jwakely@redhat.com
Mon Nov 19 11:13:00 GMT 2018


On 16/11/18 19:39 -0500, Ed Smith-Rowland wrote:
>@@ -322,67 +323,43 @@
>   //@{
>   ///  Return new complex value @a x plus @a y.
>   template<typename _Tp>
>-    inline complex<_Tp>
>+    inline _GLIBCXX20_CONSTEXPR complex<_Tp>
>     operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
>-    {
>-      complex<_Tp> __r = __x;
>-      __r += __y;
>-      return __r;
>-    }
>+    { return complex<_Tp>(__x.real() + __y.real(), __x.imag() + __y.imag()); }

Is this change (and all the similar ones) really needed?

Doesn't the fact that all the constructors and member operators of
std::complex mean that the original definition is also valid in a
constexpr function?

>@@ -1163,50 +1143,43 @@
> #endif
>
>       template<typename _Tp>
>-        complex&
>+        _GLIBCXX20_CONSTEXPR complex&
>         operator=(const complex<_Tp>&  __z)
> 	{
>-	  __real__ _M_value = __z.real();
>-	  __imag__ _M_value = __z.imag();
>+	  _M_value = __z.__rep();

These changes look OK, but I wonder if we shouldn't ask the compiler
to make it possible to use __real__ and __imag__ in constexpr
functions instead.

I assume it doesn't, and that's why you made this change. But if it
Just Worked, and the other changes I commented on above are also
unnecessary, then this patch would *mostly* just be adding
_GLIBCXX20_CONSTEXPR which is OK for stage 3 (as it doesn't affect any
dialects except C++2a).


>@@ -1872,7 +1831,7 @@
>     { return _Tp(); }
>
>   template<typename _Tp>
>-    inline typename __gnu_cxx::__promote<_Tp>::__type
>+    _GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type

This should be _GLIBCXX20_CONSTEXPR.

>Index: testsuite/26_numerics/complex/comparison_operators/more_constexpr.cc
>===================================================================
>--- testsuite/26_numerics/complex/comparison_operators/more_constexpr.cc	(nonexistent)
>+++ testsuite/26_numerics/complex/comparison_operators/more_constexpr.cc	(working copy)
>@@ -0,0 +1,51 @@
>+// { dg-do compile { target c++2a } }

All the tests with { target c++2a} should also have:

// { dg-options "-std=gnu++2a" }

Because otherwise they are skipped by default, and only get run when
RUNTESTFLAGS explicitly includes something like
--target_board=unix/-std=gnu++2a

The dg-options needs to come first, or it doesn't apply before the
check for { target c++2a }.




More information about the Libstdc++ mailing list