1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_REGEX
11#define _LIBCPP_REGEX
12
13/*
14 regex synopsis
15
16#include <compare>
17#include <initializer_list>
18
19namespace std
20{
21
22namespace regex_constants
23{
24
25enum syntax_option_type
26{
27 icase = unspecified,
28 nosubs = unspecified,
29 optimize = unspecified,
30 collate = unspecified,
31 ECMAScript = unspecified,
32 basic = unspecified,
33 extended = unspecified,
34 awk = unspecified,
35 grep = unspecified,
36 egrep = unspecified,
37 multiline = unspecified
38};
39
40constexpr syntax_option_type operator~(syntax_option_type f);
41constexpr syntax_option_type operator&(syntax_option_type lhs, syntax_option_type rhs);
42constexpr syntax_option_type operator|(syntax_option_type lhs, syntax_option_type rhs);
43
44enum match_flag_type
45{
46 match_default = 0,
47 match_not_bol = unspecified,
48 match_not_eol = unspecified,
49 match_not_bow = unspecified,
50 match_not_eow = unspecified,
51 match_any = unspecified,
52 match_not_null = unspecified,
53 match_continuous = unspecified,
54 match_prev_avail = unspecified,
55 format_default = 0,
56 format_sed = unspecified,
57 format_no_copy = unspecified,
58 format_first_only = unspecified
59};
60
61constexpr match_flag_type operator~(match_flag_type f);
62constexpr match_flag_type operator&(match_flag_type lhs, match_flag_type rhs);
63constexpr match_flag_type operator|(match_flag_type lhs, match_flag_type rhs);
64
65enum error_type
66{
67 error_collate = unspecified,
68 error_ctype = unspecified,
69 error_escape = unspecified,
70 error_backref = unspecified,
71 error_brack = unspecified,
72 error_paren = unspecified,
73 error_brace = unspecified,
74 error_badbrace = unspecified,
75 error_range = unspecified,
76 error_space = unspecified,
77 error_badrepeat = unspecified,
78 error_complexity = unspecified,
79 error_stack = unspecified
80};
81
82} // regex_constants
83
84class regex_error
85 : public runtime_error
86{
87public:
88 explicit regex_error(regex_constants::error_type ecode);
89 regex_constants::error_type code() const;
90};
91
92template <class charT>
93struct regex_traits
94{
95public:
96 typedef charT char_type;
97 typedef basic_string<char_type> string_type;
98 typedef locale locale_type;
99 typedef /bitmask_type/ char_class_type;
100
101 regex_traits();
102
103 static size_t length(const char_type* p);
104 charT translate(charT c) const;
105 charT translate_nocase(charT c) const;
106 template <class ForwardIterator>
107 string_type
108 transform(ForwardIterator first, ForwardIterator last) const;
109 template <class ForwardIterator>
110 string_type
111 transform_primary( ForwardIterator first, ForwardIterator last) const;
112 template <class ForwardIterator>
113 string_type
114 lookup_collatename(ForwardIterator first, ForwardIterator last) const;
115 template <class ForwardIterator>
116 char_class_type
117 lookup_classname(ForwardIterator first, ForwardIterator last,
118 bool icase = false) const;
119 bool isctype(charT c, char_class_type f) const;
120 int value(charT ch, int radix) const;
121 locale_type imbue(locale_type l);
122 locale_type getloc()const;
123};
124
125template <class charT, class traits = regex_traits<charT>>
126class basic_regex
127{
128public:
129 // types:
130 typedef charT value_type;
131 typedef traits traits_type;
132 typedef typename traits::string_type string_type;
133 typedef regex_constants::syntax_option_type flag_type;
134 typedef typename traits::locale_type locale_type;
135
136 // constants:
137 static constexpr regex_constants::syntax_option_type icase = regex_constants::icase;
138 static constexpr regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
139 static constexpr regex_constants::syntax_option_type optimize = regex_constants::optimize;
140 static constexpr regex_constants::syntax_option_type collate = regex_constants::collate;
141 static constexpr regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
142 static constexpr regex_constants::syntax_option_type basic = regex_constants::basic;
143 static constexpr regex_constants::syntax_option_type extended = regex_constants::extended;
144 static constexpr regex_constants::syntax_option_type awk = regex_constants::awk;
145 static constexpr regex_constants::syntax_option_type grep = regex_constants::grep;
146 static constexpr regex_constants::syntax_option_type egrep = regex_constants::egrep;
147 static constexpr regex_constants::syntax_option_type multiline = regex_constants::multiline;
148
149 // construct/copy/destroy:
150 basic_regex();
151 explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
152 basic_regex(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript);
153 basic_regex(const basic_regex&);
154 basic_regex(basic_regex&&) noexcept;
155 template <class ST, class SA>
156 explicit basic_regex(const basic_string<charT, ST, SA>& p,
157 flag_type f = regex_constants::ECMAScript);
158 template <class ForwardIterator>
159 basic_regex(ForwardIterator first, ForwardIterator last,
160 flag_type f = regex_constants::ECMAScript);
161 basic_regex(initializer_list<charT>, flag_type = regex_constants::ECMAScript);
162
163 ~basic_regex();
164
165 basic_regex& operator=(const basic_regex&);
166 basic_regex& operator=(basic_regex&&) noexcept;
167 basic_regex& operator=(const charT* ptr);
168 basic_regex& operator=(initializer_list<charT> il);
169 template <class ST, class SA>
170 basic_regex& operator=(const basic_string<charT, ST, SA>& p);
171
172 // assign:
173 basic_regex& assign(const basic_regex& that);
174 basic_regex& assign(basic_regex&& that) noexcept;
175 basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript);
176 basic_regex& assign(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript);
177 template <class string_traits, class A>
178 basic_regex& assign(const basic_string<charT, string_traits, A>& s,
179 flag_type f = regex_constants::ECMAScript);
180 template <class InputIterator>
181 basic_regex& assign(InputIterator first, InputIterator last,
182 flag_type f = regex_constants::ECMAScript);
183 basic_regex& assign(initializer_list<charT>, flag_type f = regex_constants::ECMAScript);
184
185 // const operations:
186 unsigned mark_count() const;
187 flag_type flags() const;
188
189 // locale:
190 locale_type imbue(locale_type loc);
191 locale_type getloc() const;
192
193 // swap:
194 void swap(basic_regex&);
195};
196
197template<class ForwardIterator>
198basic_regex(ForwardIterator, ForwardIterator,
199 regex_constants::syntax_option_type = regex_constants::ECMAScript)
200 -> basic_regex<typename iterator_traits<ForwardIterator>::value_type>; // C++17
201
202typedef basic_regex<char> regex;
203typedef basic_regex<wchar_t> wregex;
204
205template <class charT, class traits>
206 void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2);
207
208template <class BidirectionalIterator>
209class sub_match
210 : public pair<BidirectionalIterator, BidirectionalIterator>
211{
212public:
213 typedef typename iterator_traits<BidirectionalIterator>::value_type value_type;
214 typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;
215 typedef BidirectionalIterator iterator;
216 typedef basic_string<value_type> string_type;
217
218 bool matched;
219
220 constexpr sub_match();
221
222 difference_type length() const;
223 operator string_type() const;
224 string_type str() const;
225
226 int compare(const sub_match& s) const;
227 int compare(const string_type& s) const;
228 int compare(const value_type* s) const;
229
230 void swap(sub_match& s) noexcept(see below);
231};
232
233typedef sub_match<const char*> csub_match;
234typedef sub_match<const wchar_t*> wcsub_match;
235typedef sub_match<string::const_iterator> ssub_match;
236typedef sub_match<wstring::const_iterator> wssub_match;
237
238template <class BiIter>
239 bool
240 operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
241
242template <class BiIter>
243 auto
244 operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); // Since C++20
245
246 template <class BiIter> // Removed in C++20
247 bool
248 operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
249
250template <class BiIter> // Removed in C++20
251 bool
252 operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
253
254template <class BiIter> // Removed in C++20
255 bool
256 operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
257
258template <class BiIter> // Removed in C++20
259 bool
260 operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
261
262template <class BiIter> // Removed in C++20
263 bool
264 operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
265
266template <class BiIter, class ST, class SA> // Removed in C++20
267 bool
268 operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
269 const sub_match<BiIter>& rhs);
270
271template <class BiIter, class ST, class SA> // Removed in C++20
272 bool
273 operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
274 const sub_match<BiIter>& rhs);
275
276template <class BiIter, class ST, class SA> // Removed in C++20
277 bool
278 operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
279 const sub_match<BiIter>& rhs);
280
281template <class BiIter, class ST, class SA> // Removed in C++20
282 bool
283 operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
284 const sub_match<BiIter>& rhs);
285
286template <class BiIter, class ST, class SA> // Removed in C++20
287 bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
288 const sub_match<BiIter>& rhs);
289
290template <class BiIter, class ST, class SA> // Removed in C++20
291 bool
292 operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
293 const sub_match<BiIter>& rhs);
294
295template <class BiIter, class ST, class SA>
296 bool
297 operator==(const sub_match<BiIter>& lhs,
298 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
299
300template <class BiIter, class ST, class SA> // Since C++20
301 auto
302 operator<=>(const sub_match<BiIter>& lhs,
303 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
304
305template <class BiIter, class ST, class SA> // Removed in C++20
306 bool
307 operator!=(const sub_match<BiIter>& lhs,
308 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
309
310template <class BiIter, class ST, class SA> // Removed in C++20
311 bool
312 operator<(const sub_match<BiIter>& lhs,
313 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
314
315template <class BiIter, class ST, class SA> // Removed in C++20
316 bool
317 operator>(const sub_match<BiIter>& lhs,
318 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
319
320template <class BiIter, class ST, class SA> // Removed in C++20
321 bool
322 operator>=(const sub_match<BiIter>& lhs,
323 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
324
325template <class BiIter, class ST, class SA> // Removed in C++20
326 bool
327 operator<=(const sub_match<BiIter>& lhs,
328 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
329
330template <class BiIter> // Removed in C++20
331 bool
332 operator==(typename iterator_traits<BiIter>::value_type const* lhs,
333 const sub_match<BiIter>& rhs);
334
335template <class BiIter> // Removed in C++20
336 bool
337 operator!=(typename iterator_traits<BiIter>::value_type const* lhs,
338 const sub_match<BiIter>& rhs);
339
340template <class BiIter> // Removed in C++20
341 bool
342 operator<(typename iterator_traits<BiIter>::value_type const* lhs,
343 const sub_match<BiIter>& rhs);
344
345template <class BiIter> // Removed in C++20
346 bool
347 operator>(typename iterator_traits<BiIter>::value_type const* lhs,
348 const sub_match<BiIter>& rhs);
349
350template <class BiIter> // Removed in C++20
351 bool
352 operator>=(typename iterator_traits<BiIter>::value_type const* lhs,
353 const sub_match<BiIter>& rhs);
354
355template <class BiIter> // Removed in C++20
356 bool
357 operator<=(typename iterator_traits<BiIter>::value_type const* lhs,
358 const sub_match<BiIter>& rhs);
359
360template <class BiIter>
361 bool
362 operator==(const sub_match<BiIter>& lhs,
363 typename iterator_traits<BiIter>::value_type const* rhs);
364
365template <class BiIter> // Since C++20
366 auto
367 operator<=>(const sub_match<BiIter>& lhs,
368 typename iterator_traits<BiIter>::value_type const* rhs);
369
370template <class BiIter, class ST, class SA> // Removed in C++20
371 bool
372 operator!=(const sub_match<BiIter>& lhs,
373 typename iterator_traits<BiIter>::value_type const* rhs);
374
375template <class BiIter> // Removed in C++20
376 bool
377 operator<(const sub_match<BiIter>& lhs,
378 typename iterator_traits<BiIter>::value_type const* rhs);
379
380template <class BiIter> // Removed in C++20
381 bool
382 operator>(const sub_match<BiIter>& lhs,
383 typename iterator_traits<BiIter>::value_type const* rhs);
384
385template <class BiIter> // Removed in C++20
386 bool
387 operator>=(const sub_match<BiIter>& lhs,
388 typename iterator_traits<BiIter>::value_type const* rhs);
389
390template <class BiIter> // Removed in C++20
391 bool
392 operator<=(const sub_match<BiIter>& lhs,
393 typename iterator_traits<BiIter>::value_type const* rhs);
394
395template <class BiIter> // Removed in C++20
396 bool
397 operator==(typename iterator_traits<BiIter>::value_type const& lhs,
398 const sub_match<BiIter>& rhs);
399
400template <class BiIter> // Removed in C++20
401 bool
402 operator!=(typename iterator_traits<BiIter>::value_type const& lhs,
403 const sub_match<BiIter>& rhs);
404
405template <class BiIter> // Removed in C++20
406 bool
407 operator<(typename iterator_traits<BiIter>::value_type const& lhs,
408 const sub_match<BiIter>& rhs);
409
410template <class BiIter> // Removed in C++20
411 bool
412 operator>(typename iterator_traits<BiIter>::value_type const& lhs,
413 const sub_match<BiIter>& rhs);
414
415template <class BiIter> // Removed in C++20
416 bool
417 operator>=(typename iterator_traits<BiIter>::value_type const& lhs,
418 const sub_match<BiIter>& rhs);
419
420template <class BiIter> // Removed in C++20
421 bool
422 operator<=(typename iterator_traits<BiIter>::value_type const& lhs,
423 const sub_match<BiIter>& rhs);
424
425template <class BiIter>
426 bool
427 operator==(const sub_match<BiIter>& lhs,
428 typename iterator_traits<BiIter>::value_type const& rhs);
429
430template <class BiIter> // Since C++20
431 auto
432 operator<=>(const sub_match<BiIter>& lhs,
433 typename iterator_traits<BiIter>::value_type const& rhs);
434
435template <class BiIter> // Removed in C++20
436 bool
437 operator!=(const sub_match<BiIter>& lhs,
438 typename iterator_traits<BiIter>::value_type const& rhs);
439
440template <class BiIter> // Removed in C++20
441 bool
442 operator<(const sub_match<BiIter>& lhs,
443 typename iterator_traits<BiIter>::value_type const& rhs);
444
445template <class BiIter> // Removed in C++20
446 bool
447 operator>(const sub_match<BiIter>& lhs,
448 typename iterator_traits<BiIter>::value_type const& rhs);
449
450template <class BiIter> // Removed in C++20
451 bool
452 operator>=(const sub_match<BiIter>& lhs,
453 typename iterator_traits<BiIter>::value_type const& rhs);
454
455template <class BiIter> // Removed in C++20
456 bool
457 operator<=(const sub_match<BiIter>& lhs,
458 typename iterator_traits<BiIter>::value_type const& rhs);
459
460template <class charT, class ST, class BiIter>
461 basic_ostream<charT, ST>&
462 operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);
463
464template <class BidirectionalIterator,
465 class Allocator = allocator<sub_match<BidirectionalIterator>>>
466class match_results
467{
468public:
469 typedef sub_match<BidirectionalIterator> value_type;
470 typedef const value_type& const_reference;
471 typedef value_type& reference;
472 typedef /implementation-defined/ const_iterator;
473 typedef const_iterator iterator;
474 typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;
475 typedef typename allocator_traits<Allocator>::size_type size_type;
476 typedef Allocator allocator_type;
477 typedef typename iterator_traits<BidirectionalIterator>::value_type char_type;
478 typedef basic_string<char_type> string_type;
479
480 // construct/copy/destroy:
481 explicit match_results(const Allocator& a = Allocator()); // before C++20
482 match_results() : match_results(Allocator()) {} // C++20
483 explicit match_results(const Allocator& a); // C++20
484 match_results(const match_results& m);
485 match_results(match_results&& m) noexcept;
486 match_results& operator=(const match_results& m);
487 match_results& operator=(match_results&& m);
488 ~match_results();
489
490 bool ready() const;
491
492 // size:
493 size_type size() const;
494 size_type max_size() const;
495 bool empty() const;
496
497 // element access:
498 difference_type length(size_type sub = 0) const;
499 difference_type position(size_type sub = 0) const;
500 string_type str(size_type sub = 0) const;
501 const_reference operator[](size_type n) const;
502
503 const_reference prefix() const;
504 const_reference suffix() const;
505
506 const_iterator begin() const;
507 const_iterator end() const;
508 const_iterator cbegin() const;
509 const_iterator cend() const;
510
511 // format:
512 template <class OutputIter>
513 OutputIter
514 format(OutputIter out, const char_type* fmt_first,
515 const char_type* fmt_last,
516 regex_constants::match_flag_type flags = regex_constants::format_default) const;
517 template <class OutputIter, class ST, class SA>
518 OutputIter
519 format(OutputIter out, const basic_string<char_type, ST, SA>& fmt,
520 regex_constants::match_flag_type flags = regex_constants::format_default) const;
521 template <class ST, class SA>
522 basic_string<char_type, ST, SA>
523 format(const basic_string<char_type, ST, SA>& fmt,
524 regex_constants::match_flag_type flags = regex_constants::format_default) const;
525 string_type
526 format(const char_type* fmt,
527 regex_constants::match_flag_type flags = regex_constants::format_default) const;
528
529 // allocator:
530 allocator_type get_allocator() const;
531
532 // swap:
533 void swap(match_results& that);
534};
535
536typedef match_results<const char*> cmatch;
537typedef match_results<const wchar_t*> wcmatch;
538typedef match_results<string::const_iterator> smatch;
539typedef match_results<wstring::const_iterator> wsmatch;
540
541template <class BidirectionalIterator, class Allocator>
542 bool
543 operator==(const match_results<BidirectionalIterator, Allocator>& m1,
544 const match_results<BidirectionalIterator, Allocator>& m2);
545
546template <class BidirectionalIterator, class Allocator> // Removed in C++20
547 bool
548 operator!=(const match_results<BidirectionalIterator, Allocator>& m1,
549 const match_results<BidirectionalIterator, Allocator>& m2);
550
551template <class BidirectionalIterator, class Allocator>
552 void
553 swap(match_results<BidirectionalIterator, Allocator>& m1,
554 match_results<BidirectionalIterator, Allocator>& m2);
555
556template <class BidirectionalIterator, class Allocator, class charT, class traits>
557 bool
558 regex_match(BidirectionalIterator first, BidirectionalIterator last,
559 match_results<BidirectionalIterator, Allocator>& m,
560 const basic_regex<charT, traits>& e,
561 regex_constants::match_flag_type flags = regex_constants::match_default);
562
563template <class BidirectionalIterator, class charT, class traits>
564 bool
565 regex_match(BidirectionalIterator first, BidirectionalIterator last,
566 const basic_regex<charT, traits>& e,
567 regex_constants::match_flag_type flags = regex_constants::match_default);
568
569template <class charT, class Allocator, class traits>
570 bool
571 regex_match(const charT* str, match_results<const charT*, Allocator>& m,
572 const basic_regex<charT, traits>& e,
573 regex_constants::match_flag_type flags = regex_constants::match_default);
574
575template <class ST, class SA, class Allocator, class charT, class traits>
576 bool
577 regex_match(const basic_string<charT, ST, SA>& s,
578 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
579 const basic_regex<charT, traits>& e,
580 regex_constants::match_flag_type flags = regex_constants::match_default);
581
582template <class ST, class SA, class Allocator, class charT, class traits>
583 bool
584 regex_match(const basic_string<charT, ST, SA>&& s,
585 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
586 const basic_regex<charT, traits>& e,
587 regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14
588
589template <class charT, class traits>
590 bool
591 regex_match(const charT* str, const basic_regex<charT, traits>& e,
592 regex_constants::match_flag_type flags = regex_constants::match_default);
593
594template <class ST, class SA, class charT, class traits>
595 bool
596 regex_match(const basic_string<charT, ST, SA>& s,
597 const basic_regex<charT, traits>& e,
598 regex_constants::match_flag_type flags = regex_constants::match_default);
599
600template <class BidirectionalIterator, class Allocator, class charT, class traits>
601 bool
602 regex_search(BidirectionalIterator first, BidirectionalIterator last,
603 match_results<BidirectionalIterator, Allocator>& m,
604 const basic_regex<charT, traits>& e,
605 regex_constants::match_flag_type flags = regex_constants::match_default);
606
607template <class BidirectionalIterator, class charT, class traits>
608 bool
609 regex_search(BidirectionalIterator first, BidirectionalIterator last,
610 const basic_regex<charT, traits>& e,
611 regex_constants::match_flag_type flags = regex_constants::match_default);
612
613template <class charT, class Allocator, class traits>
614 bool
615 regex_search(const charT* str, match_results<const charT*, Allocator>& m,
616 const basic_regex<charT, traits>& e,
617 regex_constants::match_flag_type flags = regex_constants::match_default);
618
619template <class charT, class traits>
620 bool
621 regex_search(const charT* str, const basic_regex<charT, traits>& e,
622 regex_constants::match_flag_type flags = regex_constants::match_default);
623
624template <class ST, class SA, class charT, class traits>
625 bool
626 regex_search(const basic_string<charT, ST, SA>& s,
627 const basic_regex<charT, traits>& e,
628 regex_constants::match_flag_type flags = regex_constants::match_default);
629
630template <class ST, class SA, class Allocator, class charT, class traits>
631 bool
632 regex_search(const basic_string<charT, ST, SA>& s,
633 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
634 const basic_regex<charT, traits>& e,
635 regex_constants::match_flag_type flags = regex_constants::match_default);
636
637template <class ST, class SA, class Allocator, class charT, class traits>
638 bool
639 regex_search(const basic_string<charT, ST, SA>&& s,
640 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
641 const basic_regex<charT, traits>& e,
642 regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14
643
644template <class OutputIterator, class BidirectionalIterator,
645 class traits, class charT, class ST, class SA>
646 OutputIterator
647 regex_replace(OutputIterator out,
648 BidirectionalIterator first, BidirectionalIterator last,
649 const basic_regex<charT, traits>& e,
650 const basic_string<charT, ST, SA>& fmt,
651 regex_constants::match_flag_type flags = regex_constants::match_default);
652
653template <class OutputIterator, class BidirectionalIterator,
654 class traits, class charT>
655 OutputIterator
656 regex_replace(OutputIterator out,
657 BidirectionalIterator first, BidirectionalIterator last,
658 const basic_regex<charT, traits>& e, const charT* fmt,
659 regex_constants::match_flag_type flags = regex_constants::match_default);
660
661template <class traits, class charT, class ST, class SA, class FST, class FSA>
662 basic_string<charT, ST, SA>
663 regex_replace(const basic_string<charT, ST, SA>& s,
664 const basic_regex<charT, traits>& e,
665 const basic_string<charT, FST, FSA>& fmt,
666 regex_constants::match_flag_type flags = regex_constants::match_default);
667
668template <class traits, class charT, class ST, class SA>
669 basic_string<charT, ST, SA>
670 regex_replace(const basic_string<charT, ST, SA>& s,
671 const basic_regex<charT, traits>& e, const charT* fmt,
672 regex_constants::match_flag_type flags = regex_constants::match_default);
673
674template <class traits, class charT, class ST, class SA>
675 basic_string<charT>
676 regex_replace(const charT* s,
677 const basic_regex<charT, traits>& e,
678 const basic_string<charT, ST, SA>& fmt,
679 regex_constants::match_flag_type flags = regex_constants::match_default);
680
681template <class traits, class charT>
682 basic_string<charT>
683 regex_replace(const charT* s,
684 const basic_regex<charT, traits>& e,
685 const charT* fmt,
686 regex_constants::match_flag_type flags = regex_constants::match_default);
687
688template <class BidirectionalIterator,
689 class charT = typename iterator_traits< BidirectionalIterator>::value_type,
690 class traits = regex_traits<charT>>
691class regex_iterator
692{
693public:
694 typedef basic_regex<charT, traits> regex_type;
695 typedef match_results<BidirectionalIterator> value_type;
696 typedef ptrdiff_t difference_type;
697 typedef const value_type* pointer;
698 typedef const value_type& reference;
699 typedef forward_iterator_tag iterator_category;
700 typedef input_iterator_tag iterator_concept; // since C++20
701
702 regex_iterator();
703 regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
704 const regex_type& re,
705 regex_constants::match_flag_type m = regex_constants::match_default);
706 regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
707 const regex_type&& re,
708 regex_constants::match_flag_type m
709 = regex_constants::match_default) = delete; // C++14
710 regex_iterator(const regex_iterator&);
711 regex_iterator& operator=(const regex_iterator&);
712
713 bool operator==(const regex_iterator&) const;
714 bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } // since C++20
715 bool operator!=(const regex_iterator&) const; // Removed in C++20
716
717 const value_type& operator*() const;
718 const value_type* operator->() const;
719
720 regex_iterator& operator++();
721 regex_iterator operator++(int);
722};
723
724typedef regex_iterator<const char*> cregex_iterator;
725typedef regex_iterator<const wchar_t*> wcregex_iterator;
726typedef regex_iterator<string::const_iterator> sregex_iterator;
727typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
728
729template <class BidirectionalIterator,
730 class charT = typename iterator_traits<BidirectionalIterator>::value_type,
731 class traits = regex_traits<charT>>
732class regex_token_iterator
733{
734public:
735 typedef basic_regex<charT, traits> regex_type;
736 typedef sub_match<BidirectionalIterator> value_type;
737 typedef ptrdiff_t difference_type;
738 typedef const value_type* pointer;
739 typedef const value_type& reference;
740 typedef forward_iterator_tag iterator_category;
741 typedef input_iterator_tag iterator_concept; // since C++20
742
743 regex_token_iterator();
744 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
745 const regex_type& re, int submatch = 0,
746 regex_constants::match_flag_type m = regex_constants::match_default);
747 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
748 const regex_type&& re, int submatch = 0,
749 regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
750 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
751 const regex_type& re, const vector<int>& submatches,
752 regex_constants::match_flag_type m = regex_constants::match_default);
753 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
754 const regex_type&& re, const vector<int>& submatches,
755 regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
756 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
757 const regex_type& re, initializer_list<int> submatches,
758 regex_constants::match_flag_type m = regex_constants::match_default);
759 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
760 const regex_type&& re, initializer_list<int> submatches,
761 regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
762 template <size_t N>
763 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
764 const regex_type& re, const int (&submatches)[N],
765 regex_constants::match_flag_type m = regex_constants::match_default);
766 template <size_t N>
767 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
768 const regex_type&& re, const int (&submatches)[N],
769 regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
770 regex_token_iterator(const regex_token_iterator&);
771 regex_token_iterator& operator=(const regex_token_iterator&);
772
773 bool operator==(const regex_token_iterator&) const;
774 bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } // since C++20
775 bool operator!=(const regex_token_iterator&) const; // Removed in C++20
776
777 const value_type& operator*() const;
778 const value_type* operator->() const;
779
780 regex_token_iterator& operator++();
781 regex_token_iterator operator++(int);
782};
783
784typedef regex_token_iterator<const char*> cregex_token_iterator;
785typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
786typedef regex_token_iterator<string::const_iterator> sregex_token_iterator;
787typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
788
789} // std
790*/
791
792#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
793# include <__cxx03/regex>
794#else
795# include <__config>
796
797// standard-mandated includes
798
799// [iterator.range]
800# include <__iterator/access.h>
801# include <__iterator/data.h>
802# include <__iterator/empty.h>
803# include <__iterator/reverse_access.h>
804# include <__iterator/size.h>
805
806// [re.syn]
807# include <compare>
808# include <initializer_list>
809
810# if _LIBCPP_HAS_LOCALIZATION
811
812# include <__algorithm/find.h>
813# include <__algorithm/search.h>
814# include <__assert>
815# include <__iterator/back_insert_iterator.h>
816# include <__iterator/default_sentinel.h>
817# include <__iterator/wrap_iter.h>
818# include <__locale_dir/collate.h>
819# include <__locale_dir/ctype.h>
820# include <__locale_dir/ctype_base.h>
821# include <__locale_dir/locale.h>
822# include <__memory/addressof.h>
823# include <__memory/pointer_traits.h>
824# include <__memory/shared_ptr.h>
825# include <__memory_resource/polymorphic_allocator.h>
826# include <__type_traits/is_swappable.h>
827# include <__utility/move.h>
828# include <__utility/pair.h>
829# include <__utility/swap.h>
830# include <__verbose_abort>
831# include <deque>
832# include <stdexcept>
833# include <string>
834# include <vector>
835# include <version>
836
837# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
838# pragma GCC system_header
839# endif
840
841_LIBCPP_PUSH_MACROS
842# include <__undef_macros>
843
844# define _LIBCPP_REGEX_COMPLEXITY_FACTOR 4096
845
846_LIBCPP_BEGIN_NAMESPACE_STD
847_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
848
849namespace regex_constants {
850
851// syntax_option_type
852
853enum syntax_option_type {
854 icase = 1 << 0,
855 nosubs = 1 << 1,
856 optimize = 1 << 2,
857 collate = 1 << 3,
858# ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
859 ECMAScript = 1 << 9,
860# else
861 ECMAScript = 0,
862# endif
863 basic = 1 << 4,
864 extended = 1 << 5,
865 awk = 1 << 6,
866 grep = 1 << 7,
867 egrep = 1 << 8,
868 // 1 << 9 may be used by ECMAScript
869 multiline = 1 << 10
870};
871
872_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR syntax_option_type __get_grammar(syntax_option_type __g) {
873# ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
874 return static_cast<syntax_option_type>(__g & 0x3F0);
875# else
876 return static_cast<syntax_option_type>(__g & 0x1F0);
877# endif
878}
879
880inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type operator~(syntax_option_type __x) {
881 return syntax_option_type(~int(__x) & 0x1FF);
882}
883
884inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
885operator&(syntax_option_type __x, syntax_option_type __y) {
886 return syntax_option_type(int(__x) & int(__y));
887}
888
889inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
890operator|(syntax_option_type __x, syntax_option_type __y) {
891 return syntax_option_type(int(__x) | int(__y));
892}
893
894inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
895operator^(syntax_option_type __x, syntax_option_type __y) {
896 return syntax_option_type(int(__x) ^ int(__y));
897}
898
899inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator&=(syntax_option_type& __x, syntax_option_type __y) {
900 __x = __x & __y;
901 return __x;
902}
903
904inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator|=(syntax_option_type& __x, syntax_option_type __y) {
905 __x = __x | __y;
906 return __x;
907}
908
909inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator^=(syntax_option_type& __x, syntax_option_type __y) {
910 __x = __x ^ __y;
911 return __x;
912}
913
914// match_flag_type
915
916enum match_flag_type {
917 match_default = 0,
918 match_not_bol = 1 << 0,
919 match_not_eol = 1 << 1,
920 match_not_bow = 1 << 2,
921 match_not_eow = 1 << 3,
922 match_any = 1 << 4,
923 match_not_null = 1 << 5,
924 match_continuous = 1 << 6,
925 match_prev_avail = 1 << 7,
926 format_default = 0,
927 format_sed = 1 << 8,
928 format_no_copy = 1 << 9,
929 format_first_only = 1 << 10,
930 __no_update_pos = 1 << 11,
931 __full_match = 1 << 12
932};
933
934inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator~(match_flag_type __x) {
935 return match_flag_type(~int(__x) & 0x0FFF);
936}
937
938inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator&(match_flag_type __x, match_flag_type __y) {
939 return match_flag_type(int(__x) & int(__y));
940}
941
942inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator|(match_flag_type __x, match_flag_type __y) {
943 return match_flag_type(int(__x) | int(__y));
944}
945
946inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator^(match_flag_type __x, match_flag_type __y) {
947 return match_flag_type(int(__x) ^ int(__y));
948}
949
950inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator&=(match_flag_type& __x, match_flag_type __y) {
951 __x = __x & __y;
952 return __x;
953}
954
955inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator|=(match_flag_type& __x, match_flag_type __y) {
956 __x = __x | __y;
957 return __x;
958}
959
960inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator^=(match_flag_type& __x, match_flag_type __y) {
961 __x = __x ^ __y;
962 return __x;
963}
964
965enum error_type {
966 error_collate = 1,
967 error_ctype,
968 error_escape,
969 error_backref,
970 error_brack,
971 error_paren,
972 error_brace,
973 error_badbrace,
974 error_range,
975 error_space,
976 error_badrepeat,
977 error_complexity,
978 error_stack,
979 __re_err_grammar,
980 __re_err_empty,
981 __re_err_unknown,
982 __re_err_parse
983};
984
985} // namespace regex_constants
986
987class _LIBCPP_EXPORTED_FROM_ABI regex_error : public runtime_error {
988 regex_constants::error_type __code_;
989
990public:
991 explicit regex_error(regex_constants::error_type __ecode);
992 _LIBCPP_HIDE_FROM_ABI regex_error(const regex_error&) _NOEXCEPT = default;
993 ~regex_error() _NOEXCEPT override;
994 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI regex_constants::error_type code() const { return __code_; }
995};
996
997template <regex_constants::error_type _Ev>
998[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_regex_error() {
999# if _LIBCPP_HAS_EXCEPTIONS
1000 throw regex_error(_Ev);
1001# else
1002 _LIBCPP_VERBOSE_ABORT("regex_error was thrown in -fno-exceptions mode");
1003# endif
1004}
1005
1006template <class _CharT>
1007struct regex_traits {
1008public:
1009 typedef _CharT char_type;
1010 typedef basic_string<char_type> string_type;
1011 typedef locale locale_type;
1012# if defined(__BIONIC__) || _LIBCPP_LIBC_NEWLIB
1013 // Originally bionic's ctype_base used its own ctype masks because the
1014 // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask
1015 // was only 8 bits wide and already saturated, so it used a wider type here
1016 // to make room for __regex_word (then a part of this class rather than
1017 // ctype_base). Bionic has since moved to the builtin ctype_base
1018 // implementation, but this was not updated to match. Since then Android has
1019 // needed to maintain a stable libc++ ABI, and this can't be changed without
1020 // an ABI break.
1021 // We also need this workaround for newlib since newlib is
1022 // often used for space constrained environments, so it makes sense not to
1023 // duplicate the ctype table.
1024 typedef uint16_t char_class_type;
1025# else
1026 typedef ctype_base::mask char_class_type;
1027# endif
1028
1029 static const char_class_type __regex_word = ctype_base::__regex_word;
1030
1031private:
1032 locale __loc_;
1033 const ctype<char_type>* __ct_;
1034 const collate<char_type>* __col_;
1035
1036public:
1037 regex_traits();
1038
1039 _LIBCPP_HIDE_FROM_ABI static size_t length(const char_type* __p) { return char_traits<char_type>::length(__p); }
1040 _LIBCPP_HIDE_FROM_ABI char_type translate(char_type __c) const { return __c; }
1041 char_type translate_nocase(char_type __c) const;
1042 template <class _ForwardIterator>
1043 string_type transform(_ForwardIterator __f, _ForwardIterator __l) const;
1044 template <class _ForwardIterator>
1045 _LIBCPP_HIDE_FROM_ABI string_type transform_primary(_ForwardIterator __f, _ForwardIterator __l) const {
1046 return __transform_primary(__f, __l, char_type());
1047 }
1048 template <class _ForwardIterator>
1049 _LIBCPP_HIDE_FROM_ABI string_type lookup_collatename(_ForwardIterator __f, _ForwardIterator __l) const {
1050 return __lookup_collatename(__f, __l, char_type());
1051 }
1052 template <class _ForwardIterator>
1053 _LIBCPP_HIDE_FROM_ABI char_class_type
1054 lookup_classname(_ForwardIterator __f, _ForwardIterator __l, bool __icase = false) const {
1055 return __lookup_classname(__f, __l, __icase, char_type());
1056 }
1057 bool isctype(char_type __c, char_class_type __m) const;
1058 _LIBCPP_HIDE_FROM_ABI int value(char_type __ch, int __radix) const { return __regex_traits_value(__ch, __radix); }
1059 locale_type imbue(locale_type __l);
1060 _LIBCPP_HIDE_FROM_ABI locale_type getloc() const { return __loc_; }
1061
1062private:
1063 void __init();
1064
1065 template <class _ForwardIterator>
1066 string_type __transform_primary(_ForwardIterator __f, _ForwardIterator __l, char) const;
1067# if _LIBCPP_HAS_WIDE_CHARACTERS
1068 template <class _ForwardIterator>
1069 string_type __transform_primary(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
1070# endif
1071 template <class _ForwardIterator>
1072 string_type __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, char) const;
1073# if _LIBCPP_HAS_WIDE_CHARACTERS
1074 template <class _ForwardIterator>
1075 string_type __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
1076# endif
1077 template <class _ForwardIterator>
1078 char_class_type __lookup_classname(_ForwardIterator __f, _ForwardIterator __l, bool __icase, char) const;
1079# if _LIBCPP_HAS_WIDE_CHARACTERS
1080 template <class _ForwardIterator>
1081 char_class_type __lookup_classname(_ForwardIterator __f, _ForwardIterator __l, bool __icase, wchar_t) const;
1082# endif
1083
1084 static int __regex_traits_value(unsigned char __ch, int __radix);
1085 _LIBCPP_HIDE_FROM_ABI int __regex_traits_value(char __ch, int __radix) const {
1086 return __regex_traits_value(static_cast<unsigned char>(__ch), __radix);
1087 }
1088# if _LIBCPP_HAS_WIDE_CHARACTERS
1089 _LIBCPP_HIDE_FROM_ABI int __regex_traits_value(wchar_t __ch, int __radix) const;
1090# endif
1091};
1092
1093template <class _CharT>
1094const typename regex_traits<_CharT>::char_class_type regex_traits<_CharT>::__regex_word;
1095
1096template <class _CharT>
1097regex_traits<_CharT>::regex_traits() {
1098 __init();
1099}
1100
1101template <class _CharT>
1102typename regex_traits<_CharT>::char_type regex_traits<_CharT>::translate_nocase(char_type __c) const {
1103 return __ct_->tolower(__c);
1104}
1105
1106template <class _CharT>
1107template <class _ForwardIterator>
1108typename regex_traits<_CharT>::string_type
1109regex_traits<_CharT>::transform(_ForwardIterator __f, _ForwardIterator __l) const {
1110 string_type __s(__f, __l);
1111 return __col_->transform(__s.data(), __s.data() + __s.size());
1112}
1113
1114template <class _CharT>
1115void regex_traits<_CharT>::__init() {
1116 __ct_ = std::addressof(std::use_facet<ctype<char_type> >(__loc_));
1117 __col_ = std::addressof(std::use_facet<collate<char_type> >(__loc_));
1118}
1119
1120template <class _CharT>
1121typename regex_traits<_CharT>::locale_type regex_traits<_CharT>::imbue(locale_type __l) {
1122 locale __r = __loc_;
1123 __loc_ = __l;
1124 __init();
1125 return __r;
1126}
1127
1128// transform_primary is very FreeBSD-specific
1129
1130template <class _CharT>
1131template <class _ForwardIterator>
1132typename regex_traits<_CharT>::string_type
1133regex_traits<_CharT>::__transform_primary(_ForwardIterator __f, _ForwardIterator __l, char) const {
1134 const string_type __s(__f, __l);
1135 string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
1136# if defined(__FreeBSD__) || defined(__APPLE__)
1137 // FreeBSD's (and Darwin's, which shares the same collation code) strxfrm()
1138 // emits the weights one collation level at a time, separating the levels with
1139 // a byte ('.') that is chosen to sort below every weight byte. Primary
1140 // equivalence only depends on the first (primary) level, so drop everything
1141 // from the first separator onwards. This keeps characters that share a
1142 // primary weight equal (e.g. 'A' and 'A-acute' in cs_CZ) even when the lower
1143 // levels expand to a different number of weights, which the fixed-size logic
1144 // below could not handle.
1145 typename string_type::size_type __sep = __d.find('.');
1146 if (__sep != string_type::npos)
1147 __d.erase(__sep, string_type::npos);
1148# elif defined(__GLIBC__)
1149 // glibc's strxfrm() likewise writes the whole primary level first, then a
1150 // '\1' level separator (and a trailing '\0' after the last level); real
1151 // weight bytes are always >= 2. Keep only the primary level, as above.
1152 typename string_type::size_type __sep = __d.find('\1');
1153 if (__sep != string_type::npos)
1154 __d.erase(__sep, string_type::npos);
1155# else
1156 switch (__d.size()) {
1157 case 1:
1158 break;
1159 case 12:
1160 __d[11] = __d[3];
1161 break;
1162 default:
1163 __d.clear();
1164 break;
1165 }
1166# endif
1167 return __d;
1168}
1169
1170# if _LIBCPP_HAS_WIDE_CHARACTERS
1171template <class _CharT>
1172template <class _ForwardIterator>
1173typename regex_traits<_CharT>::string_type
1174regex_traits<_CharT>::__transform_primary(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const {
1175 const string_type __s(__f, __l);
1176 string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
1177# if defined(__FreeBSD__) || defined(__APPLE__) || defined(__GLIBC__)
1178 // As in the char overload above, FreeBSD's, Darwin's and glibc's wcsxfrm() all
1179 // separate the collation levels with a weight (the value 1) that sorts below
1180 // every real weight. Keep only the primary level so primary-equivalent
1181 // characters compare equal regardless of how many weights their lower levels
1182 // expand to.
1183 typename string_type::size_type __sep = __d.find(static_cast<_CharT>(1));
1184 if (__sep != string_type::npos)
1185 __d.erase(__sep, string_type::npos);
1186# else
1187 switch (__d.size()) {
1188 case 1:
1189 break;
1190 case 3:
1191 __d[2] = __d[0];
1192 break;
1193 default:
1194 __d.clear();
1195 break;
1196 }
1197# endif
1198 return __d;
1199}
1200# endif
1201
1202// lookup_collatename is very FreeBSD-specific
1203
1204_LIBCPP_EXPORTED_FROM_ABI string __get_collation_name(const char* __s);
1205
1206template <class _CharT>
1207template <class _ForwardIterator>
1208typename regex_traits<_CharT>::string_type
1209regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, char) const {
1210 string_type __s(__f, __l);
1211 string_type __r;
1212 if (!__s.empty()) {
1213 __r = std::__get_collation_name(s: __s.c_str());
1214 if (__r.empty() && __s.size() <= 2) {
1215 __r = __col_->transform(__s.data(), __s.data() + __s.size());
1216 if (__r.size() == 1 || __r.size() == 12)
1217 __r = __s;
1218 else
1219 __r.clear();
1220 }
1221 }
1222 return __r;
1223}
1224
1225# if _LIBCPP_HAS_WIDE_CHARACTERS
1226template <class _CharT>
1227template <class _ForwardIterator>
1228typename regex_traits<_CharT>::string_type
1229regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const {
1230 string_type __s(__f, __l);
1231 string __n;
1232 __n.reserve(requested_capacity: __s.size());
1233 for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end(); __i != __e; ++__i) {
1234 if (static_cast<unsigned>(*__i) >= 127)
1235 return string_type();
1236 __n.push_back(c: char(*__i));
1237 }
1238 string_type __r;
1239 if (!__s.empty()) {
1240 __n = __get_collation_name(s: __n.c_str());
1241 if (!__n.empty())
1242 __r.assign(__n.begin(), __n.end());
1243 else if (__s.size() <= 2) {
1244 __r = __col_->transform(__s.data(), __s.data() + __s.size());
1245 if (__r.size() == 1 || __r.size() == 3)
1246 __r = __s;
1247 else
1248 __r.clear();
1249 }
1250 }
1251 return __r;
1252}
1253# endif // _LIBCPP_HAS_WIDE_CHARACTERS
1254
1255// lookup_classname
1256
1257regex_traits<char>::char_class_type _LIBCPP_EXPORTED_FROM_ABI __get_classname(const char* __s, bool __icase);
1258
1259template <class _CharT>
1260template <class _ForwardIterator>
1261typename regex_traits<_CharT>::char_class_type
1262regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f, _ForwardIterator __l, bool __icase, char) const {
1263 string_type __s(__f, __l);
1264 __ct_->tolower(std::addressof(__s[0]), std::addressof(__s[0]) + __s.size());
1265 return std::__get_classname(s: __s.c_str(), __icase);
1266}
1267
1268# if _LIBCPP_HAS_WIDE_CHARACTERS
1269template <class _CharT>
1270template <class _ForwardIterator>
1271typename regex_traits<_CharT>::char_class_type
1272regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f, _ForwardIterator __l, bool __icase, wchar_t) const {
1273 string_type __s(__f, __l);
1274 __ct_->tolower(std::addressof(__s[0]), std::addressof(__s[0]) + __s.size());
1275 string __n;
1276 __n.reserve(requested_capacity: __s.size());
1277 for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end(); __i != __e; ++__i) {
1278 if (static_cast<unsigned>(*__i) >= 127)
1279 return char_class_type();
1280 __n.push_back(c: char(*__i));
1281 }
1282 return __get_classname(s: __n.c_str(), __icase);
1283}
1284# endif // _LIBCPP_HAS_WIDE_CHARACTERS
1285
1286template <class _CharT>
1287bool regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const {
1288 if (__ct_->is(__m, __c))
1289 return true;
1290 return (__c == '_' && (__m & __regex_word));
1291}
1292
1293inline _LIBCPP_HIDE_FROM_ABI bool __is_07(unsigned char __c) {
1294 return (__c & 0xF8u) ==
1295# if defined(__MVS__) && !defined(__NATIVE_ASCII_F)
1296 0xF0;
1297# else
1298 0x30;
1299# endif
1300}
1301
1302inline _LIBCPP_HIDE_FROM_ABI bool __is_89(unsigned char __c) {
1303 return (__c & 0xFEu) ==
1304# if defined(__MVS__) && !defined(__NATIVE_ASCII_F)
1305 0xF8;
1306# else
1307 0x38;
1308# endif
1309}
1310
1311inline _LIBCPP_HIDE_FROM_ABI unsigned char __to_lower(unsigned char __c) {
1312# if defined(__MVS__) && !defined(__NATIVE_ASCII_F)
1313 return __c & 0xBF;
1314# else
1315 return __c | 0x20;
1316# endif
1317}
1318
1319template <class _CharT>
1320int regex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix) {
1321 if (__is_07(c: __ch)) // '0' <= __ch && __ch <= '7'
1322 return __ch - '0';
1323 if (__radix != 8) {
1324 if (__is_89(c: __ch)) // '8' <= __ch && __ch <= '9'
1325 return __ch - '0';
1326 if (__radix == 16) {
1327 __ch = __to_lower(c: __ch); // tolower
1328 if ('a' <= __ch && __ch <= 'f')
1329 return __ch - ('a' - 10);
1330 }
1331 }
1332 return -1;
1333}
1334
1335# if _LIBCPP_HAS_WIDE_CHARACTERS
1336template <class _CharT>
1337inline int regex_traits<_CharT>::__regex_traits_value(wchar_t __ch, int __radix) const {
1338 return __regex_traits_value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
1339}
1340# endif
1341
1342template <class _CharT>
1343class __node;
1344
1345template <class _BidirectionalIterator>
1346class sub_match;
1347
1348template <class _BidirectionalIterator, class _Allocator = allocator<sub_match<_BidirectionalIterator> > >
1349class match_results;
1350
1351template <class _CharT>
1352struct __state {
1353 enum {
1354 __end_state = -1000,
1355 __consume_input, // -999
1356 __begin_marked_expr, // -998
1357 __end_marked_expr, // -997
1358 __pop_state, // -996
1359 __accept_and_consume, // -995
1360 __accept_but_not_consume, // -994
1361 __reject, // -993
1362 __split,
1363 __repeat
1364 };
1365
1366 int __do_;
1367 const _CharT* __first_;
1368 const _CharT* __current_;
1369 const _CharT* __last_;
1370 vector<sub_match<const _CharT*> > __sub_matches_;
1371 vector<pair<size_t, const _CharT*> > __loop_data_;
1372 const __node<_CharT>* __node_;
1373 regex_constants::match_flag_type __flags_;
1374 bool __at_first_;
1375
1376 _LIBCPP_HIDE_FROM_ABI __state()
1377 : __do_(0),
1378 __first_(nullptr),
1379 __current_(nullptr),
1380 __last_(nullptr),
1381 __node_(nullptr),
1382 __flags_(),
1383 __at_first_(false) {}
1384};
1385
1386// __node
1387
1388template <class _CharT>
1389class __node {
1390public:
1391 typedef std::__state<_CharT> __state;
1392
1393 _LIBCPP_HIDE_FROM_ABI __node() {}
1394 __node(const __node&) = delete;
1395 __node& operator=(const __node&) = delete;
1396 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1397 virtual ~__node() {}
1398
1399 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1400 virtual void __exec(__state&) const {}
1401 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1402 virtual void __exec_split(bool, __state&) const {}
1403};
1404
1405// __end_state
1406
1407template <class _CharT>
1408class __end_state : public __node<_CharT> {
1409public:
1410 typedef std::__state<_CharT> __state;
1411
1412 _LIBCPP_HIDE_FROM_ABI __end_state() {}
1413
1414 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1415};
1416
1417template <class _CharT>
1418void __end_state<_CharT>::__exec(__state& __s) const {
1419 __s.__do_ = __state::__end_state;
1420}
1421
1422// __has_one_state
1423
1424template <class _CharT>
1425class __has_one_state : public __node<_CharT> {
1426 __node<_CharT>* __first_;
1427
1428public:
1429 _LIBCPP_HIDE_FROM_ABI explicit __has_one_state(__node<_CharT>* __s) : __first_(__s) {}
1430
1431 _LIBCPP_HIDE_FROM_ABI __node<_CharT>* first() const { return __first_; }
1432 _LIBCPP_HIDE_FROM_ABI __node<_CharT>*& first() { return __first_; }
1433};
1434
1435// __owns_one_state
1436
1437template <class _CharT>
1438class __owns_one_state : public __has_one_state<_CharT> {
1439 typedef __has_one_state<_CharT> base;
1440
1441public:
1442 _LIBCPP_HIDE_FROM_ABI explicit __owns_one_state(__node<_CharT>* __s) : base(__s) {}
1443
1444 ~__owns_one_state() override;
1445};
1446
1447template <class _CharT>
1448__owns_one_state<_CharT>::~__owns_one_state() {
1449 delete this->first();
1450}
1451
1452// __empty_state
1453
1454template <class _CharT>
1455class __empty_state : public __owns_one_state<_CharT> {
1456 typedef __owns_one_state<_CharT> base;
1457
1458public:
1459 typedef std::__state<_CharT> __state;
1460
1461 _LIBCPP_HIDE_FROM_ABI explicit __empty_state(__node<_CharT>* __s) : base(__s) {}
1462
1463 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1464};
1465
1466template <class _CharT>
1467void __empty_state<_CharT>::__exec(__state& __s) const {
1468 __s.__do_ = __state::__accept_but_not_consume;
1469 __s.__node_ = this->first();
1470}
1471
1472// __empty_non_own_state
1473
1474template <class _CharT>
1475class __empty_non_own_state : public __has_one_state<_CharT> {
1476 typedef __has_one_state<_CharT> base;
1477
1478public:
1479 typedef std::__state<_CharT> __state;
1480
1481 _LIBCPP_HIDE_FROM_ABI explicit __empty_non_own_state(__node<_CharT>* __s) : base(__s) {}
1482
1483 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1484};
1485
1486template <class _CharT>
1487void __empty_non_own_state<_CharT>::__exec(__state& __s) const {
1488 __s.__do_ = __state::__accept_but_not_consume;
1489 __s.__node_ = this->first();
1490}
1491
1492// __repeat_one_loop
1493
1494template <class _CharT>
1495class __repeat_one_loop : public __has_one_state<_CharT> {
1496 typedef __has_one_state<_CharT> base;
1497
1498public:
1499 typedef std::__state<_CharT> __state;
1500
1501 _LIBCPP_HIDE_FROM_ABI explicit __repeat_one_loop(__node<_CharT>* __s) : base(__s) {}
1502
1503 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1504};
1505
1506template <class _CharT>
1507void __repeat_one_loop<_CharT>::__exec(__state& __s) const {
1508 __s.__do_ = __state::__repeat;
1509 __s.__node_ = this->first();
1510}
1511
1512// __owns_two_states
1513
1514template <class _CharT>
1515class __owns_two_states : public __owns_one_state<_CharT> {
1516 typedef __owns_one_state<_CharT> base;
1517
1518 base* __second_;
1519
1520public:
1521 _LIBCPP_HIDE_FROM_ABI explicit __owns_two_states(__node<_CharT>* __s1, base* __s2) : base(__s1), __second_(__s2) {}
1522
1523 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__owns_two_states();
1524
1525 _LIBCPP_HIDE_FROM_ABI base* second() const { return __second_; }
1526 _LIBCPP_HIDE_FROM_ABI base*& second() { return __second_; }
1527};
1528
1529template <class _CharT>
1530__owns_two_states<_CharT>::~__owns_two_states() {
1531 delete __second_;
1532}
1533
1534// __loop
1535
1536template <class _CharT>
1537class __loop : public __owns_two_states<_CharT> {
1538 typedef __owns_two_states<_CharT> base;
1539
1540 size_t __min_;
1541 size_t __max_;
1542 unsigned __loop_id_;
1543 unsigned __mexp_begin_;
1544 unsigned __mexp_end_;
1545 bool __greedy_;
1546
1547public:
1548 typedef std::__state<_CharT> __state;
1549
1550 _LIBCPP_HIDE_FROM_ABI explicit __loop(
1551 unsigned __loop_id,
1552 __node<_CharT>* __s1,
1553 __owns_one_state<_CharT>* __s2,
1554 unsigned __mexp_begin,
1555 unsigned __mexp_end,
1556 bool __greedy = true,
1557 size_t __min = 0,
1558 size_t __max = numeric_limits<size_t>::max())
1559 : base(__s1, __s2),
1560 __min_(__min),
1561 __max_(__max),
1562 __loop_id_(__loop_id),
1563 __mexp_begin_(__mexp_begin),
1564 __mexp_end_(__mexp_end),
1565 __greedy_(__greedy) {}
1566
1567 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
1568 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
1569
1570private:
1571 _LIBCPP_HIDE_FROM_ABI void __init_repeat(__state& __s) const {
1572 __s.__loop_data_[__loop_id_].second = __s.__current_;
1573 for (size_t __i = __mexp_begin_ - 1; __i != __mexp_end_ - 1; ++__i) {
1574 __s.__sub_matches_[__i].first = __s.__last_;
1575 __s.__sub_matches_[__i].second = __s.__last_;
1576 __s.__sub_matches_[__i].matched = false;
1577 }
1578 }
1579};
1580
1581template <class _CharT>
1582void __loop<_CharT>::__exec(__state& __s) const {
1583 if (__s.__do_ == __state::__repeat) {
1584 bool __do_repeat = ++__s.__loop_data_[__loop_id_].first < __max_;
1585 bool __do_alt = __s.__loop_data_[__loop_id_].first >= __min_;
1586 if (__do_repeat && __do_alt && __s.__loop_data_[__loop_id_].second == __s.__current_)
1587 __do_repeat = false;
1588 if (__do_repeat && __do_alt)
1589 __s.__do_ = __state::__split;
1590 else if (__do_repeat) {
1591 __s.__do_ = __state::__accept_but_not_consume;
1592 __s.__node_ = this->first();
1593 __init_repeat(__s);
1594 } else {
1595 __s.__do_ = __state::__accept_but_not_consume;
1596 __s.__node_ = this->second();
1597 }
1598 } else {
1599 __s.__loop_data_[__loop_id_].first = 0;
1600 bool __do_repeat = 0 < __max_;
1601 bool __do_alt = 0 >= __min_;
1602 if (__do_repeat && __do_alt)
1603 __s.__do_ = __state::__split;
1604 else if (__do_repeat) {
1605 __s.__do_ = __state::__accept_but_not_consume;
1606 __s.__node_ = this->first();
1607 __init_repeat(__s);
1608 } else {
1609 __s.__do_ = __state::__accept_but_not_consume;
1610 __s.__node_ = this->second();
1611 }
1612 }
1613}
1614
1615template <class _CharT>
1616void __loop<_CharT>::__exec_split(bool __second, __state& __s) const {
1617 __s.__do_ = __state::__accept_but_not_consume;
1618 if (__greedy_ != __second) {
1619 __s.__node_ = this->first();
1620 __init_repeat(__s);
1621 } else
1622 __s.__node_ = this->second();
1623}
1624
1625// __alternate
1626
1627template <class _CharT>
1628class __alternate : public __owns_two_states<_CharT> {
1629 typedef __owns_two_states<_CharT> base;
1630
1631public:
1632 typedef std::__state<_CharT> __state;
1633
1634 _LIBCPP_HIDE_FROM_ABI explicit __alternate(__owns_one_state<_CharT>* __s1, __owns_one_state<_CharT>* __s2)
1635 : base(__s1, __s2) {}
1636
1637 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
1638 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
1639};
1640
1641template <class _CharT>
1642void __alternate<_CharT>::__exec(__state& __s) const {
1643 __s.__do_ = __state::__split;
1644}
1645
1646template <class _CharT>
1647void __alternate<_CharT>::__exec_split(bool __second, __state& __s) const {
1648 __s.__do_ = __state::__accept_but_not_consume;
1649 if (__second)
1650 __s.__node_ = this->second();
1651 else
1652 __s.__node_ = this->first();
1653}
1654
1655// __begin_marked_subexpression
1656
1657template <class _CharT>
1658class __begin_marked_subexpression : public __owns_one_state<_CharT> {
1659 typedef __owns_one_state<_CharT> base;
1660
1661 unsigned __mexp_;
1662
1663public:
1664 typedef std::__state<_CharT> __state;
1665
1666 _LIBCPP_HIDE_FROM_ABI explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
1667 : base(__s), __mexp_(__mexp) {}
1668
1669 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1670};
1671
1672template <class _CharT>
1673void __begin_marked_subexpression<_CharT>::__exec(__state& __s) const {
1674 __s.__do_ = __state::__accept_but_not_consume;
1675 __s.__sub_matches_[__mexp_ - 1].first = __s.__current_;
1676 __s.__node_ = this->first();
1677}
1678
1679// __end_marked_subexpression
1680
1681template <class _CharT>
1682class __end_marked_subexpression : public __owns_one_state<_CharT> {
1683 typedef __owns_one_state<_CharT> base;
1684
1685 unsigned __mexp_;
1686
1687public:
1688 typedef std::__state<_CharT> __state;
1689
1690 _LIBCPP_HIDE_FROM_ABI explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
1691 : base(__s), __mexp_(__mexp) {}
1692
1693 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1694};
1695
1696template <class _CharT>
1697void __end_marked_subexpression<_CharT>::__exec(__state& __s) const {
1698 __s.__do_ = __state::__accept_but_not_consume;
1699 __s.__sub_matches_[__mexp_ - 1].second = __s.__current_;
1700 __s.__sub_matches_[__mexp_ - 1].matched = true;
1701 __s.__node_ = this->first();
1702}
1703
1704// __back_ref
1705
1706template <class _CharT>
1707class __back_ref : public __owns_one_state<_CharT> {
1708 typedef __owns_one_state<_CharT> base;
1709
1710 unsigned __mexp_;
1711
1712public:
1713 typedef std::__state<_CharT> __state;
1714
1715 _LIBCPP_HIDE_FROM_ABI explicit __back_ref(unsigned __mexp, __node<_CharT>* __s) : base(__s), __mexp_(__mexp) {}
1716
1717 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1718};
1719
1720template <class _CharT>
1721void __back_ref<_CharT>::__exec(__state& __s) const {
1722 if (__mexp_ > __s.__sub_matches_.size())
1723 std::__throw_regex_error<regex_constants::error_backref>();
1724 sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_ - 1];
1725 if (__sm.matched) {
1726 ptrdiff_t __len = __sm.second - __sm.first;
1727 if (__s.__last_ - __s.__current_ >= __len && std::equal(__sm.first, __sm.second, __s.__current_)) {
1728 __s.__do_ = __state::__accept_but_not_consume;
1729 __s.__current_ += __len;
1730 __s.__node_ = this->first();
1731 } else {
1732 __s.__do_ = __state::__reject;
1733 __s.__node_ = nullptr;
1734 }
1735 } else {
1736 __s.__do_ = __state::__reject;
1737 __s.__node_ = nullptr;
1738 }
1739}
1740
1741// __back_ref_icase
1742
1743template <class _CharT, class _Traits>
1744class __back_ref_icase : public __owns_one_state<_CharT> {
1745 typedef __owns_one_state<_CharT> base;
1746
1747 _Traits __traits_;
1748 unsigned __mexp_;
1749
1750public:
1751 typedef std::__state<_CharT> __state;
1752
1753 _LIBCPP_HIDE_FROM_ABI explicit __back_ref_icase(const _Traits& __traits, unsigned __mexp, __node<_CharT>* __s)
1754 : base(__s), __traits_(__traits), __mexp_(__mexp) {}
1755
1756 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1757};
1758
1759template <class _CharT, class _Traits>
1760void __back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const {
1761 sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_ - 1];
1762 if (__sm.matched) {
1763 ptrdiff_t __len = __sm.second - __sm.first;
1764 if (__s.__last_ - __s.__current_ >= __len) {
1765 for (ptrdiff_t __i = 0; __i < __len; ++__i) {
1766 if (__traits_.translate_nocase(__sm.first[__i]) != __traits_.translate_nocase(__s.__current_[__i]))
1767 goto __not_equal;
1768 }
1769 __s.__do_ = __state::__accept_but_not_consume;
1770 __s.__current_ += __len;
1771 __s.__node_ = this->first();
1772 } else {
1773 __s.__do_ = __state::__reject;
1774 __s.__node_ = nullptr;
1775 }
1776 } else {
1777 __not_equal:
1778 __s.__do_ = __state::__reject;
1779 __s.__node_ = nullptr;
1780 }
1781}
1782
1783// __back_ref_collate
1784
1785template <class _CharT, class _Traits>
1786class __back_ref_collate : public __owns_one_state<_CharT> {
1787 typedef __owns_one_state<_CharT> base;
1788
1789 _Traits __traits_;
1790 unsigned __mexp_;
1791
1792public:
1793 typedef std::__state<_CharT> __state;
1794
1795 _LIBCPP_HIDE_FROM_ABI explicit __back_ref_collate(const _Traits& __traits, unsigned __mexp, __node<_CharT>* __s)
1796 : base(__s), __traits_(__traits), __mexp_(__mexp) {}
1797
1798 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1799};
1800
1801template <class _CharT, class _Traits>
1802void __back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const {
1803 sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_ - 1];
1804 if (__sm.matched) {
1805 ptrdiff_t __len = __sm.second - __sm.first;
1806 if (__s.__last_ - __s.__current_ >= __len) {
1807 for (ptrdiff_t __i = 0; __i < __len; ++__i) {
1808 if (__traits_.translate(__sm.first[__i]) != __traits_.translate(__s.__current_[__i]))
1809 goto __not_equal;
1810 }
1811 __s.__do_ = __state::__accept_but_not_consume;
1812 __s.__current_ += __len;
1813 __s.__node_ = this->first();
1814 } else {
1815 __s.__do_ = __state::__reject;
1816 __s.__node_ = nullptr;
1817 }
1818 } else {
1819 __not_equal:
1820 __s.__do_ = __state::__reject;
1821 __s.__node_ = nullptr;
1822 }
1823}
1824
1825// __word_boundary
1826
1827template <class _CharT, class _Traits>
1828class __word_boundary : public __owns_one_state<_CharT> {
1829 typedef __owns_one_state<_CharT> base;
1830
1831 _Traits __traits_;
1832 bool __invert_;
1833
1834public:
1835 typedef std::__state<_CharT> __state;
1836
1837 _LIBCPP_HIDE_FROM_ABI explicit __word_boundary(const _Traits& __traits, bool __invert, __node<_CharT>* __s)
1838 : base(__s), __traits_(__traits), __invert_(__invert) {}
1839
1840 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1841};
1842
1843template <class _CharT, class _Traits>
1844void __word_boundary<_CharT, _Traits>::__exec(__state& __s) const {
1845 bool __is_word_b = false;
1846 if (__s.__first_ != __s.__last_) {
1847 if (__s.__current_ == __s.__last_) {
1848 if (!(__s.__flags_ & regex_constants::match_not_eow)) {
1849 _CharT __c = __s.__current_[-1];
1850 __is_word_b = __c == '_' || __traits_.isctype(__c, ctype_base::alnum);
1851 }
1852 } else if (__s.__current_ == __s.__first_ && !(__s.__flags_ & regex_constants::match_prev_avail)) {
1853 if (!(__s.__flags_ & regex_constants::match_not_bow)) {
1854 _CharT __c = *__s.__current_;
1855 __is_word_b = __c == '_' || __traits_.isctype(__c, ctype_base::alnum);
1856 }
1857 } else {
1858 _CharT __c1 = __s.__current_[-1];
1859 _CharT __c2 = *__s.__current_;
1860 bool __is_c1_b = __c1 == '_' || __traits_.isctype(__c1, ctype_base::alnum);
1861 bool __is_c2_b = __c2 == '_' || __traits_.isctype(__c2, ctype_base::alnum);
1862 __is_word_b = __is_c1_b != __is_c2_b;
1863 }
1864 }
1865 if (__is_word_b != __invert_) {
1866 __s.__do_ = __state::__accept_but_not_consume;
1867 __s.__node_ = this->first();
1868 } else {
1869 __s.__do_ = __state::__reject;
1870 __s.__node_ = nullptr;
1871 }
1872}
1873
1874// __l_anchor
1875
1876template <class _CharT>
1877_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __is_eol(_CharT __c) {
1878 return __c == '\r' || __c == '\n';
1879}
1880
1881template <class _CharT>
1882class __l_anchor_multiline : public __owns_one_state<_CharT> {
1883 typedef __owns_one_state<_CharT> base;
1884
1885 bool __multiline_;
1886
1887public:
1888 typedef std::__state<_CharT> __state;
1889
1890 _LIBCPP_HIDE_FROM_ABI __l_anchor_multiline(bool __multiline, __node<_CharT>* __s)
1891 : base(__s), __multiline_(__multiline) {}
1892
1893 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1894};
1895
1896template <class _CharT>
1897void __l_anchor_multiline<_CharT>::__exec(__state& __s) const {
1898 if (__s.__at_first_ && __s.__current_ == __s.__first_ && !(__s.__flags_ & regex_constants::match_not_bol)) {
1899 __s.__do_ = __state::__accept_but_not_consume;
1900 __s.__node_ = this->first();
1901 } else if (__multiline_ && !__s.__at_first_ && std::__is_eol(*std::prev(__s.__current_))) {
1902 __s.__do_ = __state::__accept_but_not_consume;
1903 __s.__node_ = this->first();
1904 } else {
1905 __s.__do_ = __state::__reject;
1906 __s.__node_ = nullptr;
1907 }
1908}
1909
1910// __r_anchor
1911
1912template <class _CharT>
1913class __r_anchor_multiline : public __owns_one_state<_CharT> {
1914 typedef __owns_one_state<_CharT> base;
1915
1916 bool __multiline_;
1917
1918public:
1919 typedef std::__state<_CharT> __state;
1920
1921 _LIBCPP_HIDE_FROM_ABI __r_anchor_multiline(bool __multiline, __node<_CharT>* __s)
1922 : base(__s), __multiline_(__multiline) {}
1923
1924 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1925};
1926
1927template <class _CharT>
1928void __r_anchor_multiline<_CharT>::__exec(__state& __s) const {
1929 if (__s.__current_ == __s.__last_ && !(__s.__flags_ & regex_constants::match_not_eol)) {
1930 __s.__do_ = __state::__accept_but_not_consume;
1931 __s.__node_ = this->first();
1932 } else if (__multiline_ && std::__is_eol(*__s.__current_)) {
1933 __s.__do_ = __state::__accept_but_not_consume;
1934 __s.__node_ = this->first();
1935 } else {
1936 __s.__do_ = __state::__reject;
1937 __s.__node_ = nullptr;
1938 }
1939}
1940
1941// __match_any
1942
1943template <class _CharT>
1944class __match_any : public __owns_one_state<_CharT> {
1945 typedef __owns_one_state<_CharT> base;
1946
1947public:
1948 typedef std::__state<_CharT> __state;
1949
1950 _LIBCPP_HIDE_FROM_ABI __match_any(__node<_CharT>* __s) : base(__s) {}
1951
1952 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
1953};
1954
1955template <class _CharT>
1956void __match_any<_CharT>::__exec(__state& __s) const {
1957 if (__s.__current_ != __s.__last_ && *__s.__current_ != 0) {
1958 __s.__do_ = __state::__accept_and_consume;
1959 ++__s.__current_;
1960 __s.__node_ = this->first();
1961 } else {
1962 __s.__do_ = __state::__reject;
1963 __s.__node_ = nullptr;
1964 }
1965}
1966
1967// __match_any_but_newline
1968
1969template <class _CharT>
1970class __match_any_but_newline : public __owns_one_state<_CharT> {
1971 typedef __owns_one_state<_CharT> base;
1972
1973public:
1974 typedef std::__state<_CharT> __state;
1975
1976 _LIBCPP_HIDE_FROM_ABI __match_any_but_newline(__node<_CharT>* __s) : base(__s) {}
1977
1978 void __exec(__state&) const override;
1979};
1980
1981template <>
1982_LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<char>::__exec(__state&) const;
1983# if _LIBCPP_HAS_WIDE_CHARACTERS
1984template <>
1985_LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<wchar_t>::__exec(__state&) const;
1986# endif
1987
1988// __match_char
1989
1990template <class _CharT>
1991class __match_char : public __owns_one_state<_CharT> {
1992 typedef __owns_one_state<_CharT> base;
1993
1994 _CharT __c_;
1995
1996public:
1997 typedef std::__state<_CharT> __state;
1998
1999 _LIBCPP_HIDE_FROM_ABI __match_char(_CharT __c, __node<_CharT>* __s) : base(__s), __c_(__c) {}
2000
2001 __match_char(const __match_char&) = delete;
2002 __match_char& operator=(const __match_char&) = delete;
2003
2004 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
2005};
2006
2007template <class _CharT>
2008void __match_char<_CharT>::__exec(__state& __s) const {
2009 if (__s.__current_ != __s.__last_ && *__s.__current_ == __c_) {
2010 __s.__do_ = __state::__accept_and_consume;
2011 ++__s.__current_;
2012 __s.__node_ = this->first();
2013 } else {
2014 __s.__do_ = __state::__reject;
2015 __s.__node_ = nullptr;
2016 }
2017}
2018
2019// __match_char_icase
2020
2021template <class _CharT, class _Traits>
2022class __match_char_icase : public __owns_one_state<_CharT> {
2023 typedef __owns_one_state<_CharT> base;
2024
2025 _Traits __traits_;
2026 _CharT __c_;
2027
2028public:
2029 typedef std::__state<_CharT> __state;
2030
2031 _LIBCPP_HIDE_FROM_ABI __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
2032 : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {}
2033
2034 __match_char_icase(const __match_char_icase&) = delete;
2035 __match_char_icase& operator=(const __match_char_icase&) = delete;
2036
2037 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
2038};
2039
2040template <class _CharT, class _Traits>
2041void __match_char_icase<_CharT, _Traits>::__exec(__state& __s) const {
2042 if (__s.__current_ != __s.__last_ && __traits_.translate_nocase(*__s.__current_) == __c_) {
2043 __s.__do_ = __state::__accept_and_consume;
2044 ++__s.__current_;
2045 __s.__node_ = this->first();
2046 } else {
2047 __s.__do_ = __state::__reject;
2048 __s.__node_ = nullptr;
2049 }
2050}
2051
2052// __match_char_collate
2053
2054template <class _CharT, class _Traits>
2055class __match_char_collate : public __owns_one_state<_CharT> {
2056 typedef __owns_one_state<_CharT> base;
2057
2058 _Traits __traits_;
2059 _CharT __c_;
2060
2061public:
2062 typedef std::__state<_CharT> __state;
2063
2064 _LIBCPP_HIDE_FROM_ABI __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
2065 : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {}
2066
2067 __match_char_collate(const __match_char_collate&) = delete;
2068 __match_char_collate& operator=(const __match_char_collate&) = delete;
2069
2070 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
2071};
2072
2073template <class _CharT, class _Traits>
2074void __match_char_collate<_CharT, _Traits>::__exec(__state& __s) const {
2075 if (__s.__current_ != __s.__last_ && __traits_.translate(*__s.__current_) == __c_) {
2076 __s.__do_ = __state::__accept_and_consume;
2077 ++__s.__current_;
2078 __s.__node_ = this->first();
2079 } else {
2080 __s.__do_ = __state::__reject;
2081 __s.__node_ = nullptr;
2082 }
2083}
2084
2085// __bracket_expression
2086
2087template <class _CharT, class _Traits>
2088class __bracket_expression : public __owns_one_state<_CharT> {
2089 typedef __owns_one_state<_CharT> base;
2090 typedef typename _Traits::string_type string_type;
2091
2092 _Traits __traits_;
2093 vector<_CharT> __chars_;
2094 vector<_CharT> __neg_chars_;
2095 vector<pair<string_type, string_type> > __ranges_;
2096 vector<pair<_CharT, _CharT> > __digraphs_;
2097 vector<string_type> __equivalences_;
2098 typename regex_traits<_CharT>::char_class_type __mask_;
2099 typename regex_traits<_CharT>::char_class_type __neg_mask_;
2100 bool __negate_;
2101 bool __icase_;
2102 bool __collate_;
2103 bool __might_have_digraph_;
2104
2105public:
2106 typedef std::__state<_CharT> __state;
2107
2108 _LIBCPP_HIDE_FROM_ABI
2109 __bracket_expression(const _Traits& __traits, __node<_CharT>* __s, bool __negate, bool __icase, bool __collate)
2110 : base(__s),
2111 __traits_(__traits),
2112 __mask_(),
2113 __neg_mask_(),
2114 __negate_(__negate),
2115 __icase_(__icase),
2116 __collate_(__collate),
2117 __might_have_digraph_(__traits_.getloc().name() != "C") {}
2118
2119 __bracket_expression(const __bracket_expression&) = delete;
2120 __bracket_expression& operator=(const __bracket_expression&) = delete;
2121
2122 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
2123
2124 _LIBCPP_HIDE_FROM_ABI bool __negated() const { return __negate_; }
2125
2126 _LIBCPP_HIDE_FROM_ABI void __add_char(_CharT __c) {
2127 if (__icase_)
2128 __chars_.push_back(__traits_.translate_nocase(__c));
2129 else if (__collate_)
2130 __chars_.push_back(__traits_.translate(__c));
2131 else
2132 __chars_.push_back(__c);
2133 }
2134 _LIBCPP_HIDE_FROM_ABI void __add_neg_char(_CharT __c) {
2135 if (__icase_)
2136 __neg_chars_.push_back(__traits_.translate_nocase(__c));
2137 else if (__collate_)
2138 __neg_chars_.push_back(__traits_.translate(__c));
2139 else
2140 __neg_chars_.push_back(__c);
2141 }
2142 _LIBCPP_HIDE_FROM_ABI void __add_range(string_type __b, string_type __e) {
2143 if (__collate_) {
2144 if (__icase_) {
2145 for (size_t __i = 0; __i < __b.size(); ++__i)
2146 __b[__i] = __traits_.translate_nocase(__b[__i]);
2147 for (size_t __i = 0; __i < __e.size(); ++__i)
2148 __e[__i] = __traits_.translate_nocase(__e[__i]);
2149 } else {
2150 for (size_t __i = 0; __i < __b.size(); ++__i)
2151 __b[__i] = __traits_.translate(__b[__i]);
2152 for (size_t __i = 0; __i < __e.size(); ++__i)
2153 __e[__i] = __traits_.translate(__e[__i]);
2154 }
2155 __ranges_.push_back(
2156 std::make_pair(__traits_.transform(__b.begin(), __b.end()), __traits_.transform(__e.begin(), __e.end())));
2157 } else {
2158 if (__b.size() != 1 || __e.size() != 1 || char_traits<typename string_type::value_type>::lt(__e[0], __b[0]))
2159 std::__throw_regex_error<regex_constants::error_range>();
2160 if (__icase_) {
2161 __b[0] = __traits_.translate_nocase(__b[0]);
2162 __e[0] = __traits_.translate_nocase(__e[0]);
2163 }
2164 __ranges_.push_back(std::make_pair(std::move(__b), std::move(__e)));
2165 }
2166 }
2167 _LIBCPP_HIDE_FROM_ABI void __add_digraph(_CharT __c1, _CharT __c2) {
2168 if (__icase_)
2169 __digraphs_.push_back(std::make_pair(__traits_.translate_nocase(__c1), __traits_.translate_nocase(__c2)));
2170 else if (__collate_)
2171 __digraphs_.push_back(std::make_pair(__traits_.translate(__c1), __traits_.translate(__c2)));
2172 else
2173 __digraphs_.push_back(std::make_pair(__c1, __c2));
2174 }
2175 _LIBCPP_HIDE_FROM_ABI void __add_equivalence(const string_type& __s) { __equivalences_.push_back(__s); }
2176 _LIBCPP_HIDE_FROM_ABI void __add_class(typename regex_traits<_CharT>::char_class_type __mask) { __mask_ |= __mask; }
2177 _LIBCPP_HIDE_FROM_ABI void __add_neg_class(typename regex_traits<_CharT>::char_class_type __mask) {
2178 __neg_mask_ |= __mask;
2179 }
2180};
2181
2182template <class _CharT, class _Traits>
2183void __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const {
2184 bool __found = false;
2185 unsigned __consumed = 0;
2186 if (__s.__current_ != __s.__last_) {
2187 ++__consumed;
2188 if (__might_have_digraph_) {
2189 const _CharT* __next = std::next(__s.__current_);
2190 if (__next != __s.__last_) {
2191 pair<_CharT, _CharT> __ch2(*__s.__current_, *__next);
2192 if (__icase_) {
2193 __ch2.first = __traits_.translate_nocase(__ch2.first);
2194 __ch2.second = __traits_.translate_nocase(__ch2.second);
2195 } else if (__collate_) {
2196 __ch2.first = __traits_.translate(__ch2.first);
2197 __ch2.second = __traits_.translate(__ch2.second);
2198 }
2199 if (!__traits_.lookup_collatename(std::addressof(__ch2.first), std::addressof(__ch2.first) + 2).empty()) {
2200 // __ch2 is a digraph in this locale
2201 ++__consumed;
2202 for (size_t __i = 0; __i < __digraphs_.size(); ++__i) {
2203 if (__ch2 == __digraphs_[__i]) {
2204 __found = true;
2205 goto __exit;
2206 }
2207 }
2208 if (__collate_ && !__ranges_.empty()) {
2209 string_type __s2 = __traits_.transform(std::addressof(__ch2.first), std::addressof(__ch2.first) + 2);
2210 for (size_t __i = 0; __i < __ranges_.size(); ++__i) {
2211 if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second) {
2212 __found = true;
2213 goto __exit;
2214 }
2215 }
2216 }
2217 if (!__equivalences_.empty()) {
2218 string_type __s2 =
2219 __traits_.transform_primary(std::addressof(__ch2.first), std::addressof(__ch2.first) + 2);
2220 for (size_t __i = 0; __i < __equivalences_.size(); ++__i) {
2221 if (__s2 == __equivalences_[__i]) {
2222 __found = true;
2223 goto __exit;
2224 }
2225 }
2226 }
2227 if (__traits_.isctype(__ch2.first, __mask_) && __traits_.isctype(__ch2.second, __mask_)) {
2228 __found = true;
2229 goto __exit;
2230 }
2231 if (!__traits_.isctype(__ch2.first, __neg_mask_) && !__traits_.isctype(__ch2.second, __neg_mask_)) {
2232 __found = true;
2233 goto __exit;
2234 }
2235 goto __exit;
2236 }
2237 }
2238 }
2239 // test *__s.__current_ as not a digraph
2240 _CharT __ch = *__s.__current_;
2241 if (__icase_)
2242 __ch = __traits_.translate_nocase(__ch);
2243 else if (__collate_)
2244 __ch = __traits_.translate(__ch);
2245 for (size_t __i = 0; __i < __chars_.size(); ++__i) {
2246 if (__ch == __chars_[__i]) {
2247 __found = true;
2248 goto __exit;
2249 }
2250 }
2251 // When there's at least one of __neg_chars_ and __neg_mask_, the set
2252 // of "__found" chars is
2253 // union(complement(union(__neg_chars_, __neg_mask_)),
2254 // other cases...)
2255 //
2256 // It doesn't make sense to check this when there are no __neg_chars_
2257 // and no __neg_mask_.
2258 if (!(__neg_mask_ == 0 && __neg_chars_.empty())) {
2259 const bool __in_neg_mask = __traits_.isctype(__ch, __neg_mask_);
2260 const bool __in_neg_chars = std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) != __neg_chars_.end();
2261 if (!(__in_neg_mask || __in_neg_chars)) {
2262 __found = true;
2263 goto __exit;
2264 }
2265 }
2266 if (!__ranges_.empty()) {
2267 string_type __s2 =
2268 __collate_ ? __traits_.transform(std::addressof(__ch), std::addressof(__ch) + 1) : string_type(1, __ch);
2269 for (size_t __i = 0; __i < __ranges_.size(); ++__i) {
2270 if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second) {
2271 __found = true;
2272 goto __exit;
2273 }
2274 }
2275 }
2276 if (!__equivalences_.empty()) {
2277 string_type __s2 = __traits_.transform_primary(std::addressof(__ch), std::addressof(__ch) + 1);
2278 for (size_t __i = 0; __i < __equivalences_.size(); ++__i) {
2279 if (__s2 == __equivalences_[__i]) {
2280 __found = true;
2281 goto __exit;
2282 }
2283 }
2284 }
2285 if (__traits_.isctype(__ch, __mask_)) {
2286 __found = true;
2287 goto __exit;
2288 }
2289 } else
2290 __found = __negate_; // force reject
2291__exit:
2292 if (__found != __negate_) {
2293 __s.__do_ = __state::__accept_and_consume;
2294 __s.__current_ += __consumed;
2295 __s.__node_ = this->first();
2296 } else {
2297 __s.__do_ = __state::__reject;
2298 __s.__node_ = nullptr;
2299 }
2300}
2301
2302template <class _CharT, class _Traits>
2303class __lookahead;
2304
2305template <class _CharT, class _Traits = regex_traits<_CharT> >
2306class basic_regex;
2307
2308typedef basic_regex<char> regex;
2309# if _LIBCPP_HAS_WIDE_CHARACTERS
2310typedef basic_regex<wchar_t> wregex;
2311# endif
2312
2313template <class _CharT, class _Traits>
2314class _LIBCPP_PREFERRED_NAME(regex) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wregex)) basic_regex {
2315public:
2316 // types:
2317 typedef _CharT value_type;
2318 typedef _Traits traits_type;
2319 typedef typename _Traits::string_type string_type;
2320 typedef regex_constants::syntax_option_type flag_type;
2321 typedef typename _Traits::locale_type locale_type;
2322
2323private:
2324 _Traits __traits_;
2325 flag_type __flags_;
2326 unsigned __marked_count_;
2327 unsigned __loop_count_;
2328 int __open_count_;
2329 shared_ptr<__empty_state<_CharT> > __start_;
2330 __owns_one_state<_CharT>* __end_;
2331
2332 typedef std::__state<_CharT> __state;
2333 typedef std::__node<_CharT> __node;
2334
2335public:
2336 // constants:
2337 static const regex_constants::syntax_option_type icase = regex_constants::icase;
2338 static const regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
2339 static const regex_constants::syntax_option_type optimize = regex_constants::optimize;
2340 static const regex_constants::syntax_option_type collate = regex_constants::collate;
2341 static const regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
2342 static const regex_constants::syntax_option_type basic = regex_constants::basic;
2343 static const regex_constants::syntax_option_type extended = regex_constants::extended;
2344 static const regex_constants::syntax_option_type awk = regex_constants::awk;
2345 static const regex_constants::syntax_option_type grep = regex_constants::grep;
2346 static const regex_constants::syntax_option_type egrep = regex_constants::egrep;
2347 static const regex_constants::syntax_option_type multiline = regex_constants::multiline;
2348
2349 // construct/copy/destroy:
2350 _LIBCPP_HIDE_FROM_ABI basic_regex()
2351 : __flags_(regex_constants::ECMAScript),
2352 __marked_count_(0),
2353 __loop_count_(0),
2354 __open_count_(0),
2355 __end_(nullptr) {}
2356 _LIBCPP_HIDE_FROM_ABI explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
2357 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
2358 __init(__p, __p + __traits_.length(__p));
2359 }
2360
2361 _LIBCPP_HIDE_FROM_ABI basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
2362 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
2363 __init(__p, __p + __len);
2364 }
2365
2366 // basic_regex(const basic_regex&) = default;
2367 // basic_regex(basic_regex&&) = default;
2368 template <class _ST, class _SA>
2369 _LIBCPP_HIDE_FROM_ABI explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
2370 flag_type __f = regex_constants::ECMAScript)
2371 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
2372 __init(__p.begin(), __p.end());
2373 }
2374
2375 template <class _ForwardIterator>
2376 _LIBCPP_HIDE_FROM_ABI
2377 basic_regex(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript)
2378 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
2379 __init(__first, __last);
2380 }
2381# ifndef _LIBCPP_CXX03_LANG
2382 _LIBCPP_HIDE_FROM_ABI basic_regex(initializer_list<value_type> __il, flag_type __f = regex_constants::ECMAScript)
2383 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
2384 __init(__il.begin(), __il.end());
2385 }
2386# endif // _LIBCPP_CXX03_LANG
2387
2388 // ~basic_regex() = default;
2389
2390 // basic_regex& operator=(const basic_regex&) = default;
2391 // basic_regex& operator=(basic_regex&&) = default;
2392 _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(const value_type* __p) { return assign(__p); }
2393# ifndef _LIBCPP_CXX03_LANG
2394 _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(initializer_list<value_type> __il) { return assign(__il); }
2395# endif // _LIBCPP_CXX03_LANG
2396 template <class _ST, class _SA>
2397 _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p) {
2398 return assign(__p);
2399 }
2400
2401 // assign:
2402 _LIBCPP_HIDE_FROM_ABI basic_regex& assign(const basic_regex& __that) { return *this = __that; }
2403# ifndef _LIBCPP_CXX03_LANG
2404 _LIBCPP_HIDE_FROM_ABI basic_regex& assign(basic_regex&& __that) _NOEXCEPT { return *this = std::move(__that); }
2405# endif
2406 _LIBCPP_HIDE_FROM_ABI basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript) {
2407 return assign(__p, __p + __traits_.length(__p), __f);
2408 }
2409 _LIBCPP_HIDE_FROM_ABI basic_regex&
2410 assign(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) {
2411 return assign(__p, __p + __len, __f);
2412 }
2413 template <class _ST, class _SA>
2414 _LIBCPP_HIDE_FROM_ABI basic_regex&
2415 assign(const basic_string<value_type, _ST, _SA>& __s, flag_type __f = regex_constants::ECMAScript) {
2416 return assign(__s.begin(), __s.end(), __f);
2417 }
2418
2419 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
2420 _LIBCPP_HIDE_FROM_ABI basic_regex&
2421 assign(_InputIterator __first, _InputIterator __last, flag_type __f = regex_constants::ECMAScript) {
2422 basic_string<_CharT> __t(__first, __last);
2423 return assign(__t.begin(), __t.end(), __f);
2424 }
2425
2426private:
2427 _LIBCPP_HIDE_FROM_ABI void __member_init(flag_type __f) {
2428 __flags_ = __f;
2429 __marked_count_ = 0;
2430 __loop_count_ = 0;
2431 __open_count_ = 0;
2432 __end_ = nullptr;
2433 }
2434
2435public:
2436 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
2437 _LIBCPP_HIDE_FROM_ABI basic_regex&
2438 assign(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript) {
2439 return assign(basic_regex(__first, __last, __f));
2440 }
2441
2442# ifndef _LIBCPP_CXX03_LANG
2443
2444 _LIBCPP_HIDE_FROM_ABI basic_regex&
2445 assign(initializer_list<value_type> __il, flag_type __f = regex_constants::ECMAScript) {
2446 return assign(__il.begin(), __il.end(), __f);
2447 }
2448
2449# endif // _LIBCPP_CXX03_LANG
2450
2451 // const operations:
2452 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI unsigned mark_count() const { return __marked_count_; }
2453 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI flag_type flags() const { return __flags_; }
2454
2455 // locale:
2456 _LIBCPP_HIDE_FROM_ABI locale_type imbue(locale_type __loc) {
2457 __member_init(f: ECMAScript);
2458 __start_.reset();
2459 return __traits_.imbue(__loc);
2460 }
2461 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI locale_type getloc() const { return __traits_.getloc(); }
2462
2463 // swap:
2464 void swap(basic_regex& __r);
2465
2466private:
2467 _LIBCPP_HIDE_FROM_ABI unsigned __loop_count() const { return __loop_count_; }
2468
2469 _LIBCPP_HIDE_FROM_ABI bool __use_multiline() const {
2470 return __get_grammar(g: __flags_) == ECMAScript && (__flags_ & multiline);
2471 }
2472
2473 template <class _ForwardIterator>
2474 void __init(_ForwardIterator __first, _ForwardIterator __last);
2475 template <class _ForwardIterator>
2476 _ForwardIterator __parse(_ForwardIterator __first, _ForwardIterator __last);
2477 template <class _ForwardIterator>
2478 _ForwardIterator __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
2479 template <class _ForwardIterator>
2480 _ForwardIterator __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last);
2481 template <class _ForwardIterator>
2482 _ForwardIterator __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last);
2483 template <class _ForwardIterator>
2484 _ForwardIterator __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last);
2485 template <class _ForwardIterator>
2486 _ForwardIterator __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last);
2487 template <class _ForwardIterator>
2488 _ForwardIterator __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last);
2489 template <class _ForwardIterator>
2490 _ForwardIterator __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last);
2491 template <class _ForwardIterator>
2492 _ForwardIterator __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last);
2493 template <class _ForwardIterator>
2494 _ForwardIterator __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last);
2495 template <class _ForwardIterator>
2496 _ForwardIterator __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last);
2497 template <class _ForwardIterator>
2498 _ForwardIterator __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last);
2499 template <class _ForwardIterator>
2500 _ForwardIterator __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);
2501 template <class _ForwardIterator>
2502 _ForwardIterator __parse_RE_dupl_symbol(
2503 _ForwardIterator __first,
2504 _ForwardIterator __last,
2505 __owns_one_state<_CharT>* __s,
2506 unsigned __mexp_begin,
2507 unsigned __mexp_end);
2508 template <class _ForwardIterator>
2509 _ForwardIterator __parse_ERE_dupl_symbol(
2510 _ForwardIterator __first,
2511 _ForwardIterator __last,
2512 __owns_one_state<_CharT>* __s,
2513 unsigned __mexp_begin,
2514 unsigned __mexp_end);
2515 template <class _ForwardIterator>
2516 _ForwardIterator __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last);
2517 template <class _ForwardIterator>
2518 _ForwardIterator
2519 __parse_follow_list(_ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
2520 template <class _ForwardIterator>
2521 _ForwardIterator __parse_expression_term(
2522 _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
2523 template <class _ForwardIterator>
2524 _ForwardIterator __parse_equivalence_class(
2525 _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
2526 template <class _ForwardIterator>
2527 _ForwardIterator __parse_character_class(
2528 _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
2529 template <class _ForwardIterator>
2530 _ForwardIterator
2531 __parse_collating_symbol(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>& __col_sym);
2532 template <class _ForwardIterator>
2533 _ForwardIterator __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c);
2534 template <class _ForwardIterator>
2535 _ForwardIterator __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
2536 template <class _ForwardIterator>
2537 _ForwardIterator __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last);
2538 template <class _ForwardIterator>
2539 _ForwardIterator __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last);
2540 template <class _ForwardIterator>
2541 _ForwardIterator __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last);
2542 template <class _ForwardIterator>
2543 _ForwardIterator __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
2544 template <class _ForwardIterator>
2545 _ForwardIterator __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
2546 template <class _ForwardIterator>
2547 _ForwardIterator __parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last);
2548 template <class _ForwardIterator>
2549 _ForwardIterator __parse_alternative(_ForwardIterator __first, _ForwardIterator __last);
2550 template <class _ForwardIterator>
2551 _ForwardIterator __parse_term(_ForwardIterator __first, _ForwardIterator __last);
2552 template <class _ForwardIterator>
2553 _ForwardIterator __parse_assertion(_ForwardIterator __first, _ForwardIterator __last);
2554 template <class _ForwardIterator>
2555 _ForwardIterator __parse_atom(_ForwardIterator __first, _ForwardIterator __last);
2556 template <class _ForwardIterator>
2557 _ForwardIterator __parse_atom_escape(_ForwardIterator __first, _ForwardIterator __last);
2558 template <class _ForwardIterator>
2559 _ForwardIterator __parse_decimal_escape(_ForwardIterator __first, _ForwardIterator __last);
2560 template <class _ForwardIterator>
2561 _ForwardIterator __parse_character_class_escape(_ForwardIterator __first, _ForwardIterator __last);
2562 template <class _ForwardIterator>
2563 _ForwardIterator
2564 __parse_character_escape(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str = nullptr);
2565 template <class _ForwardIterator>
2566 _ForwardIterator __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last);
2567 template <class _ForwardIterator>
2568 _ForwardIterator __parse_grep(_ForwardIterator __first, _ForwardIterator __last);
2569 template <class _ForwardIterator>
2570 _ForwardIterator __parse_egrep(_ForwardIterator __first, _ForwardIterator __last);
2571 template <class _ForwardIterator>
2572 _ForwardIterator __parse_class_escape(
2573 _ForwardIterator __first,
2574 _ForwardIterator __last,
2575 basic_string<_CharT>& __str,
2576 __bracket_expression<_CharT, _Traits>* __ml);
2577 template <class _ForwardIterator>
2578 _ForwardIterator
2579 __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str = nullptr);
2580
2581 bool __test_back_ref(_CharT);
2582
2583 _LIBCPP_HIDE_FROM_ABI void __push_l_anchor();
2584 void __push_r_anchor();
2585 void __push_match_any();
2586 void __push_match_any_but_newline();
2587 _LIBCPP_HIDE_FROM_ABI void __push_greedy_inf_repeat(
2588 size_t __min, __owns_one_state<_CharT>* __s, unsigned __mexp_begin = 0, unsigned __mexp_end = 0) {
2589 __push_loop(__min, max: numeric_limits<size_t>::max(), __s, __mexp_begin, __mexp_end);
2590 }
2591 _LIBCPP_HIDE_FROM_ABI void __push_nongreedy_inf_repeat(
2592 size_t __min, __owns_one_state<_CharT>* __s, unsigned __mexp_begin = 0, unsigned __mexp_end = 0) {
2593 __push_loop(__min, max: numeric_limits<size_t>::max(), __s, __mexp_begin, __mexp_end, greedy: false);
2594 }
2595 void __push_loop(size_t __min,
2596 size_t __max,
2597 __owns_one_state<_CharT>* __s,
2598 size_t __mexp_begin = 0,
2599 size_t __mexp_end = 0,
2600 bool __greedy = true);
2601 __bracket_expression<_CharT, _Traits>* __start_matching_list(bool __negate);
2602 void __push_char(value_type __c);
2603 void __push_back_ref(int __i);
2604 void __push_alternation(__owns_one_state<_CharT>* __sa, __owns_one_state<_CharT>* __sb);
2605 void __push_begin_marked_subexpression();
2606 void __push_end_marked_subexpression(unsigned);
2607 void __push_empty();
2608 void __push_word_boundary(bool);
2609 void __push_lookahead(const basic_regex&, bool, unsigned);
2610
2611 template <class _Allocator>
2612 bool __search(const _CharT* __first,
2613 const _CharT* __last,
2614 match_results<const _CharT*, _Allocator>& __m,
2615 regex_constants::match_flag_type __flags) const;
2616
2617 template <class _Allocator>
2618 bool __match_at_start(const _CharT* __first,
2619 const _CharT* __last,
2620 match_results<const _CharT*, _Allocator>& __m,
2621 regex_constants::match_flag_type __flags,
2622 bool) const;
2623 template <class _Allocator>
2624 bool __match_at_start_ecma(
2625 const _CharT* __first,
2626 const _CharT* __last,
2627 match_results<const _CharT*, _Allocator>& __m,
2628 regex_constants::match_flag_type __flags,
2629 bool) const;
2630 template <class _Allocator>
2631 bool __match_at_start_posix_nosubs(
2632 const _CharT* __first,
2633 const _CharT* __last,
2634 match_results<const _CharT*, _Allocator>& __m,
2635 regex_constants::match_flag_type __flags,
2636 bool) const;
2637 template <class _Allocator>
2638 bool __match_at_start_posix_subs(
2639 const _CharT* __first,
2640 const _CharT* __last,
2641 match_results<const _CharT*, _Allocator>& __m,
2642 regex_constants::match_flag_type __flags,
2643 bool) const;
2644
2645 template <class _Bp, class _Ap, class _Cp, class _Tp>
2646 friend bool
2647 regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
2648
2649 template <class _Ap, class _Cp, class _Tp>
2650 friend bool
2651 regex_search(const _Cp*,
2652 const _Cp*,
2653 match_results<const _Cp*, _Ap>&,
2654 const basic_regex<_Cp, _Tp>&,
2655 regex_constants::match_flag_type);
2656
2657 template <class _Bp, class _Cp, class _Tp>
2658 friend bool regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
2659
2660 template <class _Cp, class _Tp>
2661 friend bool regex_search(const _Cp*, const _Cp*, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
2662
2663 template <class _Cp, class _Ap, class _Tp>
2664 friend bool regex_search(
2665 const _Cp*, match_results<const _Cp*, _Ap>&, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
2666
2667 template <class _ST, class _SA, class _Cp, class _Tp>
2668 friend bool regex_search(const basic_string<_Cp, _ST, _SA>& __s,
2669 const basic_regex<_Cp, _Tp>& __e,
2670 regex_constants::match_flag_type __flags);
2671
2672 template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
2673 friend bool regex_search(const basic_string<_Cp, _ST, _SA>& __s,
2674 match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,
2675 const basic_regex<_Cp, _Tp>& __e,
2676 regex_constants::match_flag_type __flags);
2677
2678 template <class _Iter, class _Ap, class _Cp, class _Tp>
2679 friend bool
2680 regex_search(__wrap_iter<_Iter> __first,
2681 __wrap_iter<_Iter> __last,
2682 match_results<__wrap_iter<_Iter>, _Ap>& __m,
2683 const basic_regex<_Cp, _Tp>& __e,
2684 regex_constants::match_flag_type __flags);
2685
2686 template <class, class>
2687 friend class __lookahead;
2688};
2689
2690# if _LIBCPP_STD_VER >= 17
2691template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
2692basic_regex(_ForwardIterator, _ForwardIterator, regex_constants::syntax_option_type = regex_constants::ECMAScript)
2693 -> basic_regex<typename iterator_traits<_ForwardIterator>::value_type>;
2694# endif
2695
2696template <class _CharT, class _Traits>
2697const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase;
2698template <class _CharT, class _Traits>
2699const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::nosubs;
2700template <class _CharT, class _Traits>
2701const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::optimize;
2702template <class _CharT, class _Traits>
2703const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::collate;
2704template <class _CharT, class _Traits>
2705const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::ECMAScript;
2706template <class _CharT, class _Traits>
2707const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::basic;
2708template <class _CharT, class _Traits>
2709const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::extended;
2710template <class _CharT, class _Traits>
2711const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::awk;
2712template <class _CharT, class _Traits>
2713const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::grep;
2714template <class _CharT, class _Traits>
2715const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::egrep;
2716
2717template <class _CharT, class _Traits>
2718void basic_regex<_CharT, _Traits>::swap(basic_regex& __r) {
2719 using std::swap;
2720 swap(__traits_, __r.__traits_);
2721 swap(__flags_, __r.__flags_);
2722 swap(__marked_count_, __r.__marked_count_);
2723 swap(__loop_count_, __r.__loop_count_);
2724 swap(__open_count_, __r.__open_count_);
2725 swap(__start_, __r.__start_);
2726 swap(__end_, __r.__end_);
2727}
2728
2729template <class _CharT, class _Traits>
2730inline _LIBCPP_HIDE_FROM_ABI void swap(basic_regex<_CharT, _Traits>& __x, basic_regex<_CharT, _Traits>& __y) {
2731 return __x.swap(__y);
2732}
2733
2734// __lookahead
2735
2736template <class _CharT, class _Traits>
2737class __lookahead : public __owns_one_state<_CharT> {
2738 typedef __owns_one_state<_CharT> base;
2739
2740 basic_regex<_CharT, _Traits> __exp_;
2741 unsigned __mexp_;
2742 bool __invert_;
2743
2744public:
2745 typedef std::__state<_CharT> __state;
2746
2747 _LIBCPP_HIDE_FROM_ABI
2748 __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)
2749 : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {}
2750
2751 __lookahead(const __lookahead&) = delete;
2752 __lookahead& operator=(const __lookahead&) = delete;
2753
2754 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
2755};
2756
2757template <class _CharT, class _Traits>
2758void __lookahead<_CharT, _Traits>::__exec(__state& __s) const {
2759 match_results<const _CharT*> __m;
2760 __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_);
2761 bool __matched = __exp_.__match_at_start_ecma(
2762 __s.__current_,
2763 __s.__last_,
2764 __m,
2765 (__s.__flags_ | regex_constants::match_continuous) & ~regex_constants::__full_match,
2766 __s.__at_first_ && __s.__current_ == __s.__first_);
2767 if (__matched != __invert_) {
2768 __s.__do_ = __state::__accept_but_not_consume;
2769 __s.__node_ = this->first();
2770 for (unsigned __i = 1; __i < __m.size(); ++__i) {
2771 __s.__sub_matches_[__mexp_ + __i - 1] = __m.__matches_[__i];
2772 }
2773 } else {
2774 __s.__do_ = __state::__reject;
2775 __s.__node_ = nullptr;
2776 }
2777}
2778
2779template <class _CharT, class _Traits>
2780template <class _ForwardIterator>
2781void basic_regex<_CharT, _Traits>::__init(_ForwardIterator __first, _ForwardIterator __last) {
2782 if (__get_grammar(g: __flags_) == 0)
2783 __flags_ |= regex_constants::ECMAScript;
2784 _ForwardIterator __temp = __parse(__first, __last);
2785 if (__temp != __last)
2786 std::__throw_regex_error<regex_constants::__re_err_parse>();
2787}
2788
2789template <class _CharT, class _Traits>
2790template <class _ForwardIterator>
2791_ForwardIterator basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first, _ForwardIterator __last) {
2792 {
2793 unique_ptr<__node> __h(new __end_state<_CharT>);
2794 __start_.reset(new __empty_state<_CharT>(__h.get()));
2795 __h.release();
2796 __end_ = __start_.get();
2797 }
2798 switch (__get_grammar(g: __flags_)) {
2799 case ECMAScript:
2800 __first = __parse_ecma_exp(__first, __last);
2801 break;
2802 case basic:
2803 __first = __parse_basic_reg_exp(__first, __last);
2804 break;
2805 case extended:
2806 case awk:
2807 __first = __parse_extended_reg_exp(__first, __last);
2808 break;
2809 case grep:
2810 __first = __parse_grep(__first, __last);
2811 break;
2812 case egrep:
2813 __first = __parse_egrep(__first, __last);
2814 break;
2815 default:
2816 std::__throw_regex_error<regex_constants::__re_err_grammar>();
2817 }
2818 return __first;
2819}
2820
2821template <class _CharT, class _Traits>
2822template <class _ForwardIterator>
2823_ForwardIterator
2824basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last) {
2825 if (__first != __last) {
2826 if (*__first == '^') {
2827 __push_l_anchor();
2828 ++__first;
2829 }
2830 if (__first != __last) {
2831 __first = __parse_RE_expression(__first, __last);
2832 if (__first != __last) {
2833 _ForwardIterator __temp = std::next(__first);
2834 if (__temp == __last && *__first == '$') {
2835 __push_r_anchor();
2836 ++__first;
2837 }
2838 }
2839 }
2840 if (__first != __last)
2841 std::__throw_regex_error<regex_constants::__re_err_empty>();
2842 }
2843 return __first;
2844}
2845
2846template <class _CharT, class _Traits>
2847template <class _ForwardIterator>
2848_ForwardIterator
2849basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last) {
2850 __owns_one_state<_CharT>* __sa = __end_;
2851 _ForwardIterator __temp = __parse_ERE_branch(__first, __last);
2852 if (__temp == __first)
2853 std::__throw_regex_error<regex_constants::__re_err_empty>();
2854 __first = __temp;
2855 while (__first != __last && *__first == '|') {
2856 __owns_one_state<_CharT>* __sb = __end_;
2857 __temp = __parse_ERE_branch(++__first, __last);
2858 if (__temp == __first)
2859 std::__throw_regex_error<regex_constants::__re_err_empty>();
2860 __push_alternation(__sa, __sb);
2861 __first = __temp;
2862 }
2863 return __first;
2864}
2865
2866template <class _CharT, class _Traits>
2867template <class _ForwardIterator>
2868_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last) {
2869 _ForwardIterator __temp = __parse_ERE_expression(__first, __last);
2870 if (__temp == __first)
2871 std::__throw_regex_error<regex_constants::__re_err_empty>();
2872 do {
2873 __first = __temp;
2874 __temp = __parse_ERE_expression(__first, __last);
2875 } while (__temp != __first);
2876 return __first;
2877}
2878
2879template <class _CharT, class _Traits>
2880template <class _ForwardIterator>
2881_ForwardIterator
2882basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last) {
2883 __owns_one_state<_CharT>* __e = __end_;
2884 unsigned __mexp_begin = __marked_count_;
2885 _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last);
2886 if (__temp == __first && __temp != __last) {
2887 switch (*__temp) {
2888 case '^':
2889 __push_l_anchor();
2890 ++__temp;
2891 break;
2892 case '$':
2893 __push_r_anchor();
2894 ++__temp;
2895 break;
2896 case '(':
2897 __push_begin_marked_subexpression();
2898 unsigned __temp_count = __marked_count_;
2899 ++__open_count_;
2900 __temp = __parse_extended_reg_exp(++__temp, __last);
2901 if (__temp == __last || *__temp != ')')
2902 std::__throw_regex_error<regex_constants::error_paren>();
2903 __push_end_marked_subexpression(__temp_count);
2904 --__open_count_;
2905 ++__temp;
2906 break;
2907 }
2908 }
2909 if (__temp != __first)
2910 __temp = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin + 1, __marked_count_ + 1);
2911 __first = __temp;
2912 return __first;
2913}
2914
2915template <class _CharT, class _Traits>
2916template <class _ForwardIterator>
2917_ForwardIterator
2918basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last) {
2919 while (true) {
2920 _ForwardIterator __temp = __parse_simple_RE(__first, __last);
2921 if (__temp == __first)
2922 break;
2923 __first = __temp;
2924 }
2925 return __first;
2926}
2927
2928template <class _CharT, class _Traits>
2929template <class _ForwardIterator>
2930_ForwardIterator basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last) {
2931 if (__first != __last) {
2932 __owns_one_state<_CharT>* __e = __end_;
2933 unsigned __mexp_begin = __marked_count_;
2934 _ForwardIterator __temp = __parse_nondupl_RE(__first, __last);
2935 if (__temp != __first)
2936 __first = __parse_RE_dupl_symbol(__temp, __last, __e, __mexp_begin + 1, __marked_count_ + 1);
2937 }
2938 return __first;
2939}
2940
2941template <class _CharT, class _Traits>
2942template <class _ForwardIterator>
2943_ForwardIterator basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last) {
2944 _ForwardIterator __temp = __first;
2945 __first = __parse_one_char_or_coll_elem_RE(__first, __last);
2946 if (__temp == __first) {
2947 __temp = __parse_Back_open_paren(__first, __last);
2948 if (__temp != __first) {
2949 __push_begin_marked_subexpression();
2950 unsigned __temp_count = __marked_count_;
2951 __first = __parse_RE_expression(__temp, __last);
2952 __temp = __parse_Back_close_paren(__first, __last);
2953 if (__temp == __first)
2954 std::__throw_regex_error<regex_constants::error_paren>();
2955 __push_end_marked_subexpression(__temp_count);
2956 __first = __temp;
2957 } else
2958 __first = __parse_BACKREF(__first, __last);
2959 }
2960 return __first;
2961}
2962
2963template <class _CharT, class _Traits>
2964template <class _ForwardIterator>
2965_ForwardIterator
2966basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last) {
2967 _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last);
2968 if (__temp == __first) {
2969 __temp = __parse_QUOTED_CHAR(__first, __last);
2970 if (__temp == __first) {
2971 if (__temp != __last && *__temp == '.') {
2972 __push_match_any();
2973 ++__temp;
2974 } else
2975 __temp = __parse_bracket_expression(__first, __last);
2976 }
2977 }
2978 __first = __temp;
2979 return __first;
2980}
2981
2982template <class _CharT, class _Traits>
2983template <class _ForwardIterator>
2984_ForwardIterator
2985basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last) {
2986 _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last);
2987 if (__temp == __first) {
2988 __temp = __parse_QUOTED_CHAR_ERE(__first, __last);
2989 if (__temp == __first) {
2990 if (__temp != __last && *__temp == '.') {
2991 __push_match_any();
2992 ++__temp;
2993 } else
2994 __temp = __parse_bracket_expression(__first, __last);
2995 }
2996 }
2997 __first = __temp;
2998 return __first;
2999}
3000
3001template <class _CharT, class _Traits>
3002template <class _ForwardIterator>
3003_ForwardIterator
3004basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last) {
3005 if (__first != __last) {
3006 _ForwardIterator __temp = std::next(__first);
3007 if (__temp != __last) {
3008 if (*__first == '\\' && *__temp == '(')
3009 __first = ++__temp;
3010 }
3011 }
3012 return __first;
3013}
3014
3015template <class _CharT, class _Traits>
3016template <class _ForwardIterator>
3017_ForwardIterator
3018basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last) {
3019 if (__first != __last) {
3020 _ForwardIterator __temp = std::next(__first);
3021 if (__temp != __last) {
3022 if (*__first == '\\' && *__temp == ')')
3023 __first = ++__temp;
3024 }
3025 }
3026 return __first;
3027}
3028
3029template <class _CharT, class _Traits>
3030template <class _ForwardIterator>
3031_ForwardIterator
3032basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last) {
3033 if (__first != __last) {
3034 _ForwardIterator __temp = std::next(__first);
3035 if (__temp != __last) {
3036 if (*__first == '\\' && *__temp == '{')
3037 __first = ++__temp;
3038 }
3039 }
3040 return __first;
3041}
3042
3043template <class _CharT, class _Traits>
3044template <class _ForwardIterator>
3045_ForwardIterator
3046basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last) {
3047 if (__first != __last) {
3048 _ForwardIterator __temp = std::next(__first);
3049 if (__temp != __last) {
3050 if (*__first == '\\' && *__temp == '}')
3051 __first = ++__temp;
3052 }
3053 }
3054 return __first;
3055}
3056
3057template <class _CharT, class _Traits>
3058template <class _ForwardIterator>
3059_ForwardIterator basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last) {
3060 if (__first != __last) {
3061 _ForwardIterator __temp = std::next(__first);
3062 if (__temp != __last && *__first == '\\' && __test_back_ref(*__temp))
3063 __first = ++__temp;
3064 }
3065 return __first;
3066}
3067
3068template <class _CharT, class _Traits>
3069template <class _ForwardIterator>
3070_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last) {
3071 if (__first != __last) {
3072 _ForwardIterator __temp = std::next(__first);
3073 if (__temp == __last && *__first == '$')
3074 return __first;
3075 // Not called inside a bracket
3076 if (*__first == '.' || *__first == '\\' || *__first == '[')
3077 return __first;
3078 __push_char(c: *__first);
3079 ++__first;
3080 }
3081 return __first;
3082}
3083
3084template <class _CharT, class _Traits>
3085template <class _ForwardIterator>
3086_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last) {
3087 if (__first != __last) {
3088 switch (*__first) {
3089 case '^':
3090 case '.':
3091 case '[':
3092 case '$':
3093 case '(':
3094 case '|':
3095 case '*':
3096 case '+':
3097 case '?':
3098 case '{':
3099 case '\\':
3100 break;
3101 case ')':
3102 if (__open_count_ == 0) {
3103 __push_char(c: *__first);
3104 ++__first;
3105 }
3106 break;
3107 default:
3108 __push_char(c: *__first);
3109 ++__first;
3110 break;
3111 }
3112 }
3113 return __first;
3114}
3115
3116template <class _CharT, class _Traits>
3117template <class _ForwardIterator>
3118_ForwardIterator basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last) {
3119 if (__first != __last) {
3120 _ForwardIterator __temp = std::next(__first);
3121 if (__temp != __last) {
3122 if (*__first == '\\') {
3123 switch (*__temp) {
3124 case '^':
3125 case '.':
3126 case '*':
3127 case '[':
3128 case '$':
3129 case '\\':
3130 __push_char(c: *__temp);
3131 __first = ++__temp;
3132 break;
3133 }
3134 }
3135 }
3136 }
3137 return __first;
3138}
3139
3140template <class _CharT, class _Traits>
3141template <class _ForwardIterator>
3142_ForwardIterator
3143basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last) {
3144 if (__first != __last) {
3145 _ForwardIterator __temp = std::next(__first);
3146 if (__temp != __last) {
3147 if (*__first == '\\') {
3148 switch (*__temp) {
3149 case '^':
3150 case '.':
3151 case '*':
3152 case '[':
3153 case '$':
3154 case '\\':
3155 case '(':
3156 case ')':
3157 case '|':
3158 case '+':
3159 case '?':
3160 case '{':
3161 case '}':
3162 __push_char(c: *__temp);
3163 __first = ++__temp;
3164 break;
3165 default:
3166 if (__get_grammar(g: __flags_) == awk)
3167 __first = __parse_awk_escape(++__first, __last);
3168 else if (__test_back_ref(*__temp))
3169 __first = ++__temp;
3170 break;
3171 }
3172 }
3173 }
3174 }
3175 return __first;
3176}
3177
3178template <class _CharT, class _Traits>
3179template <class _ForwardIterator>
3180_ForwardIterator basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(
3181 _ForwardIterator __first,
3182 _ForwardIterator __last,
3183 __owns_one_state<_CharT>* __s,
3184 unsigned __mexp_begin,
3185 unsigned __mexp_end) {
3186 if (__first != __last) {
3187 if (*__first == '*') {
3188 __push_greedy_inf_repeat(min: 0, __s, __mexp_begin, __mexp_end);
3189 ++__first;
3190 } else {
3191 _ForwardIterator __temp = __parse_Back_open_brace(__first, __last);
3192 if (__temp != __first) {
3193 int __min = 0;
3194 __first = __temp;
3195 __temp = __parse_DUP_COUNT(__first, __last, __min);
3196 if (__temp == __first)
3197 std::__throw_regex_error<regex_constants::error_badbrace>();
3198 __first = __temp;
3199 if (__first == __last)
3200 std::__throw_regex_error<regex_constants::error_brace>();
3201 if (*__first != ',') {
3202 __temp = __parse_Back_close_brace(__first, __last);
3203 if (__temp == __first)
3204 std::__throw_regex_error<regex_constants::error_brace>();
3205 __push_loop(__min, max: __min, __s, __mexp_begin, __mexp_end, greedy: true);
3206 __first = __temp;
3207 } else {
3208 ++__first; // consume ','
3209 int __max = -1;
3210 __first = __parse_DUP_COUNT(__first, __last, __max);
3211 __temp = __parse_Back_close_brace(__first, __last);
3212 if (__temp == __first)
3213 std::__throw_regex_error<regex_constants::error_brace>();
3214 if (__max == -1)
3215 __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
3216 else {
3217 if (__max < __min)
3218 std::__throw_regex_error<regex_constants::error_badbrace>();
3219 __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, greedy: true);
3220 }
3221 __first = __temp;
3222 }
3223 }
3224 }
3225 }
3226 return __first;
3227}
3228
3229template <class _CharT, class _Traits>
3230template <class _ForwardIterator>
3231_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(
3232 _ForwardIterator __first,
3233 _ForwardIterator __last,
3234 __owns_one_state<_CharT>* __s,
3235 unsigned __mexp_begin,
3236 unsigned __mexp_end) {
3237 if (__first != __last) {
3238 unsigned __grammar = __get_grammar(g: __flags_);
3239 switch (*__first) {
3240 case '*':
3241 ++__first;
3242 if (__grammar == ECMAScript && __first != __last && *__first == '?') {
3243 ++__first;
3244 __push_nongreedy_inf_repeat(min: 0, __s, __mexp_begin, __mexp_end);
3245 } else
3246 __push_greedy_inf_repeat(min: 0, __s, __mexp_begin, __mexp_end);
3247 break;
3248 case '+':
3249 ++__first;
3250 if (__grammar == ECMAScript && __first != __last && *__first == '?') {
3251 ++__first;
3252 __push_nongreedy_inf_repeat(min: 1, __s, __mexp_begin, __mexp_end);
3253 } else
3254 __push_greedy_inf_repeat(min: 1, __s, __mexp_begin, __mexp_end);
3255 break;
3256 case '?':
3257 ++__first;
3258 if (__grammar == ECMAScript && __first != __last && *__first == '?') {
3259 ++__first;
3260 __push_loop(min: 0, max: 1, __s, __mexp_begin, __mexp_end, greedy: false);
3261 } else
3262 __push_loop(min: 0, max: 1, __s, __mexp_begin, __mexp_end);
3263 break;
3264 case '{': {
3265 int __min;
3266 _ForwardIterator __temp = __parse_DUP_COUNT(++__first, __last, __min);
3267 if (__temp == __first)
3268 std::__throw_regex_error<regex_constants::error_badbrace>();
3269 __first = __temp;
3270 if (__first == __last)
3271 std::__throw_regex_error<regex_constants::error_brace>();
3272 switch (*__first) {
3273 case '}':
3274 ++__first;
3275 if (__grammar == ECMAScript && __first != __last && *__first == '?') {
3276 ++__first;
3277 __push_loop(__min, max: __min, __s, __mexp_begin, __mexp_end, greedy: false);
3278 } else
3279 __push_loop(__min, max: __min, __s, __mexp_begin, __mexp_end);
3280 break;
3281 case ',':
3282 ++__first;
3283 if (__first == __last)
3284 std::__throw_regex_error<regex_constants::error_badbrace>();
3285 if (*__first == '}') {
3286 ++__first;
3287 if (__grammar == ECMAScript && __first != __last && *__first == '?') {
3288 ++__first;
3289 __push_nongreedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
3290 } else
3291 __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
3292 } else {
3293 int __max = -1;
3294 __temp = __parse_DUP_COUNT(__first, __last, __max);
3295 if (__temp == __first)
3296 std::__throw_regex_error<regex_constants::error_brace>();
3297 __first = __temp;
3298 if (__first == __last || *__first != '}')
3299 std::__throw_regex_error<regex_constants::error_brace>();
3300 ++__first;
3301 if (__max < __min)
3302 std::__throw_regex_error<regex_constants::error_badbrace>();
3303 if (__grammar == ECMAScript && __first != __last && *__first == '?') {
3304 ++__first;
3305 __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, greedy: false);
3306 } else
3307 __push_loop(__min, __max, __s, __mexp_begin, __mexp_end);
3308 }
3309 break;
3310 default:
3311 std::__throw_regex_error<regex_constants::error_badbrace>();
3312 }
3313 } break;
3314 }
3315 }
3316 return __first;
3317}
3318
3319template <class _CharT, class _Traits>
3320template <class _ForwardIterator>
3321_ForwardIterator
3322basic_regex<_CharT, _Traits>::__parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last) {
3323 if (__first != __last && *__first == '[') {
3324 ++__first;
3325 if (__first == __last)
3326 std::__throw_regex_error<regex_constants::error_brack>();
3327 bool __negate = false;
3328 if (*__first == '^') {
3329 ++__first;
3330 __negate = true;
3331 }
3332 __bracket_expression<_CharT, _Traits>* __ml = __start_matching_list(__negate);
3333 // __ml owned by *this
3334 if (__first == __last)
3335 std::__throw_regex_error<regex_constants::error_brack>();
3336 if (__get_grammar(g: __flags_) != ECMAScript && *__first == ']') {
3337 __ml->__add_char(']');
3338 ++__first;
3339 }
3340 __first = __parse_follow_list(__first, __last, __ml);
3341 if (__first == __last)
3342 std::__throw_regex_error<regex_constants::error_brack>();
3343 if (*__first == '-') {
3344 __ml->__add_char('-');
3345 ++__first;
3346 }
3347 if (__first == __last || *__first != ']')
3348 std::__throw_regex_error<regex_constants::error_brack>();
3349 ++__first;
3350 }
3351 return __first;
3352}
3353
3354template <class _CharT, class _Traits>
3355template <class _ForwardIterator>
3356_ForwardIterator basic_regex<_CharT, _Traits>::__parse_follow_list(
3357 _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
3358 if (__first != __last) {
3359 while (true) {
3360 _ForwardIterator __temp = __parse_expression_term(__first, __last, __ml);
3361 if (__temp == __first)
3362 break;
3363 __first = __temp;
3364 }
3365 }
3366 return __first;
3367}
3368
3369template <class _CharT, class _Traits>
3370template <class _ForwardIterator>
3371_ForwardIterator basic_regex<_CharT, _Traits>::__parse_expression_term(
3372 _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
3373 if (__first != __last && *__first != ']') {
3374 _ForwardIterator __temp = std::next(__first);
3375 basic_string<_CharT> __start_range;
3376 if (__temp != __last && *__first == '[') {
3377 if (*__temp == '=')
3378 return __parse_equivalence_class(++__temp, __last, __ml);
3379 else if (*__temp == ':')
3380 return __parse_character_class(++__temp, __last, __ml);
3381 else if (*__temp == '.')
3382 __first = __parse_collating_symbol(++__temp, __last, __start_range);
3383 }
3384 unsigned __grammar = __get_grammar(g: __flags_);
3385 if (__start_range.empty()) {
3386 if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\') {
3387 if (__grammar == ECMAScript)
3388 __first = __parse_class_escape(++__first, __last, __start_range, __ml);
3389 else
3390 __first = __parse_awk_escape(++__first, __last, std::addressof(__start_range));
3391 } else {
3392 __start_range = *__first;
3393 ++__first;
3394 }
3395 }
3396 if (__first != __last && *__first != ']') {
3397 __temp = std::next(__first);
3398 if (__temp != __last && *__first == '-' && *__temp != ']') {
3399 // parse a range
3400 basic_string<_CharT> __end_range;
3401 __first = __temp;
3402 ++__temp;
3403 if (__temp != __last && *__first == '[' && *__temp == '.')
3404 __first = __parse_collating_symbol(++__temp, __last, __end_range);
3405 else {
3406 if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\') {
3407 if (__grammar == ECMAScript)
3408 __first = __parse_class_escape(++__first, __last, __end_range, __ml);
3409 else
3410 __first = __parse_awk_escape(++__first, __last, std::addressof(__end_range));
3411 } else {
3412 __end_range = *__first;
3413 ++__first;
3414 }
3415 }
3416 __ml->__add_range(std::move(__start_range), std::move(__end_range));
3417 } else if (!__start_range.empty()) {
3418 if (__start_range.size() == 1)
3419 __ml->__add_char(__start_range[0]);
3420 else
3421 __ml->__add_digraph(__start_range[0], __start_range[1]);
3422 }
3423 } else if (!__start_range.empty()) {
3424 if (__start_range.size() == 1)
3425 __ml->__add_char(__start_range[0]);
3426 else
3427 __ml->__add_digraph(__start_range[0], __start_range[1]);
3428 }
3429 }
3430 return __first;
3431}
3432
3433template <class _CharT, class _Traits>
3434template <class _ForwardIterator>
3435_ForwardIterator basic_regex<_CharT, _Traits>::__parse_class_escape(
3436 _ForwardIterator __first,
3437 _ForwardIterator __last,
3438 basic_string<_CharT>& __str,
3439 __bracket_expression<_CharT, _Traits>* __ml) {
3440 if (__first == __last)
3441 std::__throw_regex_error<regex_constants::error_escape>();
3442 switch (*__first) {
3443 case 0:
3444 __str = *__first;
3445 return ++__first;
3446 case 'b':
3447 __str = _CharT(8);
3448 return ++__first;
3449 case 'd':
3450 __ml->__add_class(ctype_base::digit);
3451 return ++__first;
3452 case 'D':
3453 __ml->__add_neg_class(ctype_base::digit);
3454 return ++__first;
3455 case 's':
3456 __ml->__add_class(ctype_base::space);
3457 return ++__first;
3458 case 'S':
3459 __ml->__add_neg_class(ctype_base::space);
3460 return ++__first;
3461 case 'w':
3462 __ml->__add_class(ctype_base::alnum);
3463 __ml->__add_char('_');
3464 return ++__first;
3465 case 'W':
3466 __ml->__add_neg_class(ctype_base::alnum);
3467 __ml->__add_neg_char('_');
3468 return ++__first;
3469 }
3470 __first = __parse_character_escape(__first, __last, std::addressof(__str));
3471 return __first;
3472}
3473
3474template <class _CharT, class _Traits>
3475template <class _ForwardIterator>
3476_ForwardIterator basic_regex<_CharT, _Traits>::__parse_awk_escape(
3477 _ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str) {
3478 if (__first == __last)
3479 std::__throw_regex_error<regex_constants::error_escape>();
3480 switch (*__first) {
3481 case '\\':
3482 case '"':
3483 case '/':
3484 if (__str)
3485 *__str = *__first;
3486 else
3487 __push_char(c: *__first);
3488 return ++__first;
3489 case 'a':
3490 if (__str)
3491 *__str = _CharT(7);
3492 else
3493 __push_char(c: _CharT(7));
3494 return ++__first;
3495 case 'b':
3496 if (__str)
3497 *__str = _CharT(8);
3498 else
3499 __push_char(c: _CharT(8));
3500 return ++__first;
3501 case 'f':
3502 if (__str)
3503 *__str = _CharT(0xC);
3504 else
3505 __push_char(c: _CharT(0xC));
3506 return ++__first;
3507 case 'n':
3508 if (__str)
3509 *__str = _CharT(0xA);
3510 else
3511 __push_char(c: _CharT(0xA));
3512 return ++__first;
3513 case 'r':
3514 if (__str)
3515 *__str = _CharT(0xD);
3516 else
3517 __push_char(c: _CharT(0xD));
3518 return ++__first;
3519 case 't':
3520 if (__str)
3521 *__str = _CharT(0x9);
3522 else
3523 __push_char(c: _CharT(0x9));
3524 return ++__first;
3525 case 'v':
3526 if (__str)
3527 *__str = _CharT(0xB);
3528 else
3529 __push_char(c: _CharT(0xB));
3530 return ++__first;
3531 }
3532 if ('0' <= *__first && *__first <= '7') {
3533 unsigned __val = *__first - '0';
3534 if (++__first != __last && ('0' <= *__first && *__first <= '7')) {
3535 __val = 8 * __val + *__first - '0';
3536 if (++__first != __last && ('0' <= *__first && *__first <= '7'))
3537 __val = 8 * __val + *__first++ - '0';
3538 }
3539 if (__str)
3540 *__str = _CharT(__val);
3541 else
3542 __push_char(c: _CharT(__val));
3543 } else
3544 std::__throw_regex_error<regex_constants::error_escape>();
3545 return __first;
3546}
3547
3548template <class _CharT, class _Traits>
3549template <class _ForwardIterator>
3550_ForwardIterator basic_regex<_CharT, _Traits>::__parse_equivalence_class(
3551 _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
3552 // Found [=
3553 // This means =] must exist
3554 value_type __equal_close[2] = {'=', ']'};
3555 _ForwardIterator __temp = std::search(__first, __last, __equal_close, __equal_close + 2);
3556 if (__temp == __last)
3557 std::__throw_regex_error<regex_constants::error_brack>();
3558 // [__first, __temp) contains all text in [= ... =]
3559 string_type __collate_name = __traits_.lookup_collatename(__first, __temp);
3560 if (__collate_name.empty())
3561 std::__throw_regex_error<regex_constants::error_collate>();
3562 string_type __equiv_name = __traits_.transform_primary(__collate_name.begin(), __collate_name.end());
3563 if (!__equiv_name.empty())
3564 __ml->__add_equivalence(__equiv_name);
3565 else {
3566 switch (__collate_name.size()) {
3567 case 1:
3568 __ml->__add_char(__collate_name[0]);
3569 break;
3570 case 2:
3571 __ml->__add_digraph(__collate_name[0], __collate_name[1]);
3572 break;
3573 default:
3574 std::__throw_regex_error<regex_constants::error_collate>();
3575 }
3576 }
3577 __first = std::next(__temp, 2);
3578 return __first;
3579}
3580
3581template <class _CharT, class _Traits>
3582template <class _ForwardIterator>
3583_ForwardIterator basic_regex<_CharT, _Traits>::__parse_character_class(
3584 _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
3585 // Found [:
3586 // This means :] must exist
3587 value_type __colon_close[2] = {':', ']'};
3588 _ForwardIterator __temp = std::search(__first, __last, __colon_close, __colon_close + 2);
3589 if (__temp == __last)
3590 std::__throw_regex_error<regex_constants::error_brack>();
3591 // [__first, __temp) contains all text in [: ... :]
3592 typedef typename _Traits::char_class_type char_class_type;
3593 char_class_type __class_type = __traits_.lookup_classname(__first, __temp, __flags_ & icase);
3594 if (__class_type == 0)
3595 std::__throw_regex_error<regex_constants::error_ctype>();
3596 __ml->__add_class(__class_type);
3597 __first = std::next(__temp, 2);
3598 return __first;
3599}
3600
3601template <class _CharT, class _Traits>
3602template <class _ForwardIterator>
3603_ForwardIterator basic_regex<_CharT, _Traits>::__parse_collating_symbol(
3604 _ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>& __col_sym) {
3605 // Found [.
3606 // This means .] must exist
3607 value_type __dot_close[2] = {'.', ']'};
3608 _ForwardIterator __temp = std::search(__first, __last, __dot_close, __dot_close + 2);
3609 if (__temp == __last)
3610 std::__throw_regex_error<regex_constants::error_brack>();
3611 // [__first, __temp) contains all text in [. ... .]
3612 __col_sym = __traits_.lookup_collatename(__first, __temp);
3613 switch (__col_sym.size()) {
3614 case 1:
3615 case 2:
3616 break;
3617 default:
3618 std::__throw_regex_error<regex_constants::error_collate>();
3619 }
3620 __first = std::next(__temp, 2);
3621 return __first;
3622}
3623
3624template <class _CharT, class _Traits>
3625template <class _ForwardIterator>
3626_ForwardIterator
3627basic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c) {
3628 if (__first != __last) {
3629 int __val = __traits_.value(*__first, 10);
3630 if (__val != -1) {
3631 __c = __val;
3632 for (++__first; __first != __last && (__val = __traits_.value(*__first, 10)) != -1; ++__first) {
3633 if (__c >= numeric_limits<int>::max() / 10)
3634 std::__throw_regex_error<regex_constants::error_badbrace>();
3635 __c *= 10;
3636 __c += __val;
3637 }
3638 }
3639 }
3640 return __first;
3641}
3642
3643template <class _CharT, class _Traits>
3644template <class _ForwardIterator>
3645_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last) {
3646 __owns_one_state<_CharT>* __sa = __end_;
3647 _ForwardIterator __temp = __parse_alternative(__first, __last);
3648 if (__temp == __first)
3649 __push_empty();
3650 __first = __temp;
3651 while (__first != __last && *__first == '|') {
3652 __owns_one_state<_CharT>* __sb = __end_;
3653 __temp = __parse_alternative(++__first, __last);
3654 if (__temp == __first)
3655 __push_empty();
3656 __push_alternation(__sa, __sb);
3657 __first = __temp;
3658 }
3659 return __first;
3660}
3661
3662template <class _CharT, class _Traits>
3663template <class _ForwardIterator>
3664_ForwardIterator basic_regex<_CharT, _Traits>::__parse_alternative(_ForwardIterator __first, _ForwardIterator __last) {
3665 while (true) {
3666 _ForwardIterator __temp = __parse_term(__first, __last);
3667 if (__temp == __first)
3668 break;
3669 __first = __temp;
3670 }
3671 return __first;
3672}
3673
3674template <class _CharT, class _Traits>
3675template <class _ForwardIterator>
3676_ForwardIterator basic_regex<_CharT, _Traits>::__parse_term(_ForwardIterator __first, _ForwardIterator __last) {
3677 _ForwardIterator __temp = __parse_assertion(__first, __last);
3678 if (__temp == __first) {
3679 __owns_one_state<_CharT>* __e = __end_;
3680 unsigned __mexp_begin = __marked_count_;
3681 __temp = __parse_atom(__first, __last);
3682 if (__temp != __first)
3683 __first = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin + 1, __marked_count_ + 1);
3684 } else
3685 __first = __temp;
3686 return __first;
3687}
3688
3689template <class _CharT, class _Traits>
3690template <class _ForwardIterator>
3691_ForwardIterator basic_regex<_CharT, _Traits>::__parse_assertion(_ForwardIterator __first, _ForwardIterator __last) {
3692 if (__first != __last) {
3693 switch (*__first) {
3694 case '^':
3695 __push_l_anchor();
3696 ++__first;
3697 break;
3698 case '$':
3699 __push_r_anchor();
3700 ++__first;
3701 break;
3702 case '\\': {
3703 _ForwardIterator __temp = std::next(__first);
3704 if (__temp != __last) {
3705 if (*__temp == 'b') {
3706 __push_word_boundary(false);
3707 __first = ++__temp;
3708 } else if (*__temp == 'B') {
3709 __push_word_boundary(true);
3710 __first = ++__temp;
3711 }
3712 }
3713 } break;
3714 case '(': {
3715 _ForwardIterator __temp = std::next(__first);
3716 if (__temp != __last && *__temp == '?') {
3717 if (++__temp != __last) {
3718 switch (*__temp) {
3719 case '=': {
3720 basic_regex __exp;
3721 __exp.__flags_ = __flags_;
3722 __temp = __exp.__parse(++__temp, __last);
3723 unsigned __mexp = __exp.__marked_count_;
3724 __push_lookahead(std::move(__exp), false, __marked_count_);
3725 __marked_count_ += __mexp;
3726 if (__temp == __last || *__temp != ')')
3727 std::__throw_regex_error<regex_constants::error_paren>();
3728 __first = ++__temp;
3729 } break;
3730 case '!': {
3731 basic_regex __exp;
3732 __exp.__flags_ = __flags_;
3733 __temp = __exp.__parse(++__temp, __last);
3734 unsigned __mexp = __exp.__marked_count_;
3735 __push_lookahead(std::move(__exp), true, __marked_count_);
3736 __marked_count_ += __mexp;
3737 if (__temp == __last || *__temp != ')')
3738 std::__throw_regex_error<regex_constants::error_paren>();
3739 __first = ++__temp;
3740 } break;
3741 }
3742 }
3743 }
3744 } break;
3745 }
3746 }
3747 return __first;
3748}
3749
3750template <class _CharT, class _Traits>
3751template <class _ForwardIterator>
3752_ForwardIterator basic_regex<_CharT, _Traits>::__parse_atom(_ForwardIterator __first, _ForwardIterator __last) {
3753 if (__first != __last) {
3754 switch (*__first) {
3755 case '.':
3756 __push_match_any_but_newline();
3757 ++__first;
3758 break;
3759 case '\\':
3760 __first = __parse_atom_escape(__first, __last);
3761 break;
3762 case '[':
3763 __first = __parse_bracket_expression(__first, __last);
3764 break;
3765 case '(': {
3766 ++__first;
3767 if (__first == __last)
3768 std::__throw_regex_error<regex_constants::error_paren>();
3769 _ForwardIterator __temp = std::next(__first);
3770 if (__temp != __last && *__first == '?' && *__temp == ':') {
3771 ++__open_count_;
3772 __first = __parse_ecma_exp(++__temp, __last);
3773 if (__first == __last || *__first != ')')
3774 std::__throw_regex_error<regex_constants::error_paren>();
3775 --__open_count_;
3776 ++__first;
3777 } else {
3778 __push_begin_marked_subexpression();
3779 unsigned __temp_count = __marked_count_;
3780 ++__open_count_;
3781 __first = __parse_ecma_exp(__first, __last);
3782 if (__first == __last || *__first != ')')
3783 std::__throw_regex_error<regex_constants::error_paren>();
3784 __push_end_marked_subexpression(__temp_count);
3785 --__open_count_;
3786 ++__first;
3787 }
3788 } break;
3789 case '*':
3790 case '+':
3791 case '?':
3792 case '{':
3793 std::__throw_regex_error<regex_constants::error_badrepeat>();
3794 break;
3795 default:
3796 __first = __parse_pattern_character(__first, __last);
3797 break;
3798 }
3799 }
3800 return __first;
3801}
3802
3803template <class _CharT, class _Traits>
3804template <class _ForwardIterator>
3805_ForwardIterator basic_regex<_CharT, _Traits>::__parse_atom_escape(_ForwardIterator __first, _ForwardIterator __last) {
3806 if (__first != __last && *__first == '\\') {
3807 _ForwardIterator __t1 = std::next(__first);
3808 if (__t1 == __last)
3809 std::__throw_regex_error<regex_constants::error_escape>();
3810
3811 _ForwardIterator __t2 = __parse_decimal_escape(__t1, __last);
3812 if (__t2 != __t1)
3813 __first = __t2;
3814 else {
3815 __t2 = __parse_character_class_escape(__t1, __last);
3816 if (__t2 != __t1)
3817 __first = __t2;
3818 else {
3819 __t2 = __parse_character_escape(__t1, __last);
3820 if (__t2 != __t1)
3821 __first = __t2;
3822 }
3823 }
3824 }
3825 return __first;
3826}
3827
3828template <class _CharT, class _Traits>
3829template <class _ForwardIterator>
3830_ForwardIterator
3831basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first, _ForwardIterator __last) {
3832 if (__first != __last) {
3833 if (*__first == '0') {
3834 __push_char(c: _CharT());
3835 ++__first;
3836 } else if ('1' <= *__first && *__first <= '9') {
3837 unsigned __v = *__first - '0';
3838 for (++__first; __first != __last && '0' <= *__first && *__first <= '9'; ++__first) {
3839 if (__v >= numeric_limits<unsigned>::max() / 10)
3840 std::__throw_regex_error<regex_constants::error_backref>();
3841 __v = 10 * __v + *__first - '0';
3842 }
3843 if (__v == 0 || __v > mark_count())
3844 std::__throw_regex_error<regex_constants::error_backref>();
3845 __push_back_ref(i: __v);
3846 }
3847 }
3848 return __first;
3849}
3850
3851template <class _CharT, class _Traits>
3852template <class _ForwardIterator>
3853_ForwardIterator
3854basic_regex<_CharT, _Traits>::__parse_character_class_escape(_ForwardIterator __first, _ForwardIterator __last) {
3855 if (__first != __last) {
3856 __bracket_expression<_CharT, _Traits>* __ml;
3857 switch (*__first) {
3858 case 'd':
3859 __ml = __start_matching_list(negate: false);
3860 __ml->__add_class(ctype_base::digit);
3861 ++__first;
3862 break;
3863 case 'D':
3864 __ml = __start_matching_list(negate: true);
3865 __ml->__add_class(ctype_base::digit);
3866 ++__first;
3867 break;
3868 case 's':
3869 __ml = __start_matching_list(negate: false);
3870 __ml->__add_class(ctype_base::space);
3871 ++__first;
3872 break;
3873 case 'S':
3874 __ml = __start_matching_list(negate: true);
3875 __ml->__add_class(ctype_base::space);
3876 ++__first;
3877 break;
3878 case 'w':
3879 __ml = __start_matching_list(negate: false);
3880 __ml->__add_class(ctype_base::alnum);
3881 __ml->__add_char('_');
3882 ++__first;
3883 break;
3884 case 'W':
3885 __ml = __start_matching_list(negate: true);
3886 __ml->__add_class(ctype_base::alnum);
3887 __ml->__add_char('_');
3888 ++__first;
3889 break;
3890 }
3891 }
3892 return __first;
3893}
3894
3895template <class _CharT, class _Traits>
3896template <class _ForwardIterator>
3897_ForwardIterator basic_regex<_CharT, _Traits>::__parse_character_escape(
3898 _ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str) {
3899 if (__first != __last) {
3900 _ForwardIterator __t;
3901 unsigned __sum = 0;
3902 int __hd;
3903 switch (*__first) {
3904 case 'f':
3905 if (__str)
3906 *__str = _CharT(0xC);
3907 else
3908 __push_char(c: _CharT(0xC));
3909 ++__first;
3910 break;
3911 case 'n':
3912 if (__str)
3913 *__str = _CharT(0xA);
3914 else
3915 __push_char(c: _CharT(0xA));
3916 ++__first;
3917 break;
3918 case 'r':
3919 if (__str)
3920 *__str = _CharT(0xD);
3921 else
3922 __push_char(c: _CharT(0xD));
3923 ++__first;
3924 break;
3925 case 't':
3926 if (__str)
3927 *__str = _CharT(0x9);
3928 else
3929 __push_char(c: _CharT(0x9));
3930 ++__first;
3931 break;
3932 case 'v':
3933 if (__str)
3934 *__str = _CharT(0xB);
3935 else
3936 __push_char(c: _CharT(0xB));
3937 ++__first;
3938 break;
3939 case 'c':
3940 if ((__t = std::next(__first)) != __last) {
3941 if (('A' <= *__t && *__t <= 'Z') || ('a' <= *__t && *__t <= 'z')) {
3942 if (__str)
3943 *__str = _CharT(*__t % 32);
3944 else
3945 __push_char(c: _CharT(*__t % 32));
3946 __first = ++__t;
3947 } else
3948 std::__throw_regex_error<regex_constants::error_escape>();
3949 } else
3950 std::__throw_regex_error<regex_constants::error_escape>();
3951 break;
3952 case 'u':
3953 ++__first;
3954 if (__first == __last)
3955 std::__throw_regex_error<regex_constants::error_escape>();
3956 __hd = __traits_.value(*__first, 16);
3957 if (__hd == -1)
3958 std::__throw_regex_error<regex_constants::error_escape>();
3959 __sum = 16 * __sum + static_cast<unsigned>(__hd);
3960 ++__first;
3961 if (__first == __last)
3962 std::__throw_regex_error<regex_constants::error_escape>();
3963 __hd = __traits_.value(*__first, 16);
3964 if (__hd == -1)
3965 std::__throw_regex_error<regex_constants::error_escape>();
3966 __sum = 16 * __sum + static_cast<unsigned>(__hd);
3967 [[__fallthrough__]];
3968 case 'x':
3969 ++__first;
3970 if (__first == __last)
3971 std::__throw_regex_error<regex_constants::error_escape>();
3972 __hd = __traits_.value(*__first, 16);
3973 if (__hd == -1)
3974 std::__throw_regex_error<regex_constants::error_escape>();
3975 __sum = 16 * __sum + static_cast<unsigned>(__hd);
3976 ++__first;
3977 if (__first == __last)
3978 std::__throw_regex_error<regex_constants::error_escape>();
3979 __hd = __traits_.value(*__first, 16);
3980 if (__hd == -1)
3981 std::__throw_regex_error<regex_constants::error_escape>();
3982 __sum = 16 * __sum + static_cast<unsigned>(__hd);
3983 if (__str)
3984 *__str = _CharT(__sum);
3985 else
3986 __push_char(c: _CharT(__sum));
3987 ++__first;
3988 break;
3989 case '0':
3990 if (__str)
3991 *__str = _CharT(0);
3992 else
3993 __push_char(c: _CharT(0));
3994 ++__first;
3995 break;
3996 default:
3997 if (!__traits_.isctype(*__first, ctype_base::alnum)) {
3998 if (__str)
3999 *__str = *__first;
4000 else
4001 __push_char(c: *__first);
4002 ++__first;
4003 } else
4004 std::__throw_regex_error<regex_constants::error_escape>();
4005 break;
4006 }
4007 }
4008 return __first;
4009}
4010
4011template <class _CharT, class _Traits>
4012template <class _ForwardIterator>
4013_ForwardIterator
4014basic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last) {
4015 if (__first != __last) {
4016 switch (*__first) {
4017 case '^':
4018 case '$':
4019 case '\\':
4020 case '.':
4021 case '*':
4022 case '+':
4023 case '?':
4024 case '(':
4025 case ')':
4026 case '[':
4027 case ']':
4028 case '{':
4029 case '}':
4030 case '|':
4031 break;
4032 default:
4033 __push_char(c: *__first);
4034 ++__first;
4035 break;
4036 }
4037 }
4038 return __first;
4039}
4040
4041template <class _CharT, class _Traits>
4042template <class _ForwardIterator>
4043_ForwardIterator basic_regex<_CharT, _Traits>::__parse_grep(_ForwardIterator __first, _ForwardIterator __last) {
4044 __owns_one_state<_CharT>* __sa = __end_;
4045 _ForwardIterator __t1 = std::find(__first, __last, _CharT('\n'));
4046 if (__t1 != __first)
4047 __parse_basic_reg_exp(__first, __t1);
4048 else
4049 __push_empty();
4050 __first = __t1;
4051 if (__first != __last)
4052 ++__first;
4053 while (__first != __last) {
4054 __t1 = std::find(__first, __last, _CharT('\n'));
4055 __owns_one_state<_CharT>* __sb = __end_;
4056 if (__t1 != __first)
4057 __parse_basic_reg_exp(__first, __t1);
4058 else
4059 __push_empty();
4060 __push_alternation(__sa, __sb);
4061 __first = __t1;
4062 if (__first != __last)
4063 ++__first;
4064 }
4065 return __first;
4066}
4067
4068template <class _CharT, class _Traits>
4069template <class _ForwardIterator>
4070_ForwardIterator basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first, _ForwardIterator __last) {
4071 __owns_one_state<_CharT>* __sa = __end_;
4072 _ForwardIterator __t1 = std::find(__first, __last, _CharT('\n'));
4073 if (__t1 != __first)
4074 __parse_extended_reg_exp(__first, __t1);
4075 else
4076 __push_empty();
4077 __first = __t1;
4078 if (__first != __last)
4079 ++__first;
4080 while (__first != __last) {
4081 __t1 = std::find(__first, __last, _CharT('\n'));
4082 __owns_one_state<_CharT>* __sb = __end_;
4083 if (__t1 != __first)
4084 __parse_extended_reg_exp(__first, __t1);
4085 else
4086 __push_empty();
4087 __push_alternation(__sa, __sb);
4088 __first = __t1;
4089 if (__first != __last)
4090 ++__first;
4091 }
4092 return __first;
4093}
4094
4095template <class _CharT, class _Traits>
4096bool basic_regex<_CharT, _Traits>::__test_back_ref(_CharT __c) {
4097 unsigned __val = __traits_.value(__c, 10);
4098 if (__val >= 1 && __val <= 9) {
4099 if (__val > mark_count())
4100 std::__throw_regex_error<regex_constants::error_backref>();
4101 __push_back_ref(i: __val);
4102 return true;
4103 }
4104
4105 return false;
4106}
4107
4108template <class _CharT, class _Traits>
4109void basic_regex<_CharT, _Traits>::__push_loop(
4110 size_t __min, size_t __max, __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end, bool __greedy) {
4111 unique_ptr<__empty_state<_CharT> > __e1(new __empty_state<_CharT>(__end_->first()));
4112 __end_->first() = nullptr;
4113 unique_ptr<__loop<_CharT> > __e2(
4114 new __loop<_CharT>(__loop_count_, __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy, __min, __max));
4115 __s->first() = nullptr;
4116 __e1.release();
4117 __end_->first() = new __repeat_one_loop<_CharT>(__e2.get());
4118 __end_ = __e2->second();
4119 __s->first() = __e2.release();
4120 ++__loop_count_;
4121}
4122
4123template <class _CharT, class _Traits>
4124void basic_regex<_CharT, _Traits>::__push_char(value_type __c) {
4125 if (flags() & icase)
4126 __end_->first() = new __match_char_icase<_CharT, _Traits>(__traits_, __c, __end_->first());
4127 else if (flags() & collate)
4128 __end_->first() = new __match_char_collate<_CharT, _Traits>(__traits_, __c, __end_->first());
4129 else
4130 __end_->first() = new __match_char<_CharT>(__c, __end_->first());
4131 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4132}
4133
4134template <class _CharT, class _Traits>
4135void basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression() {
4136 if (!(__flags_ & nosubs)) {
4137 __end_->first() = new __begin_marked_subexpression<_CharT>(++__marked_count_, __end_->first());
4138 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4139 }
4140}
4141
4142template <class _CharT, class _Traits>
4143void basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub) {
4144 if (!(__flags_ & nosubs)) {
4145 __end_->first() = new __end_marked_subexpression<_CharT>(__sub, __end_->first());
4146 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4147 }
4148}
4149
4150template <class _CharT, class _Traits>
4151void basic_regex<_CharT, _Traits>::__push_l_anchor() {
4152 __end_->first() = new __l_anchor_multiline<_CharT>(__use_multiline(), __end_->first());
4153 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4154}
4155
4156template <class _CharT, class _Traits>
4157void basic_regex<_CharT, _Traits>::__push_r_anchor() {
4158 __end_->first() = new __r_anchor_multiline<_CharT>(__use_multiline(), __end_->first());
4159 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4160}
4161
4162template <class _CharT, class _Traits>
4163void basic_regex<_CharT, _Traits>::__push_match_any() {
4164 __end_->first() = new __match_any<_CharT>(__end_->first());
4165 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4166}
4167
4168template <class _CharT, class _Traits>
4169void basic_regex<_CharT, _Traits>::__push_match_any_but_newline() {
4170 __end_->first() = new __match_any_but_newline<_CharT>(__end_->first());
4171 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4172}
4173
4174template <class _CharT, class _Traits>
4175void basic_regex<_CharT, _Traits>::__push_empty() {
4176 __end_->first() = new __empty_state<_CharT>(__end_->first());
4177 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4178}
4179
4180template <class _CharT, class _Traits>
4181void basic_regex<_CharT, _Traits>::__push_word_boundary(bool __invert) {
4182 __end_->first() = new __word_boundary<_CharT, _Traits>(__traits_, __invert, __end_->first());
4183 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4184}
4185
4186template <class _CharT, class _Traits>
4187void basic_regex<_CharT, _Traits>::__push_back_ref(int __i) {
4188 if (flags() & icase)
4189 __end_->first() = new __back_ref_icase<_CharT, _Traits>(__traits_, __i, __end_->first());
4190 else if (flags() & collate)
4191 __end_->first() = new __back_ref_collate<_CharT, _Traits>(__traits_, __i, __end_->first());
4192 else
4193 __end_->first() = new __back_ref<_CharT>(__i, __end_->first());
4194 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4195}
4196
4197template <class _CharT, class _Traits>
4198void basic_regex<_CharT, _Traits>::__push_alternation(__owns_one_state<_CharT>* __sa, __owns_one_state<_CharT>* __ea) {
4199 __sa->first() = new __alternate<_CharT>(
4200 static_cast<__owns_one_state<_CharT>*>(__sa->first()), static_cast<__owns_one_state<_CharT>*>(__ea->first()));
4201 __ea->first() = nullptr;
4202 __ea->first() = new __empty_state<_CharT>(__end_->first());
4203 __end_->first() = nullptr;
4204 __end_->first() = new __empty_non_own_state<_CharT>(__ea->first());
4205 __end_ = static_cast<__owns_one_state<_CharT>*>(__ea->first());
4206}
4207
4208template <class _CharT, class _Traits>
4209__bracket_expression<_CharT, _Traits>* basic_regex<_CharT, _Traits>::__start_matching_list(bool __negate) {
4210 __bracket_expression<_CharT, _Traits>* __r = new __bracket_expression<_CharT, _Traits>(
4211 __traits_, __end_->first(), __negate, __flags_ & icase, __flags_ & collate);
4212 __end_->first() = __r;
4213 __end_ = __r;
4214 return __r;
4215}
4216
4217template <class _CharT, class _Traits>
4218void basic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp, bool __invert, unsigned __mexp) {
4219 __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert, __end_->first(), __mexp);
4220 __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
4221}
4222
4223// sub_match
4224
4225typedef sub_match<const char*> csub_match;
4226typedef sub_match<string::const_iterator> ssub_match;
4227# if _LIBCPP_HAS_WIDE_CHARACTERS
4228typedef sub_match<const wchar_t*> wcsub_match;
4229typedef sub_match<wstring::const_iterator> wssub_match;
4230# endif
4231
4232template <class _BidirectionalIterator>
4233class _LIBCPP_PREFERRED_NAME(csub_match) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wcsub_match))
4234 _LIBCPP_PREFERRED_NAME(ssub_match) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wssub_match)) sub_match
4235 : public pair<_BidirectionalIterator, _BidirectionalIterator> {
4236public:
4237 typedef _BidirectionalIterator iterator;
4238 typedef typename iterator_traits<iterator>::value_type value_type;
4239 typedef typename iterator_traits<iterator>::difference_type difference_type;
4240 typedef basic_string<value_type> string_type;
4241
4242 bool matched;
4243
4244 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR sub_match() : matched() {}
4245
4246 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI difference_type length() const {
4247 return matched ? std::distance(this->first, this->second) : 0;
4248 }
4249 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const {
4250 return matched ? string_type(this->first, this->second) : string_type();
4251 }
4252 _LIBCPP_HIDE_FROM_ABI operator string_type() const { return str(); }
4253
4254 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int compare(const sub_match& __s) const { return str().compare(__s.str()); }
4255 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return str().compare(__s); }
4256 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return str().compare(__s); }
4257
4258 _LIBCPP_HIDE_FROM_ABI void swap(sub_match& __s) _NOEXCEPT_(__is_nothrow_swappable_v<_BidirectionalIterator>) {
4259 this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s);
4260 std::swap(x&: matched, y&: __s.matched);
4261 }
4262};
4263
4264template <class _BiIter>
4265inline _LIBCPP_HIDE_FROM_ABI bool operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
4266 return __x.compare(__y) == 0;
4267}
4268
4269# if _LIBCPP_STD_VER >= 20
4270template <class _BiIter>
4271using __sub_match_cat _LIBCPP_NODEBUG =
4272 compare_three_way_result_t<basic_string<typename iterator_traits<_BiIter>::value_type>>;
4273
4274template <class _BiIter>
4275_LIBCPP_HIDE_FROM_ABI auto operator<=>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
4276 return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0);
4277}
4278# else // _LIBCPP_STD_VER >= 20
4279template <class _BiIter>
4280inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
4281 return !(__x == __y);
4282}
4283
4284template <class _BiIter>
4285inline _LIBCPP_HIDE_FROM_ABI bool operator<(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
4286 return __x.compare(__y) < 0;
4287}
4288
4289template <class _BiIter>
4290inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
4291 return !(__y < __x);
4292}
4293
4294template <class _BiIter>
4295inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
4296 return !(__x < __y);
4297}
4298
4299template <class _BiIter>
4300inline _LIBCPP_HIDE_FROM_ABI bool operator>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) {
4301 return __y < __x;
4302}
4303
4304template <class _BiIter, class _ST, class _SA>
4305inline _LIBCPP_HIDE_FROM_ABI bool
4306operator==(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
4307 const sub_match<_BiIter>& __y) {
4308 return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) == 0;
4309}
4310
4311template <class _BiIter, class _ST, class _SA>
4312inline _LIBCPP_HIDE_FROM_ABI bool
4313operator!=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
4314 const sub_match<_BiIter>& __y) {
4315 return !(__x == __y);
4316}
4317
4318template <class _BiIter, class _ST, class _SA>
4319inline _LIBCPP_HIDE_FROM_ABI bool
4320operator<(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
4321 const sub_match<_BiIter>& __y) {
4322 return __y.compare(typename sub_match<_BiIter>::string_type(__x.data(), __x.size())) > 0;
4323}
4324
4325template <class _BiIter, class _ST, class _SA>
4326inline _LIBCPP_HIDE_FROM_ABI bool
4327operator>(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
4328 const sub_match<_BiIter>& __y) {
4329 return __y < __x;
4330}
4331
4332template <class _BiIter, class _ST, class _SA>
4333inline _LIBCPP_HIDE_FROM_ABI bool
4334operator>=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
4335 const sub_match<_BiIter>& __y) {
4336 return !(__x < __y);
4337}
4338
4339template <class _BiIter, class _ST, class _SA>
4340inline _LIBCPP_HIDE_FROM_ABI bool
4341operator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
4342 const sub_match<_BiIter>& __y) {
4343 return !(__y < __x);
4344}
4345# endif // _LIBCPP_STD_VER >= 20
4346
4347template <class _BiIter, class _ST, class _SA>
4348inline _LIBCPP_HIDE_FROM_ABI bool
4349operator==(const sub_match<_BiIter>& __x,
4350 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
4351 return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) == 0;
4352}
4353
4354# if _LIBCPP_STD_VER >= 20
4355template <class _BiIter, class _ST, class _SA>
4356_LIBCPP_HIDE_FROM_ABI auto
4357operator<=>(const sub_match<_BiIter>& __x,
4358 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
4359 return static_cast<__sub_match_cat<_BiIter>>(
4360 __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) <=> 0);
4361}
4362# else // _LIBCPP_STD_VER >= 20
4363template <class _BiIter, class _ST, class _SA>
4364inline _LIBCPP_HIDE_FROM_ABI bool
4365operator!=(const sub_match<_BiIter>& __x,
4366 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
4367 return !(__x == __y);
4368}
4369
4370template <class _BiIter, class _ST, class _SA>
4371inline _LIBCPP_HIDE_FROM_ABI bool
4372operator<(const sub_match<_BiIter>& __x,
4373 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
4374 return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) < 0;
4375}
4376
4377template <class _BiIter, class _ST, class _SA>
4378inline _LIBCPP_HIDE_FROM_ABI bool
4379operator>(const sub_match<_BiIter>& __x,
4380 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
4381 return __y < __x;
4382}
4383
4384template <class _BiIter, class _ST, class _SA>
4385inline _LIBCPP_HIDE_FROM_ABI bool
4386operator>=(const sub_match<_BiIter>& __x,
4387 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
4388 return !(__x < __y);
4389}
4390
4391template <class _BiIter, class _ST, class _SA>
4392inline _LIBCPP_HIDE_FROM_ABI bool
4393operator<=(const sub_match<_BiIter>& __x,
4394 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) {
4395 return !(__y < __x);
4396}
4397
4398template <class _BiIter>
4399inline _LIBCPP_HIDE_FROM_ABI bool
4400operator==(typename iterator_traits<_BiIter>::value_type const* __x, const sub_match<_BiIter>& __y) {
4401 return __y.compare(__x) == 0;
4402}
4403
4404template <class _BiIter>
4405inline _LIBCPP_HIDE_FROM_ABI bool
4406operator!=(typename iterator_traits<_BiIter>::value_type const* __x, const sub_match<_BiIter>& __y) {
4407 return !(__x == __y);
4408}
4409
4410template <class _BiIter>
4411inline _LIBCPP_HIDE_FROM_ABI bool
4412operator<(typename iterator_traits<_BiIter>::value_type const* __x, const sub_match<_BiIter>& __y) {
4413 return __y.compare(__x) > 0;
4414}
4415
4416template <class _BiIter>
4417inline _LIBCPP_HIDE_FROM_ABI bool
4418operator>(typename iterator_traits<_BiIter>::value_type const* __x, const sub_match<_BiIter>& __y) {
4419 return __y < __x;
4420}
4421
4422template <class _BiIter>
4423inline _LIBCPP_HIDE_FROM_ABI bool
4424operator>=(typename iterator_traits<_BiIter>::value_type const* __x, const sub_match<_BiIter>& __y) {
4425 return !(__x < __y);
4426}
4427
4428template <class _BiIter>
4429inline _LIBCPP_HIDE_FROM_ABI bool
4430operator<=(typename iterator_traits<_BiIter>::value_type const* __x, const sub_match<_BiIter>& __y) {
4431 return !(__y < __x);
4432}
4433# endif // _LIBCPP_STD_VER >= 20
4434
4435template <class _BiIter>
4436inline _LIBCPP_HIDE_FROM_ABI bool
4437operator==(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
4438 return __x.compare(__y) == 0;
4439}
4440
4441# if _LIBCPP_STD_VER >= 20
4442template <class _BiIter>
4443_LIBCPP_HIDE_FROM_ABI auto
4444operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
4445 return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0);
4446}
4447# else // _LIBCPP_STD_VER >= 20
4448template <class _BiIter>
4449inline _LIBCPP_HIDE_FROM_ABI bool
4450operator!=(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
4451 return !(__x == __y);
4452}
4453
4454template <class _BiIter>
4455inline _LIBCPP_HIDE_FROM_ABI bool
4456operator<(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
4457 return __x.compare(__y) < 0;
4458}
4459
4460template <class _BiIter>
4461inline _LIBCPP_HIDE_FROM_ABI bool
4462operator>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
4463 return __y < __x;
4464}
4465
4466template <class _BiIter>
4467inline _LIBCPP_HIDE_FROM_ABI bool
4468operator>=(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
4469 return !(__x < __y);
4470}
4471
4472template <class _BiIter>
4473inline _LIBCPP_HIDE_FROM_ABI bool
4474operator<=(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) {
4475 return !(__y < __x);
4476}
4477
4478template <class _BiIter>
4479inline _LIBCPP_HIDE_FROM_ABI bool
4480operator==(typename iterator_traits<_BiIter>::value_type const& __x, const sub_match<_BiIter>& __y) {
4481 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
4482 return __y.compare(string_type(1, __x)) == 0;
4483}
4484
4485template <class _BiIter>
4486inline _LIBCPP_HIDE_FROM_ABI bool
4487operator!=(typename iterator_traits<_BiIter>::value_type const& __x, const sub_match<_BiIter>& __y) {
4488 return !(__x == __y);
4489}
4490
4491template <class _BiIter>
4492inline _LIBCPP_HIDE_FROM_ABI bool
4493operator<(typename iterator_traits<_BiIter>::value_type const& __x, const sub_match<_BiIter>& __y) {
4494 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
4495 return __y.compare(string_type(1, __x)) > 0;
4496}
4497
4498template <class _BiIter>
4499inline _LIBCPP_HIDE_FROM_ABI bool
4500operator>(typename iterator_traits<_BiIter>::value_type const& __x, const sub_match<_BiIter>& __y) {
4501 return __y < __x;
4502}
4503
4504template <class _BiIter>
4505inline _LIBCPP_HIDE_FROM_ABI bool
4506operator>=(typename iterator_traits<_BiIter>::value_type const& __x, const sub_match<_BiIter>& __y) {
4507 return !(__x < __y);
4508}
4509
4510template <class _BiIter>
4511inline _LIBCPP_HIDE_FROM_ABI bool
4512operator<=(typename iterator_traits<_BiIter>::value_type const& __x, const sub_match<_BiIter>& __y) {
4513 return !(__y < __x);
4514}
4515# endif // _LIBCPP_STD_VER >= 20
4516
4517template <class _BiIter>
4518inline _LIBCPP_HIDE_FROM_ABI bool
4519operator==(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
4520 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
4521 return __x.compare(string_type(1, __y)) == 0;
4522}
4523
4524# if _LIBCPP_STD_VER >= 20
4525template <class _BiIter>
4526_LIBCPP_HIDE_FROM_ABI auto
4527operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
4528 using string_type = basic_string<typename iterator_traits<_BiIter>::value_type>;
4529 return static_cast<__sub_match_cat<_BiIter>>(__x.compare(string_type(1, __y)) <=> 0);
4530}
4531# else // _LIBCPP_STD_VER >= 20
4532template <class _BiIter>
4533inline _LIBCPP_HIDE_FROM_ABI bool
4534operator!=(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
4535 return !(__x == __y);
4536}
4537
4538template <class _BiIter>
4539inline _LIBCPP_HIDE_FROM_ABI bool
4540operator<(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
4541 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
4542 return __x.compare(string_type(1, __y)) < 0;
4543}
4544
4545template <class _BiIter>
4546inline _LIBCPP_HIDE_FROM_ABI bool
4547operator>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
4548 return __y < __x;
4549}
4550
4551template <class _BiIter>
4552inline _LIBCPP_HIDE_FROM_ABI bool
4553operator>=(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
4554 return !(__x < __y);
4555}
4556
4557template <class _BiIter>
4558inline _LIBCPP_HIDE_FROM_ABI bool
4559operator<=(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) {
4560 return !(__y < __x);
4561}
4562# endif // _LIBCPP_STD_VER >= 20
4563
4564template <class _CharT, class _ST, class _BiIter>
4565inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _ST>&
4566operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m) {
4567 return __os << __m.str();
4568}
4569
4570typedef match_results<const char*> cmatch;
4571typedef match_results<string::const_iterator> smatch;
4572# if _LIBCPP_HAS_WIDE_CHARACTERS
4573typedef match_results<const wchar_t*> wcmatch;
4574typedef match_results<wstring::const_iterator> wsmatch;
4575# endif
4576
4577template <class _BidirectionalIterator, class _Allocator>
4578class _LIBCPP_PREFERRED_NAME(cmatch) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wcmatch))
4579 _LIBCPP_PREFERRED_NAME(smatch) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wsmatch)) match_results {
4580public:
4581 typedef _Allocator allocator_type;
4582 typedef sub_match<_BidirectionalIterator> value_type;
4583
4584private:
4585 typedef vector<value_type, allocator_type> __container_type;
4586
4587 __container_type __matches_;
4588 value_type __unmatched_;
4589 value_type __prefix_;
4590 value_type __suffix_;
4591 bool __ready_;
4592
4593public:
4594 _BidirectionalIterator __position_start_;
4595 typedef const value_type& const_reference;
4596 typedef value_type& reference;
4597 typedef typename __container_type::const_iterator const_iterator;
4598 typedef const_iterator iterator;
4599 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
4600 typedef typename allocator_traits<allocator_type>::size_type size_type;
4601 typedef typename iterator_traits<_BidirectionalIterator>::value_type char_type;
4602 typedef basic_string<char_type> string_type;
4603
4604 // construct/copy/destroy:
4605# ifndef _LIBCPP_CXX03_LANG
4606 match_results() : match_results(allocator_type()) {}
4607 explicit match_results(const allocator_type& __a);
4608# else
4609 explicit match_results(const allocator_type& __a = allocator_type());
4610# endif
4611
4612 // match_results(const match_results&) = default;
4613 // match_results& operator=(const match_results&) = default;
4614 // match_results(match_results&& __m) = default;
4615 // match_results& operator=(match_results&& __m) = default;
4616 // ~match_results() = default;
4617
4618 _LIBCPP_HIDE_FROM_ABI bool ready() const { return __ready_; }
4619
4620 // size:
4621 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __matches_.size(); }
4622 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __matches_.max_size(); }
4623 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return size() == 0; }
4624
4625 // element access:
4626 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI difference_type length(size_type __sub = 0) const {
4627 // If the match results are not ready, this will return `0`.
4628 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::length() called when not ready");
4629 return (*this)[__sub].length();
4630 }
4631 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI difference_type position(size_type __sub = 0) const {
4632 // If the match results are not ready, this will return the result of subtracting two default-constructed iterators
4633 // (which is typically a well-defined operation).
4634 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::position() called when not ready");
4635 return std::distance(__position_start_, (*this)[__sub].first);
4636 }
4637 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str(size_type __sub = 0) const {
4638 // If the match results are not ready, this will return an empty string.
4639 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::str() called when not ready");
4640 return (*this)[__sub].str();
4641 }
4642 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __n) const {
4643 // If the match results are not ready, this call will be equivalent to calling this function with `__n >= size()`,
4644 // returning an empty subrange.
4645 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::operator[]() called when not ready");
4646 return __n < __matches_.size() ? __matches_[__n] : __unmatched_;
4647 }
4648
4649 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference prefix() const {
4650 // If the match results are not ready, this will return a default-constructed empty `__suffix_`.
4651 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::prefix() called when not ready");
4652 return __prefix_;
4653 }
4654 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reference suffix() const {
4655 // If the match results are not ready, this will return a default-constructed empty `__suffix_`.
4656 _LIBCPP_ASSERT_PEDANTIC(ready(), "match_results::suffix() called when not ready");
4657 return __suffix_;
4658 }
4659
4660 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const {
4661 return empty() ? __matches_.end() : __matches_.begin();
4662 }
4663 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __matches_.end(); }
4664 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const {
4665 return empty() ? __matches_.end() : __matches_.begin();
4666 }
4667 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const { return __matches_.end(); }
4668
4669 // format:
4670 template <class _OutputIter>
4671 _OutputIter format(_OutputIter __output_iter,
4672 const char_type* __fmt_first,
4673 const char_type* __fmt_last,
4674 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
4675 template <class _OutputIter, class _ST, class _SA>
4676 _LIBCPP_HIDE_FROM_ABI _OutputIter
4677 format(_OutputIter __output_iter,
4678 const basic_string<char_type, _ST, _SA>& __fmt,
4679 regex_constants::match_flag_type __flags = regex_constants::format_default) const {
4680 return format(__output_iter, __fmt.data(), __fmt.data() + __fmt.size(), __flags);
4681 }
4682 template <class _ST, class _SA>
4683 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, _ST, _SA>
4684 format(const basic_string<char_type, _ST, _SA>& __fmt,
4685 regex_constants::match_flag_type __flags = regex_constants::format_default) const {
4686 basic_string<char_type, _ST, _SA> __r;
4687 format(std::back_inserter(__r), __fmt.data(), __fmt.data() + __fmt.size(), __flags);
4688 return __r;
4689 }
4690 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type
4691 format(const char_type* __fmt, regex_constants::match_flag_type __flags = regex_constants::format_default) const {
4692 string_type __r;
4693 format(std::back_inserter(__r), __fmt, __fmt + char_traits<char_type>::length(__fmt), __flags);
4694 return __r;
4695 }
4696
4697 // allocator:
4698 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return __matches_.get_allocator(); }
4699
4700 // swap:
4701 void swap(match_results& __m);
4702
4703 template <class _Bp, class _Ap>
4704 _LIBCPP_HIDE_FROM_ABI void
4705 __assign(_BidirectionalIterator __f,
4706 _BidirectionalIterator __l,
4707 const match_results<_Bp, _Ap>& __m,
4708 bool __no_update_pos) {
4709 _Bp __mf = __m.prefix().first;
4710 __matches_.resize(__m.size());
4711 for (size_type __i = 0; __i < __matches_.size(); ++__i) {
4712 __matches_[__i].first = std::next(__f, std::distance(__mf, __m[__i].first));
4713 __matches_[__i].second = std::next(__f, std::distance(__mf, __m[__i].second));
4714 __matches_[__i].matched = __m[__i].matched;
4715 }
4716 __unmatched_.first = __l;
4717 __unmatched_.second = __l;
4718 __unmatched_.matched = false;
4719 __prefix_.first = std::next(__f, std::distance(__mf, __m.prefix().first));
4720 __prefix_.second = std::next(__f, std::distance(__mf, __m.prefix().second));
4721 __prefix_.matched = __m.prefix().matched;
4722 __suffix_.first = std::next(__f, std::distance(__mf, __m.suffix().first));
4723 __suffix_.second = std::next(__f, std::distance(__mf, __m.suffix().second));
4724 __suffix_.matched = __m.suffix().matched;
4725 if (!__no_update_pos)
4726 __position_start_ = __prefix_.first;
4727 __ready_ = __m.ready();
4728 }
4729
4730private:
4731 void __init(unsigned __s, _BidirectionalIterator __f, _BidirectionalIterator __l, bool __no_update_pos = false);
4732
4733 template <class, class>
4734 friend class basic_regex;
4735
4736 template <class _Bp, class _Ap, class _Cp, class _Tp>
4737 friend bool
4738 regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
4739
4740 template <class _Bp, class _Ap>
4741 friend bool operator==(const match_results<_Bp, _Ap>&, const match_results<_Bp, _Ap>&);
4742
4743 template <class, class>
4744 friend class __lookahead;
4745
4746 template <class, class, class>
4747 friend class regex_iterator;
4748};
4749
4750template <class _BidirectionalIterator, class _Allocator>
4751match_results<_BidirectionalIterator, _Allocator>::match_results(const allocator_type& __a)
4752 : __matches_(__a), __unmatched_(), __prefix_(), __suffix_(), __ready_(false), __position_start_() {}
4753
4754template <class _BidirectionalIterator, class _Allocator>
4755void match_results<_BidirectionalIterator, _Allocator>::__init(
4756 unsigned __s, _BidirectionalIterator __f, _BidirectionalIterator __l, bool __no_update_pos) {
4757 __unmatched_.first = __l;
4758 __unmatched_.second = __l;
4759 __unmatched_.matched = false;
4760 __matches_.assign(__s, __unmatched_);
4761 __prefix_.first = __f;
4762 __prefix_.second = __f;
4763 __prefix_.matched = false;
4764 __suffix_ = __unmatched_;
4765 if (!__no_update_pos)
4766 __position_start_ = __prefix_.first;
4767 __ready_ = true;
4768}
4769
4770template <class _BidirectionalIterator, class _Allocator>
4771template <class _OutputIter>
4772_OutputIter match_results<_BidirectionalIterator, _Allocator>::format(
4773 _OutputIter __output_iter,
4774 const char_type* __fmt_first,
4775 const char_type* __fmt_last,
4776 regex_constants::match_flag_type __flags) const {
4777 // Note: this duplicates a check in `vector::operator[]` but provides a better error message.
4778 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ready(), "match_results::format() called when not ready");
4779 if (__flags & regex_constants::format_sed) {
4780 for (; __fmt_first != __fmt_last; ++__fmt_first) {
4781 if (*__fmt_first == '&')
4782 __output_iter = std::copy(__matches_[0].first, __matches_[0].second, __output_iter);
4783 else if (*__fmt_first == '\\' && __fmt_first + 1 != __fmt_last) {
4784 ++__fmt_first;
4785 if ('0' <= *__fmt_first && *__fmt_first <= '9') {
4786 size_t __i = *__fmt_first - '0';
4787 __output_iter = std::copy((*this)[__i].first, (*this)[__i].second, __output_iter);
4788 } else {
4789 *__output_iter = *__fmt_first;
4790 ++__output_iter;
4791 }
4792 } else {
4793 *__output_iter = *__fmt_first;
4794 ++__output_iter;
4795 }
4796 }
4797 } else {
4798 for (; __fmt_first != __fmt_last; ++__fmt_first) {
4799 if (*__fmt_first == '$' && __fmt_first + 1 != __fmt_last) {
4800 switch (__fmt_first[1]) {
4801 case '$':
4802 *__output_iter = *++__fmt_first;
4803 ++__output_iter;
4804 break;
4805 case '&':
4806 ++__fmt_first;
4807 __output_iter = std::copy(__matches_[0].first, __matches_[0].second, __output_iter);
4808 break;
4809 case '`':
4810 ++__fmt_first;
4811 __output_iter = std::copy(__prefix_.first, __prefix_.second, __output_iter);
4812 break;
4813 case '\'':
4814 ++__fmt_first;
4815 __output_iter = std::copy(__suffix_.first, __suffix_.second, __output_iter);
4816 break;
4817 default:
4818 if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9') {
4819 ++__fmt_first;
4820 size_t __idx = *__fmt_first - '0';
4821 if (__fmt_first + 1 != __fmt_last && '0' <= __fmt_first[1] && __fmt_first[1] <= '9') {
4822 ++__fmt_first;
4823 if (__idx >= numeric_limits<size_t>::max() / 10)
4824 std::__throw_regex_error<regex_constants::error_escape>();
4825 __idx = 10 * __idx + *__fmt_first - '0';
4826 }
4827 __output_iter = std::copy((*this)[__idx].first, (*this)[__idx].second, __output_iter);
4828 } else {
4829 *__output_iter = *__fmt_first;
4830 ++__output_iter;
4831 }
4832 break;
4833 }
4834 } else {
4835 *__output_iter = *__fmt_first;
4836 ++__output_iter;
4837 }
4838 }
4839 }
4840 return __output_iter;
4841}
4842
4843template <class _BidirectionalIterator, class _Allocator>
4844void match_results<_BidirectionalIterator, _Allocator>::swap(match_results& __m) {
4845 using std::swap;
4846 swap(__matches_, __m.__matches_);
4847 swap(__unmatched_, __m.__unmatched_);
4848 swap(__prefix_, __m.__prefix_);
4849 swap(__suffix_, __m.__suffix_);
4850 swap(__position_start_, __m.__position_start_);
4851 swap(__ready_, __m.__ready_);
4852}
4853
4854template <class _BidirectionalIterator, class _Allocator>
4855_LIBCPP_HIDE_FROM_ABI bool operator==(const match_results<_BidirectionalIterator, _Allocator>& __x,
4856 const match_results<_BidirectionalIterator, _Allocator>& __y) {
4857 if (__x.__ready_ != __y.__ready_)
4858 return false;
4859 if (!__x.__ready_)
4860 return true;
4861 return __x.__matches_ == __y.__matches_ && __x.__prefix_ == __y.__prefix_ && __x.__suffix_ == __y.__suffix_;
4862}
4863
4864# if _LIBCPP_STD_VER < 20
4865template <class _BidirectionalIterator, class _Allocator>
4866inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x,
4867 const match_results<_BidirectionalIterator, _Allocator>& __y) {
4868 return !(__x == __y);
4869}
4870# endif
4871
4872template <class _BidirectionalIterator, class _Allocator>
4873inline _LIBCPP_HIDE_FROM_ABI void
4874swap(match_results<_BidirectionalIterator, _Allocator>& __x, match_results<_BidirectionalIterator, _Allocator>& __y) {
4875 __x.swap(__y);
4876}
4877
4878// regex_search
4879
4880template <class _CharT, class _Traits>
4881template <class _Allocator>
4882bool basic_regex<_CharT, _Traits>::__match_at_start_ecma(
4883 const _CharT* __first,
4884 const _CharT* __last,
4885 match_results<const _CharT*, _Allocator>& __m,
4886 regex_constants::match_flag_type __flags,
4887 bool __at_first) const {
4888 vector<__state> __states;
4889 __node* __st = __start_.get();
4890 if (__st) {
4891 sub_match<const _CharT*> __unmatched;
4892 __unmatched.first = __last;
4893 __unmatched.second = __last;
4894 __unmatched.matched = false;
4895
4896 __states.push_back(__state());
4897 __states.back().__do_ = 0;
4898 __states.back().__first_ = __first;
4899 __states.back().__current_ = __first;
4900 __states.back().__last_ = __last;
4901 __states.back().__sub_matches_.resize(mark_count(), __unmatched);
4902 __states.back().__loop_data_.resize(__loop_count());
4903 __states.back().__node_ = __st;
4904 __states.back().__flags_ = __flags;
4905 __states.back().__at_first_ = __at_first;
4906 int __counter = 0;
4907 int __length = __last - __first;
4908 do {
4909 ++__counter;
4910 if (__counter % _LIBCPP_REGEX_COMPLEXITY_FACTOR == 0 && __counter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
4911 std::__throw_regex_error<regex_constants::error_complexity>();
4912 __state& __s = __states.back();
4913 if (__s.__node_)
4914 __s.__node_->__exec(__s);
4915 switch (__s.__do_) {
4916 case __state::__end_state:
4917 if ((__flags & regex_constants::match_not_null) && __s.__current_ == __first) {
4918 __states.pop_back();
4919 break;
4920 }
4921 if ((__flags & regex_constants::__full_match) && __s.__current_ != __last) {
4922 __states.pop_back();
4923 break;
4924 }
4925 __m.__matches_[0].first = __first;
4926 __m.__matches_[0].second = std::next(__first, __s.__current_ - __first);
4927 __m.__matches_[0].matched = true;
4928 for (unsigned __i = 0; __i < __s.__sub_matches_.size(); ++__i)
4929 __m.__matches_[__i + 1] = __s.__sub_matches_[__i];
4930 return true;
4931 case __state::__accept_and_consume:
4932 case __state::__repeat:
4933 case __state::__accept_but_not_consume:
4934 break;
4935 case __state::__split: {
4936 __state __snext = __s;
4937 __s.__node_->__exec_split(true, __s);
4938 __snext.__node_->__exec_split(false, __snext);
4939 __states.push_back(std::move(__snext));
4940 } break;
4941 case __state::__reject:
4942 __states.pop_back();
4943 break;
4944 default:
4945 std::__throw_regex_error<regex_constants::__re_err_unknown>();
4946 break;
4947 }
4948 } while (!__states.empty());
4949 }
4950 return false;
4951}
4952
4953template <class _CharT, class _Traits>
4954template <class _Allocator>
4955bool basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
4956 const _CharT* __first,
4957 const _CharT* __last,
4958 match_results<const _CharT*, _Allocator>& __m,
4959 regex_constants::match_flag_type __flags,
4960 bool __at_first) const {
4961 deque<__state> __states;
4962 ptrdiff_t __highest_j = 0;
4963 ptrdiff_t __np = std::distance(__first, __last);
4964 __node* __st = __start_.get();
4965 if (__st) {
4966 __states.push_back(__state());
4967 __states.back().__do_ = 0;
4968 __states.back().__first_ = __first;
4969 __states.back().__current_ = __first;
4970 __states.back().__last_ = __last;
4971 __states.back().__loop_data_.resize(__loop_count());
4972 __states.back().__node_ = __st;
4973 __states.back().__flags_ = __flags;
4974 __states.back().__at_first_ = __at_first;
4975 bool __matched = false;
4976 int __counter = 0;
4977 int __length = __last - __first;
4978 do {
4979 ++__counter;
4980 if (__counter % _LIBCPP_REGEX_COMPLEXITY_FACTOR == 0 && __counter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
4981 std::__throw_regex_error<regex_constants::error_complexity>();
4982 __state& __s = __states.back();
4983 if (__s.__node_)
4984 __s.__node_->__exec(__s);
4985 switch (__s.__do_) {
4986 case __state::__end_state:
4987 if ((__flags & regex_constants::match_not_null) && __s.__current_ == __first) {
4988 __states.pop_back();
4989 break;
4990 }
4991 if ((__flags & regex_constants::__full_match) && __s.__current_ != __last) {
4992 __states.pop_back();
4993 break;
4994 }
4995 if (!__matched || __highest_j < __s.__current_ - __s.__first_)
4996 __highest_j = __s.__current_ - __s.__first_;
4997 __matched = true;
4998 if (__highest_j == __np)
4999 __states.clear();
5000 else
5001 __states.pop_back();
5002 break;
5003 case __state::__consume_input:
5004 break;
5005 case __state::__accept_and_consume:
5006 __states.push_front(std::move(__s));
5007 __states.pop_back();
5008 break;
5009 case __state::__repeat:
5010 case __state::__accept_but_not_consume:
5011 break;
5012 case __state::__split: {
5013 __state __snext = __s;
5014 __s.__node_->__exec_split(true, __s);
5015 __snext.__node_->__exec_split(false, __snext);
5016 __states.push_back(std::move(__snext));
5017 } break;
5018 case __state::__reject:
5019 __states.pop_back();
5020 break;
5021 default:
5022 std::__throw_regex_error<regex_constants::__re_err_unknown>();
5023 break;
5024 }
5025 } while (!__states.empty());
5026 if (__matched) {
5027 __m.__matches_[0].first = __first;
5028 __m.__matches_[0].second = std::next(__first, __highest_j);
5029 __m.__matches_[0].matched = true;
5030 return true;
5031 }
5032 }
5033 return false;
5034}
5035
5036template <class _CharT, class _Traits>
5037template <class _Allocator>
5038bool basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
5039 const _CharT* __first,
5040 const _CharT* __last,
5041 match_results<const _CharT*, _Allocator>& __m,
5042 regex_constants::match_flag_type __flags,
5043 bool __at_first) const {
5044 vector<__state> __states;
5045 __state __best_state;
5046 ptrdiff_t __highest_j = 0;
5047 ptrdiff_t __np = std::distance(__first, __last);
5048 __node* __st = __start_.get();
5049 if (__st) {
5050 sub_match<const _CharT*> __unmatched;
5051 __unmatched.first = __last;
5052 __unmatched.second = __last;
5053 __unmatched.matched = false;
5054
5055 __states.push_back(__state());
5056 __states.back().__do_ = 0;
5057 __states.back().__first_ = __first;
5058 __states.back().__current_ = __first;
5059 __states.back().__last_ = __last;
5060 __states.back().__sub_matches_.resize(mark_count(), __unmatched);
5061 __states.back().__loop_data_.resize(__loop_count());
5062 __states.back().__node_ = __st;
5063 __states.back().__flags_ = __flags;
5064 __states.back().__at_first_ = __at_first;
5065 bool __matched = false;
5066 int __counter = 0;
5067 int __length = __last - __first;
5068 do {
5069 ++__counter;
5070 if (__counter % _LIBCPP_REGEX_COMPLEXITY_FACTOR == 0 && __counter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
5071 std::__throw_regex_error<regex_constants::error_complexity>();
5072 __state& __s = __states.back();
5073 if (__s.__node_)
5074 __s.__node_->__exec(__s);
5075 switch (__s.__do_) {
5076 case __state::__end_state:
5077 if ((__flags & regex_constants::match_not_null) && __s.__current_ == __first) {
5078 __states.pop_back();
5079 break;
5080 }
5081 if ((__flags & regex_constants::__full_match) && __s.__current_ != __last) {
5082 __states.pop_back();
5083 break;
5084 }
5085 if (!__matched || __highest_j < __s.__current_ - __s.__first_) {
5086 __highest_j = __s.__current_ - __s.__first_;
5087 __best_state = __s;
5088 }
5089 __matched = true;
5090 if (__highest_j == __np)
5091 __states.clear();
5092 else
5093 __states.pop_back();
5094 break;
5095 case __state::__accept_and_consume:
5096 case __state::__repeat:
5097 case __state::__accept_but_not_consume:
5098 break;
5099 case __state::__split: {
5100 __state __snext = __s;
5101 __s.__node_->__exec_split(true, __s);
5102 __snext.__node_->__exec_split(false, __snext);
5103 __states.push_back(std::move(__snext));
5104 } break;
5105 case __state::__reject:
5106 __states.pop_back();
5107 break;
5108 default:
5109 std::__throw_regex_error<regex_constants::__re_err_unknown>();
5110 break;
5111 }
5112 } while (!__states.empty());
5113 if (__matched) {
5114 __m.__matches_[0].first = __first;
5115 __m.__matches_[0].second = std::next(__first, __highest_j);
5116 __m.__matches_[0].matched = true;
5117 for (unsigned __i = 0; __i < __best_state.__sub_matches_.size(); ++__i)
5118 __m.__matches_[__i + 1] = __best_state.__sub_matches_[__i];
5119 return true;
5120 }
5121 }
5122 return false;
5123}
5124
5125template <class _CharT, class _Traits>
5126template <class _Allocator>
5127bool basic_regex<_CharT, _Traits>::__match_at_start(
5128 const _CharT* __first,
5129 const _CharT* __last,
5130 match_results<const _CharT*, _Allocator>& __m,
5131 regex_constants::match_flag_type __flags,
5132 bool __at_first) const {
5133 if (__get_grammar(g: __flags_) == ECMAScript)
5134 return __match_at_start_ecma(__first, __last, __m, __flags, __at_first);
5135 if (mark_count() == 0)
5136 return __match_at_start_posix_nosubs(__first, __last, __m, __flags, __at_first);
5137 return __match_at_start_posix_subs(__first, __last, __m, __flags, __at_first);
5138}
5139
5140template <class _CharT, class _Traits>
5141template <class _Allocator>
5142bool basic_regex<_CharT, _Traits>::__search(
5143 const _CharT* __first,
5144 const _CharT* __last,
5145 match_results<const _CharT*, _Allocator>& __m,
5146 regex_constants::match_flag_type __flags) const {
5147 if (__flags & regex_constants::match_prev_avail)
5148 __flags &= ~(regex_constants::match_not_bol | regex_constants::match_not_bow);
5149
5150 __m.__init(1 + mark_count(), __first, __last, __flags & regex_constants::__no_update_pos);
5151 if (__match_at_start(__first, __last, __m, __flags, !(__flags & regex_constants::__no_update_pos))) {
5152 __m.__prefix_.second = __m[0].first;
5153 __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
5154 __m.__suffix_.first = __m[0].second;
5155 __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
5156 return true;
5157 }
5158 if (__first != __last && !(__flags & regex_constants::match_continuous)) {
5159 __flags |= regex_constants::match_prev_avail;
5160 for (++__first; __first != __last; ++__first) {
5161 __m.__matches_.assign(__m.size(), __m.__unmatched_);
5162 if (__match_at_start(__first, __last, __m, __flags, false)) {
5163 __m.__prefix_.second = __m[0].first;
5164 __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
5165 __m.__suffix_.first = __m[0].second;
5166 __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
5167 return true;
5168 }
5169 __m.__matches_.assign(__m.size(), __m.__unmatched_);
5170 }
5171 __m.__matches_.assign(__m.size(), __m.__unmatched_);
5172 if (__match_at_start(__first, __last, __m, __flags, false)) {
5173 __m.__prefix_.second = __m[0].first;
5174 __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
5175 __m.__suffix_.first = __m[0].second;
5176 __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
5177 return true;
5178 }
5179 }
5180 __m.__matches_.clear();
5181 return false;
5182}
5183
5184template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
5185inline _LIBCPP_HIDE_FROM_ABI bool
5186regex_search(_BidirectionalIterator __first,
5187 _BidirectionalIterator __last,
5188 match_results<_BidirectionalIterator, _Allocator>& __m,
5189 const basic_regex<_CharT, _Traits>& __e,
5190 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5191 int __offset = (__flags & regex_constants::match_prev_avail) ? 1 : 0;
5192 basic_string<_CharT> __s(std::prev(__first, __offset), __last);
5193 match_results<const _CharT*> __mc;
5194 bool __r = __e.__search(__s.data() + __offset, __s.data() + __s.size(), __mc, __flags);
5195 __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);
5196 return __r;
5197}
5198
5199template <class _Iter, class _Allocator, class _CharT, class _Traits>
5200inline _LIBCPP_HIDE_FROM_ABI bool
5201regex_search(__wrap_iter<_Iter> __first,
5202 __wrap_iter<_Iter> __last,
5203 match_results<__wrap_iter<_Iter>, _Allocator>& __m,
5204 const basic_regex<_CharT, _Traits>& __e,
5205 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5206 match_results<const _CharT*> __mc;
5207 bool __r = __e.__search(std::__to_address(__first), std::__to_address(__last), __mc, __flags);
5208 __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);
5209 return __r;
5210}
5211
5212template <class _Allocator, class _CharT, class _Traits>
5213inline _LIBCPP_HIDE_FROM_ABI bool
5214regex_search(const _CharT* __first,
5215 const _CharT* __last,
5216 match_results<const _CharT*, _Allocator>& __m,
5217 const basic_regex<_CharT, _Traits>& __e,
5218 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5219 return __e.__search(__first, __last, __m, __flags);
5220}
5221
5222template <class _BidirectionalIterator, class _CharT, class _Traits>
5223inline _LIBCPP_HIDE_FROM_ABI bool
5224regex_search(_BidirectionalIterator __first,
5225 _BidirectionalIterator __last,
5226 const basic_regex<_CharT, _Traits>& __e,
5227 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5228 basic_string<_CharT> __s(__first, __last);
5229 match_results<const _CharT*> __mc;
5230 return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
5231}
5232
5233template <class _CharT, class _Traits>
5234inline _LIBCPP_HIDE_FROM_ABI bool
5235regex_search(const _CharT* __first,
5236 const _CharT* __last,
5237 const basic_regex<_CharT, _Traits>& __e,
5238 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5239 match_results<const _CharT*> __mc;
5240 return __e.__search(__first, __last, __mc, __flags);
5241}
5242
5243template <class _CharT, class _Allocator, class _Traits>
5244inline _LIBCPP_HIDE_FROM_ABI bool
5245regex_search(const _CharT* __str,
5246 match_results<const _CharT*, _Allocator>& __m,
5247 const basic_regex<_CharT, _Traits>& __e,
5248 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5249 return __e.__search(__str, __str + _Traits::length(__str), __m, __flags);
5250}
5251
5252template <class _CharT, class _Traits>
5253inline _LIBCPP_HIDE_FROM_ABI bool
5254regex_search(const _CharT* __str,
5255 const basic_regex<_CharT, _Traits>& __e,
5256 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5257 match_results<const _CharT*> __m;
5258 return std::regex_search(__str, __m, __e, __flags);
5259}
5260
5261template <class _ST, class _SA, class _CharT, class _Traits>
5262inline _LIBCPP_HIDE_FROM_ABI bool
5263regex_search(const basic_string<_CharT, _ST, _SA>& __s,
5264 const basic_regex<_CharT, _Traits>& __e,
5265 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5266 match_results<const _CharT*> __mc;
5267 return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
5268}
5269
5270template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
5271inline _LIBCPP_HIDE_FROM_ABI bool
5272regex_search(const basic_string<_CharT, _ST, _SA>& __s,
5273 match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
5274 const basic_regex<_CharT, _Traits>& __e,
5275 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5276 match_results<const _CharT*> __mc;
5277 bool __r = __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
5278 __m.__assign(__s.begin(), __s.end(), __mc, __flags & regex_constants::__no_update_pos);
5279 return __r;
5280}
5281
5282# if _LIBCPP_STD_VER >= 14
5283template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
5284bool regex_search(const basic_string<_Cp, _ST, _SA>&& __s,
5285 match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,
5286 const basic_regex<_Cp, _Tp>& __e,
5287 regex_constants::match_flag_type __flags = regex_constants::match_default) = delete;
5288# endif
5289
5290// regex_match
5291
5292template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
5293_LIBCPP_HIDE_FROM_ABI bool
5294regex_match(_BidirectionalIterator __first,
5295 _BidirectionalIterator __last,
5296 match_results<_BidirectionalIterator, _Allocator>& __m,
5297 const basic_regex<_CharT, _Traits>& __e,
5298 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5299 bool __r = std::regex_search(
5300 __first, __last, __m, __e, __flags | regex_constants::match_continuous | regex_constants::__full_match);
5301 if (__r) {
5302 __r = !__m.suffix().matched;
5303 if (!__r)
5304 __m.__matches_.clear();
5305 }
5306 return __r;
5307}
5308
5309template <class _BidirectionalIterator, class _CharT, class _Traits>
5310inline _LIBCPP_HIDE_FROM_ABI bool
5311regex_match(_BidirectionalIterator __first,
5312 _BidirectionalIterator __last,
5313 const basic_regex<_CharT, _Traits>& __e,
5314 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5315 match_results<_BidirectionalIterator> __m;
5316 return std::regex_match(__first, __last, __m, __e, __flags);
5317}
5318
5319template <class _CharT, class _Allocator, class _Traits>
5320inline _LIBCPP_HIDE_FROM_ABI bool
5321regex_match(const _CharT* __str,
5322 match_results<const _CharT*, _Allocator>& __m,
5323 const basic_regex<_CharT, _Traits>& __e,
5324 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5325 return std::regex_match(__str, __str + _Traits::length(__str), __m, __e, __flags);
5326}
5327
5328template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
5329inline _LIBCPP_HIDE_FROM_ABI bool
5330regex_match(const basic_string<_CharT, _ST, _SA>& __s,
5331 match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
5332 const basic_regex<_CharT, _Traits>& __e,
5333 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5334 return std::regex_match(__s.begin(), __s.end(), __m, __e, __flags);
5335}
5336
5337# if _LIBCPP_STD_VER >= 14
5338template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
5339inline _LIBCPP_HIDE_FROM_ABI bool
5340regex_match(const basic_string<_CharT, _ST, _SA>&& __s,
5341 match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
5342 const basic_regex<_CharT, _Traits>& __e,
5343 regex_constants::match_flag_type __flags = regex_constants::match_default) = delete;
5344# endif
5345
5346template <class _CharT, class _Traits>
5347inline _LIBCPP_HIDE_FROM_ABI bool
5348regex_match(const _CharT* __str,
5349 const basic_regex<_CharT, _Traits>& __e,
5350 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5351 return std::regex_match(__str, __str + _Traits::length(__str), __e, __flags);
5352}
5353
5354template <class _ST, class _SA, class _CharT, class _Traits>
5355inline _LIBCPP_HIDE_FROM_ABI bool
5356regex_match(const basic_string<_CharT, _ST, _SA>& __s,
5357 const basic_regex<_CharT, _Traits>& __e,
5358 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5359 return std::regex_match(__s.begin(), __s.end(), __e, __flags);
5360}
5361
5362// regex_iterator
5363
5364template <class _BidirectionalIterator,
5365 class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
5366 class _Traits = regex_traits<_CharT> >
5367class regex_iterator;
5368
5369typedef regex_iterator<const char*> cregex_iterator;
5370typedef regex_iterator<string::const_iterator> sregex_iterator;
5371# if _LIBCPP_HAS_WIDE_CHARACTERS
5372typedef regex_iterator<const wchar_t*> wcregex_iterator;
5373typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
5374# endif
5375
5376template <class _BidirectionalIterator, class _CharT, class _Traits>
5377class _LIBCPP_PREFERRED_NAME(cregex_iterator) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wcregex_iterator))
5378 _LIBCPP_PREFERRED_NAME(sregex_iterator)
5379 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wsregex_iterator)) regex_iterator {
5380public:
5381 typedef basic_regex<_CharT, _Traits> regex_type;
5382 typedef match_results<_BidirectionalIterator> value_type;
5383 typedef ptrdiff_t difference_type;
5384 typedef const value_type* pointer;
5385 typedef const value_type& reference;
5386 typedef forward_iterator_tag iterator_category;
5387# if _LIBCPP_STD_VER >= 20
5388 typedef input_iterator_tag iterator_concept;
5389# endif
5390
5391private:
5392 _BidirectionalIterator __begin_;
5393 _BidirectionalIterator __end_;
5394 const regex_type* __pregex_;
5395 regex_constants::match_flag_type __flags_;
5396 value_type __match_;
5397
5398public:
5399 regex_iterator();
5400 regex_iterator(_BidirectionalIterator __a,
5401 _BidirectionalIterator __b,
5402 const regex_type& __re,
5403 regex_constants::match_flag_type __m = regex_constants::match_default);
5404# if _LIBCPP_STD_VER >= 14
5405 regex_iterator(_BidirectionalIterator __a,
5406 _BidirectionalIterator __b,
5407 const regex_type&& __re,
5408 regex_constants::match_flag_type __m = regex_constants::match_default) = delete;
5409# endif
5410
5411 _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_iterator& __x) const;
5412# if _LIBCPP_STD_VER >= 20
5413 _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const { return *this == regex_iterator(); }
5414# endif
5415# if _LIBCPP_STD_VER < 20
5416 _LIBCPP_HIDE_FROM_ABI bool operator!=(const regex_iterator& __x) const { return !(*this == __x); }
5417# endif
5418
5419 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __match_; }
5420 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return std::addressof(__match_); }
5421
5422 regex_iterator& operator++();
5423 _LIBCPP_HIDE_FROM_ABI regex_iterator operator++(int) {
5424 regex_iterator __t(*this);
5425 ++(*this);
5426 return __t;
5427 }
5428};
5429
5430template <class _BidirectionalIterator, class _CharT, class _Traits>
5431regex_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_iterator()
5432 : __begin_(), __end_(), __pregex_(nullptr), __flags_(), __match_() {}
5433
5434template <class _BidirectionalIterator, class _CharT, class _Traits>
5435regex_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_iterator(
5436 _BidirectionalIterator __a,
5437 _BidirectionalIterator __b,
5438 const regex_type& __re,
5439 regex_constants::match_flag_type __m)
5440 : __begin_(__a), __end_(__b), __pregex_(std::addressof(__re)), __flags_(__m) {
5441 std::regex_search(__begin_, __end_, __match_, *__pregex_, __flags_);
5442}
5443
5444template <class _BidirectionalIterator, class _CharT, class _Traits>
5445bool regex_iterator<_BidirectionalIterator, _CharT, _Traits>::operator==(const regex_iterator& __x) const {
5446 if (__match_.empty() && __x.__match_.empty())
5447 return true;
5448 if (__match_.empty() || __x.__match_.empty())
5449 return false;
5450 return __begin_ == __x.__begin_ && __end_ == __x.__end_ && __pregex_ == __x.__pregex_ && __flags_ == __x.__flags_ &&
5451 __match_[0] == __x.__match_[0];
5452}
5453
5454template <class _BidirectionalIterator, class _CharT, class _Traits>
5455regex_iterator<_BidirectionalIterator, _CharT, _Traits>&
5456regex_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++() {
5457 __flags_ |= regex_constants::__no_update_pos;
5458 _BidirectionalIterator __start = __match_[0].second;
5459 _BidirectionalIterator __prefix_start = __start;
5460
5461 if (__match_[0].first == __match_[0].second) {
5462 if (__start == __end_) {
5463 __match_ = value_type();
5464 return *this;
5465 } else if (std::regex_search(__start,
5466 __end_,
5467 __match_,
5468 *__pregex_,
5469 __flags_ | regex_constants::match_not_null | regex_constants::match_continuous))
5470 return *this;
5471 else
5472 ++__start;
5473 }
5474
5475 __flags_ |= regex_constants::match_prev_avail;
5476 if (!std::regex_search(__start, __end_, __match_, *__pregex_, __flags_)) {
5477 __match_ = value_type();
5478
5479 } else {
5480 // The Standard mandates that if `regex_search` returns true ([re.regiter.incr]), "`match.prefix().first` shall be
5481 // equal to the previous value of `match[0].second`... It is unspecified how the implementation makes these
5482 // adjustments." The adjustment is necessary if we incremented `__start` above (the branch that deals with
5483 // zero-length matches).
5484 auto& __prefix = __match_.__prefix_;
5485 __prefix.first = __prefix_start;
5486 __prefix.matched = __prefix.first != __prefix.second;
5487 }
5488
5489 return *this;
5490}
5491
5492// regex_token_iterator
5493
5494template <class _BidirectionalIterator,
5495 class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
5496 class _Traits = regex_traits<_CharT> >
5497class regex_token_iterator;
5498
5499typedef regex_token_iterator<const char*> cregex_token_iterator;
5500typedef regex_token_iterator<string::const_iterator> sregex_token_iterator;
5501# if _LIBCPP_HAS_WIDE_CHARACTERS
5502typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
5503typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
5504# endif
5505
5506template <class _BidirectionalIterator, class _CharT, class _Traits>
5507class _LIBCPP_PREFERRED_NAME(cregex_token_iterator)
5508 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wcregex_token_iterator))
5509 _LIBCPP_PREFERRED_NAME(sregex_token_iterator)
5510 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wsregex_token_iterator)) regex_token_iterator {
5511public:
5512 typedef basic_regex<_CharT, _Traits> regex_type;
5513 typedef sub_match<_BidirectionalIterator> value_type;
5514 typedef ptrdiff_t difference_type;
5515 typedef const value_type* pointer;
5516 typedef const value_type& reference;
5517 typedef forward_iterator_tag iterator_category;
5518# if _LIBCPP_STD_VER >= 20
5519 typedef input_iterator_tag iterator_concept;
5520# endif
5521
5522private:
5523 typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Position;
5524
5525 _Position __position_;
5526 const value_type* __result_;
5527 value_type __suffix_;
5528 ptrdiff_t __n_;
5529 vector<int> __subs_;
5530
5531public:
5532 regex_token_iterator();
5533 regex_token_iterator(_BidirectionalIterator __a,
5534 _BidirectionalIterator __b,
5535 const regex_type& __re,
5536 int __submatch = 0,
5537 regex_constants::match_flag_type __m = regex_constants::match_default);
5538# if _LIBCPP_STD_VER >= 14
5539 regex_token_iterator(_BidirectionalIterator __a,
5540 _BidirectionalIterator __b,
5541 const regex_type&& __re,
5542 int __submatch = 0,
5543 regex_constants::match_flag_type __m = regex_constants::match_default) = delete;
5544# endif
5545
5546 regex_token_iterator(_BidirectionalIterator __a,
5547 _BidirectionalIterator __b,
5548 const regex_type& __re,
5549 const vector<int>& __submatches,
5550 regex_constants::match_flag_type __m = regex_constants::match_default);
5551# if _LIBCPP_STD_VER >= 14
5552 regex_token_iterator(_BidirectionalIterator __a,
5553 _BidirectionalIterator __b,
5554 const regex_type&& __re,
5555 const vector<int>& __submatches,
5556 regex_constants::match_flag_type __m = regex_constants::match_default) = delete;
5557# endif
5558
5559# ifndef _LIBCPP_CXX03_LANG
5560 regex_token_iterator(_BidirectionalIterator __a,
5561 _BidirectionalIterator __b,
5562 const regex_type& __re,
5563 initializer_list<int> __submatches,
5564 regex_constants::match_flag_type __m = regex_constants::match_default);
5565
5566# if _LIBCPP_STD_VER >= 14
5567 regex_token_iterator(_BidirectionalIterator __a,
5568 _BidirectionalIterator __b,
5569 const regex_type&& __re,
5570 initializer_list<int> __submatches,
5571 regex_constants::match_flag_type __m = regex_constants::match_default) = delete;
5572# endif
5573# endif // _LIBCPP_CXX03_LANG
5574 template <size_t _Np>
5575 regex_token_iterator(_BidirectionalIterator __a,
5576 _BidirectionalIterator __b,
5577 const regex_type& __re,
5578 const int (&__submatches)[_Np],
5579 regex_constants::match_flag_type __m = regex_constants::match_default);
5580# if _LIBCPP_STD_VER >= 14
5581 template <size_t _Np>
5582 regex_token_iterator(_BidirectionalIterator __a,
5583 _BidirectionalIterator __b,
5584 const regex_type&& __re,
5585 const int (&__submatches)[_Np],
5586 regex_constants::match_flag_type __m = regex_constants::match_default) = delete;
5587# endif
5588
5589 regex_token_iterator(const regex_token_iterator&);
5590 regex_token_iterator& operator=(const regex_token_iterator&);
5591
5592 _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_token_iterator& __x) const;
5593# if _LIBCPP_STD_VER >= 20
5594 _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); }
5595# endif
5596# if _LIBCPP_STD_VER < 20
5597 _LIBCPP_HIDE_FROM_ABI bool operator!=(const regex_token_iterator& __x) const { return !(*this == __x); }
5598# endif
5599
5600 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const value_type& operator*() const { return *__result_; }
5601 _LIBCPP_HIDE_FROM_ABI const value_type* operator->() const { return __result_; }
5602
5603 regex_token_iterator& operator++();
5604 _LIBCPP_HIDE_FROM_ABI regex_token_iterator operator++(int) {
5605 regex_token_iterator __t(*this);
5606 ++(*this);
5607 return __t;
5608 }
5609
5610private:
5611 void __init(_BidirectionalIterator __a, _BidirectionalIterator __b);
5612 void __establish_result() {
5613 if (__subs_[__n_] == -1)
5614 __result_ = std::addressof(__position_->prefix());
5615 else
5616 __result_ = std::addressof((*__position_)[__subs_[__n_]]);
5617 }
5618};
5619
5620template <class _BidirectionalIterator, class _CharT, class _Traits>
5621regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_token_iterator()
5622 : __result_(nullptr), __suffix_(), __n_(0) {}
5623
5624template <class _BidirectionalIterator, class _CharT, class _Traits>
5625void regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::__init(
5626 _BidirectionalIterator __a, _BidirectionalIterator __b) {
5627 if (__position_ != _Position())
5628 __establish_result();
5629 else if (__subs_[__n_] == -1) {
5630 __suffix_.matched = true;
5631 __suffix_.first = __a;
5632 __suffix_.second = __b;
5633 __result_ = std::addressof(__suffix_);
5634 } else
5635 __result_ = nullptr;
5636}
5637
5638template <class _BidirectionalIterator, class _CharT, class _Traits>
5639regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_token_iterator(
5640 _BidirectionalIterator __a,
5641 _BidirectionalIterator __b,
5642 const regex_type& __re,
5643 int __submatch,
5644 regex_constants::match_flag_type __m)
5645 : __position_(__a, __b, __re, __m), __n_(0), __subs_(1, __submatch) {
5646 __init(__a, __b);
5647}
5648
5649template <class _BidirectionalIterator, class _CharT, class _Traits>
5650regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_token_iterator(
5651 _BidirectionalIterator __a,
5652 _BidirectionalIterator __b,
5653 const regex_type& __re,
5654 const vector<int>& __submatches,
5655 regex_constants::match_flag_type __m)
5656 : __position_(__a, __b, __re, __m), __n_(0), __subs_(__submatches) {
5657 __init(__a, __b);
5658}
5659
5660# ifndef _LIBCPP_CXX03_LANG
5661
5662template <class _BidirectionalIterator, class _CharT, class _Traits>
5663regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_token_iterator(
5664 _BidirectionalIterator __a,
5665 _BidirectionalIterator __b,
5666 const regex_type& __re,
5667 initializer_list<int> __submatches,
5668 regex_constants::match_flag_type __m)
5669 : __position_(__a, __b, __re, __m), __n_(0), __subs_(__submatches) {
5670 __init(__a, __b);
5671}
5672
5673# endif // _LIBCPP_CXX03_LANG
5674
5675template <class _BidirectionalIterator, class _CharT, class _Traits>
5676template <size_t _Np>
5677regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_token_iterator(
5678 _BidirectionalIterator __a,
5679 _BidirectionalIterator __b,
5680 const regex_type& __re,
5681 const int (&__submatches)[_Np],
5682 regex_constants::match_flag_type __m)
5683 : __position_(__a, __b, __re, __m), __n_(0), __subs_(begin(__submatches), end(__submatches)) {
5684 __init(__a, __b);
5685}
5686
5687template <class _BidirectionalIterator, class _CharT, class _Traits>
5688regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_token_iterator(const regex_token_iterator& __x)
5689 : __position_(__x.__position_),
5690 __result_(__x.__result_),
5691 __suffix_(__x.__suffix_),
5692 __n_(__x.__n_),
5693 __subs_(__x.__subs_) {
5694 if (__x.__result_ == std::addressof(__x.__suffix_))
5695 __result_ = std::addressof(__suffix_);
5696 else if (__result_ != nullptr)
5697 __establish_result();
5698}
5699
5700template <class _BidirectionalIterator, class _CharT, class _Traits>
5701regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>&
5702regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator=(const regex_token_iterator& __x) {
5703 if (this != std::addressof(__x)) {
5704 __position_ = __x.__position_;
5705 if (__x.__result_ == std::addressof(__x.__suffix_))
5706 __result_ = std::addressof(__suffix_);
5707 else
5708 __result_ = __x.__result_;
5709 __suffix_ = __x.__suffix_;
5710 __n_ = __x.__n_;
5711 __subs_ = __x.__subs_;
5712
5713 if (__result_ != nullptr && __result_ != std::addressof(__suffix_))
5714 __establish_result();
5715 }
5716 return *this;
5717}
5718
5719template <class _BidirectionalIterator, class _CharT, class _Traits>
5720bool regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator==(const regex_token_iterator& __x) const {
5721 if (__result_ == nullptr && __x.__result_ == nullptr)
5722 return true;
5723 if (__result_ == std::addressof(__suffix_) && __x.__result_ == std::addressof(__x.__suffix_) &&
5724 __suffix_ == __x.__suffix_)
5725 return true;
5726 if (__result_ == nullptr || __x.__result_ == nullptr)
5727 return false;
5728 if (__result_ == std::addressof(__suffix_) || __x.__result_ == std::addressof(__x.__suffix_))
5729 return false;
5730 return __position_ == __x.__position_ && __n_ == __x.__n_ && __subs_ == __x.__subs_;
5731}
5732
5733template <class _BidirectionalIterator, class _CharT, class _Traits>
5734regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>&
5735regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++() {
5736 _Position __prev = __position_;
5737 if (__result_ == std::addressof(__suffix_))
5738 __result_ = nullptr;
5739 else if (static_cast<size_t>(__n_ + 1) < __subs_.size()) {
5740 ++__n_;
5741 __establish_result();
5742 } else {
5743 __n_ = 0;
5744 ++__position_;
5745 if (__position_ != _Position())
5746 __establish_result();
5747 else {
5748 if (std::find(first: __subs_.begin(), last: __subs_.end(), value: -1) != __subs_.end() && __prev->suffix().length() != 0) {
5749 __suffix_.matched = true;
5750 __suffix_.first = __prev->suffix().first;
5751 __suffix_.second = __prev->suffix().second;
5752 __result_ = std::addressof(__suffix_);
5753 } else
5754 __result_ = nullptr;
5755 }
5756 }
5757 return *this;
5758}
5759
5760// regex_replace
5761
5762template <class _OutputIterator, class _BidirectionalIterator, class _Traits, class _CharT>
5763_LIBCPP_HIDE_FROM_ABI _OutputIterator regex_replace(
5764 _OutputIterator __output_iter,
5765 _BidirectionalIterator __first,
5766 _BidirectionalIterator __last,
5767 const basic_regex<_CharT, _Traits>& __e,
5768 const _CharT* __fmt,
5769 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5770 typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Iter;
5771 _Iter __i(__first, __last, __e, __flags);
5772 _Iter __eof;
5773 if (__i == __eof) {
5774 if (!(__flags & regex_constants::format_no_copy))
5775 __output_iter = std::copy(__first, __last, __output_iter);
5776 } else {
5777 sub_match<_BidirectionalIterator> __lm;
5778 for (size_t __len = char_traits<_CharT>::length(__fmt); __i != __eof; ++__i) {
5779 if (!(__flags & regex_constants::format_no_copy))
5780 __output_iter = std::copy(__i->prefix().first, __i->prefix().second, __output_iter);
5781 __output_iter = __i->format(__output_iter, __fmt, __fmt + __len, __flags);
5782 __lm = __i->suffix();
5783 if (__flags & regex_constants::format_first_only)
5784 break;
5785 }
5786 if (!(__flags & regex_constants::format_no_copy))
5787 __output_iter = std::copy(__lm.first, __lm.second, __output_iter);
5788 }
5789 return __output_iter;
5790}
5791
5792template <class _OutputIterator, class _BidirectionalIterator, class _Traits, class _CharT, class _ST, class _SA>
5793inline _LIBCPP_HIDE_FROM_ABI _OutputIterator regex_replace(
5794 _OutputIterator __output_iter,
5795 _BidirectionalIterator __first,
5796 _BidirectionalIterator __last,
5797 const basic_regex<_CharT, _Traits>& __e,
5798 const basic_string<_CharT, _ST, _SA>& __fmt,
5799 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5800 return std::regex_replace(__output_iter, __first, __last, __e, __fmt.c_str(), __flags);
5801}
5802
5803template <class _Traits, class _CharT, class _ST, class _SA, class _FST, class _FSA>
5804inline _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _ST, _SA>
5805regex_replace(const basic_string<_CharT, _ST, _SA>& __s,
5806 const basic_regex<_CharT, _Traits>& __e,
5807 const basic_string<_CharT, _FST, _FSA>& __fmt,
5808 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5809 basic_string<_CharT, _ST, _SA> __r;
5810 std::regex_replace(std::back_inserter(__r), __s.begin(), __s.end(), __e, __fmt.c_str(), __flags);
5811 return __r;
5812}
5813
5814template <class _Traits, class _CharT, class _ST, class _SA>
5815inline _LIBCPP_HIDE_FROM_ABI basic_string<_CharT, _ST, _SA>
5816regex_replace(const basic_string<_CharT, _ST, _SA>& __s,
5817 const basic_regex<_CharT, _Traits>& __e,
5818 const _CharT* __fmt,
5819 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5820 basic_string<_CharT, _ST, _SA> __r;
5821 std::regex_replace(std::back_inserter(__r), __s.begin(), __s.end(), __e, __fmt, __flags);
5822 return __r;
5823}
5824
5825template <class _Traits, class _CharT, class _ST, class _SA>
5826inline _LIBCPP_HIDE_FROM_ABI basic_string<_CharT>
5827regex_replace(const _CharT* __s,
5828 const basic_regex<_CharT, _Traits>& __e,
5829 const basic_string<_CharT, _ST, _SA>& __fmt,
5830 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5831 basic_string<_CharT> __r;
5832 std::regex_replace(std::back_inserter(__r), __s, __s + char_traits<_CharT>::length(__s), __e, __fmt.c_str(), __flags);
5833 return __r;
5834}
5835
5836template <class _Traits, class _CharT>
5837inline _LIBCPP_HIDE_FROM_ABI basic_string<_CharT>
5838regex_replace(const _CharT* __s,
5839 const basic_regex<_CharT, _Traits>& __e,
5840 const _CharT* __fmt,
5841 regex_constants::match_flag_type __flags = regex_constants::match_default) {
5842 basic_string<_CharT> __r;
5843 std::regex_replace(std::back_inserter(__r), __s, __s + char_traits<_CharT>::length(__s), __e, __fmt, __flags);
5844 return __r;
5845}
5846
5847_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
5848_LIBCPP_END_NAMESPACE_STD
5849
5850# if _LIBCPP_STD_VER >= 17
5851_LIBCPP_BEGIN_NAMESPACE_STD
5852namespace pmr {
5853template <class _BidirT>
5854using match_results _LIBCPP_AVAILABILITY_PMR =
5855 std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>;
5856
5857using cmatch _LIBCPP_AVAILABILITY_PMR = match_results<const char*>;
5858using smatch _LIBCPP_AVAILABILITY_PMR = match_results<std::pmr::string::const_iterator>;
5859
5860# if _LIBCPP_HAS_WIDE_CHARACTERS
5861using wcmatch _LIBCPP_AVAILABILITY_PMR = match_results<const wchar_t*>;
5862using wsmatch _LIBCPP_AVAILABILITY_PMR = match_results<std::pmr::wstring::const_iterator>;
5863# endif
5864} // namespace pmr
5865_LIBCPP_END_NAMESPACE_STD
5866# endif
5867
5868_LIBCPP_POP_MACROS
5869
5870# endif // _LIBCPP_HAS_LOCALIZATION
5871
5872#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
5873
5874#endif // _LIBCPP_REGEX
5875