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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10
11 // constexpr auto begin();
12 // constexpr auto begin() const requires forward_range<View> && forward_range<const View>;
13
14 #include <ranges>
15
16 #include <cassert>
17 #include <utility>
18 #include "test_iterators.h"
19 #include "test_range.h"
20 #include "types.h"
21
22 template <class View>
23 concept ConstBeginDisabled = !requires (const View v) {
24 { (*v.begin()) };
25 };
26
test()27 constexpr bool test() {
28 // non-const: forward_range<View> && simple-view<View> -> outer-iterator<Const = true>
29 // const: forward_range<View> && forward_range<const View> -> outer-iterator<Const = true>
30 {
31 using V = ForwardView;
32 using P = V;
33
34 static_assert(std::ranges::forward_range<V>);
35 static_assert(std::ranges::forward_range<const V>);
36 static_assert(simple_view<V>);
37 static_assert(simple_view<P>);
38
39 {
40 std::ranges::lazy_split_view<V, P> v;
41 auto it = v.begin();
42 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
43 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
44 }
45
46 {
47 const std::ranges::lazy_split_view<V, P> cv;
48 auto it = cv.begin();
49 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
50 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
51 }
52 }
53
54 // non-const: forward_range<View> && !simple-view<View> -> outer-iterator<Const = false>
55 // const: forward_range<View> && forward_range<const View> -> outer-iterator<Const = true>
56 {
57 using V = ForwardDiffView;
58 using P = V;
59
60 static_assert(std::ranges::forward_range<V>);
61 static_assert(std::ranges::forward_range<const V>);
62 static_assert(!simple_view<V>);
63 static_assert(!simple_view<P>);
64
65 {
66 std::ranges::lazy_split_view<V, P> v;
67 auto it = v.begin();
68 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
69 static_assert(std::is_same_v<decltype(*(*it).begin()), char&>);
70 }
71
72 {
73 const std::ranges::lazy_split_view<V, P> cv;
74 auto it = cv.begin();
75 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
76 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
77 }
78 }
79
80 // non-const: forward_range<View> && !simple-view<View> -> outer-iterator<Const = false>
81 // const: forward_range<View> && !forward_range<const View> -> disabled
82 {
83 using V = ForwardOnlyIfNonConstView;
84 using P = V;
85 static_assert(std::ranges::forward_range<V>);
86 static_assert(!std::ranges::forward_range<const V>);
87 static_assert(!simple_view<V>);
88 static_assert(!simple_view<P>);
89
90 std::ranges::lazy_split_view<V, P> v;
91 auto it = v.begin();
92 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
93 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
94
95 static_assert(ConstBeginDisabled<decltype(v)>);
96 }
97
98 // non-const: forward_range<View> && simple-view<View> && !simple-view<Pattern> -> outer-iterator<Const = false>
99 // const: forward_range<View> && forward_range<const View> -> outer-iterator<Const = true>
100 {
101 using V = ForwardView;
102 using P = ForwardOnlyIfNonConstView;
103
104 static_assert(std::ranges::forward_range<V>);
105 static_assert(std::ranges::forward_range<const V>);
106 static_assert(simple_view<V>);
107 static_assert(!simple_view<P>);
108
109 {
110 std::ranges::lazy_split_view<V, P> v;
111 auto it = v.begin();
112 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
113 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
114 }
115
116 {
117 const std::ranges::lazy_split_view<V, P> cv;
118 auto it = cv.begin();
119 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
120 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
121 }
122 }
123
124 // non-const: !forward_range<View> && tiny-range<Pattern> -> outer-iterator<Const = false>
125 // const: !forward_range<View> -> disabled
126 {
127 using V = InputView;
128 using P = ForwardTinyView;
129
130 static_assert(!std::ranges::forward_range<V>);
131 static_assert(std::ranges::forward_range<P>);
132
133 std::ranges::lazy_split_view<V, P> v;
134 auto it = v.begin();
135 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::input_iterator_tag>);
136 static_assert(std::is_same_v<decltype(*(*it).begin()), char&>);
137
138 static_assert(ConstBeginDisabled<decltype(v)>);
139 }
140
141 return true;
142 }
143
main(int,char **)144 int main(int, char**) {
145 test();
146 static_assert(test());
147
148 return 0;
149 }
150