134 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++2310 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 29template <typename T>30constexpr 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 bindings84 {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 ranges103 {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 120constexpr bool test() {121 test<float>();122 test<double>();123 test<long double>();124 125 return true;126}127 128int main(int, char**) {129 test();130 static_assert(test());131 132 return 0;133}134