brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · f88091f Raw
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