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// This is a compile-only test, so "inline function is not defined" warnings are irrelevant.
12// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-undefined-inline
13
14// template<input_range V, forward_range Pattern>
15// requires view<V> && view<Pattern> &&
16// indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
17// (forward_range<V> || tiny-range<Pattern>)
18// class lazy_split_view;
19
20#include <functional>
21#include <ranges>
22
23#include "test_iterators.h"
24#include "types.h"
25
26struct ForwardRange {
27 forward_iterator<int*> begin() const;
28 forward_iterator<int*> end() const;
29};
30static_assert( std::ranges::forward_range<ForwardRange>);
31
32template <class View, class Pattern>
33concept CanInstantiate = requires {
34 typename std::ranges::lazy_split_view<View, Pattern>;
35};
36
37// All constraints satisfied (`View` and `Pattern` are forward views).
38namespace test1 {
39
40 using View = ForwardView;
41 using Pattern = ForwardView;
42 static_assert( std::ranges::forward_range<View>);
43 static_assert( std::ranges::forward_range<Pattern>);
44 static_assert( std::ranges::view<View>);
45 static_assert( std::ranges::view<Pattern>);
46 static_assert( std::indirectly_comparable<
47 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
48 static_assert( CanInstantiate<View, Pattern>);
49
50} // namespace test1
51
52// All constraints satisfied (`View` is an input view and `Pattern` is a tiny view).
53namespace test2 {
54
55 using View = InputView;
56 using Pattern = ForwardTinyView;
57 static_assert( std::ranges::input_range<View>);
58 static_assert( std::ranges::forward_range<Pattern>);
59 static_assert( std::ranges::view<View>);
60 static_assert( std::ranges::view<Pattern>);
61 static_assert( std::indirectly_comparable<
62 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
63 static_assert( CanInstantiate<View, Pattern>);
64
65} // namespace test2
66
67// `View` is not an input range.
68namespace test3 {
69
70 struct AlmostInputIterator {
71 using value_type = char;
72 using difference_type = std::ptrdiff_t;
73 using iterator_concept = int;
74
75 constexpr const char& operator*() const;
76 constexpr AlmostInputIterator& operator++();
77 constexpr void operator++(int);
78 constexpr bool operator==(const AlmostInputIterator&) const;
79 };
80
81 static_assert( std::input_or_output_iterator<AlmostInputIterator>);
82 static_assert(!std::input_iterator<AlmostInputIterator>);
83
84 struct NonInputView : std::ranges::view_base {
85 AlmostInputIterator begin() const;
86 AlmostInputIterator end() const;
87 };
88
89 using View = NonInputView;
90 using Pattern = ForwardTinyView;
91 static_assert(!std::ranges::input_range<View>);
92 static_assert( std::ranges::forward_range<Pattern>);
93 static_assert( std::ranges::view<View>);
94 static_assert( std::ranges::view<Pattern>);
95 static_assert( std::indirectly_comparable<
96 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
97 static_assert(!CanInstantiate<View, Pattern>);
98
99} // namespace test3
100
101// `View` is not a view.
102namespace test4 {
103
104 using View = ForwardRange;
105 using Pattern = ForwardView;
106 static_assert( std::ranges::input_range<View>);
107 static_assert( std::ranges::forward_range<Pattern>);
108 static_assert(!std::ranges::view<View>);
109 static_assert( std::ranges::view<Pattern>);
110 static_assert( std::indirectly_comparable<
111 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
112 static_assert(!CanInstantiate<View, Pattern>);
113
114} // namespace test4
115
116// `Pattern` is not a forward range.
117namespace test5 {
118
119 using View = ForwardView;
120 using Pattern = InputView;
121 static_assert( std::ranges::input_range<View>);
122 static_assert(!std::ranges::forward_range<Pattern>);
123 static_assert( std::ranges::view<View>);
124 static_assert( std::ranges::view<Pattern>);
125 static_assert( std::indirectly_comparable<
126 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
127 static_assert(!CanInstantiate<View, Pattern>);
128
129} // namespace test5
130
131// Not indirectly comparable.
132namespace test6 {
133
134 struct Empty{};
135 struct IntForwardView : std::ranges::view_base {
136 constexpr forward_iterator<Empty*> begin() const { return {}; }
137 constexpr forward_iterator<Empty*> end() const { return {}; }
138 };
139
140 using View = ForwardView;
141 using Pattern = IntForwardView;
142 static_assert( std::ranges::input_range<View>);
143 static_assert( std::ranges::forward_range<Pattern>);
144 static_assert( std::ranges::view<View>);
145 static_assert( std::ranges::view<Pattern>);
146 static_assert(!std::indirectly_comparable<
147 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
148 static_assert(!CanInstantiate<View, Pattern>);
149
150} // namespace test6
151
152// `View` is an input range and `Pattern` is not a tiny range.
153namespace test7 {
154
155 using View = InputView;
156 using Pattern = ForwardView;
157 static_assert( std::ranges::input_range<View>);
158 static_assert(!std::ranges::forward_range<View>);
159 static_assert( std::ranges::forward_range<Pattern>);
160 LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);
161 static_assert( std::ranges::view<View>);
162 static_assert( std::ranges::view<Pattern>);
163 static_assert( std::indirectly_comparable<
164 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
165 static_assert(!CanInstantiate<View, Pattern>);
166
167} // namespace test7
168
169// `View` is an input range and `Pattern` is almost a tiny range, except the `size()` function is not `constexpr`.
170namespace test8 {
171
172 struct AlmostTinyRange : std::ranges::view_base {
173 int* begin() const;
174 int* end() const;
175 static std::size_t size() { return 1; }
176 };
177
178 using View = InputView;
179 using Pattern = AlmostTinyRange;
180 static_assert( std::ranges::input_range<View>);
181 static_assert(!std::ranges::forward_range<View>);
182 static_assert( std::ranges::forward_range<Pattern>);
183 LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);
184 static_assert( std::ranges::view<View>);
185 static_assert( std::ranges::view<Pattern>);
186 static_assert( std::indirectly_comparable<
187 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
188 static_assert(!CanInstantiate<View, Pattern>);
189
190} // namespace test8
191
192// `View` is an input range and `Pattern` is almost a tiny range, except the `size()` returns a number `>2`.
193namespace test9 {
194
195 struct AlmostTinyRange : std::ranges::view_base {
196 int* begin() const;
197 int* end() const;
198 constexpr static std::size_t size() { return 2; }
199 };
200
201 using View = InputView;
202 using Pattern = ForwardView;
203 static_assert( std::ranges::input_range<View>);
204 static_assert(!std::ranges::forward_range<View>);
205 static_assert( std::ranges::forward_range<Pattern>);
206 LIBCPP_STATIC_ASSERT(!std::ranges::__tiny_range<Pattern>);
207 static_assert( std::ranges::view<View>);
208 static_assert( std::ranges::view<Pattern>);
209 static_assert( std::indirectly_comparable<
210 std::ranges::iterator_t<View>, std::ranges::iterator_t<Pattern>, std::ranges::equal_to>);
211 static_assert(!CanInstantiate<View, Pattern>);
212
213} // namespace test9
214

source code of libcxx/test/std/ranges/range.adaptors/range.lazy.split/constraints.compile.pass.cpp