xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/end.pass.cpp (revision 94461822c75d5080bf648f86552f7a59b76905c9)
1*94461822SHui Xie //===----------------------------------------------------------------------===//
2*94461822SHui Xie //
3*94461822SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*94461822SHui Xie // See https://llvm.org/LICENSE.txt for license information.
5*94461822SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*94461822SHui Xie //
7*94461822SHui Xie //===----------------------------------------------------------------------===//
8*94461822SHui Xie 
9*94461822SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17
10*94461822SHui Xie 
11*94461822SHui Xie // constexpr auto end() requires (!simple-view<V> && !common_range<V>)
12*94461822SHui Xie // constexpr auto end() requires (!simple-view<V> && common_range<V>)
13*94461822SHui Xie // constexpr auto end() const requires range<const V>
14*94461822SHui Xie // constexpr auto end() const requires common_range<const V>
15*94461822SHui Xie 
16*94461822SHui Xie #include <cassert>
17*94461822SHui Xie #include <iterator>
18*94461822SHui Xie #include <ranges>
19*94461822SHui Xie #include <type_traits>
20*94461822SHui Xie #include <utility>
21*94461822SHui Xie 
22*94461822SHui Xie #include "types.h"
23*94461822SHui Xie 
24*94461822SHui Xie // | simple | common |      v.end()     | as_const(v)
25*94461822SHui Xie // |        |        |                  |   .end()
26*94461822SHui Xie // |--------|--------|------------------|---------------
27*94461822SHui Xie // |   Y    |   Y    |  iterator<true>  | iterator<true>
28*94461822SHui Xie // |   Y    |   N    |  sentinel<true>  | sentinel<true>
29*94461822SHui Xie // |   N    |   Y    |  iterator<false> | iterator<true>
30*94461822SHui Xie // |   N    |   N    |  sentinel<false> | sentinel<true>
31*94461822SHui Xie 
32*94461822SHui Xie // !range<const V>
33*94461822SHui Xie template <class T>
34*94461822SHui Xie concept HasEnd = requires(T t) { t.end(); };
35*94461822SHui Xie 
36*94461822SHui Xie template <class T>
37*94461822SHui Xie concept HasConstEnd = requires(const T ct) { ct.end(); };
38*94461822SHui Xie 
39*94461822SHui Xie struct NoConstEndView : TupleBufferView {
40*94461822SHui Xie   using TupleBufferView::TupleBufferView;
beginNoConstEndView41*94461822SHui Xie   constexpr std::tuple<int>* begin() { return buffer_; }
endNoConstEndView42*94461822SHui Xie   constexpr std::tuple<int>* end() { return buffer_ + size_; }
43*94461822SHui Xie };
44*94461822SHui Xie 
45*94461822SHui Xie static_assert(HasEnd<std::ranges::elements_view<NoConstEndView, 0>>);
46*94461822SHui Xie static_assert(!HasConstEnd<std::ranges::elements_view<NoConstEndView, 0>>);
47*94461822SHui Xie 
test()48*94461822SHui Xie constexpr bool test() {
49*94461822SHui Xie   std::tuple<int> buffer[] = {{1}, {2}, {3}};
50*94461822SHui Xie 
51*94461822SHui Xie   // simple-view && common_view
52*94461822SHui Xie   {
53*94461822SHui Xie     SimpleCommon v{buffer};
54*94461822SHui Xie     auto ev = std::views::elements<0>(v);
55*94461822SHui Xie 
56*94461822SHui Xie     auto it           = ev.begin();
57*94461822SHui Xie     decltype(auto) st = ev.end();
58*94461822SHui Xie     assert(st == it + 3);
59*94461822SHui Xie 
60*94461822SHui Xie     auto const_it           = std::as_const(ev).begin();
61*94461822SHui Xie     decltype(auto) const_st = std::as_const(ev).end();
62*94461822SHui Xie     assert(const_st == const_it + 3);
63*94461822SHui Xie 
64*94461822SHui Xie     // Both iterator<true>
65*94461822SHui Xie     static_assert(std::same_as<decltype(st), decltype(const_st)>);
66*94461822SHui Xie     static_assert(std::same_as<decltype(st), decltype(it)>);
67*94461822SHui Xie     static_assert(std::same_as<decltype(const_st), decltype(const_it)>);
68*94461822SHui Xie   }
69*94461822SHui Xie 
70*94461822SHui Xie   // simple-view && !common_view
71*94461822SHui Xie   {
72*94461822SHui Xie     SimpleNonCommon v{buffer};
73*94461822SHui Xie     auto ev = std::views::elements<0>(v);
74*94461822SHui Xie 
75*94461822SHui Xie     auto it           = ev.begin();
76*94461822SHui Xie     decltype(auto) st = ev.end();
77*94461822SHui Xie     assert(st == it + 3);
78*94461822SHui Xie 
79*94461822SHui Xie     auto const_it           = std::as_const(ev).begin();
80*94461822SHui Xie     decltype(auto) const_st = std::as_const(ev).end();
81*94461822SHui Xie     assert(const_st == const_it + 3);
82*94461822SHui Xie 
83*94461822SHui Xie     // Both iterator<true>
84*94461822SHui Xie     static_assert(std::same_as<decltype(st), decltype(const_st)>);
85*94461822SHui Xie     static_assert(!std::same_as<decltype(st), decltype(it)>);
86*94461822SHui Xie     static_assert(!std::same_as<decltype(const_st), decltype(const_it)>);
87*94461822SHui Xie   }
88*94461822SHui Xie 
89*94461822SHui Xie   // !simple-view && common_view
90*94461822SHui Xie   {
91*94461822SHui Xie     NonSimpleCommon v{buffer};
92*94461822SHui Xie     auto ev = std::views::elements<0>(v);
93*94461822SHui Xie 
94*94461822SHui Xie     auto it           = ev.begin();
95*94461822SHui Xie     decltype(auto) st = ev.end();
96*94461822SHui Xie     assert(st == it + 3);
97*94461822SHui Xie 
98*94461822SHui Xie     auto const_it           = std::as_const(ev).begin();
99*94461822SHui Xie     decltype(auto) const_st = std::as_const(ev).end();
100*94461822SHui Xie     assert(const_st == const_it + 3);
101*94461822SHui Xie 
102*94461822SHui Xie     // iterator<false> and iterator<true>
103*94461822SHui Xie     static_assert(!std::same_as<decltype(st), decltype(const_st)>);
104*94461822SHui Xie     static_assert(std::same_as<decltype(st), decltype(it)>);
105*94461822SHui Xie     static_assert(std::same_as<decltype(const_st), decltype(const_it)>);
106*94461822SHui Xie   }
107*94461822SHui Xie 
108*94461822SHui Xie   // !simple-view && !common_view
109*94461822SHui Xie   {
110*94461822SHui Xie     NonSimpleNonCommon v{buffer};
111*94461822SHui Xie     auto ev = std::views::elements<0>(v);
112*94461822SHui Xie 
113*94461822SHui Xie     auto it           = ev.begin();
114*94461822SHui Xie     decltype(auto) st = ev.end();
115*94461822SHui Xie     assert(st == it + 3);
116*94461822SHui Xie 
117*94461822SHui Xie     auto const_it           = std::as_const(ev).begin();
118*94461822SHui Xie     decltype(auto) const_st = std::as_const(ev).end();
119*94461822SHui Xie     assert(const_st == const_it + 3);
120*94461822SHui Xie 
121*94461822SHui Xie     // sentinel<false> and sentinel<true>
122*94461822SHui Xie     static_assert(!std::same_as<decltype(st), decltype(const_st)>);
123*94461822SHui Xie     static_assert(!std::same_as<decltype(st), decltype(it)>);
124*94461822SHui Xie     static_assert(!std::same_as<decltype(const_st), decltype(const_it)>);
125*94461822SHui Xie   }
126*94461822SHui Xie 
127*94461822SHui Xie   // LWG 3406 elements_view::begin() and elements_view::end() have incompatible constraints
128*94461822SHui Xie   {
129*94461822SHui Xie     std::tuple<int, int> x[] = {{0, 0}};
130*94461822SHui Xie     std::ranges::subrange r  = {std::counted_iterator(x, 1), std::default_sentinel};
131*94461822SHui Xie     auto v                   = r | std::views::elements<0>;
132*94461822SHui Xie     assert(v.begin() != v.end());
133*94461822SHui Xie   }
134*94461822SHui Xie 
135*94461822SHui Xie   return true;
136*94461822SHui Xie }
137*94461822SHui Xie 
main(int,char **)138*94461822SHui Xie int main(int, char**) {
139*94461822SHui Xie   test();
140*94461822SHui Xie   static_assert(test());
141*94461822SHui Xie   return 0;
142*94461822SHui Xie }
143