blob: 1150861ae0aa4ed3fa9ee2e524d95bfffe036021 [file] [log] [blame]
// { dg-do compile { target c++26 } }
#include <complex>
#include <ranges>
#include <algorithm>
#include <string_view>
#include <type_traits>
#include <tuple>
#include <utility>
#include <testsuite_hooks.h>
template <typename T>
constexpr
void
test_sanity()
{
using C = std::complex<T>;
static_assert(std::tuple_size_v<C> == 2);
static_assert(std::is_same_v<std::tuple_element_t<0, C>, T>);
static_assert(std::is_same_v<std::tuple_element_t<1, C>, T>);
static_assert(std::is_same_v<decltype(get<0>(std::declval<C&>())), T&>);
static_assert(std::is_same_v<decltype(get<1>(std::declval<C&>())), T&>);
static_assert(std::is_same_v<decltype(get<0>(std::declval<const C&>())), const T&>);
static_assert(std::is_same_v<decltype(get<1>(std::declval<const C&>())), const T&>);
static_assert(std::is_same_v<decltype(get<0>(std::declval<C>())), T&&>);
static_assert(std::is_same_v<decltype(get<1>(std::declval<C>())), T&&>);
static_assert(std::is_same_v<decltype(get<0>(std::declval<const C>())), const T&&>);
static_assert(std::is_same_v<decltype(get<1>(std::declval<const C>())), const T&&>);
}
template <typename T>
constexpr
void
test_get()
{
using C = std::complex<T>;
C cpx(T(1), T(2));
VERIFY(std::get<0>(cpx) == T(1));
VERIFY(std::get<1>(cpx) == T(2));
const C cpx2(T(3), T(4));
VERIFY(std::get<0>(cpx2) == T(3));
VERIFY(std::get<1>(cpx2) == T(4));
struct derived : public C { using C::C; };
derived cpx3(T(5), T(6));
VERIFY(std::get<0>(cpx3) == T(5));
VERIFY(std::get<1>(cpx3) == T(6));
}
template <typename T>
constexpr
void
test_structured_binding()
{
using C = std::complex<T>;
C cpx(T(1), T(2));
auto& [r, i] = cpx;
VERIFY(r == T(1));
VERIFY(i == T(2));
r = T(3);
VERIFY(cpx.real() == T(3));
VERIFY(cpx.imag() == T(2));
i = T(4);
VERIFY(cpx.real() == T(3));
VERIFY(cpx.imag() == T(4));
const C cpx2(T(5), T(6));
auto& [r2, i2] = cpx2;
VERIFY(r2 == T(5));
VERIFY(i2 == T(6));
}
template <typename T>
constexpr
void
test_tuple_cat()
{
std::complex<T> cpx(T(1), T(2));
std::pair<int, std::string_view> p(42, "hello");
auto r = std::tuple_cat(cpx, p, cpx);
static_assert(std::is_same_v<decltype(r), std::tuple<T, T, int, std::string_view, T, T>>);
VERIFY(std::get<0>(r) == T(1));
VERIFY(std::get<1>(r) == T(2));
VERIFY(std::get<2>(r) == 42);
VERIFY(std::get<3>(r) == "hello");
VERIFY(std::get<4>(r) == T(1));
VERIFY(std::get<5>(r) == T(2));
}
template <typename T>
constexpr
void
test_element_view()
{
std::complex<T> array[5] = {
{ T(0), T(1) },
{ T(2), T(3) },
{ T(4), T(5) },
{ T(6), T(7) },
{ T(8), T(9) }
};
T real_reduction = std::ranges::fold_left(array | std::views::keys, {}, std::plus{});
VERIFY(real_reduction == T(20));
T imag_reduction = std::ranges::fold_left(array | std::views::values, {}, std::plus{});
VERIFY(imag_reduction == T(25));
}
template <typename T>
constexpr
void
test_apply()
{
std::complex<T> cpx(T(1), T(2));
auto f = [](T a, T b) { return a + b; };
auto result = std::apply(f, cpx);
VERIFY(result == T(3));
}
template <typename T>
constexpr
bool
all_tests()
{
test_sanity<T>();
test_structured_binding<T>();
test_tuple_cat<T>();
test_element_view<T>();
test_apply<T>();
test_get<T>();
return true;
}
#define TEST(T) \
static_assert(all_tests<T>()); \
template T& std::get<0, T>(std::complex<T>&); \
template T& std::get<1, T>(std::complex<T>&); \
template T&& std::get<0, T>(std::complex<T>&&); \
template T&& std::get<1, T>(std::complex<T>&&); \
template const T& std::get<0, T>(const std::complex<T>&); \
template const T& std::get<1, T>(const std::complex<T>&); \
template const T&& std::get<0, T>(const std::complex<T>&&); \
template const T&& std::get<1, T>(const std::complex<T>&&); \
TEST(float)
TEST(double)
TEST(long double)
#ifdef __STDCPP_FLOAT16_T__
TEST(_Float16)
#endif
#ifdef __STDCPP_FLOAT32_T__
TEST(_Float32)
#endif
#ifdef __STDCPP_FLOAT64_T__
TEST(_Float64)
#endif
#ifdef __STDCPP_FLOAT128_T__
TEST(_Float128)
#endif
#ifdef __STDCPP_BFLOAT16_T__
TEST(__gnu_cxx::__bfloat16_t)
#endif
TEST(char)
TEST(int)
TEST(unsigned int)
TEST(long)