101 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++1710 11// constexpr decltype(auto) operator*() const;12 13#include <array>14#include <cassert>15#include <ranges>16#include <tuple>17#include <utility>18 19template <std::size_t N, class T, std::size_t Size>20constexpr void testReference(T (&ts)[Size]) {21 auto ev = ts | std::views::elements<N>;22 auto it = ev.begin();23 24 decltype(auto) result = *it;25 using ExpectedType = decltype(std::get<N>(ts[0]));26 static_assert(std::is_same_v<decltype(result), ExpectedType>);27 28 if constexpr (std::is_reference_v<ExpectedType>) {29 // tuple/array/pair30 assert(&result == &std::get<N>(ts[0]));31 } else {32 // subrange33 assert(result == std::get<N>(ts[0]));34 }35}36 37// LWG 3502 elements_view should not be allowed to return dangling references38template <std::size_t N, class T>39constexpr void testValue(T t) {40 auto ev = std::views::iota(0, 1) | std::views::transform([&t](int) { return t; }) | std::views::elements<N>;41 auto it = ev.begin();42 43 decltype(auto) result = *it;44 using ExpectedType = std::remove_cvref_t<decltype(std::get<N>(t))>;45 static_assert(std::is_same_v<decltype(result), ExpectedType>);46 47 assert(result == std::get<N>(t));48}49 50constexpr bool test() {51 // test tuple52 {53 std::tuple<int, short, long> ts[] = {{1, short{2}, 3}, {4, short{5}, 6}};54 testReference<0>(ts);55 testReference<1>(ts);56 testReference<2>(ts);57 testValue<0>(ts[0]);58 testValue<1>(ts[0]);59 testValue<2>(ts[0]);60 }61 62 // test pair63 {64 std::pair<int, short> ps[] = {{1, short{2}}, {4, short{5}}};65 testReference<0>(ps);66 testReference<1>(ps);67 testValue<0>(ps[0]);68 testValue<1>(ps[0]);69 }70 71 // test array72 {73 std::array<int, 3> arrs[] = {{1, 2, 3}, {3, 4, 5}};74 testReference<0>(arrs);75 testReference<1>(arrs);76 testReference<2>(arrs);77 testValue<0>(arrs[0]);78 testValue<1>(arrs[0]);79 testValue<2>(arrs[0]);80 }81 82 // test subrange83 {84 int i = 5;85 std::ranges::subrange<int*> srs[] = {{&i, &i}, {&i, &i}};86 testReference<0>(srs);87 testReference<1>(srs);88 testValue<0>(srs[0]);89 testValue<1>(srs[0]);90 }91 92 return true;93}94 95int main(int, char**) {96 test();97 static_assert(test());98 99 return 0;100}101