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 | // <regex> |
10 | |
11 | // template <class BidirectionalIterator> class sub_match; |
12 | |
13 | // Note in C++20 several of these operators have been removed and implicitly |
14 | // generated by the compiler using operator== and operator<=>. |
15 | |
16 | // template <class BiIter> |
17 | // bool |
18 | // operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
19 | // |
20 | // template <class BiIter> |
21 | // bool |
22 | // operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
23 | // |
24 | // template <class BiIter> |
25 | // bool |
26 | // operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
27 | // |
28 | // template <class BiIter> |
29 | // bool |
30 | // operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
31 | // |
32 | // template <class BiIter> |
33 | // bool |
34 | // operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
35 | // |
36 | // template <class BiIter> |
37 | // bool |
38 | // operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
39 | // |
40 | // template <class BiIter, class ST, class SA> |
41 | // bool |
42 | // operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
43 | // const sub_match<BiIter>& rhs); |
44 | // |
45 | // template <class BiIter, class ST, class SA> |
46 | // bool |
47 | // operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
48 | // const sub_match<BiIter>& rhs); |
49 | // |
50 | // template <class BiIter, class ST, class SA> |
51 | // bool |
52 | // operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
53 | // const sub_match<BiIter>& rhs); |
54 | // |
55 | // template <class BiIter, class ST, class SA> |
56 | // bool |
57 | // operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
58 | // const sub_match<BiIter>& rhs); |
59 | // |
60 | // template <class BiIter, class ST, class SA> |
61 | // bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
62 | // const sub_match<BiIter>& rhs); |
63 | // |
64 | // template <class BiIter, class ST, class SA> |
65 | // bool |
66 | // operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
67 | // const sub_match<BiIter>& rhs); |
68 | // |
69 | // template <class BiIter, class ST, class SA> |
70 | // bool |
71 | // operator==(const sub_match<BiIter>& lhs, |
72 | // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
73 | // |
74 | // template <class BiIter, class ST, class SA> |
75 | // bool |
76 | // operator!=(const sub_match<BiIter>& lhs, |
77 | // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
78 | // |
79 | // template <class BiIter, class ST, class SA> |
80 | // bool |
81 | // operator<(const sub_match<BiIter>& lhs, |
82 | // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
83 | // |
84 | // template <class BiIter, class ST, class SA> |
85 | // bool operator>(const sub_match<BiIter>& lhs, |
86 | // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
87 | // |
88 | // template <class BiIter, class ST, class SA> |
89 | // bool |
90 | // operator>=(const sub_match<BiIter>& lhs, |
91 | // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
92 | // |
93 | // template <class BiIter, class ST, class SA> |
94 | // bool |
95 | // operator<=(const sub_match<BiIter>& lhs, |
96 | // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
97 | // |
98 | // template <class BiIter> |
99 | // bool |
100 | // operator==(typename iterator_traits<BiIter>::value_type const* lhs, |
101 | // const sub_match<BiIter>& rhs); |
102 | // |
103 | // template <class BiIter> |
104 | // bool |
105 | // operator!=(typename iterator_traits<BiIter>::value_type const* lhs, |
106 | // const sub_match<BiIter>& rhs); |
107 | // |
108 | // template <class BiIter> |
109 | // bool |
110 | // operator<(typename iterator_traits<BiIter>::value_type const* lhs, |
111 | // const sub_match<BiIter>& rhs); |
112 | // |
113 | // template <class BiIter> |
114 | // bool |
115 | // operator>(typename iterator_traits<BiIter>::value_type const* lhs, |
116 | // const sub_match<BiIter>& rhs); |
117 | // |
118 | // template <class BiIter> |
119 | // bool |
120 | // operator>=(typename iterator_traits<BiIter>::value_type const* lhs, |
121 | // const sub_match<BiIter>& rhs); |
122 | // |
123 | // template <class BiIter> |
124 | // bool |
125 | // operator<=(typename iterator_traits<BiIter>::value_type const* lhs, |
126 | // const sub_match<BiIter>& rhs); |
127 | // |
128 | // template <class BiIter> |
129 | // bool |
130 | // operator==(const sub_match<BiIter>& lhs, |
131 | // typename iterator_traits<BiIter>::value_type const* rhs); |
132 | // |
133 | // template <class BiIter> |
134 | // bool |
135 | // operator!=(const sub_match<BiIter>& lhs, |
136 | // typename iterator_traits<BiIter>::value_type const* rhs); |
137 | // |
138 | // template <class BiIter> |
139 | // bool |
140 | // operator<(const sub_match<BiIter>& lhs, |
141 | // typename iterator_traits<BiIter>::value_type const* rhs); |
142 | // |
143 | // template <class BiIter> |
144 | // bool |
145 | // operator>(const sub_match<BiIter>& lhs, |
146 | // typename iterator_traits<BiIter>::value_type const* rhs); |
147 | // |
148 | // template <class BiIter> |
149 | // bool |
150 | // operator>=(const sub_match<BiIter>& lhs, |
151 | // typename iterator_traits<BiIter>::value_type const* rhs); |
152 | // |
153 | // template <class BiIter> |
154 | // bool |
155 | // operator<=(const sub_match<BiIter>& lhs, |
156 | // typename iterator_traits<BiIter>::value_type const* rhs); |
157 | // |
158 | // template <class BiIter> |
159 | // bool |
160 | // operator==(typename iterator_traits<BiIter>::value_type const& lhs, |
161 | // const sub_match<BiIter>& rhs); |
162 | // |
163 | // template <class BiIter> |
164 | // bool |
165 | // operator!=(typename iterator_traits<BiIter>::value_type const& lhs, |
166 | // const sub_match<BiIter>& rhs); |
167 | // |
168 | // template <class BiIter> |
169 | // bool |
170 | // operator<(typename iterator_traits<BiIter>::value_type const& lhs, |
171 | // const sub_match<BiIter>& rhs); |
172 | // |
173 | // template <class BiIter> |
174 | // bool |
175 | // operator>(typename iterator_traits<BiIter>::value_type const& lhs, |
176 | // const sub_match<BiIter>& rhs); |
177 | // |
178 | // template <class BiIter> |
179 | // bool |
180 | // operator>=(typename iterator_traits<BiIter>::value_type const& lhs, |
181 | // const sub_match<BiIter>& rhs); |
182 | // |
183 | // template <class BiIter> |
184 | // bool |
185 | // operator<=(typename iterator_traits<BiIter>::value_type const& lhs, |
186 | // const sub_match<BiIter>& rhs); |
187 | // |
188 | // template <class BiIter> |
189 | // bool |
190 | // operator==(const sub_match<BiIter>& lhs, |
191 | // typename iterator_traits<BiIter>::value_type const& rhs); |
192 | // |
193 | // template <class BiIter> |
194 | // bool |
195 | // operator!=(const sub_match<BiIter>& lhs, |
196 | // typename iterator_traits<BiIter>::value_type const& rhs); |
197 | // |
198 | // template <class BiIter> |
199 | // bool |
200 | // operator<(const sub_match<BiIter>& lhs, |
201 | // typename iterator_traits<BiIter>::value_type const& rhs); |
202 | // |
203 | // template <class BiIter> |
204 | // bool |
205 | // operator>(const sub_match<BiIter>& lhs, |
206 | // typename iterator_traits<BiIter>::value_type const& rhs); |
207 | // |
208 | // template <class BiIter> |
209 | // bool |
210 | // operator>=(const sub_match<BiIter>& lhs, |
211 | // typename iterator_traits<BiIter>::value_type const& rhs); |
212 | // |
213 | // template <class BiIter> |
214 | // bool |
215 | // operator<=(const sub_match<BiIter>& lhs, |
216 | // typename iterator_traits<BiIter>::value_type const& rhs); |
217 | |
218 | // Added in C++20 |
219 | // template <class BiIter> |
220 | // auto |
221 | // operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
222 | // template <class BiIter, class ST, class SA> |
223 | // auto |
224 | // operator<=>(const sub_match<BiIter>& lhs, |
225 | // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
226 | // |
227 | // template <class BiIter> |
228 | // auto |
229 | // operator<=>(const sub_match<BiIter>& lhs, |
230 | // typename iterator_traits<BiIter>::value_type const* rhs); |
231 | // |
232 | // template <class BiIter> |
233 | // auto |
234 | // operator<=>(const sub_match<BiIter>& lhs, |
235 | // typename iterator_traits<BiIter>::value_type const& rhs); |
236 | |
237 | #include <regex> |
238 | #include <array> |
239 | #include <cassert> |
240 | |
241 | #include "constexpr_char_traits.h" |
242 | #include "make_string.h" |
243 | #include "test_comparisons.h" |
244 | #include "test_macros.h" |
245 | |
246 | |
247 | #define SV(S) MAKE_STRING_VIEW(CharT, S) |
248 | |
249 | template <class CharT> |
250 | void |
251 | test(const std::basic_string<CharT>& x, const std::basic_string<CharT>& y, bool doCStrTests = true) |
252 | { |
253 | typedef std::basic_string<CharT> string; |
254 | typedef std::sub_match<typename string::const_iterator> sub_match; |
255 | #if TEST_STD_VER > 17 |
256 | AssertOrderReturn<std::strong_ordering, sub_match>(); |
257 | AssertOrderReturn<std::strong_ordering, sub_match, string>(); |
258 | #else |
259 | AssertComparisonsReturnBool<sub_match>(); |
260 | AssertComparisonsReturnBool<sub_match, string>(); |
261 | #endif |
262 | sub_match sm1; |
263 | sm1.first = x.begin(); |
264 | sm1.second = x.end(); |
265 | sm1.matched = true; |
266 | sub_match sm2; |
267 | sm2.first = y.begin(); |
268 | sm2.second = y.end(); |
269 | sm2.matched = true; |
270 | |
271 | assert(testComparisons(sm1, sm2, x == y, x < y)); |
272 | assert(testComparisons(x, sm2, x == y, x < y)); |
273 | assert(testComparisons(sm1, y, x == y, x < y)); |
274 | #if TEST_STD_VER > 17 |
275 | assert(testOrder(sm1, sm2, x <=> y)); |
276 | assert(testOrder(x, sm2, x <=> y)); |
277 | assert(testOrder(sm1, y, x <=> y)); |
278 | #endif |
279 | |
280 | if (doCStrTests) { |
281 | assert(testComparisons(x.c_str(), sm2, x == y, x < y)); |
282 | assert(testComparisons(sm1, y.c_str(), x == y, x < y)); |
283 | #if TEST_STD_VER > 17 |
284 | assert(testOrder(x.c_str(), sm2, x <=> y)); |
285 | assert(testOrder(sm1, y.c_str(), x <=> y)); |
286 | #endif |
287 | } |
288 | |
289 | assert(testComparisons(x[0], sm2, string(1, x[0]) == y, string(1, x[0]) < y)); |
290 | assert(testComparisons(sm1, y[0], x == string(1, y[0]), x < string(1, y[0]))); |
291 | #if TEST_STD_VER > 17 |
292 | assert(testOrder(x[0], sm2, (string(1, x[0]) <=> y))); |
293 | assert(testOrder(sm1, y[0], x <=> (string(1, y[0])))); |
294 | #endif |
295 | } |
296 | |
297 | #if TEST_STD_VER > 17 |
298 | template <class CharT, class Ordering> |
299 | struct char_traits : public constexpr_char_traits<CharT> { |
300 | using comparison_category = Ordering; |
301 | }; |
302 | |
303 | template <class T, class Ordering = std::strong_ordering> |
304 | constexpr void test() { |
305 | AssertOrderAreNoexcept<T>(); |
306 | AssertOrderReturn<Ordering, T>(); |
307 | |
308 | using CharT = typename T::value_type; |
309 | |
310 | // sorted values |
311 | std::array s = [] { |
312 | std::array input{SV("" ), SV("abc" ), SV("abcdef" )}; |
313 | return std::array{ |
314 | T{input[0].begin(), input[0].end()}, T{input[1].begin(), input[1].end()}, T{input[2].begin(), input[2].end()}}; |
315 | }(); |
316 | auto ctor = [](const T& string) { |
317 | std::sub_match<typename T::const_iterator> sm; |
318 | sm.first = string.begin(); |
319 | sm.second = string.end(); |
320 | sm.matched = true; |
321 | return sm; |
322 | }; |
323 | std::array sm{ctor(s[0]), ctor(s[1]), ctor(s[2])}; |
324 | |
325 | for (std::size_t i = 0; i < s.size(); ++i) { |
326 | for (std::size_t j = 0; j < s.size(); ++j) { |
327 | assert(testOrder(s[i], sm[j], i == j ? Ordering::equivalent : i < j ? Ordering::less : Ordering::greater)); |
328 | } |
329 | } |
330 | } |
331 | |
332 | template <class CharT> |
333 | constexpr void test_all_orderings() { |
334 | test<std::basic_string<CharT>>(); // Strong ordering in its char_traits |
335 | test<std::basic_string<CharT, constexpr_char_traits<CharT>>, |
336 | std::weak_ordering>(); // No ordering in its char_traits |
337 | test<std::basic_string<CharT, char_traits<CharT, std::weak_ordering>>, std::weak_ordering>(); |
338 | test<std::basic_string<CharT, char_traits<CharT, std::partial_ordering>>, std::partial_ordering>(); |
339 | } |
340 | #endif // TEST_STD_VER > 17 |
341 | |
342 | int main(int, char**) |
343 | { |
344 | test(x: std::string("123" ), y: std::string("123" )); |
345 | test(x: std::string("1234" ), y: std::string("123" )); |
346 | test(x: std::string("123\000" "56" , 6), y: std::string("123\000" "56" , 6), doCStrTests: false); |
347 | #if TEST_STD_VER > 17 |
348 | test_all_orderings<char>(); |
349 | #endif |
350 | |
351 | #ifndef TEST_HAS_NO_WIDE_CHARACTERS |
352 | test(x: std::wstring(L"123" ), y: std::wstring(L"123" )); |
353 | test(x: std::wstring(L"1234" ), y: std::wstring(L"123" )); |
354 | test(x: std::wstring(L"123\000" L"56" , 6), y: std::wstring(L"123\000" L"56" , 6), doCStrTests: false); |
355 | #if TEST_STD_VER > 17 |
356 | test_all_orderings<wchar_t>(); |
357 | #endif |
358 | #endif // TEST_HAS_NO_WIDE_CHARACTERS |
359 | |
360 | return 0; |
361 | } |
362 | |