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
test(const std::basic_string<CharT> & x,const std::basic_string<CharT> & y,bool doCStrTests=true)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>
test()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>
test_all_orderings()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
main(int,char **)342 int main(int, char**)
343 {
344 test(std::string("123"), std::string("123"));
345 test(std::string("1234"), std::string("123"));
346 test(std::string("123\000" "56", 6), std::string("123\000" "56", 6), false);
347 #if TEST_STD_VER > 17
348 test_all_orderings<char>();
349 #endif
350
351 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
352 test(std::wstring(L"123"), std::wstring(L"123"));
353 test(std::wstring(L"1234"), std::wstring(L"123"));
354 test(std::wstring(L"123\000" L"56", 6), std::wstring(L"123\000" L"56", 6), 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