143 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 auto end() requires (!simple-view<V> && !common_range<V>)12// constexpr auto end() requires (!simple-view<V> && common_range<V>)13// constexpr auto end() const requires range<const V>14// constexpr auto end() const requires common_range<const V>15 16#include <cassert>17#include <iterator>18#include <ranges>19#include <type_traits>20#include <utility>21 22#include "types.h"23 24// | simple | common | v.end() | as_const(v)25// | | | | .end()26// |--------|--------|------------------|---------------27// | Y | Y | iterator<true> | iterator<true>28// | Y | N | sentinel<true> | sentinel<true>29// | N | Y | iterator<false> | iterator<true>30// | N | N | sentinel<false> | sentinel<true>31 32// !range<const V>33template <class T>34concept HasEnd = requires(T t) { t.end(); };35 36template <class T>37concept HasConstEnd = requires(const T ct) { ct.end(); };38 39struct NoConstEndView : TupleBufferView {40 using TupleBufferView::TupleBufferView;41 constexpr std::tuple<int>* begin() { return buffer_; }42 constexpr std::tuple<int>* end() { return buffer_ + size_; }43};44 45static_assert(HasEnd<std::ranges::elements_view<NoConstEndView, 0>>);46static_assert(!HasConstEnd<std::ranges::elements_view<NoConstEndView, 0>>);47 48constexpr bool test() {49 std::tuple<int> buffer[] = {{1}, {2}, {3}};50 51 // simple-view && common_view52 {53 SimpleCommon v{buffer};54 auto ev = std::views::elements<0>(v);55 56 auto it = ev.begin();57 decltype(auto) st = ev.end();58 assert(st == it + 3);59 60 auto const_it = std::as_const(ev).begin();61 decltype(auto) const_st = std::as_const(ev).end();62 assert(const_st == const_it + 3);63 64 // Both iterator<true>65 static_assert(std::same_as<decltype(st), decltype(const_st)>);66 static_assert(std::same_as<decltype(st), decltype(it)>);67 static_assert(std::same_as<decltype(const_st), decltype(const_it)>);68 }69 70 // simple-view && !common_view71 {72 SimpleNonCommon v{buffer};73 auto ev = std::views::elements<0>(v);74 75 auto it = ev.begin();76 decltype(auto) st = ev.end();77 assert(st == it + 3);78 79 auto const_it = std::as_const(ev).begin();80 decltype(auto) const_st = std::as_const(ev).end();81 assert(const_st == const_it + 3);82 83 // Both iterator<true>84 static_assert(std::same_as<decltype(st), decltype(const_st)>);85 static_assert(!std::same_as<decltype(st), decltype(it)>);86 static_assert(!std::same_as<decltype(const_st), decltype(const_it)>);87 }88 89 // !simple-view && common_view90 {91 NonSimpleCommon v{buffer};92 auto ev = std::views::elements<0>(v);93 94 auto it = ev.begin();95 decltype(auto) st = ev.end();96 assert(st == it + 3);97 98 auto const_it = std::as_const(ev).begin();99 decltype(auto) const_st = std::as_const(ev).end();100 assert(const_st == const_it + 3);101 102 // iterator<false> and iterator<true>103 static_assert(!std::same_as<decltype(st), decltype(const_st)>);104 static_assert(std::same_as<decltype(st), decltype(it)>);105 static_assert(std::same_as<decltype(const_st), decltype(const_it)>);106 }107 108 // !simple-view && !common_view109 {110 NonSimpleNonCommon v{buffer};111 auto ev = std::views::elements<0>(v);112 113 auto it = ev.begin();114 decltype(auto) st = ev.end();115 assert(st == it + 3);116 117 auto const_it = std::as_const(ev).begin();118 decltype(auto) const_st = std::as_const(ev).end();119 assert(const_st == const_it + 3);120 121 // sentinel<false> and sentinel<true>122 static_assert(!std::same_as<decltype(st), decltype(const_st)>);123 static_assert(!std::same_as<decltype(st), decltype(it)>);124 static_assert(!std::same_as<decltype(const_st), decltype(const_it)>);125 }126 127 // LWG 3406 elements_view::begin() and elements_view::end() have incompatible constraints128 {129 std::tuple<int, int> x[] = {{0, 0}};130 std::ranges::subrange r = {std::counted_iterator(x, 1), std::default_sentinel};131 auto v = r | std::views::elements<0>;132 assert(v.begin() != v.end());133 }134 135 return true;136}137 138int main(int, char**) {139 test();140 static_assert(test());141 return 0;142}143