1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
10
11 // <complex>
12
13 // template<size_t I, class T>
14 // constexpr T& get(complex<T>&) noexcept;
15 // template<size_t I, class T>
16 // constexpr T&& get(complex<T>&&) noexcept;
17 // template<size_t I, class T>
18 // constexpr const T& get(const complex<T>&) noexcept;
19 // template<size_t I, class T>
20 // constexpr const T&& get(const complex<T>&&) noexcept;
21
22 #include <cassert>
23 #include <complex>
24 #include <concepts>
25 #include <ranges>
26 #include <vector>
27 #include <utility>
28
29 template <typename T>
test()30 constexpr void test() {
31 // &
32 {
33 std::complex<T> c{T{27}, T{28}};
34
35 std::same_as<T&> decltype(auto) r = get<0>(c);
36 static_assert(noexcept(get<0>(c)));
37 assert(r == T{27});
38 std::same_as<T&> decltype(auto) i = get<1>(c);
39 static_assert(noexcept(get<1>(c)));
40 assert(i == T{28});
41 }
42 // &&
43 {
44 std::complex<T> c{T{27}, T{28}};
45
46 std::same_as<T&&> decltype(auto) r = get<0>(std::move(c));
47 static_assert(noexcept(get<0>(c)));
48 assert(r == T{27});
49 }
50 {
51 std::complex<T> c{T{27}, T{28}};
52
53 std::same_as<T&&> decltype(auto) i = get<1>(std::move(c));
54 static_assert(noexcept(get<1>(c)));
55 assert(i == T{28});
56 }
57 // const &
58 {
59 const std::complex<T> c{T{27}, T{28}};
60
61 std::same_as<const T&> decltype(auto) r = get<0>(c);
62 static_assert(noexcept(get<0>(c)));
63 assert(r == T{27});
64 std::same_as<const T&> decltype(auto) i = get<1>(c);
65 static_assert(noexcept(get<1>(c)));
66 assert(i == T{28});
67 }
68 // const &&
69 {
70 const std::complex<T> c{T{27}, T{28}};
71
72 std::same_as<const T&&> decltype(auto) r = get<0>(std::move(c));
73 static_assert(noexcept(get<0>(c)));
74 assert(r == T{27});
75 }
76 {
77 const std::complex<T> c{T{27}, T{28}};
78
79 std::same_as<const T&&> decltype(auto) i = get<1>(std::move(c));
80 static_assert(noexcept(get<1>(c)));
81 assert(i == T{28});
82 }
83 // `get()` allows using `complex` with structured bindings
84 {
85 std::complex<T> c{T{27}, T{28}};
86
87 auto [r, i]{c};
88 static_assert(std::same_as<T, decltype(r)>);
89 assert(r == T{27});
90 static_assert(std::same_as<T, decltype(i)>);
91 assert(i == T{28});
92 }
93 {
94 std::complex<T> c{T{27}, T{28}};
95
96 auto& [r, i]{c};
97 static_assert(std::same_as<T, decltype(r)>);
98 assert(r == T{27});
99 static_assert(std::same_as<T, decltype(i)>);
100 assert(i == T{28});
101 }
102 // `get()` allows using `complex` with ranges
103 {
104 std::complex<T> arr[]{{T{27}, T{28}}, {T{82}, T{94}}};
105
106 std::same_as<std::vector<T>> decltype(auto) reals{
107 arr | std::views::elements<0> | std::ranges::to<std::vector<T>>()};
108 assert(reals.size() == 2);
109 assert(reals[0] == T{27});
110 assert(reals[1] == T{82});
111
112 std::same_as<std::vector<T>> decltype(auto) imags{
113 arr | std::views::elements<1> | std::ranges::to<std::vector<T>>()};
114 assert(imags.size() == 2);
115 assert(imags[0] == T{28});
116 assert(imags[1] == T{94});
117 }
118 }
119
test()120 constexpr bool test() {
121 test<float>();
122 test<double>();
123 test<long double>();
124
125 return true;
126 }
127
main(int,char **)128 int main(int, char**) {
129 test();
130 static_assert(test());
131
132 return 0;
133 }
134