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