12ea5d167SHristo Hristov //===----------------------------------------------------------------------===//
22ea5d167SHristo Hristov //
32ea5d167SHristo Hristov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42ea5d167SHristo Hristov // See https://llvm.org/LICENSE.txt for license information.
52ea5d167SHristo Hristov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62ea5d167SHristo Hristov //
72ea5d167SHristo Hristov //===----------------------------------------------------------------------===//
82ea5d167SHristo Hristov
92ea5d167SHristo Hristov // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
102ea5d167SHristo Hristov
112ea5d167SHristo Hristov // <complex>
122ea5d167SHristo Hristov
132ea5d167SHristo Hristov // template<size_t I, class T>
142ea5d167SHristo Hristov // constexpr T& get(complex<T>&) noexcept;
152ea5d167SHristo Hristov // template<size_t I, class T>
162ea5d167SHristo Hristov // constexpr T&& get(complex<T>&&) noexcept;
172ea5d167SHristo Hristov // template<size_t I, class T>
182ea5d167SHristo Hristov // constexpr const T& get(const complex<T>&) noexcept;
192ea5d167SHristo Hristov // template<size_t I, class T>
202ea5d167SHristo Hristov // constexpr const T&& get(const complex<T>&&) noexcept;
212ea5d167SHristo Hristov
222ea5d167SHristo Hristov #include <cassert>
232ea5d167SHristo Hristov #include <complex>
242ea5d167SHristo Hristov #include <concepts>
252ea5d167SHristo Hristov #include <ranges>
262ea5d167SHristo Hristov #include <vector>
272ea5d167SHristo Hristov #include <utility>
282ea5d167SHristo Hristov
292ea5d167SHristo Hristov template <typename T>
test()302ea5d167SHristo Hristov constexpr void test() {
312ea5d167SHristo Hristov // &
322ea5d167SHristo Hristov {
332ea5d167SHristo Hristov std::complex<T> c{T{27}, T{28}};
342ea5d167SHristo Hristov
352ea5d167SHristo Hristov std::same_as<T&> decltype(auto) r = get<0>(c);
362ea5d167SHristo Hristov static_assert(noexcept(get<0>(c)));
372ea5d167SHristo Hristov assert(r == T{27});
382ea5d167SHristo Hristov std::same_as<T&> decltype(auto) i = get<1>(c);
392ea5d167SHristo Hristov static_assert(noexcept(get<1>(c)));
402ea5d167SHristo Hristov assert(i == T{28});
412ea5d167SHristo Hristov }
422ea5d167SHristo Hristov // &&
432ea5d167SHristo Hristov {
442ea5d167SHristo Hristov std::complex<T> c{T{27}, T{28}};
452ea5d167SHristo Hristov
462ea5d167SHristo Hristov std::same_as<T&&> decltype(auto) r = get<0>(std::move(c));
472ea5d167SHristo Hristov static_assert(noexcept(get<0>(c)));
482ea5d167SHristo Hristov assert(r == T{27});
492ea5d167SHristo Hristov }
502ea5d167SHristo Hristov {
512ea5d167SHristo Hristov std::complex<T> c{T{27}, T{28}};
522ea5d167SHristo Hristov
532ea5d167SHristo Hristov std::same_as<T&&> decltype(auto) i = get<1>(std::move(c));
542ea5d167SHristo Hristov static_assert(noexcept(get<1>(c)));
552ea5d167SHristo Hristov assert(i == T{28});
562ea5d167SHristo Hristov }
572ea5d167SHristo Hristov // const &
582ea5d167SHristo Hristov {
592ea5d167SHristo Hristov const std::complex<T> c{T{27}, T{28}};
602ea5d167SHristo Hristov
612ea5d167SHristo Hristov std::same_as<const T&> decltype(auto) r = get<0>(c);
622ea5d167SHristo Hristov static_assert(noexcept(get<0>(c)));
632ea5d167SHristo Hristov assert(r == T{27});
642ea5d167SHristo Hristov std::same_as<const T&> decltype(auto) i = get<1>(c);
652ea5d167SHristo Hristov static_assert(noexcept(get<1>(c)));
662ea5d167SHristo Hristov assert(i == T{28});
672ea5d167SHristo Hristov }
682ea5d167SHristo Hristov // const &&
692ea5d167SHristo Hristov {
702ea5d167SHristo Hristov const std::complex<T> c{T{27}, T{28}};
712ea5d167SHristo Hristov
722ea5d167SHristo Hristov std::same_as<const T&&> decltype(auto) r = get<0>(std::move(c));
732ea5d167SHristo Hristov static_assert(noexcept(get<0>(c)));
742ea5d167SHristo Hristov assert(r == T{27});
752ea5d167SHristo Hristov }
762ea5d167SHristo Hristov {
772ea5d167SHristo Hristov const std::complex<T> c{T{27}, T{28}};
782ea5d167SHristo Hristov
792ea5d167SHristo Hristov std::same_as<const T&&> decltype(auto) i = get<1>(std::move(c));
802ea5d167SHristo Hristov static_assert(noexcept(get<1>(c)));
812ea5d167SHristo Hristov assert(i == T{28});
822ea5d167SHristo Hristov }
832ea5d167SHristo Hristov // `get()` allows using `complex` with structured bindings
842ea5d167SHristo Hristov {
852ea5d167SHristo Hristov std::complex<T> c{T{27}, T{28}};
862ea5d167SHristo Hristov
872ea5d167SHristo Hristov auto [r, i]{c};
882ea5d167SHristo Hristov static_assert(std::same_as<T, decltype(r)>);
892ea5d167SHristo Hristov assert(r == T{27});
902ea5d167SHristo Hristov static_assert(std::same_as<T, decltype(i)>);
912ea5d167SHristo Hristov assert(i == T{28});
922ea5d167SHristo Hristov }
932ea5d167SHristo Hristov {
942ea5d167SHristo Hristov std::complex<T> c{T{27}, T{28}};
952ea5d167SHristo Hristov
962ea5d167SHristo Hristov auto& [r, i]{c};
972ea5d167SHristo Hristov static_assert(std::same_as<T, decltype(r)>);
982ea5d167SHristo Hristov assert(r == T{27});
992ea5d167SHristo Hristov static_assert(std::same_as<T, decltype(i)>);
1002ea5d167SHristo Hristov assert(i == T{28});
1012ea5d167SHristo Hristov }
1022ea5d167SHristo Hristov // `get()` allows using `complex` with ranges
1032ea5d167SHristo Hristov {
1042ea5d167SHristo Hristov std::complex<T> arr[]{{T{27}, T{28}}, {T{82}, T{94}}};
1052ea5d167SHristo Hristov
1062ea5d167SHristo Hristov std::same_as<std::vector<T>> decltype(auto) reals{
1072ea5d167SHristo Hristov arr | std::views::elements<0> | std::ranges::to<std::vector<T>>()};
1082ea5d167SHristo Hristov assert(reals.size() == 2);
1092ea5d167SHristo Hristov assert(reals[0] == T{27});
1102ea5d167SHristo Hristov assert(reals[1] == T{82});
1112ea5d167SHristo Hristov
1122ea5d167SHristo Hristov std::same_as<std::vector<T>> decltype(auto) imags{
1132ea5d167SHristo Hristov arr | std::views::elements<1> | std::ranges::to<std::vector<T>>()};
114*9af7f406SHristo Hristov assert(imags.size() == 2);
1152ea5d167SHristo Hristov assert(imags[0] == T{28});
1162ea5d167SHristo Hristov assert(imags[1] == T{94});
1172ea5d167SHristo Hristov }
1182ea5d167SHristo Hristov }
1192ea5d167SHristo Hristov
test()1202ea5d167SHristo Hristov constexpr bool test() {
1212ea5d167SHristo Hristov test<float>();
1222ea5d167SHristo Hristov test<double>();
1232ea5d167SHristo Hristov test<long double>();
1242ea5d167SHristo Hristov
1252ea5d167SHristo Hristov return true;
1262ea5d167SHristo Hristov }
1272ea5d167SHristo Hristov
main(int,char **)1282ea5d167SHristo Hristov int main(int, char**) {
1292ea5d167SHristo Hristov test();
1302ea5d167SHristo Hristov static_assert(test());
1312ea5d167SHristo Hristov
1322ea5d167SHristo Hristov return 0;
1332ea5d167SHristo Hristov }
134