From e987fb1ebecc7494f9869071e487deef70a792f6 Mon Sep 17 00:00:00 2001 From: Edward Smith-Rowland <3dw4rd@verizon.net> Date: Fri, 23 Nov 2018 18:17:04 +0000 Subject: [PATCH] Implement P0415 More constexpr for std::complex. 2018-11-23 Edward Smith-Rowland <3dw4rd@verizon.net> Implement P0415 More constexpr for std::complex. * include/std/complex (conj(complex), norm(complex)): Constexpr; (real(Tp), imag(Tp)): Constexpr; (operator@=(Tp), operator@=(complex)): Constexpr; (operator@(Tp,complex), operator@(complex,Tp) operator@(complex,complex)): Constexpr. * testsuite/26_numerics/complex/comparison_operators/ more_constexpr.cc: New test. * testsuite/26_numerics/complex/operators/more_constexpr.cc: New test. * testsuite/26_numerics/complex/requirements/ more_constexpr.cc: New test. * testsuite/26_numerics/complex/value_operations/ more_constexpr.cc: New test. * testsuite/26_numerics/headers/complex/synopsis.cc: Add _GLIBCXX20_CONSTEXPR to applicable operators; Add missing proj(). * testsuite/26_numerics/headers/complex/synopsis.cc: Add _GLIBCXX20_CONSTEXPR to relevant decls. From-SVN: r266416 --- libstdc++-v3/ChangeLog | 20 ++ libstdc++-v3/include/std/complex | 224 ++++++++---------- .../comparison_operators/more_constexpr.cc | 52 ++++ .../complex/operators/more_constexpr.cc | 62 +++++ .../complex/requirements/more_constexpr.cc | 171 +++++++++++++ .../value_operations/more_constexpr.cc | 59 +++++ .../26_numerics/headers/complex/synopsis.cc | 90 ++++--- 7 files changed, 524 insertions(+), 154 deletions(-) create mode 100644 libstdc++-v3/testsuite/26_numerics/complex/comparison_operators/more_constexpr.cc create mode 100644 libstdc++-v3/testsuite/26_numerics/complex/operators/more_constexpr.cc create mode 100644 libstdc++-v3/testsuite/26_numerics/complex/requirements/more_constexpr.cc create mode 100644 libstdc++-v3/testsuite/26_numerics/complex/value_operations/more_constexpr.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6898733042d..24351cb7ad5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2018-11-23 Edward Smith-Rowland <3dw4rd@verizon.net> + + Implement P0415 More constexpr for std::complex. + * include/std/complex (conj(complex), norm(complex)): Constexpr; + (real(Tp), imag(Tp)): Constexpr; + (operator@=(Tp), operator@=(complex)): Constexpr; + (operator@(Tp,complex), operator@(complex,Tp) + operator@(complex,complex)): Constexpr. + * testsuite/26_numerics/complex/comparison_operators/ + more_constexpr.cc: New test. + * testsuite/26_numerics/complex/operators/more_constexpr.cc: New test. + * testsuite/26_numerics/complex/requirements/ + more_constexpr.cc: New test. + * testsuite/26_numerics/complex/value_operations/ + more_constexpr.cc: New test. + * testsuite/26_numerics/headers/complex/synopsis.cc: + Add _GLIBCXX20_CONSTEXPR to applicable operators; Add missing proj(). + * testsuite/26_numerics/headers/complex/synopsis.cc: + Add _GLIBCXX20_CONSTEXPR to relevant decls. + 2018-11-23 Martin Sebor Jonathan Wakely diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex index 2d1cc1831d0..b30346203b1 100644 --- a/libstdc++-v3/include/std/complex +++ b/libstdc++-v3/include/std/complex @@ -70,10 +70,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Return phase angle of @a z. template _Tp arg(const complex<_Tp>&); /// Return @a z magnitude squared. - template _Tp norm(const complex<_Tp>&); + template _Tp _GLIBCXX20_CONSTEXPR norm(const complex<_Tp>&); /// Return complex conjugate of @a z. - template complex<_Tp> conj(const complex<_Tp>&); + template + _GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>&); /// Return complex with magnitude @a rho and angle @a theta. template complex<_Tp> polar(const _Tp&, const _Tp& = 0); @@ -169,18 +170,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 387. std::complex over-encapsulated. - void + _GLIBCXX20_CONSTEXPR void real(_Tp __val) { _M_real = __val; } - void + _GLIBCXX20_CONSTEXPR void imag(_Tp __val) { _M_imag = __val; } /// Assign a scalar to this complex number. - complex<_Tp>& operator=(const _Tp&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const _Tp&); /// Add a scalar to this complex number. // 26.2.5/1 - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator+=(const _Tp& __t) { _M_real += __t; @@ -189,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Subtract a scalar from this complex number. // 26.2.5/3 - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator-=(const _Tp& __t) { _M_real -= __t; @@ -197,30 +198,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// Multiply this complex number by a scalar. - complex<_Tp>& operator*=(const _Tp&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const _Tp&); /// Divide this complex number by a scalar. - complex<_Tp>& operator/=(const _Tp&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const _Tp&); // Let the compiler synthesize the copy assignment operator #if __cplusplus >= 201103L - complex& operator=(const complex&) = default; + _GLIBCXX20_CONSTEXPR complex& operator=(const complex&) = default; #endif /// Assign another complex number to this one. template - complex<_Tp>& operator=(const complex<_Up>&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const complex<_Up>&); /// Add another complex number to this one. template - complex<_Tp>& operator+=(const complex<_Up>&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator+=(const complex<_Up>&); /// Subtract another complex number from this one. template - complex<_Tp>& operator-=(const complex<_Up>&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator-=(const complex<_Up>&); /// Multiply this complex number by another. template - complex<_Tp>& operator*=(const complex<_Up>&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const complex<_Up>&); /// Divide this complex number by another. template - complex<_Tp>& operator/=(const complex<_Up>&); + _GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const complex<_Up>&); _GLIBCXX_CONSTEXPR complex __rep() const { return *this; } @@ -231,7 +232,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator=(const _Tp& __t) { _M_real = __t; @@ -241,7 +242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 26.2.5/5 template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator*=(const _Tp& __t) { _M_real *= __t; @@ -251,7 +252,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 26.2.5/7 template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator/=(const _Tp& __t) { _M_real /= __t; @@ -261,7 +262,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator=(const complex<_Up>& __z) { _M_real = __z.real(); @@ -272,7 +273,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 26.2.5/9 template template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator+=(const complex<_Up>& __z) { _M_real += __z.real(); @@ -283,7 +284,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 26.2.5/11 template template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator-=(const complex<_Up>& __z) { _M_real -= __z.real(); @@ -295,7 +296,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // XXX: This is a grammar school implementation. template template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator*=(const complex<_Up>& __z) { const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); @@ -308,7 +309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // XXX: This is a grammar school implementation. template template - complex<_Tp>& + _GLIBCXX20_CONSTEXPR complex<_Tp>& complex<_Tp>::operator/=(const complex<_Up>& __z) { const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); @@ -322,7 +323,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION //@{ /// Return new complex value @a x plus @a y. template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) { complex<_Tp> __r = __x; @@ -331,7 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator+(const complex<_Tp>& __x, const _Tp& __y) { complex<_Tp> __r = __x; @@ -340,7 +341,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator+(const _Tp& __x, const complex<_Tp>& __y) { complex<_Tp> __r = __y; @@ -352,7 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION //@{ /// Return new complex value @a x minus @a y. template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) { complex<_Tp> __r = __x; @@ -361,7 +362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator-(const complex<_Tp>& __x, const _Tp& __y) { complex<_Tp> __r = __x; @@ -370,11 +371,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator-(const _Tp& __x, const complex<_Tp>& __y) { - complex<_Tp> __r(__x, -__y.imag()); - __r -= __y.real(); + complex<_Tp> __r = -__y; + __r += __x; return __r; } //@} @@ -382,7 +383,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION //@{ /// Return new complex value @a x times @a y. template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) { complex<_Tp> __r = __x; @@ -391,7 +392,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator*(const complex<_Tp>& __x, const _Tp& __y) { complex<_Tp> __r = __x; @@ -400,7 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator*(const _Tp& __x, const complex<_Tp>& __y) { complex<_Tp> __r = __y; @@ -412,7 +413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION //@{ /// Return new complex value @a x divided by @a y. template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) { complex<_Tp> __r = __x; @@ -421,7 +422,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator/(const complex<_Tp>& __x, const _Tp& __y) { complex<_Tp> __r = __x; @@ -430,7 +431,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator/(const _Tp& __x, const complex<_Tp>& __y) { complex<_Tp> __r = __x; @@ -441,15 +442,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Return @a x. template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator+(const complex<_Tp>& __x) { return __x; } /// Return complex negation of @a x. template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> operator-(const complex<_Tp>& __x) - { return complex<_Tp>(-__x.real(), -__x.imag()); } + { return complex<_Tp>(-__x.real(), -__x.imag()); } //@{ /// Return true if @a x is equal to @a y. @@ -658,7 +659,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Norm_helper { template - static inline _Tp _S_do_it(const complex<_Tp>& __z) + static inline _GLIBCXX_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z) { const _Tp __x = __z.real(); const _Tp __y = __z.imag(); @@ -670,15 +671,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Norm_helper { template - static inline _Tp _S_do_it(const complex<_Tp>& __z) + static inline _GLIBCXX_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z) { - _Tp __res = std::abs(__z); - return __res * __res; + //_Tp __res = std::abs(__z); + //return __res * __res; + const _Tp __x = __z.real(); + const _Tp __y = __z.imag(); + return __x * __x + __y * __y; } }; template - inline _Tp + inline _GLIBCXX20_CONSTEXPR _Tp norm(const complex<_Tp>& __z) { return _Norm_helper<__is_floating<_Tp>::__value @@ -694,7 +698,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline complex<_Tp> + inline _GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>& __z) { return complex<_Tp>(__z.real(), -__z.imag()); } @@ -1115,41 +1119,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 387. std::complex over-encapsulated. - void + _GLIBCXX20_CONSTEXPR void real(float __val) { __real__ _M_value = __val; } - void + _GLIBCXX20_CONSTEXPR void imag(float __val) { __imag__ _M_value = __val; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator=(float __f) { _M_value = __f; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator+=(float __f) { _M_value += __f; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator-=(float __f) { _M_value -= __f; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator*=(float __f) { _M_value *= __f; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator/=(float __f) { _M_value /= __f; @@ -1163,7 +1167,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif template - complex& + _GLIBCXX20_CONSTEXPR complex& operator=(const complex<_Tp>& __z) { __real__ _M_value = __z.real(); @@ -1172,41 +1176,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator+=(const complex<_Tp>& __z) { - __real__ _M_value += __z.real(); - __imag__ _M_value += __z.imag(); + _M_value += __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator-=(const complex<_Tp>& __z) { - __real__ _M_value -= __z.real(); - __imag__ _M_value -= __z.imag(); + _M_value -= __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator*=(const complex<_Tp>& __z) { - _ComplexT __t; - __real__ __t = __z.real(); - __imag__ __t = __z.imag(); + const _ComplexT __t = __z.__rep(); _M_value *= __t; return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator/=(const complex<_Tp>& __z) { - _ComplexT __t; - __real__ __t = __z.real(); - __imag__ __t = __z.imag(); + const _ComplexT __t = __z.__rep(); _M_value /= __t; return *this; } @@ -1268,41 +1266,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 387. std::complex over-encapsulated. - void + _GLIBCXX20_CONSTEXPR void real(double __val) { __real__ _M_value = __val; } - void + _GLIBCXX20_CONSTEXPR void imag(double __val) { __imag__ _M_value = __val; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator=(double __d) { _M_value = __d; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator+=(double __d) { _M_value += __d; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator-=(double __d) { _M_value -= __d; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator*=(double __d) { _M_value *= __d; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator/=(double __d) { _M_value /= __d; @@ -1315,50 +1313,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif template - complex& + _GLIBCXX20_CONSTEXPR complex& operator=(const complex<_Tp>& __z) { - __real__ _M_value = __z.real(); - __imag__ _M_value = __z.imag(); + _M_value = __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator+=(const complex<_Tp>& __z) { - __real__ _M_value += __z.real(); - __imag__ _M_value += __z.imag(); + _M_value += __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator-=(const complex<_Tp>& __z) { - __real__ _M_value -= __z.real(); - __imag__ _M_value -= __z.imag(); + _M_value -= __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator*=(const complex<_Tp>& __z) { - _ComplexT __t; - __real__ __t = __z.real(); - __imag__ __t = __z.imag(); + const _ComplexT __t = __z.__rep(); _M_value *= __t; return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator/=(const complex<_Tp>& __z) { - _ComplexT __t; - __real__ __t = __z.real(); - __imag__ __t = __z.imag(); + const _ComplexT __t = __z.__rep(); _M_value /= __t; return *this; } @@ -1422,41 +1413,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 387. std::complex over-encapsulated. - void + _GLIBCXX20_CONSTEXPR void real(long double __val) { __real__ _M_value = __val; } - void + _GLIBCXX20_CONSTEXPR void imag(long double __val) { __imag__ _M_value = __val; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator=(long double __r) { _M_value = __r; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator+=(long double __r) { _M_value += __r; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator-=(long double __r) { _M_value -= __r; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator*=(long double __r) { _M_value *= __r; return *this; } - complex& + _GLIBCXX20_CONSTEXPR complex& operator/=(long double __r) { _M_value /= __r; @@ -1469,50 +1460,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif template - complex& + _GLIBCXX20_CONSTEXPR complex& operator=(const complex<_Tp>& __z) { - __real__ _M_value = __z.real(); - __imag__ _M_value = __z.imag(); + _M_value = __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator+=(const complex<_Tp>& __z) { - __real__ _M_value += __z.real(); - __imag__ _M_value += __z.imag(); + _M_value += __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator-=(const complex<_Tp>& __z) { - __real__ _M_value -= __z.real(); - __imag__ _M_value -= __z.imag(); + _M_value -= __z.__rep(); return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator*=(const complex<_Tp>& __z) { - _ComplexT __t; - __real__ __t = __z.real(); - __imag__ __t = __z.imag(); + const _ComplexT __t = __z.__rep(); _M_value *= __t; return *this; } template - complex& + _GLIBCXX20_CONSTEXPR complex& operator/=(const complex<_Tp>& __z) { - _ComplexT __t; - __real__ __t = __z.real(); - __imag__ __t = __z.imag(); + const _ComplexT __t = __z.__rep(); _M_value /= __t; return *this; } @@ -1872,7 +1856,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _Tp(); } template - inline typename __gnu_cxx::__promote<_Tp>::__type + _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type norm(_Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; @@ -1911,7 +1895,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Forward declarations. // DR 781. - template std::complex<_Tp> proj(const std::complex<_Tp>&); + template + std::complex<_Tp> proj(const std::complex<_Tp>&); template std::complex<_Tp> @@ -1957,7 +1942,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - inline std::complex::__type> + inline _GLIBCXX20_CONSTEXPR + std::complex::__type> conj(_Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; diff --git a/libstdc++-v3/testsuite/26_numerics/complex/comparison_operators/more_constexpr.cc b/libstdc++-v3/testsuite/26_numerics/complex/comparison_operators/more_constexpr.cc new file mode 100644 index 00000000000..6dc90da78da --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/complex/comparison_operators/more_constexpr.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2018 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 +// . + +#include +#include + +template + struct thing + { }; + +// +template + void + test_comparison() + { + constexpr std::complex<_Tp> a{1.1, 2.2}; + constexpr std::complex<_Tp> b{3.3, 4.4}; + if constexpr (a == b) + auto c [[maybe_unused]] = a + b; + if constexpr (a != b) + auto c [[maybe_unused]] = a - b; + + thing thing1 [[maybe_unused]]; + thing thing2 [[maybe_unused]]; + } + +int +main() +{ + test_comparison(); + test_comparison(); + test_comparison(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/complex/operators/more_constexpr.cc b/libstdc++-v3/testsuite/26_numerics/complex/operators/more_constexpr.cc new file mode 100644 index 00000000000..a6571559f70 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/complex/operators/more_constexpr.cc @@ -0,0 +1,62 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2018 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 +// . + +#include +#include + +namespace __gnu_test +{ + // Test constexpr symmetric complex @ real, real @ complex, complex @ complex. + template + void + test_operators() + { + constexpr std::complex<_Tp> a{1, 2}; + constexpr std::complex<_Tp> b{3, 4}; + constexpr _Tp c = 5; + + constexpr auto w [[maybe_unused]] = +a; + constexpr auto z [[maybe_unused]] = -a; + + constexpr auto apc [[maybe_unused]] = a + c; + constexpr auto amc [[maybe_unused]] = a - c; + constexpr auto atc [[maybe_unused]] = a * c; + constexpr auto adc [[maybe_unused]] = a / c; + + constexpr auto cpa [[maybe_unused]] = c + a; + constexpr auto cma [[maybe_unused]] = c - a; + constexpr auto cta [[maybe_unused]] = c * a; + constexpr auto cda [[maybe_unused]] = c / a; + + constexpr auto apb [[maybe_unused]] = a + b; + constexpr auto amb [[maybe_unused]] = a - b; + constexpr auto atb [[maybe_unused]] = a * b; + constexpr auto adb [[maybe_unused]] = a / b; + } +} + +int main() +{ + __gnu_test::test_operators(); + __gnu_test::test_operators(); + __gnu_test::test_operators(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/complex/requirements/more_constexpr.cc b/libstdc++-v3/testsuite/26_numerics/complex/requirements/more_constexpr.cc new file mode 100644 index 00000000000..902e7ce8e87 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/complex/requirements/more_constexpr.cc @@ -0,0 +1,171 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2018 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 +// . + +#include +#include + +namespace __gnu_test +{ + + // Test constexpr real(val) imag(val). + template + inline void + set_real(std::complex<_Tp>& a) + { a.real(_Val); } + + template + inline void + set_imag(std::complex<_Tp>& a) + { a.imag(_Val); } + + template + void + test_members() + { + constexpr std::complex<_Tp> a{1.1, 2.2}; + + std::complex<_Tp> z = a; + + set_real<_Tp, 33>(z); + set_imag<_Tp, 44>(z); + } + + // Test operators @=complex and @=real. + template + constexpr std::complex<_Tp> + sum(const std::complex<_Tp>& z, const std::complex<_Up>& w) + { + std::complex<_Tp> x = z; + x += w; + return x; + } + + template + constexpr std::complex<_Tp> + sum(const std::complex<_Tp>& z, _Up w) + { + std::complex<_Tp> x = z; + x += w; + return x; + } + + template + constexpr std::complex<_Tp> + dif(const std::complex<_Tp>& z, const std::complex<_Up>& w) + { + std::complex<_Tp> x = z; + x -= w; + return x; + } + + template + constexpr std::complex<_Tp> + dif(const std::complex<_Tp>& z, _Up w) + { + std::complex<_Tp> x = z; + x -= w; + return x; + } + + template + constexpr std::complex<_Tp> + prod(const std::complex<_Tp>& z, const std::complex<_Up>& w) + { + std::complex<_Tp> x = z; + x *= w; + return x; + } + + template + constexpr std::complex<_Tp> + prod(const std::complex<_Tp>& z, _Up w) + { + std::complex<_Tp> x = z; + x *= w; + return x; + } + + template + constexpr std::complex<_Tp> + quot(const std::complex<_Tp>& z, const std::complex<_Up>& w) + { + std::complex<_Tp> x = z; + x /= w; + return x; + } + + template + constexpr std::complex<_Tp> + quot(const std::complex<_Tp>& z, _Up w) + { + std::complex<_Tp> x = z; + x /= w; + return x; + } + + template + void + test_operator_members() + { + constexpr std::complex<_Tp> a{10, 20}; + constexpr std::complex<_Up> b{6, 8}; + constexpr _Up c{10}; + + constexpr auto apc = sum(a, c); + static_assert(apc == std::complex<_Tp>{20, 20}); + constexpr auto amc = dif(a, c); + static_assert(amc == std::complex<_Tp>{0, 20}); + constexpr auto atc = prod(a, c); + static_assert(atc == std::complex<_Tp>{100, 200}); + constexpr auto adc = quot(a, c); + static_assert(adc == std::complex<_Tp>{1, 2}); + + constexpr auto apb = sum(a, b); + static_assert(apb == std::complex<_Tp>{16, 28}); + constexpr auto amb = dif(a, b); + static_assert(amb == std::complex<_Tp>{4, 12}); + constexpr auto atb = prod(a, b); + static_assert(atb == std::complex<_Tp>{-100, 200}); + constexpr auto adb = quot(a, b); + static_assert(adb == std::complex<_Tp>{11/_Tp{5}, 2/_Tp{5}}); + } +} + +int main() +{ + __gnu_test::test_members(); + __gnu_test::test_members(); + __gnu_test::test_members(); + + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + __gnu_test::test_operator_members(); + + // Test primary template. + __gnu_test::test_operator_members<__float128, __float128>(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/complex/value_operations/more_constexpr.cc b/libstdc++-v3/testsuite/26_numerics/complex/value_operations/more_constexpr.cc new file mode 100644 index 00000000000..e98eacd4332 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/complex/value_operations/more_constexpr.cc @@ -0,0 +1,59 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2018 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 +// . + +#include +#include + +namespace __gnu_test +{ + struct constexpr_functions + { + template + void + operator()() + { + struct _Concept + { + void __constraint() + { + typedef typename _Ttesttype::_ComplexT _ComplexT; + constexpr _ComplexT cc = { 1.1 }; + constexpr _Ttesttype a(cc); + constexpr auto v1 [[maybe_unused]] = norm(a); + constexpr auto v2 [[maybe_unused]] = conj(a); + } + }; + + _Concept c; + c.__constraint(); + } + }; +} + +int main() +{ + __gnu_test::constexpr_functions test; + + test.operator()>(); + test.operator()>(); + test.operator()>(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/headers/complex/synopsis.cc b/libstdc++-v3/testsuite/26_numerics/headers/complex/synopsis.cc index 8bee4bf0053..81941a49284 100644 --- a/libstdc++-v3/testsuite/26_numerics/headers/complex/synopsis.cc +++ b/libstdc++-v3/testsuite/26_numerics/headers/complex/synopsis.cc @@ -28,51 +28,71 @@ namespace std { // 26.2.6 operators: template - complex operator+(const complex&, const complex&); - template complex operator+(const complex&, const T&); - template complex operator+(const T&, const complex&); - template complex operator- - (const complex&, const complex&); - template complex operator-(const complex&, const T&); - template complex operator-(const T&, const complex&); - template complex operator* - (const complex&, const complex&); - template complex operator*(const complex&, const T&); - template complex operator*(const T&, const complex&); - template complex operator/ - (const complex&, const complex&); - template complex operator/(const complex&, const T&); - template complex operator/(const T&, const complex&); - template complex operator+(const complex&); - template complex operator-(const complex&); - template _GLIBCXX_CONSTEXPR bool operator== - (const complex&, const complex&); - template _GLIBCXX_CONSTEXPR bool operator== - (const complex&, const T&); - template _GLIBCXX_CONSTEXPR bool operator== - (const T&, const complex&); + _GLIBCXX20_CONSTEXPR complex + operator+(const complex&, const complex&); + template + _GLIBCXX20_CONSTEXPR complex operator+(const complex&, const T&); + template + _GLIBCXX20_CONSTEXPR complex operator+(const T&, const complex&); + template + _GLIBCXX20_CONSTEXPR complex + operator-(const complex&, const complex&); + template + _GLIBCXX20_CONSTEXPR complex operator-(const complex&, const T&); + template + _GLIBCXX20_CONSTEXPR complex operator-(const T&, const complex&); - template _GLIBCXX_CONSTEXPR bool operator!= + template + _GLIBCXX20_CONSTEXPR complex operator* (const complex&, const complex&); - template _GLIBCXX_CONSTEXPR bool operator!= - (const complex&, const T&); - template _GLIBCXX_CONSTEXPR bool operator!= - (const T&, const complex&); + template + _GLIBCXX20_CONSTEXPR complex operator*(const complex&, const T&); + template + _GLIBCXX20_CONSTEXPR complex operator*(const T&, const complex&); + + template + _GLIBCXX20_CONSTEXPR complex + operator/(const complex&, const complex&); + template + _GLIBCXX20_CONSTEXPR complex operator/(const complex&, const T&); + template + _GLIBCXX20_CONSTEXPR complex operator/(const T&, const complex&); + + template + _GLIBCXX20_CONSTEXPR complex operator+(const complex&); + template + _GLIBCXX20_CONSTEXPR complex operator-(const complex&); + + template + _GLIBCXX_CONSTEXPR bool operator==(const complex&, const complex&); + template + _GLIBCXX_CONSTEXPR bool operator==(const complex&, const T&); + template + _GLIBCXX_CONSTEXPR bool operator==(const T&, const complex&); + + template + _GLIBCXX_CONSTEXPR bool operator!=(const complex&, const complex&); + template + _GLIBCXX_CONSTEXPR bool operator!=(const complex&, const T&); + template + _GLIBCXX_CONSTEXPR bool operator!=(const T&, const complex&); + template - basic_istream& - operator>>(basic_istream&, complex&); + basic_istream& + operator>>(basic_istream&, complex&); template - basic_ostream& - operator<<(basic_ostream&, const complex&); + basic_ostream& + operator<<(basic_ostream&, const complex&); // 26.2.7 values: template _GLIBCXX_CONSTEXPR T real(const complex&); template _GLIBCXX_CONSTEXPR T imag(const complex&); template T abs(const complex&); - template T arg(const complex&); - template T norm(const complex&); - template complex conj(const complex&); + template _GLIBCXX20_CONSTEXPR T arg(const complex&); + template _GLIBCXX20_CONSTEXPR T norm(const complex&); + template _GLIBCXX20_CONSTEXPR complex conj(const complex&); + template _GLIBCXX20_CONSTEXPR complex proj(const complex&); template complex polar(const T& rho, const T& theta); // 26.2.8 transcendentals: