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
249template <class CharT>
250void
251test(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
298template <class CharT, class Ordering>
299struct char_traits : public constexpr_char_traits<CharT> {
300 using comparison_category = Ordering;
301};
302
303template <class T, class Ordering = std::strong_ordering>
304constexpr 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
332template <class CharT>
333constexpr 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
342int 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

source code of libcxx/test/std/re/re.submatch/re.submatch.op/compare.pass.cpp