xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.lazy.split/begin.pass.cpp (revision e07a2f49e3d3c13b6e9b89e0f6118652f2b2d3ac)
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