xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.lazy.split/end.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 end() requires forward_range<View> && common_range<View>;
12 // constexpr auto end() const;
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 struct ForwardViewCommonIfConst : std::ranges::view_base {
23   std::string_view view_;
24   constexpr explicit ForwardViewCommonIfConst() = default;
ForwardViewCommonIfConstForwardViewCommonIfConst25   constexpr ForwardViewCommonIfConst(const char* ptr) : view_(ptr) {}
ForwardViewCommonIfConstForwardViewCommonIfConst26   constexpr ForwardViewCommonIfConst(std::string_view v) : view_(v) {}
27   constexpr ForwardViewCommonIfConst(ForwardViewCommonIfConst&&) = default;
28   constexpr ForwardViewCommonIfConst& operator=(ForwardViewCommonIfConst&&) = default;
29   constexpr ForwardViewCommonIfConst(const ForwardViewCommonIfConst&) = default;
30   constexpr ForwardViewCommonIfConst& operator=(const ForwardViewCommonIfConst&) = default;
beginForwardViewCommonIfConst31   constexpr forward_iterator<char*> begin() { return forward_iterator<char*>(nullptr); }
endForwardViewCommonIfConst32   constexpr std::default_sentinel_t end()  { return std::default_sentinel; }
beginForwardViewCommonIfConst33   constexpr forward_iterator<std::string_view::const_iterator> begin() const { return forward_iterator<std::string_view::const_iterator>(view_.begin()); }
endForwardViewCommonIfConst34   constexpr forward_iterator<std::string_view::const_iterator> end() const { return forward_iterator<std::string_view::const_iterator>(view_.end()); }
35 };
operator ==(forward_iterator<char * >,std::default_sentinel_t)36 bool operator==(forward_iterator<char*>, std::default_sentinel_t) { return false; }
37 
38 struct ForwardViewNonCommonRange : std::ranges::view_base {
39   std::string_view view_;
40   constexpr explicit ForwardViewNonCommonRange() = default;
ForwardViewNonCommonRangeForwardViewNonCommonRange41   constexpr ForwardViewNonCommonRange(const char* ptr) : view_(ptr) {}
ForwardViewNonCommonRangeForwardViewNonCommonRange42   constexpr ForwardViewNonCommonRange(std::string_view v) : view_(v) {}
43   constexpr ForwardViewNonCommonRange(ForwardViewNonCommonRange&&) = default;
44   constexpr ForwardViewNonCommonRange& operator=(ForwardViewNonCommonRange&&) = default;
45   constexpr ForwardViewNonCommonRange(const ForwardViewNonCommonRange&) = default;
46   constexpr ForwardViewNonCommonRange& operator=(const ForwardViewNonCommonRange&) = default;
beginForwardViewNonCommonRange47   constexpr forward_iterator<char*> begin() { return forward_iterator<char*>(nullptr); }
endForwardViewNonCommonRange48   constexpr std::default_sentinel_t end()  { return std::default_sentinel; }
beginForwardViewNonCommonRange49   constexpr forward_iterator<std::string_view::const_iterator> begin() const { return forward_iterator<std::string_view::const_iterator>(view_.begin()); }
endForwardViewNonCommonRange50   constexpr std::default_sentinel_t end() const { return std::default_sentinel; }
51 };
operator ==(forward_iterator<std::string_view::const_iterator>,std::default_sentinel_t)52 bool operator==(forward_iterator<std::string_view::const_iterator>, std::default_sentinel_t) { return false; }
53 
test()54 constexpr bool test() {
55   // non-const: forward_range<V> && simple_view<V> && simple_view<P> -> outer-iterator<Const = true>
56   // const: forward_range<V> && common_range<V> -> outer-iterator<Const = true>
57   {
58     using V = ForwardView;
59     using P = V;
60 
61     static_assert(std::ranges::forward_range<V>);
62     static_assert(std::ranges::common_range<const V>);
63     static_assert(simple_view<V>);
64     static_assert(simple_view<P>);
65 
66     {
67       std::ranges::lazy_split_view<V, P> v;
68       auto it = v.end();
69       static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
70       static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
71     }
72 
73     {
74       const std::ranges::lazy_split_view<V, P> cv;
75       auto it = cv.end();
76       static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
77       static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
78     }
79   }
80 
81   // non-const: forward_range<V> && common_range<V> && simple_view<V> && !simple_view<P> -> outer-iterator<Const=false>
82   // const: forward_range<V> && forward_range<const V> && common_range<const V> -> outer-iterator<Const = false>
83   {
84     using V = ForwardView;
85     using P = ForwardDiffView;
86 
87     static_assert(std::ranges::forward_range<V>);
88     static_assert(std::ranges::common_range<V>);
89     static_assert(simple_view<V>);
90     static_assert(!simple_view<P>);
91     static_assert(std::ranges::forward_range<const V>);
92     static_assert(std::ranges::common_range<const V>);
93 
94     {
95       std::ranges::lazy_split_view<V, P> v;
96       auto it = v.end();
97       static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
98       static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
99     }
100 
101     {
102       const std::ranges::lazy_split_view<V, P> cv;
103       auto it = cv.end();
104       static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
105       static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
106     }
107   }
108 
109   // non-const: forward_range<V> && !common_range<V> -> disabled
110   // const: forward_range<V> && forward_range<const V> && common_range<const V> -> outer-iterator<Const = true>
111   {
112     using V = ForwardViewCommonIfConst;
113     using P = V;
114 
115     static_assert(std::ranges::forward_range<V>);
116     static_assert(!std::ranges::common_range<V>);
117     static_assert(std::ranges::forward_range<const V>);
118     static_assert(std::ranges::common_range<const V>);
119 
120     {
121       std::ranges::lazy_split_view<V, P> v;
122       auto it = v.begin();
123       static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
124       static_assert(std::is_same_v<decltype(*(*it).begin()), char&>);
125     }
126 
127     {
128       const std::ranges::lazy_split_view<V, P> cv;
129       auto it = cv.begin();
130       static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>);
131       static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>);
132     }
133   }
134 
135   // non-const: forward_range<V> && !common_range<V> -> disabled
136   // const: forward_range<V> && forward_range<const V> && !common_range<const V> -> outer-iterator<Const = false>
137   {
138     using V = ForwardViewNonCommonRange;
139     using P = V;
140 
141     static_assert(std::ranges::forward_range<V>);
142     static_assert(!std::ranges::common_range<V>);
143     static_assert(std::ranges::forward_range<const V>);
144     static_assert(!std::ranges::common_range<const V>);
145 
146     {
147       std::ranges::lazy_split_view<V, P> v;
148       auto it = v.end();
149       static_assert(std::same_as<decltype(it), std::default_sentinel_t>);
150     }
151 
152     {
153       const std::ranges::lazy_split_view<V, P> cv;
154       auto it = cv.end();
155       static_assert(std::same_as<decltype(it), std::default_sentinel_t>);
156     }
157   }
158 
159   return true;
160 }
161 
main(int,char **)162 int main(int, char**) {
163   test();
164   static_assert(test());
165 
166   return 0;
167 }
168