blob: adc8365e1fae8e95b426b5aebe17399778dcbd24 [file] [log] [blame]
// { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } }
// Copyright (C) 2018-2021 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>();
#ifndef __LONG_DOUBLE_IBM128__ // IBM128 format is not constexpr foldable
__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>();
#endif
#if defined(_GLIBCXX_USE_FLOAT128)
// Test primary template.
__gnu_test::test_operator_members<__float128, __float128>();
#endif
return 0;
}