+2018-11-23 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement P0415 More constexpr for std::complex.
+ * include/std/complex (conj(complex<Tp>), norm(complex<Tp>)): Constexpr;
+ (real(Tp), imag(Tp)): Constexpr;
+ (operator@=(Tp), operator@=(complex<Tp>)): Constexpr;
+ (operator@(Tp,complex<Tp>), operator@(complex<Tp>,Tp)
+ operator@(complex<Tp>,complex<Tp>)): 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 <msebor@redhat.com>
Jonathan Wakely <jwakely@redhat.com>
/// Return phase angle of @a z.
template<typename _Tp> _Tp arg(const complex<_Tp>&);
/// Return @a z magnitude squared.
- template<typename _Tp> _Tp norm(const complex<_Tp>&);
+ template<typename _Tp> _Tp _GLIBCXX20_CONSTEXPR norm(const complex<_Tp>&);
/// Return complex conjugate of @a z.
- template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&);
+ template<typename _Tp>
+ _GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>&);
/// Return complex with magnitude @a rho and angle @a theta.
template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
// _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;
/// Subtract a scalar from this complex number.
// 26.2.5/3
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
operator-=(const _Tp& __t)
{
_M_real -= __t;
}
/// 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<typename _Up>
- complex<_Tp>& operator=(const complex<_Up>&);
+ _GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const complex<_Up>&);
/// Add another complex number to this one.
template<typename _Up>
- complex<_Tp>& operator+=(const complex<_Up>&);
+ _GLIBCXX20_CONSTEXPR complex<_Tp>& operator+=(const complex<_Up>&);
/// Subtract another complex number from this one.
template<typename _Up>
- complex<_Tp>& operator-=(const complex<_Up>&);
+ _GLIBCXX20_CONSTEXPR complex<_Tp>& operator-=(const complex<_Up>&);
/// Multiply this complex number by another.
template<typename _Up>
- complex<_Tp>& operator*=(const complex<_Up>&);
+ _GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const complex<_Up>&);
/// Divide this complex number by another.
template<typename _Up>
- complex<_Tp>& operator/=(const complex<_Up>&);
+ _GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const complex<_Up>&);
_GLIBCXX_CONSTEXPR complex __rep() const
{ return *this; }
};
template<typename _Tp>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator=(const _Tp& __t)
{
_M_real = __t;
// 26.2.5/5
template<typename _Tp>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator*=(const _Tp& __t)
{
_M_real *= __t;
// 26.2.5/7
template<typename _Tp>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator/=(const _Tp& __t)
{
_M_real /= __t;
template<typename _Tp>
template<typename _Up>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator=(const complex<_Up>& __z)
{
_M_real = __z.real();
// 26.2.5/9
template<typename _Tp>
template<typename _Up>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator+=(const complex<_Up>& __z)
{
_M_real += __z.real();
// 26.2.5/11
template<typename _Tp>
template<typename _Up>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator-=(const complex<_Up>& __z)
{
_M_real -= __z.real();
// XXX: This is a grammar school implementation.
template<typename _Tp>
template<typename _Up>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator*=(const complex<_Up>& __z)
{
const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
// XXX: This is a grammar school implementation.
template<typename _Tp>
template<typename _Up>
- complex<_Tp>&
+ _GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator/=(const complex<_Up>& __z)
{
const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag();
//@{
/// 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;
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator+(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator+(const _Tp& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __y;
//@{
/// Return new complex value @a x minus @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;
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator-(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
}
template<typename _Tp>
- 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;
}
//@}
//@{
/// Return new complex value @a x times @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;
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator*(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator*(const _Tp& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __y;
//@{
/// Return new complex value @a x divided by @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;
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator/(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator/(const _Tp& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __x;
/// Return @a x.
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator+(const complex<_Tp>& __x)
{ return __x; }
/// Return complex negation of @a x.
template<typename _Tp>
- 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.
struct _Norm_helper
{
template<typename _Tp>
- 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();
struct _Norm_helper<true>
{
template<typename _Tp>
- 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<typename _Tp>
- inline _Tp
+ inline _GLIBCXX20_CONSTEXPR _Tp
norm(const complex<_Tp>& __z)
{
return _Norm_helper<__is_floating<_Tp>::__value
}
template<typename _Tp>
- inline complex<_Tp>
+ inline _GLIBCXX20_CONSTEXPR complex<_Tp>
conj(const complex<_Tp>& __z)
{ return complex<_Tp>(__z.real(), -__z.imag()); }
// _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;
#endif
template<typename _Tp>
- complex&
+ _GLIBCXX20_CONSTEXPR complex&
operator=(const complex<_Tp>& __z)
{
__real__ _M_value = __z.real();
}
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();
return *this;
}
template<class _Tp>
- 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<class _Tp>
- 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<class _Tp>
- 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;
}
// _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;
#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();
return *this;
}
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();
return *this;
}
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();
return *this;
}
template<typename _Tp>
- 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<typename _Tp>
- 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;
}
// _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;
#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();
return *this;
}
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();
return *this;
}
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();
return *this;
}
template<typename _Tp>
- 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<typename _Tp>
- 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;
}
{ return _Tp(); }
template<typename _Tp>
- 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;
// Forward declarations.
// DR 781.
- template<typename _Tp> std::complex<_Tp> proj(const std::complex<_Tp>&);
+ template<typename _Tp>
+ std::complex<_Tp> proj(const std::complex<_Tp>&);
template<typename _Tp>
std::complex<_Tp>
}
template<typename _Tp>
- inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
+ inline _GLIBCXX20_CONSTEXPR
+ std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
conj(_Tp __x)
{
typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
--- /dev/null
+// { 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
+// <http://www.gnu.org/licenses/>.
+
+#include <complex>
+#include <testsuite_common_types.h>
+
+template<bool ok>
+ struct thing
+ { };
+
+//
+template<typename _Tp>
+ 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<a == b> thing1 [[maybe_unused]];
+ thing<a != b> thing2 [[maybe_unused]];
+ }
+
+int
+main()
+{
+ test_comparison<float>();
+ test_comparison<double>();
+ test_comparison<long double>();
+
+ return 0;
+}
--- /dev/null
+// { 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
+// <http://www.gnu.org/licenses/>.
+
+#include <complex>
+#include <testsuite_common_types.h>
+
+namespace __gnu_test
+{
+ // Test constexpr symmetric complex @ real, real @ complex, complex @ complex.
+ template<typename _Tp>
+ 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<float>();
+ __gnu_test::test_operators<double>();
+ __gnu_test::test_operators<long double>();
+
+ return 0;
+}
--- /dev/null
+// { 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
+// <http://www.gnu.org/licenses/>.
+
+#include <complex>
+#include <testsuite_common_types.h>
+
+namespace __gnu_test
+{
+
+ // Test constexpr real(val) imag(val).
+ template<typename _Tp, const int _Val = 42>
+ inline void
+ set_real(std::complex<_Tp>& a)
+ { a.real(_Val); }
+
+ template<typename _Tp, const int _Val = 42>
+ inline void
+ set_imag(std::complex<_Tp>& a)
+ { a.imag(_Val); }
+
+ template<typename _Tp>
+ 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<typename _Tp, typename _Up>
+ 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<typename _Tp, typename _Up>
+ constexpr std::complex<_Tp>
+ sum(const std::complex<_Tp>& z, _Up w)
+ {
+ std::complex<_Tp> x = z;
+ x += w;
+ return x;
+ }
+
+ template<typename _Tp, typename _Up>
+ 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<typename _Tp, typename _Up>
+ constexpr std::complex<_Tp>
+ dif(const std::complex<_Tp>& z, _Up w)
+ {
+ std::complex<_Tp> x = z;
+ x -= w;
+ return x;
+ }
+
+ template<typename _Tp, typename _Up>
+ 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<typename _Tp, typename _Up>
+ constexpr std::complex<_Tp>
+ prod(const std::complex<_Tp>& z, _Up w)
+ {
+ std::complex<_Tp> x = z;
+ x *= w;
+ return x;
+ }
+
+ template<typename _Tp, typename _Up>
+ 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<typename _Tp, typename _Up>
+ constexpr std::complex<_Tp>
+ quot(const std::complex<_Tp>& z, _Up w)
+ {
+ std::complex<_Tp> x = z;
+ x /= w;
+ return x;
+ }
+
+ template<typename _Tp, typename _Up>
+ 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<float>();
+ __gnu_test::test_members<double>();
+ __gnu_test::test_members<long double>();
+
+ __gnu_test::test_operator_members<float, float>();
+ __gnu_test::test_operator_members<float, double>();
+ __gnu_test::test_operator_members<float, long double>();
+ __gnu_test::test_operator_members<double, float>();
+ __gnu_test::test_operator_members<double, double>();
+ __gnu_test::test_operator_members<double, long double>();
+ __gnu_test::test_operator_members<long double, float>();
+ __gnu_test::test_operator_members<long double, double>();
+ __gnu_test::test_operator_members<long double, long double>();
+
+ // Test primary template.
+ __gnu_test::test_operator_members<__float128, __float128>();
+
+ return 0;
+}
--- /dev/null
+// { 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
+// <http://www.gnu.org/licenses/>.
+
+#include <complex>
+#include <testsuite_common_types.h>
+
+namespace __gnu_test
+{
+ struct constexpr_functions
+ {
+ template<typename _Ttesttype>
+ 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()<std::complex<float>>();
+ test.operator()<std::complex<double>>();
+ test.operator()<std::complex<long double>>();
+
+ return 0;
+}
// 26.2.6 operators:
template<class T>
- complex<T> operator+(const complex<T>&, const complex<T>&);
- template<class T> complex<T> operator+(const complex<T>&, const T&);
- template<class T> complex<T> operator+(const T&, const complex<T>&);
- template<class T> complex<T> operator-
- (const complex<T>&, const complex<T>&);
- template<class T> complex<T> operator-(const complex<T>&, const T&);
- template<class T> complex<T> operator-(const T&, const complex<T>&);
- template<class T> complex<T> operator*
- (const complex<T>&, const complex<T>&);
- template<class T> complex<T> operator*(const complex<T>&, const T&);
- template<class T> complex<T> operator*(const T&, const complex<T>&);
- template<class T> complex<T> operator/
- (const complex<T>&, const complex<T>&);
- template<class T> complex<T> operator/(const complex<T>&, const T&);
- template<class T> complex<T> operator/(const T&, const complex<T>&);
- template<class T> complex<T> operator+(const complex<T>&);
- template<class T> complex<T> operator-(const complex<T>&);
- template<class T> _GLIBCXX_CONSTEXPR bool operator==
- (const complex<T>&, const complex<T>&);
- template<class T> _GLIBCXX_CONSTEXPR bool operator==
- (const complex<T>&, const T&);
- template<class T> _GLIBCXX_CONSTEXPR bool operator==
- (const T&, const complex<T>&);
+ _GLIBCXX20_CONSTEXPR complex<T>
+ operator+(const complex<T>&, const complex<T>&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator+(const complex<T>&, const T&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator+(const T&, const complex<T>&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T>
+ operator-(const complex<T>&, const complex<T>&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator-(const complex<T>&, const T&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator-(const T&, const complex<T>&);
- template<class T> _GLIBCXX_CONSTEXPR bool operator!=
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator*
(const complex<T>&, const complex<T>&);
- template<class T> _GLIBCXX_CONSTEXPR bool operator!=
- (const complex<T>&, const T&);
- template<class T> _GLIBCXX_CONSTEXPR bool operator!=
- (const T&, const complex<T>&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator*(const complex<T>&, const T&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator*(const T&, const complex<T>&);
+
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T>
+ operator/(const complex<T>&, const complex<T>&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator/(const complex<T>&, const T&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator/(const T&, const complex<T>&);
+
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator+(const complex<T>&);
+ template<class T>
+ _GLIBCXX20_CONSTEXPR complex<T> operator-(const complex<T>&);
+
+ template<class T>
+ _GLIBCXX_CONSTEXPR bool operator==(const complex<T>&, const complex<T>&);
+ template<class T>
+ _GLIBCXX_CONSTEXPR bool operator==(const complex<T>&, const T&);
+ template<class T>
+ _GLIBCXX_CONSTEXPR bool operator==(const T&, const complex<T>&);
+
+ template<class T>
+ _GLIBCXX_CONSTEXPR bool operator!=(const complex<T>&, const complex<T>&);
+ template<class T>
+ _GLIBCXX_CONSTEXPR bool operator!=(const complex<T>&, const T&);
+ template<class T>
+ _GLIBCXX_CONSTEXPR bool operator!=(const T&, const complex<T>&);
+
template<class T, class charT, class traits>
- basic_istream<charT, traits>&
- operator>>(basic_istream<charT, traits>&, complex<T>&);
+ basic_istream<charT, traits>&
+ operator>>(basic_istream<charT, traits>&, complex<T>&);
template<class T, class charT, class traits>
- basic_ostream<charT, traits>&
- operator<<(basic_ostream<charT, traits>&, const complex<T>&);
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>&, const complex<T>&);
// 26.2.7 values:
template<class T> _GLIBCXX_CONSTEXPR T real(const complex<T>&);
template<class T> _GLIBCXX_CONSTEXPR T imag(const complex<T>&);
template<class T> T abs(const complex<T>&);
- template<class T> T arg(const complex<T>&);
- template<class T> T norm(const complex<T>&);
- template<class T> complex<T> conj(const complex<T>&);
+ template<class T> _GLIBCXX20_CONSTEXPR T arg(const complex<T>&);
+ template<class T> _GLIBCXX20_CONSTEXPR T norm(const complex<T>&);
+ template<class T> _GLIBCXX20_CONSTEXPR complex<T> conj(const complex<T>&);
+ template<class T> _GLIBCXX20_CONSTEXPR complex<T> proj(const complex<T>&);
template<class T> complex<T> polar(const T& rho, const T& theta);
// 26.2.8 transcendentals: