xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.lazy.split/constraints.compile.pass.cpp (revision 64addd65210db59c8cb3794f792720e03e25b5af)
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 
26 struct ForwardRange {
27   forward_iterator<int*> begin() const;
28   forward_iterator<int*> end() const;
29 };
30 static_assert( std::ranges::forward_range<ForwardRange>);
31 
32 template <class View, class Pattern>
33 concept CanInstantiate = requires {
34   typename std::ranges::lazy_split_view<View, Pattern>;
35 };
36 
37 // All constraints satisfied (`View` and `Pattern` are forward views).
38 namespace 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).
53 namespace 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.
68 namespace 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.
102 namespace 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.
117 namespace 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.
132 namespace test6 {
133 
134   struct Empty{};
135   struct IntForwardView : std::ranges::view_base {
begintest6::IntForwardView136     constexpr forward_iterator<Empty*> begin() const { return {}; }
endtest6::IntForwardView137     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.
153 namespace 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`.
170 namespace test8 {
171 
172   struct AlmostTinyRange : std::ranges::view_base {
173     int* begin() const;
174     int* end() const;
sizetest8::AlmostTinyRange175     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`.
193 namespace test9 {
194 
195   struct AlmostTinyRange : std::ranges::view_base {
196     int* begin() const;
197     int* end() const;
sizetest9::AlmostTinyRange198     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