xref: /llvm-project/libcxx/test/std/re/re.submatch/re.submatch.op/compare.pass.cpp (revision a79a6ea4a831facc564a36911d79d4472ad93cec)
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