blob: c1bacffa2de88e3cf7238f75bcdd8e983017a26c [file] [log] [blame]
Howard Hinnant3257c982010-06-17 00:34:59 +00001// -*- C++ -*-
2//===--------------------------- regex ------------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_REGEX
12#define _LIBCPP_REGEX
13
14/*
15 regex synopsis
16
17#include <initializer_list>
18
19namespace std
20{
21
22namespace regex_constants
23{
24
25emum 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};
38
39constexpr syntax_option_type operator~(syntax_option_type f);
40constexpr syntax_option_type operator&(syntax_option_type lhs, syntax_option_type rhs);
41constexpr syntax_option_type operator|(syntax_option_type lhs, syntax_option_type rhs);
42
43enum match_flag_type
44{
45 match_default = 0,
46 match_not_bol = unspecified,
47 match_not_eol = unspecified,
48 match_not_bow = unspecified,
49 match_not_eow = unspecified,
50 match_any = unspecified,
51 match_not_null = unspecified,
52 match_continuous = unspecified,
53 match_prev_avail = unspecified,
54 format_default = 0,
55 format_sed = unspecified,
56 format_no_copy = unspecified,
57 format_first_only = unspecified
58};
59
60constexpr match_flag_type operator~(match_flag_type f);
61constexpr match_flag_type operator&(match_flag_type lhs, match_flag_type rhs);
62constexpr match_flag_type operator|(match_flag_type lhs, match_flag_type rhs);
63
64enum error_type
65{
66 error_collate = unspecified,
67 error_ctype = unspecified,
68 error_escape = unspecified,
69 error_backref = unspecified,
70 error_brack = unspecified,
71 error_paren = unspecified,
72 error_brace = unspecified,
73 error_badbrace = unspecified,
74 error_range = unspecified,
75 error_space = unspecified,
76 error_badrepeat = unspecified,
77 error_complexity = unspecified,
78 error_stack = unspecified
79};
80
81} // regex_constants
82
83class regex_error
84 : public runtime_error
85{
86public:
87 explicit regex_error(regex_constants::error_type ecode);
88 regex_constants::error_type code() const;
89};
90
91template <class charT>
92struct regex_traits
93{
94public:
95 typedef charT char_type;
96 typedef basic_string<char_type> string_type;
97 typedef locale locale_type;
98 typedef /bitmask_type/ char_class_type;
99
100 regex_traits();
101
102 static size_t length(const char_type* p);
103 charT translate(charT c) const;
104 charT translate_nocase(charT c) const;
105 template <class ForwardIterator>
106 string_type
107 transform(ForwardIterator first, ForwardIterator last) const;
108 template <class ForwardIterator>
109 string_type
110 transform_primary( ForwardIterator first, ForwardIterator last) const;
111 template <class ForwardIterator>
112 string_type
113 lookup_collatename(ForwardIterator first, ForwardIterator last) const;
114 template <class ForwardIterator>
115 char_class_type
116 lookup_classname(ForwardIterator first, ForwardIterator last,
117 bool icase = false) const;
118 bool isctype(charT c, char_class_type f) const;
119 int value(charT ch, int radix) const;
120 locale_type imbue(locale_type l);
121 locale_type getloc()const;
122};
123
124template <class charT, class traits = regex_traits<charT>>
125class basic_regex
126{
127public:
128 // types:
129 typedef charT value_type;
130 typedef regex_constants::syntax_option_type flag_type;
131 typedef typename traits::locale_type locale_type;
132
133 // constants:
134 static constexpr regex_constants::syntax_option_type icase = regex_constants::icase;
135 static constexpr regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
136 static constexpr regex_constants::syntax_option_type optimize = regex_constants::optimize;
137 static constexpr regex_constants::syntax_option_type collate = regex_constants::collate;
138 static constexpr regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
139 static constexpr regex_constants::syntax_option_type basic = regex_constants::basic;
140 static constexpr regex_constants::syntax_option_type extended = regex_constants::extended;
141 static constexpr regex_constants::syntax_option_type awk = regex_constants::awk;
142 static constexpr regex_constants::syntax_option_type grep = regex_constants::grep;
143 static constexpr regex_constants::syntax_option_type egrep = regex_constants::egrep;
144
145 // construct/copy/destroy:
146 basic_regex();
147 explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
148 basic_regex(const charT* p, size_t len, flag_type f);
149 basic_regex(const basic_regex&);
150 basic_regex(basic_regex&&);
151 template <class ST, class SA>
152 explicit basic_regex(const basic_string<charT, ST, SA>& p,
153 flag_type f = regex_constants::ECMAScript);
154 template <class ForwardIterator>
155 basic_regex(ForwardIterator first, ForwardIterator last,
156 flag_type f = regex_constants::ECMAScript);
157 basic_regex(initializer_list<charT>, flag_type = regex_constants::ECMAScript);
158
159 ~basic_regex();
160
161 basic_regex& operator=(const basic_regex&);
162 basic_regex& operator=(basic_regex&&);
163 basic_regex& operator=(const charT* ptr);
164 basic_regex& operator=(initializer_list<charT> il);
165 template <class ST, class SA>
166 basic_regex& operator=(const basic_string<charT, ST, SA>& p);
167
168 // assign:
169 basic_regex& assign(const basic_regex& that);
170 basic_regex& assign(basic_regex&& that);
171 basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript);
172 basic_regex& assign(const charT* p, size_t len, flag_type f);
173 template <class string_traits, class A>
174 basic_regex& assign(const basic_string<charT, string_traits, A>& s,
175 flag_type f = regex_constants::ECMAScript);
176 template <class InputIterator>
177 basic_regex& assign(InputIterator first, InputIterator last,
178 flag_type f = regex_constants::ECMAScript);
179 basic_regex& assign(initializer_list<charT>, flag_type = regex_constants::ECMAScript);
180
181 // const operations:
182 unsigned mark_count() const;
183 flag_type flags() const;
184
185 // locale:
186 locale_type imbue(locale_type loc);
187 locale_type getloc() const;
188
189 // swap:
190 void swap(basic_regex&);
191};
192
193typedef basic_regex<char> regex;
194typedef basic_regex<wchar_t> wregex;
195
196template <class charT, class traits>
197 void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2);
198
199template <class BidirectionalIterator>
200class sub_match
201 : public pair<BidirectionalIterator, BidirectionalIterator>
202{
203public:
204 typedef typename iterator_traits<BidirectionalIterator>::value_type value_type;
205 typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;
206 typedef BidirectionalIterator iterator;
207 typedef basic_string<value_type> string_type;
208
209 bool matched;
210
211 difference_type length() const;
212 operator string_type() const;
213 string_type str() const;
214
215 int compare(const sub_match& s) const;
216 int compare(const string_type& s) const;
217 int compare(const value_type* s) const;
218};
219
220typedef sub_match<const char*> csub_match;
221typedef sub_match<const wchar_t*> wcsub_match;
222typedef sub_match<string::const_iterator> ssub_match;
223typedef sub_match<wstring::const_iterator> wssub_match;
224
225template <class BiIter>
226 bool
227 operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
228
229template <class BiIter>
230 bool
231 operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
232
233template <class BiIter>
234 bool
235 operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
236
237template <class BiIter>
238 bool
239 operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
240
241template <class BiIter>
242 bool
243 operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
244
245template <class BiIter>
246 bool
247 operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
248
249template <class BiIter, class ST, class SA>
250 bool
251 operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
252 const sub_match<BiIter>& rhs);
253
254template <class BiIter, class ST, class SA>
255 bool
256 operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
257 const sub_match<BiIter>& rhs);
258
259template <class BiIter, class ST, class SA>
260 bool
261 operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
262 const sub_match<BiIter>& rhs);
263
264template <class BiIter, class ST, class SA>
265 bool
266 operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
267 const sub_match<BiIter>& rhs);
268
269template <class BiIter, class ST, class SA>
270 bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
271 const sub_match<BiIter>& rhs);
272
273template <class BiIter, class ST, class SA>
274 bool
275 operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
276 const sub_match<BiIter>& rhs);
277
278template <class BiIter, class ST, class SA>
279 bool
280 operator==(const sub_match<BiIter>& lhs,
281 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
282
283template <class BiIter, class ST, class SA>
284 bool
285 operator!=(const sub_match<BiIter>& lhs,
286 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
287
288template <class BiIter, class ST, class SA>
289 bool
290 operator<(const sub_match<BiIter>& lhs,
291 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
292
293template <class BiIter, class ST, class SA>
294 bool operator>(const sub_match<BiIter>& lhs,
295 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
296
297template <class BiIter, class ST, class SA>
298 bool
299 operator>=(const sub_match<BiIter>& lhs,
300 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
301
302template <class BiIter, class ST, class SA>
303 bool
304 operator<=(const sub_match<BiIter>& lhs,
305 const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
306
307template <class BiIter>
308 bool
309 operator==(typename iterator_traits<BiIter>::value_type const* lhs,
310 const sub_match<BiIter>& rhs);
311
312template <class BiIter>
313 bool
314 operator!=(typename iterator_traits<BiIter>::value_type const* lhs,
315 const sub_match<BiIter>& rhs);
316
317template <class BiIter>
318 bool
319 operator<(typename iterator_traits<BiIter>::value_type const* lhs,
320 const sub_match<BiIter>& rhs);
321
322template <class BiIter>
323 bool
324 operator>(typename iterator_traits<BiIter>::value_type const* lhs,
325 const sub_match<BiIter>& rhs);
326
327template <class BiIter>
328 bool
329 operator>=(typename iterator_traits<BiIter>::value_type const* lhs,
330 const sub_match<BiIter>& rhs);
331
332template <class BiIter>
333 bool
334 operator<=(typename iterator_traits<BiIter>::value_type const* lhs,
335 const sub_match<BiIter>& rhs);
336
337template <class BiIter>
338 bool
339 operator==(const sub_match<BiIter>& lhs,
340 typename iterator_traits<BiIter>::value_type const* rhs);
341
342template <class BiIter>
343 bool
344 operator!=(const sub_match<BiIter>& lhs,
345 typename iterator_traits<BiIter>::value_type const* rhs);
346
347template <class BiIter>
348 bool
349 operator<(const sub_match<BiIter>& lhs,
350 typename iterator_traits<BiIter>::value_type const* rhs);
351
352template <class BiIter>
353 bool
354 operator>(const sub_match<BiIter>& lhs,
355 typename iterator_traits<BiIter>::value_type const* rhs);
356
357template <class BiIter>
358 bool
359 operator>=(const sub_match<BiIter>& lhs,
360 typename iterator_traits<BiIter>::value_type const* rhs);
361
362template <class BiIter>
363 bool
364 operator<=(const sub_match<BiIter>& lhs,
365 typename iterator_traits<BiIter>::value_type const* rhs);
366
367template <class BiIter>
368 bool
369 operator==(typename iterator_traits<BiIter>::value_type const& lhs,
370 const sub_match<BiIter>& rhs);
371
372template <class BiIter>
373 bool
374 operator!=(typename iterator_traits<BiIter>::value_type const& lhs,
375 const sub_match<BiIter>& rhs);
376
377template <class BiIter>
378 bool
379 operator<(typename iterator_traits<BiIter>::value_type const& lhs,
380 const sub_match<BiIter>& rhs);
381
382template <class BiIter>
383 bool
384 operator>(typename iterator_traits<BiIter>::value_type const& lhs,
385 const sub_match<BiIter>& rhs);
386
387template <class BiIter>
388 bool
389 operator>=(typename iterator_traits<BiIter>::value_type const& lhs,
390 const sub_match<BiIter>& rhs);
391
392template <class BiIter>
393 bool
394 operator<=(typename iterator_traits<BiIter>::value_type const& lhs,
395 const sub_match<BiIter>& rhs);
396
397template <class BiIter>
398 bool
399 operator==(const sub_match<BiIter>& lhs,
400 typename iterator_traits<BiIter>::value_type const& rhs);
401
402template <class BiIter>
403 bool
404 operator!=(const sub_match<BiIter>& lhs,
405 typename iterator_traits<BiIter>::value_type const& rhs);
406
407template <class BiIter>
408 bool
409 operator<(const sub_match<BiIter>& lhs,
410 typename iterator_traits<BiIter>::value_type const& rhs);
411
412template <class BiIter>
413 bool
414 operator>(const sub_match<BiIter>& lhs,
415 typename iterator_traits<BiIter>::value_type const& rhs);
416
417template <class BiIter>
418 bool
419 operator>=(const sub_match<BiIter>& lhs,
420 typename iterator_traits<BiIter>::value_type const& rhs);
421
422template <class BiIter>
423 bool
424 operator<=(const sub_match<BiIter>& lhs,
425 typename iterator_traits<BiIter>::value_type const& rhs);
426
427template <class charT, class ST, class BiIter>
428 basic_ostream<charT, ST>&
429 operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);
430
431template <class BidirectionalIterator,
432 class Allocator = allocator<sub_match<BidirectionalIterator>>>
433class match_results
434{
435public:
436 typedef sub_match<BidirectionalIterator> value_type;
437 typedef const value_type& const_reference;
438 typedef const_reference reference;
439 typedef /implementation-defined/ const_iterator;
440 typedef const_iterator iterator;
441 typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;
442 typedef typename allocator_traits<Allocator>::size_type size_type;
443 typedef Allocator allocator_type;
444 typedef typename iterator_traits<BidirectionalIterator>::value_type char_type;
445 typedef basic_string<char_type> string_type;
446
447 // construct/copy/destroy:
448 explicit match_results(const Allocator& a = Allocator());
449 match_results(const match_results& m);
450 match_results(match_results&& m);
451 match_results& operator=(const match_results& m);
452 match_results& operator=(match_results&& m);
453 ~match_results();
454
455 // size:
456 size_type size() const;
457 size_type max_size() const;
458 bool empty() const;
459
460 // element access:
461 difference_type length(size_type sub = 0) const;
462 difference_type position(size_type sub = 0) const;
463 string_type str(size_type sub = 0) const;
464 const_reference operator[](size_type n) const;
465
466 const_reference prefix() const;
467 const_reference suffix() const;
468
469 const_iterator begin() const;
470 const_iterator end() const;
471 const_iterator cbegin() const;
472 const_iterator cend() const;
473
474 // format:
475 template <class OutputIter>
476 OutputIter
477 format(OutputIter out, const char_type* fmt_first,
478 const char_type* fmt_last,
479 regex_constants::match_flag_type flags = regex_constants::format_default) const;
480 template <class OutputIter, class ST, class SA>
481 OutputIter
482 format(OutputIter out, const basic_string<char_type, ST, SA>& fmt,
483 regex_constants::match_flag_type flags = regex_constants::format_default) const;
484 template <class ST, class SA>
485 basic_string<char_type, ST, SA>
486 format(const basic_string<char_type, ST, SA>& fmt,
487 regex_constants::match_flag_type flags = regex_constants::format_default) const;
488 string_type
489 format(const char_type* fmt,
490 regex_constants::match_flag_type flags = regex_constants::format_default) const;
491
492 // allocator:
493 allocator_type get_allocator() const;
494
495 // swap:
496 void swap(match_results& that);
497};
498
499typedef match_results<const char*> cmatch;
500typedef match_results<const wchar_t*> wcmatch;
501typedef match_results<string::const_iterator> smatch;
502typedef match_results<wstring::const_iterator> wsmatch;
503
504template <class BidirectionalIterator, class Allocator>
505 bool
506 operator==(const match_results<BidirectionalIterator, Allocator>& m1,
507 const match_results<BidirectionalIterator, Allocator>& m2);
508
509template <class BidirectionalIterator, class Allocator>
510 bool
511 operator!=(const match_results<BidirectionalIterator, Allocator>& m1,
512 const match_results<BidirectionalIterator, Allocator>& m2);
513
514template <class BidirectionalIterator, class Allocator>
515 void
516 swap(match_results<BidirectionalIterator, Allocator>& m1,
517 match_results<BidirectionalIterator, Allocator>& m2);
518
519template <class BidirectionalIterator, class Allocator, class charT, class traits>
520 bool
521 regex_match(BidirectionalIterator first, BidirectionalIterator last,
522 match_results<BidirectionalIterator, Allocator>& m,
523 const basic_regex<charT, traits>& e,
524 regex_constants::match_flag_type flags = regex_constants::match_default);
525
526template <class BidirectionalIterator, class charT, class traits>
527 bool
528 regex_match(BidirectionalIterator first, BidirectionalIterator last,
529 const basic_regex<charT, traits>& e,
530 regex_constants::match_flag_type flags = regex_constants::match_default);
531
532template <class charT, class Allocator, class traits>
533 bool
534 regex_match(const charT* str, match_results<const charT*, Allocator>& m,
535 const basic_regex<charT, traits>& e,
536 regex_constants::match_flag_type flags = regex_constants::match_default);
537
538template <class ST, class SA, class Allocator, class charT, class traits>
539 bool
540 regex_match(const basic_string<charT, ST, SA>& s,
541 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
542 const basic_regex<charT, traits>& e,
543 regex_constants::match_flag_type flags = regex_constants::match_default);
544
545template <class charT, class traits>
546 bool
547 regex_match(const charT* str, const basic_regex<charT, traits>& e,
548 regex_constants::match_flag_type flags = regex_constants::match_default);
549
550template <class ST, class SA, class charT, class traits>
551 bool
552 regex_match(const basic_string<charT, ST, SA>& s,
553 const basic_regex<charT, traits>& e,
554 regex_constants::match_flag_type flags = regex_constants::match_default);
555
556template <class BidirectionalIterator, class Allocator, class charT, class traits>
557 bool
558 regex_search(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_search(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_search(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 charT, class traits>
576 bool
577 regex_search(const charT* str, const basic_regex<charT, traits>& e,
578 regex_constants::match_flag_type flags = regex_constants::match_default);
579
580template <class ST, class SA, class charT, class traits>
581 bool
582 regex_search(const basic_string<charT, ST, SA>& s,
583 const basic_regex<charT, traits>& e,
584 regex_constants::match_flag_type flags = regex_constants::match_default);
585
586template <class ST, class SA, class Allocator, class charT, class traits>
587 bool
588 regex_search(const basic_string<charT, ST, SA>& s,
589 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
590 const basic_regex<charT, traits>& e,
591 regex_constants::match_flag_type flags = regex_constants::match_default);
592
593template <class OutputIterator, class BidirectionalIterator,
594 class traits, class charT, class ST, class SA>
595 OutputIterator
596 regex_replace(OutputIterator out,
597 BidirectionalIterator first, BidirectionalIterator last,
598 const basic_regex<charT, traits>& e,
599 const basic_string<charT, ST, SA>& fmt,
600 regex_constants::match_flag_type flags = regex_constants::match_default);
601
602template <class OutputIterator, class BidirectionalIterator,
603 class traits, class charT>
604 OutputIterator
605 regex_replace(OutputIterator out,
606 BidirectionalIterator first, BidirectionalIterator last,
607 const basic_regex<charT, traits>& e, const charT* fmt,
608 regex_constants::match_flag_type flags = regex_constants::match_default);
609
610template <class traits, class charT, class ST, class SA, class FST, class FSA>>
611 basic_string<charT, ST, SA>
612 regex_replace(const basic_string<charT, ST, SA>& s,
613 const basic_regex<charT, traits>& e,
614 const basic_string<charT, FST, FSA>& fmt,
615 regex_constants::match_flag_type flags = regex_constants::match_default);
616
617template <class traits, class charT, class ST, class SA>
618 basic_string<charT, ST, SA>
619 regex_replace(const basic_string<charT, ST, SA>& s,
620 const basic_regex<charT, traits>& e, const charT* fmt,
621 regex_constants::match_flag_type flags = regex_constants::match_default);
622
623template <class traits, class charT, class ST, class SA>
624 basic_string<charT>
625 regex_replace(const charT* s,
626 const basic_regex<charT, traits>& e,
627 const basic_string<charT, ST, SA>& fmt,
628 regex_constants::match_flag_type flags = regex_constants::match_default);
629
630template <class traits, class charT>
631 basic_string<charT>
632 regex_replace(const charT* s,
633 const basic_regex<charT, traits>& e,
634 const charT* fmt,
635 regex_constants::match_flag_type flags = regex_constants::match_default);
636
637template <class BidirectionalIterator,
638 class charT = typename iterator_traits< BidirectionalIterator>::value_type,
639 class traits = regex_traits<charT>>
640class regex_iterator
641{
642public:
643 typedef basic_regex<charT, traits> regex_type;
644 typedef match_results<BidirectionalIterator> value_type;
645 typedef ptrdiff_t difference_type;
646 typedef const value_type* pointer;
647 typedef const value_type& reference;
648 typedef forward_iterator_tag iterator_category;
649
650 regex_iterator();
651 regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
652 const regex_type& re,
653 regex_constants::match_flag_type m = regex_constants::match_default);
654 regex_iterator(const regex_iterator&);
655 regex_iterator& operator=(const regex_iterator&);
656
657 bool operator==(const regex_iterator&) const;
658 bool operator!=(const regex_iterator&) const;
659
660 const value_type& operator*() const;
661 const value_type* operator->() const;
662
663 regex_iterator& operator++();
664 regex_iterator operator++(int);
665};
666
667typedef regex_iterator<const char*> cregex_iterator;
668typedef regex_iterator<const wchar_t*> wcregex_iterator;
669typedef regex_iterator<string::const_iterator> sregex_iterator;
670typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
671
672template <class BidirectionalIterator,
673 class charT = typename iterator_traits< BidirectionalIterator>::value_type,
674 class traits = regex_traits<charT>>
675class regex_token_iterator
676{
677public:
678 typedef basic_regex<charT, traits> regex_type;
679 typedef sub_match<BidirectionalIterator> value_type;
680 typedef ptrdiff_t difference_type;
681 typedef const value_type* pointer;
682 typedef const value_type& reference;
683 typedef forward_iterator_tag iterator_category;
684
685 regex_token_iterator();
686 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
687 const regex_type& re, int submatch = 0,
688 regex_constants::match_flag_type m = regex_constants::match_default);
689 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
690 const regex_type& re, const vector<int>& submatches,
691 regex_constants::match_flag_type m = regex_constants::match_default);
692 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
693 const regex_type& re, initializer_list<int> submatches,
694 regex_constants::match_flag_type m = regex_constants::match_default);
695 template <size_t N>
696 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
697 const regex_type& re, const int (&submatches)[N],
698 regex_constants::match_flag_type m = regex_constants::match_default);
699 regex_token_iterator(const regex_token_iterator&);
700 regex_token_iterator& operator=(const regex_token_iterator&);
701
702 bool operator==(const regex_token_iterator&) const;
703 bool operator!=(const regex_token_iterator&) const;
704
705 const value_type& operator*() const;
706 const value_type* operator->() const;
707
708 regex_token_iterator& operator++();
709 regex_token_iterator operator++(int);
710};
711
712typedef regex_token_iterator<const char*> cregex_token_iterator;
713typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
714typedef regex_token_iterator<string::const_iterator> sregex_token_iterator;
715typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
716
717} // std
718*/
719
720#include <__config>
721#include <stdexcept>
722#include <__locale>
Howard Hinnant8c2c18d2010-06-24 21:28:00 +0000723#include <initializer_list>
Howard Hinnantcd85b9e2010-06-29 18:37:43 +0000724#include <utility>
725#include <iterator>
726#include <string>
Howard Hinnant7e9d84b2010-06-30 00:21:42 +0000727#include <memory>
728#include <vector>
Howard Hinnantf8ce4592010-07-07 19:14:52 +0000729#include <__split_buffer>
Howard Hinnant3257c982010-06-17 00:34:59 +0000730
731#pragma GCC system_header
732
733_LIBCPP_BEGIN_NAMESPACE_STD
734
735namespace regex_constants
736{
737
738// syntax_option_type
739
740enum syntax_option_type
741{
742 icase = 1 << 0,
743 nosubs = 1 << 1,
744 optimize = 1 << 2,
745 collate = 1 << 3,
746 ECMAScript = 1 << 4,
747 basic = 1 << 5,
748 extended = 1 << 6,
749 awk = 1 << 7,
750 grep = 1 << 8,
751 egrep = 1 << 9
752};
753
754inline
755/*constexpr*/
756syntax_option_type
757operator~(syntax_option_type __x)
758{
759 return syntax_option_type(~int(__x));
760}
761
762inline
763/*constexpr*/
764syntax_option_type
765operator&(syntax_option_type __x, syntax_option_type __y)
766{
767 return syntax_option_type(int(__x) & int(__y));
768}
769
770inline
771/*constexpr*/
772syntax_option_type
773operator|(syntax_option_type __x, syntax_option_type __y)
774{
775 return syntax_option_type(int(__x) | int(__y));
776}
777
778inline
779/*constexpr*/
780syntax_option_type
781operator^(syntax_option_type __x, syntax_option_type __y)
782{
783 return syntax_option_type(int(__x) ^ int(__y));
784}
785
786inline
787/*constexpr*/
788syntax_option_type&
789operator&=(syntax_option_type& __x, syntax_option_type __y)
790{
791 __x = __x & __y;
792 return __x;
793}
794
795inline
796/*constexpr*/
797syntax_option_type&
798operator|=(syntax_option_type& __x, syntax_option_type __y)
799{
800 __x = __x | __y;
801 return __x;
802}
803
804inline
805/*constexpr*/
806syntax_option_type&
807operator^=(syntax_option_type& __x, syntax_option_type __y)
808{
809 __x = __x ^ __y;
810 return __x;
811}
812
813// match_flag_type
814
815enum match_flag_type
816{
817 match_default = 0,
818 match_not_bol = 1 << 0,
819 match_not_eol = 1 << 1,
820 match_not_bow = 1 << 2,
821 match_not_eow = 1 << 3,
822 match_any = 1 << 4,
823 match_not_null = 1 << 5,
824 match_continuous = 1 << 6,
825 match_prev_avail = 1 << 7,
826 format_default = 0,
827 format_sed = 1 << 8,
828 format_no_copy = 1 << 9,
829 format_first_only = 1 << 10
830};
831
832inline
833/*constexpr*/
834match_flag_type
835operator~(match_flag_type __x)
836{
837 return match_flag_type(~int(__x));
838}
839
840inline
841/*constexpr*/
842match_flag_type
843operator&(match_flag_type __x, match_flag_type __y)
844{
845 return match_flag_type(int(__x) & int(__y));
846}
847
848inline
849/*constexpr*/
850match_flag_type
851operator|(match_flag_type __x, match_flag_type __y)
852{
853 return match_flag_type(int(__x) | int(__y));
854}
855
856inline
857/*constexpr*/
858match_flag_type
859operator^(match_flag_type __x, match_flag_type __y)
860{
861 return match_flag_type(int(__x) ^ int(__y));
862}
863
864inline
865/*constexpr*/
866match_flag_type&
867operator&=(match_flag_type& __x, match_flag_type __y)
868{
869 __x = __x & __y;
870 return __x;
871}
872
873inline
874/*constexpr*/
875match_flag_type&
876operator|=(match_flag_type& __x, match_flag_type __y)
877{
878 __x = __x | __y;
879 return __x;
880}
881
882inline
883/*constexpr*/
884match_flag_type&
885operator^=(match_flag_type& __x, match_flag_type __y)
886{
887 __x = __x ^ __y;
888 return __x;
889}
890
891enum error_type
892{
893 error_collate = 1,
894 error_ctype,
895 error_escape,
896 error_backref,
897 error_brack,
898 error_paren,
899 error_brace,
900 error_badbrace,
901 error_range,
902 error_space,
903 error_badrepeat,
904 error_complexity,
Howard Hinnant8c2c18d2010-06-24 21:28:00 +0000905 error_stack,
906 error_temp
Howard Hinnant3257c982010-06-17 00:34:59 +0000907};
908
909} // regex_constants
910
911class _LIBCPP_EXCEPTION_ABI regex_error
912 : public runtime_error
913{
914 regex_constants::error_type __code_;
915public:
916 explicit regex_error(regex_constants::error_type __ecode);
917 virtual ~regex_error() throw();
918 regex_constants::error_type code() const {return __code_;}
919};
920
921template <class _CharT>
922struct regex_traits
923{
924public:
925 typedef _CharT char_type;
926 typedef basic_string<char_type> string_type;
927 typedef locale locale_type;
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000928 typedef ctype_base::mask char_class_type;
Howard Hinnant3257c982010-06-17 00:34:59 +0000929
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000930 static const char_class_type __regex_word = 0x80;
Howard Hinnant3257c982010-06-17 00:34:59 +0000931private:
932 locale __loc_;
933 const ctype<char_type>* __ct_;
934 const collate<char_type>* __col_;
935
936public:
937 regex_traits();
938
939 static size_t length(const char_type* __p)
940 {return char_traits<char_type>::length(__p);}
941 char_type translate(char_type __c) const {return __c;}
942 char_type translate_nocase(char_type __c) const;
943 template <class _ForwardIterator>
944 string_type
945 transform(_ForwardIterator __f, _ForwardIterator __l) const;
946 template <class _ForwardIterator>
947 string_type
948 transform_primary( _ForwardIterator __f, _ForwardIterator __l) const
949 {return __transform_primary(__f, __l, char_type());}
950 template <class _ForwardIterator>
951 string_type
952 lookup_collatename(_ForwardIterator __f, _ForwardIterator __l) const
953 {return __lookup_collatename(__f, __l, char_type());}
954 template <class _ForwardIterator>
955 char_class_type
956 lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000957 bool __icase = false) const
958 {return __lookup_classname(__f, __l, __icase, char_type());}
959 bool isctype(char_type __c, char_class_type __m) const;
960 int value(char_type __ch, int __radix) const
961 {return __value(__ch, __radix);}
Howard Hinnant3257c982010-06-17 00:34:59 +0000962 locale_type imbue(locale_type __l);
963 locale_type getloc()const {return __loc_;}
964
965private:
966 void __init();
967
968 template <class _ForwardIterator>
969 string_type
970 __transform_primary(_ForwardIterator __f, _ForwardIterator __l, char) const;
971 template <class _ForwardIterator>
972 string_type
973 __transform_primary(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
974
975 template <class _ForwardIterator>
976 string_type
977 __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, char) const;
978 template <class _ForwardIterator>
979 string_type
980 __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000981
982 template <class _ForwardIterator>
983 char_class_type
984 __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
985 bool __icase, char) const;
986 template <class _ForwardIterator>
987 char_class_type
988 __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
989 bool __icase, wchar_t) const;
990
991 static int __value(unsigned char __ch, int __radix);
992 int __value(char __ch, int __radix) const
993 {return __value(static_cast<unsigned char>(__ch), __radix);}
994 int __value(wchar_t __ch, int __radix) const;
Howard Hinnant3257c982010-06-17 00:34:59 +0000995};
996
997template <class _CharT>
998regex_traits<_CharT>::regex_traits()
999{
1000 __init();
1001}
1002
1003template <class _CharT>
1004typename regex_traits<_CharT>::char_type
1005regex_traits<_CharT>::translate_nocase(char_type __c) const
1006{
1007 return __ct_->tolower(__c);
1008}
1009
1010template <class _CharT>
1011template <class _ForwardIterator>
1012typename regex_traits<_CharT>::string_type
1013regex_traits<_CharT>::transform(_ForwardIterator __f, _ForwardIterator __l) const
1014{
1015 string_type __s(__f, __l);
1016 return __col_->transform(__s.data(), __s.data() + __s.size());
1017}
1018
1019template <class _CharT>
1020void
1021regex_traits<_CharT>::__init()
1022{
1023 __ct_ = &use_facet<ctype<char_type> >(__loc_);
1024 __col_ = &use_facet<collate<char_type> >(__loc_);
1025}
1026
1027template <class _CharT>
1028typename regex_traits<_CharT>::locale_type
1029regex_traits<_CharT>::imbue(locale_type __l)
1030{
1031 locale __r = __loc_;
1032 __loc_ = __l;
1033 __init();
1034 return __r;
1035}
1036
1037// transform_primary is very FreeBSD-specific
1038
1039template <class _CharT>
1040template <class _ForwardIterator>
1041typename regex_traits<_CharT>::string_type
1042regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
1043 _ForwardIterator __l, char) const
1044{
1045 const string_type __s(__f, __l);
1046 string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
1047 switch (__d.size())
1048 {
1049 case 1:
1050 break;
1051 case 12:
1052 __d[11] = __d[3];
1053 break;
1054 default:
1055 __d.clear();
1056 break;
1057 }
1058 return __d;
1059}
1060
1061template <class _CharT>
1062template <class _ForwardIterator>
1063typename regex_traits<_CharT>::string_type
1064regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
1065 _ForwardIterator __l, wchar_t) const
1066{
1067 const string_type __s(__f, __l);
1068 string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
1069 switch (__d.size())
1070 {
1071 case 1:
1072 break;
1073 case 3:
1074 __d[2] = __d[0];
1075 break;
1076 default:
1077 __d.clear();
1078 break;
1079 }
1080 return __d;
1081}
1082
1083// lookup_collatename is very FreeBSD-specific
1084
Howard Hinnantf409d2f2010-06-21 21:01:43 +00001085string __get_collation_name(const char* __s);
Howard Hinnant3257c982010-06-17 00:34:59 +00001086
1087template <class _CharT>
1088template <class _ForwardIterator>
1089typename regex_traits<_CharT>::string_type
1090regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
1091 _ForwardIterator __l, char) const
1092{
1093 string_type __s(__f, __l);
1094 string_type __r;
1095 if (!__s.empty())
1096 {
1097 __r = __get_collation_name(__s.c_str());
1098 if (__r.empty() && __s.size() <= 2)
1099 {
1100 __r = __col_->transform(__s.data(), __s.data() + __s.size());
1101 if (__r.size() == 1 || __r.size() == 12)
1102 __r = __s;
1103 else
1104 __r.clear();
1105 }
1106 }
1107 return __r;
1108}
1109
1110template <class _CharT>
1111template <class _ForwardIterator>
1112typename regex_traits<_CharT>::string_type
1113regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
1114 _ForwardIterator __l, wchar_t) const
1115{
1116 string_type __s(__f, __l);
1117 string __n;
1118 __n.reserve(__s.size());
1119 for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();
1120 __i != __e; ++__i)
1121 {
1122 if (static_cast<unsigned>(*__i) >= 127)
1123 return string_type();
1124 __n.push_back(char(*__i));
1125 }
1126 string_type __r;
1127 if (!__s.empty())
1128 {
1129 __n = __get_collation_name(__n.c_str());
1130 if (!__n.empty())
1131 __r.assign(__n.begin(), __n.end());
1132 else if (__s.size() <= 2)
1133 {
1134 __r = __col_->transform(__s.data(), __s.data() + __s.size());
1135 if (__r.size() == 1 || __r.size() == 3)
1136 __r = __s;
1137 else
1138 __r.clear();
1139 }
1140 }
1141 return __r;
1142}
1143
Howard Hinnantf409d2f2010-06-21 21:01:43 +00001144// lookup_classname
1145
1146ctype_base::mask __get_classname(const char* __s, bool __icase);
1147
1148template <class _CharT>
1149template <class _ForwardIterator>
1150typename regex_traits<_CharT>::char_class_type
1151regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,
1152 _ForwardIterator __l,
1153 bool __icase, char) const
1154{
1155 string_type __s(__f, __l);
1156 __ct_->tolower(&__s[0], &__s[0] + __s.size());
1157 return __get_classname(__s.c_str(), __icase);
1158}
1159
1160template <class _CharT>
1161template <class _ForwardIterator>
1162typename regex_traits<_CharT>::char_class_type
1163regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,
1164 _ForwardIterator __l,
1165 bool __icase, wchar_t) const
1166{
1167 string_type __s(__f, __l);
1168 __ct_->tolower(&__s[0], &__s[0] + __s.size());
1169 string __n;
1170 __n.reserve(__s.size());
1171 for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();
1172 __i != __e; ++__i)
1173 {
1174 if (static_cast<unsigned>(*__i) >= 127)
1175 return char_class_type();
1176 __n.push_back(char(*__i));
1177 }
1178 return __get_classname(__n.c_str(), __icase);
1179}
1180
1181template <class _CharT>
1182bool
1183regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const
1184{
1185 if (__ct_->is(__m, __c))
1186 return true;
1187 return (__c == '_' && (__m & __regex_word));
1188}
1189
1190template <class _CharT>
1191int
1192regex_traits<_CharT>::__value(unsigned char __ch, int __radix)
1193{
1194 if ((__ch & 0xF8u) == 0x30) // '0' <= __ch && __ch <= '7'
1195 return __ch - '0';
1196 if (__radix != 8)
1197 {
1198 if ((__ch & 0xFEu) == 0x38) // '8' <= __ch && __ch <= '9'
1199 return __ch - '0';
1200 if (__radix == 16)
1201 {
1202 __ch |= 0x20; // tolower
1203 if ('a' <= __ch && __ch <= 'f')
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001204 return __ch - ('a' - 10);
Howard Hinnantf409d2f2010-06-21 21:01:43 +00001205 }
1206 }
1207 return -1;
1208}
1209
1210template <class _CharT>
1211inline
1212int
1213regex_traits<_CharT>::__value(wchar_t __ch, int __radix) const
1214{
1215 return __value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
1216}
1217
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001218template <class _CharT> class __state;
1219
1220template <class _CharT>
1221struct __command
1222{
1223 enum
1224 {
1225 __end_state = -1000,
1226 __consume_input, // -999
1227// __try_state, // -998
1228 __begin_marked_expr, // -998
1229 __end_marked_expr, // -997
1230 __go_back, // -996
1231 __accept_and_consume, // -995
1232 __accept_but_not_consume, // -994
1233 __reject, // -993
1234 __zero_loop_count,
1235 __increment_loop_count,
1236 __zero_marked_exprs,
1237 };
1238
1239 typedef __state<_CharT> __state;
1240
1241 int __do_;
1242 int __data_;
1243 const __state* first;
1244 const __state* second;
1245
1246 __command() : __do_(__reject), first(nullptr), second(nullptr) {}
1247 explicit __command(int __do)
1248 : __do_(__do), first(nullptr), second(nullptr) {}
1249 __command(int __do, const __state* __s1, const __state* __s2 = nullptr)
1250 : __do_(__do), first(__s1), second(__s2) {}
1251 explicit __command(const __state* __s1, const __state* __s2 = nullptr)
1252 : __do_(0), first(__s1), second(__s2) {}
1253};
1254
1255template <class _BidirectionalIterator> class sub_match;
1256
1257// __state
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001258
1259template <class _CharT>
1260class __state
1261{
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001262 __state(const __state&);
1263 __state& operator=(const __state&);
1264public:
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001265 typedef __command<_CharT> __command;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001266
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001267 __state() {}
1268 virtual ~__state() {}
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001269
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001270 virtual __command __test(const _CharT* __first, const _CharT* __current,
1271 const _CharT* __last,
1272 vector<size_t>& __lc,
1273 sub_match<const _CharT*>* __m,
1274 regex_constants::match_flag_type __flags) const = 0;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001275};
1276
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001277// __end_state
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001278
1279template <class _CharT>
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001280class __end_state
1281 : public __state<_CharT>
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001282{
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001283public:
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001284 typedef __command<_CharT> __command;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001285
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001286 __end_state() {}
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001287
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001288 virtual __command __test(const _CharT*, const _CharT*,
1289 const _CharT*,
1290 vector<size_t>&,
1291 sub_match<const _CharT*>*,
1292 regex_constants::match_flag_type) const;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001293};
1294
1295template <class _CharT>
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001296__command<_CharT>
1297__end_state<_CharT>::__test(const _CharT*, const _CharT*,
1298 const _CharT*,
1299 vector<size_t>&,
1300 sub_match<const _CharT*>*,
1301 regex_constants::match_flag_type) const
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001302{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001303 return __command(__command::__end_state);
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001304}
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001305
1306// __has_one_state
1307
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001308template <class _CharT>
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001309class __has_one_state
1310 : public __state<_CharT>
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001311{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001312 __state<_CharT>* __first_;
1313
1314public:
1315 explicit __has_one_state(__state<_CharT>* __s)
1316 : __first_(__s) {}
1317
1318 __state<_CharT>* first() const {return __first_;}
1319 __state<_CharT>*& first() {return __first_;}
1320};
1321
1322// __owns_one_state
1323
1324template <class _CharT>
1325class __owns_one_state
1326 : public __has_one_state<_CharT>
1327{
1328 typedef __has_one_state<_CharT> base;
1329
1330public:
1331 explicit __owns_one_state(__state<_CharT>* __s)
1332 : base(__s) {}
1333
1334 virtual ~__owns_one_state();
1335};
1336
1337template <class _CharT>
1338__owns_one_state<_CharT>::~__owns_one_state()
1339{
1340 delete this->first();
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001341}
1342
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001343// __empty_state
1344
1345template <class _CharT>
1346class __empty_state
1347 : public __owns_one_state<_CharT>
1348{
1349 typedef __owns_one_state<_CharT> base;
1350
1351public:
1352 typedef __command<_CharT> __command;
1353
1354 explicit __empty_state(__state<_CharT>* __s)
1355 : base(__s) {}
1356
1357 virtual __command __test(const _CharT*, const _CharT*,
1358 const _CharT*,
1359 vector<size_t>&,
1360 sub_match<const _CharT*>*,
1361 regex_constants::match_flag_type) const;
1362};
1363
1364template <class _CharT>
1365__command<_CharT>
1366__empty_state<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
1367 vector<size_t>&,
1368 sub_match<const _CharT*>*,
1369 regex_constants::match_flag_type) const
1370{
1371 return __command(__command::__accept_but_not_consume, this->first());
1372}
1373
1374// __empty_non_own_state
1375
1376template <class _CharT>
1377class __empty_non_own_state
1378 : public __has_one_state<_CharT>
1379{
1380 typedef __has_one_state<_CharT> base;
1381
1382public:
1383 typedef __command<_CharT> __command;
1384
1385 explicit __empty_non_own_state(__state<_CharT>* __s)
1386 : base(__s) {}
1387
1388 virtual __command __test(const _CharT*, const _CharT*,
1389 const _CharT*,
1390 vector<size_t>&,
1391 sub_match<const _CharT*>*,
1392 regex_constants::match_flag_type) const;
1393};
1394
1395template <class _CharT>
1396__command<_CharT>
1397__empty_non_own_state<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
1398 vector<size_t>&,
1399 sub_match<const _CharT*>*,
1400 regex_constants::match_flag_type) const
1401{
1402 return __command(__command::__accept_but_not_consume, this->first());
1403}
1404
1405// __owns_two_states
1406
1407template <class _CharT>
1408class __owns_two_states
1409 : public __owns_one_state<_CharT>
1410{
1411 typedef __owns_one_state<_CharT> base;
1412
1413 base* __second_;
1414
1415public:
1416 explicit __owns_two_states(__state<_CharT>* __s1, base* __s2)
1417 : base(__s1), __second_(__s2) {}
1418
1419 virtual ~__owns_two_states();
1420
1421 base* second() const {return __second_;}
1422 base*& second() {return __second_;}
1423};
1424
1425template <class _CharT>
1426__owns_two_states<_CharT>::~__owns_two_states()
1427{
1428 delete __second_;
1429}
1430
1431// __loop
1432
1433template <class _CharT>
1434class __loop
1435 : public __owns_two_states<_CharT>
1436{
1437 typedef __owns_two_states<_CharT> base;
1438
1439 size_t __min_;
1440 size_t __max_;
1441 unsigned __loop_id_;
1442 bool __greedy_;
1443
1444public:
1445 typedef __command<_CharT> __command;
1446
1447 explicit __loop(unsigned __loop_id,
1448 __state<_CharT>* __s1, __owns_one_state<_CharT>* __s2,
1449 bool __greedy = true,
1450 size_t __min = 0,
1451 size_t __max = numeric_limits<size_t>::max())
1452 : base(__s1, __s2), __min_(__min), __max_(__max), __loop_id_(__loop_id),
1453 __greedy_(__greedy) {}
1454
1455 virtual __command __test(const _CharT* __first, const _CharT* __current,
1456 const _CharT* __last,
1457 vector<size_t>&,
1458 sub_match<const _CharT*>*,
1459 regex_constants::match_flag_type __flags) const;
1460};
1461
1462template <class _CharT>
1463__command<_CharT>
1464__loop<_CharT>::__test(const _CharT* __first, const _CharT* __current,
1465 const _CharT* __last,
1466 vector<size_t>& __lc,
1467 sub_match<const _CharT*>* __m,
1468 regex_constants::match_flag_type __flags) const
1469{
1470 size_t __count = __lc[__loop_id_];
1471 if (__min_ <= __count && __count < __max_)
1472 if (__greedy_)
1473 return __command(__command::__accept_but_not_consume, this->first(),
1474 this->second());
1475 else
1476 return __command(__command::__accept_but_not_consume, this->second(),
1477 this->first());
1478 if (__min_ <= __count)
1479 return __command(__command::__accept_but_not_consume, this->second());
1480 if (__count < __max_)
1481 return __command(__command::__accept_but_not_consume, this->first());
1482 throw regex_error(regex_constants::error_temp);
1483}
1484
1485// __zero_loop_count
1486
1487template <class _CharT>
1488class __zero_loop_count
1489 : public __owns_one_state<_CharT>
1490{
1491 typedef __owns_one_state<_CharT> base;
1492
1493 size_t __loop_id_;
1494
1495public:
1496 typedef __command<_CharT> __command;
1497
1498 explicit __zero_loop_count(size_t __loop_id,
1499 __state<_CharT>* __s1)
1500 : base(__s1), __loop_id_(__loop_id) {}
1501
1502 virtual __command __test(const _CharT*, const _CharT*, const _CharT*,
1503 vector<size_t>& __lc,
1504 sub_match<const _CharT*>*,
1505 regex_constants::match_flag_type) const;
1506};
1507
1508template <class _CharT>
1509__command<_CharT>
1510__zero_loop_count<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
1511 vector<size_t>& __lc,
1512 sub_match<const _CharT*>*,
1513 regex_constants::match_flag_type) const
1514{
1515 __lc[__loop_id_] = 0;
1516 return __command(__command::__accept_but_not_consume, this->first());
1517}
1518
1519// __increment_loop_count
1520
1521template <class _CharT>
1522class __increment_loop_count
1523 : public __has_one_state<_CharT>
1524{
1525 typedef __has_one_state<_CharT> base;
1526
1527 size_t __loop_id_;
1528
1529public:
1530 typedef __command<_CharT> __command;
1531
1532 explicit __increment_loop_count(size_t __loop_id,
1533 __state<_CharT>* __s1)
1534 : base(__s1), __loop_id_(__loop_id) {}
1535
1536 virtual __command __test(const _CharT*, const _CharT*, const _CharT*,
1537 vector<size_t>& __lc,
1538 sub_match<const _CharT*>*,
1539 regex_constants::match_flag_type) const;
1540};
1541
1542template <class _CharT>
1543__command<_CharT>
1544__increment_loop_count<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
1545 vector<size_t>& __lc,
1546 sub_match<const _CharT*>*,
1547 regex_constants::match_flag_type) const
1548{
1549 ++__lc[__loop_id_];
1550 return __command(__command::__accept_but_not_consume, this->first());
1551}
1552
1553// __zero_marked_exprs
1554
1555template <class _CharT>
1556class __zero_marked_exprs
1557 : public __owns_one_state<_CharT>
1558{
1559 typedef __owns_one_state<_CharT> base;
1560
1561 size_t __begin_;
1562 size_t __end_;
1563
1564public:
1565 typedef __command<_CharT> __command;
1566
1567 explicit __zero_marked_exprs(size_t __begin, size_t __end,
1568 __state<_CharT>* __s1)
1569 : base(__s1), __begin_(__begin), __end_(__end) {}
1570
1571 virtual __command __test(const _CharT*, const _CharT*, const _CharT*,
1572 vector<size_t>&,
1573 sub_match<const _CharT*>* __sm,
1574 regex_constants::match_flag_type) const;
1575};
1576
1577template <class _CharT>
1578__command<_CharT>
1579__zero_marked_exprs<_CharT>::__test(const _CharT*, const _CharT*,
1580 const _CharT* __last,
1581 vector<size_t>&,
1582 sub_match<const _CharT*>* __sm,
1583 regex_constants::match_flag_type) const
1584{
1585 for (size_t __i = __begin_; __i != __end_; ++__i)
1586 {
1587 __sm[__i].first = __last;
1588 __sm[__i].second = __last;
1589 __sm[__i].matched = false;
1590 }
1591 return __command(__command::__accept_but_not_consume, this->first());
1592}
1593
1594// __begin_marked_subexpression
1595
1596template <class _CharT>
1597class __begin_marked_subexpression
1598 : public __owns_one_state<_CharT>
1599{
1600 typedef __owns_one_state<_CharT> base;
1601
1602 __begin_marked_subexpression(const __begin_marked_subexpression&);
1603 __begin_marked_subexpression& operator=(const __begin_marked_subexpression&);
1604public:
1605 typedef __command<_CharT> __command;
1606
1607 explicit __begin_marked_subexpression(__state<_CharT>* __s)
1608 : base(__s) {}
1609
1610 virtual __command __test(const _CharT*, const _CharT*,
1611 const _CharT*,
1612 vector<size_t>&,
1613 sub_match<const _CharT*>*,
1614 regex_constants::match_flag_type) const;
1615};
1616
1617template <class _CharT>
1618__command<_CharT>
1619__begin_marked_subexpression<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
1620 vector<size_t>&,
1621 sub_match<const _CharT*>*,
1622 regex_constants::match_flag_type) const
1623{
1624 return __command(__command::__begin_marked_expr, this->first());
1625}
1626
1627// __end_marked_subexpression
1628
1629template <class _CharT>
1630class __end_marked_subexpression
1631 : public __owns_one_state<_CharT>
1632{
1633 typedef __owns_one_state<_CharT> base;
1634
1635 __end_marked_subexpression(const __end_marked_subexpression&);
1636 __end_marked_subexpression& operator=(const __end_marked_subexpression&);
1637public:
1638 typedef __command<_CharT> __command;
1639
1640 explicit __end_marked_subexpression(__state<_CharT>* __s)
1641 : base(__s) {}
1642
1643 virtual __command __test(const _CharT*, const _CharT*,
1644 const _CharT*,
1645 vector<size_t>&,
1646 sub_match<const _CharT*>*,
1647 regex_constants::match_flag_type) const;
1648};
1649
1650template <class _CharT>
1651__command<_CharT>
1652__end_marked_subexpression<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
1653 vector<size_t>&,
1654 sub_match<const _CharT*>*,
1655 regex_constants::match_flag_type) const
1656{
1657 return __command(__command::__end_marked_expr, this->first());
1658}
1659
1660// __state_arg
1661
1662template <class _CharT>
1663class __state_arg
1664 : public __owns_one_state<_CharT>
1665{
1666 typedef __owns_one_state<_CharT> base;
1667
1668 unsigned __arg_;
1669
1670 __state_arg(const __state_arg&);
1671 __state_arg& operator=(const __state_arg&);
1672public:
1673 typedef __command<_CharT> __command;
1674
1675 __state_arg(unsigned __a, __state<_CharT>* __s)
1676 : base(__s), __arg_(__a) {}
1677
1678 virtual __command __test(const _CharT*, const _CharT*,
1679 const _CharT*,
1680 vector<size_t>&,
1681 sub_match<const _CharT*>*,
1682 regex_constants::match_flag_type) const;
1683};
1684
1685template <class _CharT>
1686__command<_CharT>
1687__state_arg<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
1688 vector<size_t>&,
1689 sub_match<const _CharT*>*,
1690 regex_constants::match_flag_type) const
1691{
1692 return __command(__arg_, this->first());
1693}
1694
1695// __match_char
1696
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001697template <class _CharT>
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001698class __match_char
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001699 : public __owns_one_state<_CharT>
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001700{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001701 typedef __owns_one_state<_CharT> base;
1702
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001703 _CharT __c_;
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001704
1705 __match_char(const __match_char&);
1706 __match_char& operator=(const __match_char&);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001707public:
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001708 typedef __command<_CharT> __command;
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001709
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001710 __match_char(_CharT __c, __state<_CharT>* __s)
1711 : base(__s), __c_(__c) {}
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001712
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001713 virtual __command __test(const _CharT*, const _CharT* __c,
1714 const _CharT*,
1715 vector<size_t>&,
1716 sub_match<const _CharT*>*,
1717 regex_constants::match_flag_type) const;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001718};
1719
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001720template <class _CharT>
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001721__command<_CharT>
1722__match_char<_CharT>::__test(const _CharT*, const _CharT* __c,
1723 const _CharT*,
1724 vector<size_t>&,
1725 sub_match<const _CharT*>*,
1726 regex_constants::match_flag_type) const
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001727{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001728 return __c_ == *__c ?
1729 __command(__command::__accept_and_consume, this->first()) : __command();
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001730}
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001731
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001732template <class, class> class match_results;
1733
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001734template <class _CharT, class _Traits = regex_traits<_CharT> >
1735class basic_regex
1736{
1737public:
1738 // types:
1739 typedef _CharT value_type;
1740 typedef regex_constants::syntax_option_type flag_type;
1741 typedef typename _Traits::locale_type locale_type;
1742
1743private:
1744 _Traits __traits_;
1745 flag_type __flags_;
1746 unsigned __marked_count_;
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001747 unsigned __loop_count_;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001748 int __open_count_;
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001749 shared_ptr<__empty_state<_CharT> > __start_;
1750 __owns_one_state<_CharT>* __end_;
1751
1752 typedef __command<_CharT> __command;
1753 typedef __state<_CharT> __state;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001754
1755public:
1756 // constants:
1757 static const/*expr*/ regex_constants::syntax_option_type icase = regex_constants::icase;
1758 static const/*expr*/ regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
1759 static const/*expr*/ regex_constants::syntax_option_type optimize = regex_constants::optimize;
1760 static const/*expr*/ regex_constants::syntax_option_type collate = regex_constants::collate;
1761 static const/*expr*/ regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
1762 static const/*expr*/ regex_constants::syntax_option_type basic = regex_constants::basic;
1763 static const/*expr*/ regex_constants::syntax_option_type extended = regex_constants::extended;
1764 static const/*expr*/ regex_constants::syntax_option_type awk = regex_constants::awk;
1765 static const/*expr*/ regex_constants::syntax_option_type grep = regex_constants::grep;
1766 static const/*expr*/ regex_constants::syntax_option_type egrep = regex_constants::egrep;
1767
1768 // construct/copy/destroy:
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001769 basic_regex()
1770 : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
1771 {}
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001772 explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001773 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001774 {__parse(__p, __p + __traits_.length(__p));}
1775 basic_regex(const value_type* __p, size_t __len, flag_type __f)
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001776 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001777 {__parse(__p, __p + __len);}
1778 basic_regex(const basic_regex&);
1779#ifdef _LIBCPP_MOVE
1780 basic_regex(basic_regex&&);
1781#endif
1782 template <class _ST, class _SA>
1783 explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
1784 flag_type __f = regex_constants::ECMAScript)
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001785 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001786 {__parse(__p.begin(), __p.end());}
1787 template <class _ForwardIterator>
1788 basic_regex(_ForwardIterator __first, _ForwardIterator __last,
1789 flag_type __f = regex_constants::ECMAScript)
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001790 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001791 {__parse(__first, __last);}
1792 basic_regex(initializer_list<value_type> __il,
1793 flag_type __f = regex_constants::ECMAScript)
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001794 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001795 {__parse(__il.begin(), __il.end());}
1796
1797 ~basic_regex();
1798
1799 basic_regex& operator=(const basic_regex&);
1800#ifdef _LIBCPP_MOVE
1801 basic_regex& operator=(basic_regex&&);
1802#endif
1803 basic_regex& operator=(const value_type* __p);
1804 basic_regex& operator=(initializer_list<value_type> __il);
1805 template <class _ST, class _SA>
1806 basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p);
1807
1808 // assign:
1809 basic_regex& assign(const basic_regex& __that);
1810#ifdef _LIBCPP_MOVE
1811 basic_regex& assign(basic_regex&& __that);
1812#endif
1813 basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript);
1814 basic_regex& assign(const value_type* __p, size_t __len, flag_type __f);
1815 template <class _ST, class _SA>
1816 basic_regex& assign(const basic_string<value_type, _ST, _SA>& __s,
1817 flag_type __f = regex_constants::ECMAScript);
1818 template <class _InputIterator>
1819 basic_regex& assign(_InputIterator __first, _InputIterator __last,
1820 flag_type __f = regex_constants::ECMAScript);
1821 basic_regex& assign(initializer_list<value_type> __il,
1822 flag_type = regex_constants::ECMAScript);
1823
1824 // const operations:
1825 unsigned mark_count() const {return __marked_count_;}
1826 flag_type flags() const {return __flags_;}
1827
1828 // locale:
1829 locale_type imbue(locale_type __loc) {return __traits_.imbue(__loc);}
1830 locale_type getloc() const {return __traits_.getloc();}
1831
1832 // swap:
1833 void swap(basic_regex&);
1834
1835private:
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001836 unsigned __loop_count() const {return __loop_count_;}
1837
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001838 template <class _ForwardIterator>
1839 void __parse(_ForwardIterator __first, _ForwardIterator __last);
1840 template <class _ForwardIterator>
1841 _ForwardIterator
1842 __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
1843 template <class _ForwardIterator>
1844 _ForwardIterator
1845 __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last);
1846 template <class _ForwardIterator>
1847 _ForwardIterator
1848 __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last);
1849 template <class _ForwardIterator>
1850 _ForwardIterator
1851 __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last);
1852 template <class _ForwardIterator>
1853 _ForwardIterator
1854 __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last);
1855 template <class _ForwardIterator>
1856 _ForwardIterator
1857 __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last);
1858 template <class _ForwardIterator>
1859 _ForwardIterator
1860 __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last);
1861 template <class _ForwardIterator>
1862 _ForwardIterator
1863 __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last);
1864 template <class _ForwardIterator>
1865 _ForwardIterator
1866 __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last);
1867 template <class _ForwardIterator>
1868 _ForwardIterator
1869 __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last);
1870 template <class _ForwardIterator>
1871 _ForwardIterator
1872 __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last);
1873 template <class _ForwardIterator>
1874 _ForwardIterator
1875 __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);
1876 template <class _ForwardIterator>
1877 _ForwardIterator
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001878 __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last,
1879 __owns_one_state<_CharT>* __s);
Howard Hinnant0de86b62010-06-25 20:56:08 +00001880 template <class _ForwardIterator>
1881 _ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001882 __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last);
1883 template <class _ForwardIterator>
1884 _ForwardIterator
Howard Hinnant0de86b62010-06-25 20:56:08 +00001885 __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last);
1886 template <class _ForwardIterator>
1887 _ForwardIterator
1888 __parse_follow_list(_ForwardIterator __first, _ForwardIterator __last);
1889 template <class _ForwardIterator>
1890 _ForwardIterator
1891 __parse_expression_term(_ForwardIterator __first, _ForwardIterator __last);
1892 template <class _ForwardIterator>
1893 _ForwardIterator
1894 __parse_equivalence_class(_ForwardIterator __first, _ForwardIterator __last);
1895 template <class _ForwardIterator>
1896 _ForwardIterator
1897 __parse_character_class(_ForwardIterator __first, _ForwardIterator __last);
1898 template <class _ForwardIterator>
1899 _ForwardIterator
1900 __parse_collating_symbol(_ForwardIterator __first, _ForwardIterator __last);
1901 template <class _ForwardIterator>
1902 _ForwardIterator
1903 __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001904 template <class _ForwardIterator>
1905 _ForwardIterator
1906 __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
1907 template <class _ForwardIterator>
1908 _ForwardIterator
1909 __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last);
1910 template <class _ForwardIterator>
1911 _ForwardIterator
1912 __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last);
1913 template <class _ForwardIterator>
1914 _ForwardIterator
1915 __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last);
1916 template <class _ForwardIterator>
1917 _ForwardIterator
1918 __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
1919 template <class _ForwardIterator>
1920 _ForwardIterator
1921 __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001922
Howard Hinnant0de86b62010-06-25 20:56:08 +00001923 void __push_l_anchor() {}
1924 void __push_r_anchor() {}
1925 void __push_match_any() {}
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001926 void __push_greedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s)
1927 {__push_loop(__min, numeric_limits<size_t>::max(), __s);}
Howard Hinnant0de86b62010-06-25 20:56:08 +00001928 void __push_exact_repeat(int __count) {}
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001929 void __push_loop(size_t __min, size_t __max, __owns_one_state<_CharT>* __s,
1930 size_t __mexp_begin = 0, size_t __mexp_end = 0,
1931 bool __greedy = true);
Howard Hinnant0de86b62010-06-25 20:56:08 +00001932 void __start_nonmatching_list() {}
1933 void __start_matching_list() {}
1934 void __end_nonmatching_list() {}
1935 void __end_matching_list() {}
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001936 void __push_char(value_type __c);
Howard Hinnant0de86b62010-06-25 20:56:08 +00001937 void __push_char(const typename _Traits::string_type& __c) {}
1938 void __push_range() {}
1939 void __push_class_type(typename _Traits::char_class_type) {}
1940 void __push_back_ref(int __i) {}
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001941 void __push_alternation() {}
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00001942 void __push_begin_marked_subexpression();
1943 void __push_end_marked_subexpression(unsigned);
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001944
1945 template <class _BidirectionalIterator, class _Allocator>
1946 bool
1947 __search(_BidirectionalIterator __first, _BidirectionalIterator __last,
1948 match_results<_BidirectionalIterator, _Allocator>& __m,
1949 regex_constants::match_flag_type __flags) const;
1950
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001951 template <class _BidirectionalIterator, class _Allocator>
1952 bool
1953 __match_at_start(_BidirectionalIterator __first, _BidirectionalIterator __last,
1954 match_results<_BidirectionalIterator, _Allocator>& __m,
1955 vector<size_t>& __lc,
1956 regex_constants::match_flag_type __flags) const;
1957 template <class _BidirectionalIterator, class _Allocator>
1958 bool
1959 __match_at_start_ecma(_BidirectionalIterator __first, _BidirectionalIterator __last,
1960 match_results<_BidirectionalIterator, _Allocator>& __m,
1961 regex_constants::match_flag_type __flags) const;
1962 template <class _BidirectionalIterator, class _Allocator>
1963 bool
1964 __match_at_start_posix_nosubs(const _CharT* __first, const _CharT* __last,
1965 match_results<_BidirectionalIterator, _Allocator>& __m,
1966 vector<size_t>& __lc,
1967 regex_constants::match_flag_type __flags) const;
1968 template <class _BidirectionalIterator, class _Allocator>
1969 bool
1970 __match_at_start_posix_subs(_BidirectionalIterator __first, _BidirectionalIterator __last,
1971 match_results<_BidirectionalIterator, _Allocator>& __m,
1972 regex_constants::match_flag_type __flags) const;
1973
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001974 template <class _B, class _A, class _C, class _T>
1975 friend
1976 bool
1977 regex_search(_B, _B, match_results<_B, _A>&, const basic_regex<_C, _T>&,
1978 regex_constants::match_flag_type);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001979
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001980};
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001981
1982template <class _CharT, class _Traits>
1983basic_regex<_CharT, _Traits>::~basic_regex()
1984{
1985}
1986
1987template <class _CharT, class _Traits>
1988template <class _ForwardIterator>
1989void
1990basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
1991 _ForwardIterator __last)
1992{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00001993 {
1994 unique_ptr<__state> __h(new __end_state<_CharT>);
1995 __start_.reset(new __empty_state<_CharT>(__h.get()));
1996 __h.release();
1997 __end_ = __start_.get();
1998 }
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001999 switch (__flags_ & 0x3F0)
2000 {
2001 case ECMAScript:
2002 break;
2003 case basic:
2004 __parse_basic_reg_exp(__first, __last);
2005 break;
2006 case extended:
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002007 __parse_extended_reg_exp(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002008 break;
2009 case awk:
2010 break;
2011 case grep:
2012 break;
2013 case egrep:
2014 break;
2015 default:
2016 throw regex_error(regex_constants::error_temp);
2017 }
2018}
2019
2020template <class _CharT, class _Traits>
2021template <class _ForwardIterator>
2022_ForwardIterator
2023basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first,
2024 _ForwardIterator __last)
2025{
2026 if (__first != __last)
2027 {
2028 if (*__first == '^')
2029 {
2030 __push_l_anchor();
2031 ++__first;
2032 }
2033 if (__first != __last)
2034 {
2035 __first = __parse_RE_expression(__first, __last);
2036 if (__first != __last)
2037 {
2038 _ForwardIterator __temp = next(__first);
2039 if (__temp == __last && *__first == '$')
2040 {
2041 __push_r_anchor();
2042 ++__first;
2043 }
2044 }
2045 }
2046 if (__first != __last)
2047 throw regex_error(regex_constants::error_temp);
2048 }
2049 return __first;
2050}
2051
2052template <class _CharT, class _Traits>
2053template <class _ForwardIterator>
2054_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002055basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first,
2056 _ForwardIterator __last)
2057{
2058 while (true)
2059 {
2060 _ForwardIterator __temp = __parse_ERE_branch(__first, __last);
2061 if (__temp == __first)
2062 throw regex_error(regex_constants::error_temp);
2063 __first = __temp;
2064 if (__first == __last)
2065 break;
2066 if (*__first != '|')
2067 throw regex_error(regex_constants::error_temp);
2068 __push_alternation();
2069 ++__first;
2070 }
2071 return __first;
2072}
2073
2074template <class _CharT, class _Traits>
2075template <class _ForwardIterator>
2076_ForwardIterator
2077basic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first,
2078 _ForwardIterator __last)
2079{
2080 _ForwardIterator __temp = __parse_ERE_expression(__first, __last);
2081 if (__temp == __first)
2082 throw regex_error(regex_constants::error_temp);
2083 do
2084 {
2085 __first = __temp;
2086 __temp = __parse_ERE_expression(__first, __last);
2087 } while (__temp != __first);
2088 return __first;
2089}
2090
2091template <class _CharT, class _Traits>
2092template <class _ForwardIterator>
2093_ForwardIterator
2094basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first,
2095 _ForwardIterator __last)
2096{
2097 _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last);
2098 if (__temp == __first && __temp != __last)
2099 {
2100 switch (*__temp)
2101 {
2102 case '^':
2103 __push_l_anchor();
2104 ++__temp;
2105 break;
2106 case '$':
2107 __push_r_anchor();
2108 ++__temp;
2109 break;
2110 case '(':
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00002111 __push_begin_marked_subexpression();
2112 unsigned __temp_count = __marked_count_;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002113 ++__open_count_;
2114 __temp = __parse_extended_reg_exp(++__temp, __last);
2115 if (__temp == __last || *__temp != ')')
2116 throw regex_error(regex_constants::error_paren);
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00002117 __push_end_marked_subexpression(__temp_count);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002118 --__open_count_;
2119 ++__temp;
2120 break;
2121 }
2122 }
2123 if (__temp != __first)
2124 __temp = __parse_ERE_dupl_symbol(__temp, __last);
2125 __first = __temp;
2126 return __first;
2127}
2128
2129template <class _CharT, class _Traits>
2130template <class _ForwardIterator>
2131_ForwardIterator
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002132basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first,
2133 _ForwardIterator __last)
2134{
2135 while (true)
2136 {
2137 _ForwardIterator __temp = __parse_simple_RE(__first, __last);
2138 if (__temp == __first)
2139 break;
2140 __first = __temp;
2141 }
2142 return __first;
2143}
2144
2145template <class _CharT, class _Traits>
2146template <class _ForwardIterator>
2147_ForwardIterator
2148basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first,
2149 _ForwardIterator __last)
2150{
2151 if (__first != __last)
2152 {
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002153 __owns_one_state<_CharT>* __e = __end_;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002154 _ForwardIterator __temp = __parse_nondupl_RE(__first, __last);
2155 if (__temp != __first)
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002156 __first = __parse_RE_dupl_symbol(__temp, __last, __e);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002157 }
2158 return __first;
2159}
2160
2161template <class _CharT, class _Traits>
2162template <class _ForwardIterator>
2163_ForwardIterator
2164basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first,
2165 _ForwardIterator __last)
2166{
2167 _ForwardIterator __temp = __first;
2168 __first = __parse_one_char_or_coll_elem_RE(__first, __last);
2169 if (__temp == __first)
2170 {
2171 __temp = __parse_Back_open_paren(__first, __last);
2172 if (__temp != __first)
2173 {
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00002174 __push_begin_marked_subexpression();
2175 unsigned __temp_count = __marked_count_;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002176 __first = __parse_RE_expression(__temp, __last);
2177 __temp = __parse_Back_close_paren(__first, __last);
2178 if (__temp == __first)
2179 throw regex_error(regex_constants::error_paren);
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00002180 __push_end_marked_subexpression(__temp_count);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002181 __first = __temp;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002182 }
2183 else
2184 __first = __parse_BACKREF(__first, __last);
2185 }
2186 return __first;
2187}
2188
2189template <class _CharT, class _Traits>
2190template <class _ForwardIterator>
2191_ForwardIterator
2192basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE(
2193 _ForwardIterator __first,
2194 _ForwardIterator __last)
2195{
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002196 _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002197 if (__temp == __first)
2198 {
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002199 __temp = __parse_QUOTED_CHAR(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002200 if (__temp == __first)
2201 {
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002202 if (__temp != __last && *__temp == '.')
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002203 {
2204 __push_match_any();
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002205 ++__temp;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002206 }
2207 else
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002208 __temp = __parse_bracket_expression(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002209 }
2210 }
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002211 __first = __temp;
2212 return __first;
2213}
2214
2215template <class _CharT, class _Traits>
2216template <class _ForwardIterator>
2217_ForwardIterator
2218basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE(
2219 _ForwardIterator __first,
2220 _ForwardIterator __last)
2221{
2222 _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last);
2223 if (__temp == __first)
2224 {
2225 __temp = __parse_QUOTED_CHAR_ERE(__first, __last);
2226 if (__temp == __first)
2227 {
2228 if (__temp != __last && *__temp == '.')
2229 {
2230 __push_match_any();
2231 ++__temp;
2232 }
2233 else
2234 __temp = __parse_bracket_expression(__first, __last);
2235 }
2236 }
2237 __first = __temp;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002238 return __first;
2239}
2240
2241template <class _CharT, class _Traits>
2242template <class _ForwardIterator>
2243_ForwardIterator
2244basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first,
2245 _ForwardIterator __last)
2246{
2247 if (__first != __last)
2248 {
2249 _ForwardIterator __temp = next(__first);
2250 if (__temp != __last)
2251 {
2252 if (*__first == '\\' && *__temp == '(')
2253 __first = ++__temp;
2254 }
2255 }
2256 return __first;
2257}
2258
2259template <class _CharT, class _Traits>
2260template <class _ForwardIterator>
2261_ForwardIterator
2262basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first,
2263 _ForwardIterator __last)
2264{
2265 if (__first != __last)
2266 {
2267 _ForwardIterator __temp = next(__first);
2268 if (__temp != __last)
2269 {
2270 if (*__first == '\\' && *__temp == ')')
2271 __first = ++__temp;
2272 }
2273 }
2274 return __first;
2275}
2276
2277template <class _CharT, class _Traits>
2278template <class _ForwardIterator>
2279_ForwardIterator
2280basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first,
2281 _ForwardIterator __last)
2282{
2283 if (__first != __last)
2284 {
2285 _ForwardIterator __temp = next(__first);
2286 if (__temp != __last)
2287 {
2288 if (*__first == '\\' && *__temp == '{')
2289 __first = ++__temp;
2290 }
2291 }
2292 return __first;
2293}
2294
2295template <class _CharT, class _Traits>
2296template <class _ForwardIterator>
2297_ForwardIterator
2298basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first,
2299 _ForwardIterator __last)
2300{
2301 if (__first != __last)
2302 {
2303 _ForwardIterator __temp = next(__first);
2304 if (__temp != __last)
2305 {
2306 if (*__first == '\\' && *__temp == '}')
2307 __first = ++__temp;
2308 }
2309 }
2310 return __first;
2311}
2312
2313template <class _CharT, class _Traits>
2314template <class _ForwardIterator>
2315_ForwardIterator
2316basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,
2317 _ForwardIterator __last)
2318{
2319 if (__first != __last)
2320 {
2321 _ForwardIterator __temp = next(__first);
2322 if (__temp != __last)
2323 {
2324 if (*__first == '\\' && '1' <= *__temp && *__temp <= '9')
2325 {
2326 __push_back_ref(*__temp - '0');
2327 __first = ++__temp;
2328 }
2329 }
2330 }
2331 return __first;
2332}
2333
2334template <class _CharT, class _Traits>
2335template <class _ForwardIterator>
2336_ForwardIterator
2337basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first,
2338 _ForwardIterator __last)
2339{
2340 if (__first != __last)
2341 {
2342 _ForwardIterator __temp = next(__first);
2343 if (__temp == __last && *__first == '$')
2344 return __first;
2345 // Not called inside a bracket
2346 if (*__first == '.' || *__first == '\\' || *__first == '[')
2347 return __first;
Howard Hinnant0de86b62010-06-25 20:56:08 +00002348 __push_char(*__first);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002349 ++__first;
2350 }
2351 return __first;
2352}
2353
2354template <class _CharT, class _Traits>
2355template <class _ForwardIterator>
2356_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002357basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first,
2358 _ForwardIterator __last)
2359{
2360 if (__first != __last)
2361 {
2362 switch (*__first)
2363 {
2364 case '^':
2365 case '.':
2366 case '[':
2367 case '$':
2368 case '(':
2369 case '|':
2370 case '*':
2371 case '+':
2372 case '?':
2373 case '{':
2374 case '\\':
2375 break;
2376 case ')':
2377 if (__open_count_ == 0)
2378 {
2379 __push_char(*__first);
2380 ++__first;
2381 }
2382 break;
2383 default:
2384 __push_char(*__first);
2385 ++__first;
2386 break;
2387 }
2388 }
2389 return __first;
2390}
2391
2392template <class _CharT, class _Traits>
2393template <class _ForwardIterator>
2394_ForwardIterator
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002395basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first,
2396 _ForwardIterator __last)
2397{
2398 if (__first != __last)
2399 {
2400 _ForwardIterator __temp = next(__first);
2401 if (__temp != __last)
2402 {
2403 if (*__first == '\\')
2404 {
2405 switch (*__temp)
2406 {
2407 case '^':
2408 case '.':
2409 case '*':
2410 case '[':
2411 case '$':
2412 case '\\':
Howard Hinnant0de86b62010-06-25 20:56:08 +00002413 __push_char(*__temp);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002414 __first = ++__temp;
2415 break;
2416 }
2417 }
2418 }
2419 }
2420 return __first;
2421}
2422
2423template <class _CharT, class _Traits>
2424template <class _ForwardIterator>
2425_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002426basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,
2427 _ForwardIterator __last)
2428{
2429 if (__first != __last)
2430 {
2431 _ForwardIterator __temp = next(__first);
2432 if (__temp != __last)
2433 {
2434 if (*__first == '\\')
2435 {
2436 switch (*__temp)
2437 {
2438 case '^':
2439 case '.':
2440 case '*':
2441 case '[':
2442 case '$':
2443 case '\\':
2444 case '(':
2445 case ')':
2446 case '|':
2447 case '+':
2448 case '?':
2449 case '{':
2450 __push_char(*__temp);
2451 __first = ++__temp;
2452 break;
2453 }
2454 }
2455 }
2456 }
2457 return __first;
2458}
2459
2460template <class _CharT, class _Traits>
2461template <class _ForwardIterator>
2462_ForwardIterator
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002463basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first,
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002464 _ForwardIterator __last,
2465 __owns_one_state<_CharT>* __s)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002466{
2467 if (__first != __last)
2468 {
Howard Hinnant0de86b62010-06-25 20:56:08 +00002469 if (*__first == '*')
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002470 {
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002471 __push_greedy_inf_repeat(0, __s);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002472 ++__first;
2473 }
2474 else
2475 {
2476 _ForwardIterator __temp = __parse_Back_open_brace(__first, __last);
2477 if (__temp != __first)
2478 {
2479 int __min = 0;
2480 __first = __temp;
2481 __temp = __parse_DUP_COUNT(__first, __last, __min);
2482 if (__temp == __first)
2483 throw regex_error(regex_constants::error_badbrace);
2484 __first = __temp;
2485 if (__first == __last)
2486 throw regex_error(regex_constants::error_brace);
2487 if (*__first != ',')
2488 {
2489 __temp = __parse_Back_close_brace(__first, __last);
2490 if (__temp == __first)
2491 throw regex_error(regex_constants::error_brace);
2492 __push_exact_repeat(__min);
2493 __first = __temp;
2494 }
2495 else
2496 {
2497 ++__first; // consume ','
2498 int __max = -1;
2499 __first = __parse_DUP_COUNT(__first, __last, __max);
2500 __temp = __parse_Back_close_brace(__first, __last);
2501 if (__temp == __first)
2502 throw regex_error(regex_constants::error_brace);
2503 if (__max == -1)
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002504 __push_greedy_inf_repeat(__min, __s);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002505 else
2506 {
2507 if (__max < __min)
2508 throw regex_error(regex_constants::error_badbrace);
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002509 __push_loop(__min, __max, __s);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002510 }
2511 __first = __temp;
2512 }
2513 }
2514 }
2515 }
2516 return __first;
2517}
2518
Howard Hinnant0de86b62010-06-25 20:56:08 +00002519template <class _CharT, class _Traits>
2520template <class _ForwardIterator>
2521_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002522basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first,
2523 _ForwardIterator __last)
2524{
2525 if (__first != __last)
2526 {
2527 switch (*__first)
2528 {
2529 case '*':
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002530 __push_greedy_inf_repeat(0, nullptr);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002531 ++__first;
2532 break;
2533 case '+':
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002534 __push_greedy_inf_repeat(1, nullptr);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002535 ++__first;
2536 break;
2537 case '?':
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002538 __push_loop(0, 1, nullptr);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002539 ++__first;
2540 break;
2541 case '{':
2542 {
2543 int __min;
2544 _ForwardIterator __temp = __parse_DUP_COUNT(__first, __last, __min);
2545 if (__temp == __first)
2546 throw regex_error(regex_constants::error_badbrace);
2547 __first = __temp;
2548 if (__first == __last)
2549 throw regex_error(regex_constants::error_brace);
2550 switch (*__first)
2551 {
2552 case '}':
2553 __push_exact_repeat(__min);
2554 ++__first;
2555 break;
2556 case ',':
2557 if (++__first == __last)
2558 throw regex_error(regex_constants::error_badbrace);
2559 if (*__first == '}')
2560 {
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002561 __push_greedy_inf_repeat(__min, nullptr);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002562 ++__first;
2563 }
2564 else
2565 {
2566 int __max;
2567 __temp = __parse_DUP_COUNT(__first, __last, __max);
2568 if (__temp == __first)
2569 throw regex_error(regex_constants::error_brace);
2570 __first = __temp;
2571 if (__first == __last || *__first != '}')
2572 throw regex_error(regex_constants::error_brace);
2573 ++__first;
2574 if (__max < __min)
2575 throw regex_error(regex_constants::error_badbrace);
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002576 __push_loop(__min, __max, nullptr);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002577 }
2578 default:
2579 throw regex_error(regex_constants::error_badbrace);
2580 }
2581 }
2582 break;
2583 }
2584 }
2585 return __first;
2586}
2587
2588template <class _CharT, class _Traits>
2589template <class _ForwardIterator>
2590_ForwardIterator
Howard Hinnant0de86b62010-06-25 20:56:08 +00002591basic_regex<_CharT, _Traits>::__parse_bracket_expression(_ForwardIterator __first,
2592 _ForwardIterator __last)
2593{
2594 if (__first != __last && *__first == '[')
2595 {
2596 if (++__first == __last)
2597 throw regex_error(regex_constants::error_brack);
2598 bool __non_matching = false;
2599 if (*__first == '^')
2600 {
2601 ++__first;
2602 __non_matching = true;
2603 __start_nonmatching_list();
2604 }
2605 else
2606 __start_matching_list();
2607 if (__first == __last)
2608 throw regex_error(regex_constants::error_brack);
2609 if (*__first == ']')
2610 {
2611 __push_char(']');
2612 ++__first;
2613 }
2614 __first = __parse_follow_list(__first, __last);
2615 if (__first == __last)
2616 throw regex_error(regex_constants::error_brack);
2617 if (*__first == '-')
2618 {
2619 __push_char('-');
2620 ++__first;
2621 }
2622 if (__first == __last || *__first != ']')
2623 throw regex_error(regex_constants::error_brack);
2624 if (__non_matching)
2625 __end_nonmatching_list();
2626 else
2627 __end_matching_list();
2628 ++__first;
2629 }
2630 return __first;
2631}
2632
2633template <class _CharT, class _Traits>
2634template <class _ForwardIterator>
2635_ForwardIterator
2636basic_regex<_CharT, _Traits>::__parse_follow_list(_ForwardIterator __first,
2637 _ForwardIterator __last)
2638{
2639 if (__first != __last)
2640 {
2641 while (true)
2642 {
2643 _ForwardIterator __temp = __parse_expression_term(__first, __last);
2644 if (__temp == __first)
2645 break;
2646 __first = __temp;
2647 }
2648 }
2649 return __first;
2650}
2651
2652template <class _CharT, class _Traits>
2653template <class _ForwardIterator>
2654_ForwardIterator
2655basic_regex<_CharT, _Traits>::__parse_expression_term(_ForwardIterator __first,
2656 _ForwardIterator __last)
2657{
2658 if (__first != __last && *__first != ']')
2659 {
2660 bool __parsed_one = false;
2661 _ForwardIterator __temp = next(__first);
2662 if (__temp != __last && *__first == '[')
2663 {
2664 if (*__temp == '=')
2665 return __parse_equivalence_class(++__temp, __last);
2666 else if (*__temp == ':')
2667 return __parse_character_class(++__temp, __last);
2668 else if (*__temp == '.')
2669 {
2670 __first = __parse_collating_symbol(++__temp, __last);
2671 __parsed_one = true;
2672 }
2673 }
2674 if (!__parsed_one)
2675 {
2676 __push_char(*__first);
2677 ++__first;
2678 }
2679 if (__first != __last && *__first != ']')
2680 {
2681 __temp = next(__first);
2682 if (__temp != __last && *__first == '-' && *__temp != ']')
2683 {
2684 // parse a range
2685 __first = __temp;
2686 ++__temp;
2687 if (__temp != __last && *__first == '[' && *__temp == '.')
2688 __first = __parse_collating_symbol(++__temp, __last);
2689 else
2690 {
2691 __push_char(*__first);
2692 ++__first;
2693 }
2694 __push_range();
2695 }
2696 }
2697 }
2698 return __first;
2699}
2700
2701template <class _CharT, class _Traits>
2702template <class _ForwardIterator>
2703_ForwardIterator
2704basic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first,
2705 _ForwardIterator __last)
2706{
2707 // Found [=
2708 // This means =] must exist
2709 value_type _Equal_close[2] = {'=', ']'};
2710 _ForwardIterator __temp = _STD::search(__first, __last, _Equal_close,
2711 _Equal_close+2);
2712 if (__temp == __last)
2713 throw regex_error(regex_constants::error_brack);
2714 // [__first, __temp) contains all text in [= ... =]
2715 typedef typename _Traits::string_type string_type;
2716 string_type __collate_name =
2717 __traits_.lookup_collatename(__first, __temp);
2718 if (__collate_name.empty())
2719 throw regex_error(regex_constants::error_brack);
2720 string_type __equiv_name =
2721 __traits_.transform_primary(__collate_name.begin(),
2722 __collate_name.end());
2723 if (!__equiv_name.empty())
2724 __push_char(__equiv_name);
2725 else
2726 __push_char(__collate_name);
2727 __first = next(__temp, 2);
2728 return __first;
2729}
2730
2731template <class _CharT, class _Traits>
2732template <class _ForwardIterator>
2733_ForwardIterator
2734basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first,
2735 _ForwardIterator __last)
2736{
2737 // Found [:
2738 // This means :] must exist
2739 value_type _Colon_close[2] = {':', ']'};
2740 _ForwardIterator __temp = _STD::search(__first, __last, _Colon_close,
2741 _Colon_close+2);
2742 if (__temp == __last)
2743 throw regex_error(regex_constants::error_brack);
2744 // [__first, __temp) contains all text in [: ... :]
2745 typedef typename _Traits::char_class_type char_class_type;
2746 char_class_type __class_type =
2747 __traits_.lookup_classname(__first, __temp, __flags_ & icase);
2748 if (__class_type == 0)
2749 throw regex_error(regex_constants::error_brack);
2750 __push_class_type(__class_type);
2751 __first = next(__temp, 2);
2752 return __first;
2753}
2754
2755template <class _CharT, class _Traits>
2756template <class _ForwardIterator>
2757_ForwardIterator
2758basic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first,
2759 _ForwardIterator __last)
2760{
2761 // Found [.
2762 // This means .] must exist
2763 value_type _Dot_close[2] = {'.', ']'};
2764 _ForwardIterator __temp = _STD::search(__first, __last, _Dot_close,
2765 _Dot_close+2);
2766 if (__temp == __last)
2767 throw regex_error(regex_constants::error_brack);
2768 // [__first, __temp) contains all text in [. ... .]
2769 typedef typename _Traits::string_type string_type;
2770 string_type __collate_name =
2771 __traits_.lookup_collatename(__first, __temp);
2772 if (__collate_name.empty())
2773 throw regex_error(regex_constants::error_brack);
2774 __push_char(__collate_name);
2775 __first = next(__temp, 2);
2776 return __first;
2777}
2778
2779template <class _CharT, class _Traits>
2780template <class _ForwardIterator>
2781_ForwardIterator
2782basic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first,
2783 _ForwardIterator __last,
2784 int& __c)
2785{
2786 if (__first != __last && '0' <= *__first && *__first <= '9')
2787 {
2788 __c = *__first - '0';
2789 for (++__first; __first != __last && '0' <= *__first && *__first <= '9';
2790 ++__first)
2791 {
2792 __c *= 10;
2793 __c += *__first - '0';
2794 }
2795 }
2796 return __first;
2797}
2798
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002799template <class _CharT, class _Traits>
2800void
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002801basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max,
2802 __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end,
2803 bool __greedy)
2804{
2805 unique_ptr<__empty_state<_CharT> > __e1(new __empty_state<_CharT>(__end_->first()));
2806 __end_->first() = nullptr;
2807 unique_ptr<__loop<_CharT> > __e2;
2808 if (__mexp_begin != __mexp_end)
2809 {
2810 unique_ptr<__zero_marked_exprs<_CharT> >
2811 __e3(new __zero_marked_exprs<_CharT>(__mexp_begin, __mexp_end,
2812 __s->first()));
2813 __s->first() = nullptr;
2814 __e2.reset(new __loop<_CharT>(__loop_count_, __e3.get(), __e1.get(),
2815 __greedy, __min, __max));
2816 __e3.release();
2817 __e1.release();
2818 }
2819 else
2820 {
2821 __e2.reset(new __loop<_CharT>(__loop_count_, __s->first(), __e1.get(),
2822 __greedy, __min, __max));
2823 __s->first() = nullptr;
2824 __e1.release();
2825 }
2826 __end_->first() = new __increment_loop_count<_CharT>(__loop_count_, __e2.get());
2827 __end_ = __e2->second();
2828 __s->first() = new __zero_loop_count<_CharT>(__loop_count_, __e2.get());
2829 __e2.release();
2830 ++__loop_count_;
2831}
2832
2833template <class _CharT, class _Traits>
2834void
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002835basic_regex<_CharT, _Traits>::__push_char(value_type __c)
2836{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002837 __match_char<_CharT>* __s = new __match_char<_CharT>(__c, __end_->first());
2838 __end_->first() = __s;
2839 __end_ = __s;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002840}
2841
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00002842template <class _CharT, class _Traits>
2843void
2844basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression()
2845{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002846 __begin_marked_subexpression<_CharT>* __s =
2847 new __begin_marked_subexpression<_CharT>(__end_->first());
2848 __end_->first() = __s;
2849 __end_ = __s;
2850 __state_arg<_CharT>* __a = new __state_arg<_CharT>(++__marked_count_,
2851 __end_->first());
2852 __end_->first() = __a;
2853 __end_ = __a;
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00002854}
2855
2856template <class _CharT, class _Traits>
2857void
2858basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub)
2859{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00002860 __end_marked_subexpression<_CharT>* __s =
2861 new __end_marked_subexpression<_CharT>(__end_->first());
2862 __end_->first() = __s;
2863 __end_ = __s;
2864 __state_arg<_CharT>* __a = new __state_arg<_CharT>(++__marked_count_,
2865 __end_->first());
2866 __end_->first() = __a;
2867 __end_ = __a;
Howard Hinnant0dca5fc2010-06-30 20:30:19 +00002868}
2869
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002870typedef basic_regex<char> regex;
2871typedef basic_regex<wchar_t> wregex;
2872
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002873// sub_match
2874
2875template <class _BidirectionalIterator>
2876class sub_match
2877 : public pair<_BidirectionalIterator, _BidirectionalIterator>
2878{
2879public:
2880 typedef _BidirectionalIterator iterator;
2881 typedef typename iterator_traits<iterator>::value_type value_type;
2882 typedef typename iterator_traits<iterator>::difference_type difference_type;
2883 typedef basic_string<value_type> string_type;
2884
2885 bool matched;
2886
2887 difference_type length() const
2888 {return matched ? _STD::distance(this->first, this->second) : 0;}
2889 string_type str() const
2890 {return matched ? string_type(this->first, this->second) : string_type();}
2891 operator string_type() const
2892 {return str();}
2893
2894 int compare(const sub_match& __s) const
2895 {return str().compare(__s.str());}
2896 int compare(const string_type& __s) const
2897 {return str().compare(__s);}
2898 int compare(const value_type* __s) const
2899 {return str().compare(__s);}
2900};
2901
2902typedef sub_match<const char*> csub_match;
2903typedef sub_match<const wchar_t*> wcsub_match;
2904typedef sub_match<string::const_iterator> ssub_match;
2905typedef sub_match<wstring::const_iterator> wssub_match;
2906
2907template <class _BiIter>
2908inline _LIBCPP_INLINE_VISIBILITY
2909bool
2910operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2911{
2912 return __x.compare(__y) == 0;
2913}
2914
2915template <class _BiIter>
2916inline _LIBCPP_INLINE_VISIBILITY
2917bool
2918operator!=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2919{
2920 return !(__x == __y);
2921}
2922
2923template <class _BiIter>
2924inline _LIBCPP_INLINE_VISIBILITY
2925bool
2926operator<(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2927{
2928 return __x.compare(__y) < 0;
2929}
2930
2931template <class _BiIter>
2932inline _LIBCPP_INLINE_VISIBILITY
2933bool
2934operator<=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2935{
2936 return !(__y < __x);
2937}
2938
2939template <class _BiIter>
2940inline _LIBCPP_INLINE_VISIBILITY
2941bool
2942operator>=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2943{
2944 return !(__x < __y);
2945}
2946
2947template <class _BiIter>
2948inline _LIBCPP_INLINE_VISIBILITY
2949bool
2950operator>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2951{
2952 return __y < __x;
2953}
2954
2955template <class _BiIter, class _ST, class _SA>
2956inline _LIBCPP_INLINE_VISIBILITY
2957bool
2958operator==(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2959 const sub_match<_BiIter>& __y)
2960{
2961 return __y.compare(__x.c_str()) == 0;
2962}
2963
2964template <class _BiIter, class _ST, class _SA>
2965inline _LIBCPP_INLINE_VISIBILITY
2966bool
2967operator!=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2968 const sub_match<_BiIter>& __y)
2969{
2970 return !(__x == __y);
2971}
2972
2973template <class _BiIter, class _ST, class _SA>
2974inline _LIBCPP_INLINE_VISIBILITY
2975bool
2976operator<(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2977 const sub_match<_BiIter>& __y)
2978{
2979 return __y.compare(__x.c_str()) > 0;
2980}
2981
2982template <class _BiIter, class _ST, class _SA>
2983inline _LIBCPP_INLINE_VISIBILITY
2984bool
2985operator>(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2986 const sub_match<_BiIter>& __y)
2987{
2988 return __y < __x;
2989}
2990
2991template <class _BiIter, class _ST, class _SA>
2992inline _LIBCPP_INLINE_VISIBILITY
2993bool operator>=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2994 const sub_match<_BiIter>& __y)
2995{
2996 return !(__x < __y);
2997}
2998
2999template <class _BiIter, class _ST, class _SA>
3000inline _LIBCPP_INLINE_VISIBILITY
3001bool
3002operator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
3003 const sub_match<_BiIter>& __y)
3004{
3005 return !(__y < __x);
3006}
3007
3008template <class _BiIter, class _ST, class _SA>
3009inline _LIBCPP_INLINE_VISIBILITY
3010bool
3011operator==(const sub_match<_BiIter>& __x,
3012 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
3013{
3014 return __x.compare(__y.c_str()) == 0;
3015}
3016
3017template <class _BiIter, class _ST, class _SA>
3018inline _LIBCPP_INLINE_VISIBILITY
3019bool
3020operator!=(const sub_match<_BiIter>& __x,
3021 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
3022{
3023 return !(__x == __y);
3024}
3025
3026template <class _BiIter, class _ST, class _SA>
3027inline _LIBCPP_INLINE_VISIBILITY
3028bool
3029operator<(const sub_match<_BiIter>& __x,
3030 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
3031{
3032 return __x.compare(__y.c_str()) < 0;
3033}
3034
3035template <class _BiIter, class _ST, class _SA>
3036inline _LIBCPP_INLINE_VISIBILITY
3037bool operator>(const sub_match<_BiIter>& __x,
3038 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
3039{
3040 return __y < __x;
3041}
3042
3043template <class _BiIter, class _ST, class _SA>
3044inline _LIBCPP_INLINE_VISIBILITY
3045bool
3046operator>=(const sub_match<_BiIter>& __x,
3047 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
3048{
3049 return !(__x < __y);
3050}
3051
3052template <class _BiIter, class _ST, class _SA>
3053inline _LIBCPP_INLINE_VISIBILITY
3054bool
3055operator<=(const sub_match<_BiIter>& __x,
3056 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
3057{
3058 return !(__y < __x);
3059}
3060
3061template <class _BiIter>
3062inline _LIBCPP_INLINE_VISIBILITY
3063bool
3064operator==(typename iterator_traits<_BiIter>::value_type const* __x,
3065 const sub_match<_BiIter>& __y)
3066{
3067 return __y.compare(__x) == 0;
3068}
3069
3070template <class _BiIter>
3071inline _LIBCPP_INLINE_VISIBILITY
3072bool
3073operator!=(typename iterator_traits<_BiIter>::value_type const* __x,
3074 const sub_match<_BiIter>& __y)
3075{
3076 return !(__x == __y);
3077}
3078
3079template <class _BiIter>
3080inline _LIBCPP_INLINE_VISIBILITY
3081bool
3082operator<(typename iterator_traits<_BiIter>::value_type const* __x,
3083 const sub_match<_BiIter>& __y)
3084{
3085 return __y.compare(__x) > 0;
3086}
3087
3088template <class _BiIter>
3089inline _LIBCPP_INLINE_VISIBILITY
3090bool
3091operator>(typename iterator_traits<_BiIter>::value_type const* __x,
3092 const sub_match<_BiIter>& __y)
3093{
3094 return __y < __x;
3095}
3096
3097template <class _BiIter>
3098inline _LIBCPP_INLINE_VISIBILITY
3099bool
3100operator>=(typename iterator_traits<_BiIter>::value_type const* __x,
3101 const sub_match<_BiIter>& __y)
3102{
3103 return !(__x < __y);
3104}
3105
3106template <class _BiIter>
3107inline _LIBCPP_INLINE_VISIBILITY
3108bool
3109operator<=(typename iterator_traits<_BiIter>::value_type const* __x,
3110 const sub_match<_BiIter>& __y)
3111{
3112 return !(__y < __x);
3113}
3114
3115template <class _BiIter>
3116inline _LIBCPP_INLINE_VISIBILITY
3117bool
3118operator==(const sub_match<_BiIter>& __x,
3119 typename iterator_traits<_BiIter>::value_type const* __y)
3120{
3121 return __x.compare(__y) == 0;
3122}
3123
3124template <class _BiIter>
3125inline _LIBCPP_INLINE_VISIBILITY
3126bool
3127operator!=(const sub_match<_BiIter>& __x,
3128 typename iterator_traits<_BiIter>::value_type const* __y)
3129{
3130 return !(__x == __y);
3131}
3132
3133template <class _BiIter>
3134inline _LIBCPP_INLINE_VISIBILITY
3135bool
3136operator<(const sub_match<_BiIter>& __x,
3137 typename iterator_traits<_BiIter>::value_type const* __y)
3138{
3139 return __x.compare(__y) < 0;
3140}
3141
3142template <class _BiIter>
3143inline _LIBCPP_INLINE_VISIBILITY
3144bool
3145operator>(const sub_match<_BiIter>& __x,
3146 typename iterator_traits<_BiIter>::value_type const* __y)
3147{
3148 return __y < __x;
3149}
3150
3151template <class _BiIter>
3152inline _LIBCPP_INLINE_VISIBILITY
3153bool
3154operator>=(const sub_match<_BiIter>& __x,
3155 typename iterator_traits<_BiIter>::value_type const* __y)
3156{
3157 return !(__x < __y);
3158}
3159
3160template <class _BiIter>
3161inline _LIBCPP_INLINE_VISIBILITY
3162bool
3163operator<=(const sub_match<_BiIter>& __x,
3164 typename iterator_traits<_BiIter>::value_type const* __y)
3165{
3166 return !(__y < __x);
3167}
3168
3169template <class _BiIter>
3170inline _LIBCPP_INLINE_VISIBILITY
3171bool
3172operator==(typename iterator_traits<_BiIter>::value_type const& __x,
3173 const sub_match<_BiIter>& __y)
3174{
3175 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
3176 return __y.compare(string_type(1, __x)) == 0;
3177}
3178
3179template <class _BiIter>
3180inline _LIBCPP_INLINE_VISIBILITY
3181bool
3182operator!=(typename iterator_traits<_BiIter>::value_type const& __x,
3183 const sub_match<_BiIter>& __y)
3184{
3185 return !(__x == __y);
3186}
3187
3188template <class _BiIter>
3189inline _LIBCPP_INLINE_VISIBILITY
3190bool
3191operator<(typename iterator_traits<_BiIter>::value_type const& __x,
3192 const sub_match<_BiIter>& __y)
3193{
3194 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
3195 return __y.compare(string_type(1, __x)) > 0;
3196}
3197
3198template <class _BiIter>
3199inline _LIBCPP_INLINE_VISIBILITY
3200bool
3201operator>(typename iterator_traits<_BiIter>::value_type const& __x,
3202 const sub_match<_BiIter>& __y)
3203{
3204 return __y < __x;
3205}
3206
3207template <class _BiIter>
3208inline _LIBCPP_INLINE_VISIBILITY
3209bool
3210operator>=(typename iterator_traits<_BiIter>::value_type const& __x,
3211 const sub_match<_BiIter>& __y)
3212{
3213 return !(__x < __y);
3214}
3215
3216template <class _BiIter>
3217inline _LIBCPP_INLINE_VISIBILITY
3218bool
3219operator<=(typename iterator_traits<_BiIter>::value_type const& __x,
3220 const sub_match<_BiIter>& __y)
3221{
3222 return !(__y < __x);
3223}
3224
3225template <class _BiIter>
3226inline _LIBCPP_INLINE_VISIBILITY
3227bool
3228operator==(const sub_match<_BiIter>& __x,
3229 typename iterator_traits<_BiIter>::value_type const& __y)
3230{
3231 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
3232 return __x.compare(string_type(1, __y)) == 0;
3233}
3234
3235template <class _BiIter>
3236inline _LIBCPP_INLINE_VISIBILITY
3237bool
3238operator!=(const sub_match<_BiIter>& __x,
3239 typename iterator_traits<_BiIter>::value_type const& __y)
3240{
3241 return !(__x == __y);
3242}
3243
3244template <class _BiIter>
3245inline _LIBCPP_INLINE_VISIBILITY
3246bool
3247operator<(const sub_match<_BiIter>& __x,
3248 typename iterator_traits<_BiIter>::value_type const& __y)
3249{
3250 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
3251 return __x.compare(string_type(1, __y)) < 0;
3252}
3253
3254template <class _BiIter>
3255inline _LIBCPP_INLINE_VISIBILITY
3256bool
3257operator>(const sub_match<_BiIter>& __x,
3258 typename iterator_traits<_BiIter>::value_type const& __y)
3259{
3260 return __y < __x;
3261}
3262
3263template <class _BiIter>
3264inline _LIBCPP_INLINE_VISIBILITY
3265bool
3266operator>=(const sub_match<_BiIter>& __x,
3267 typename iterator_traits<_BiIter>::value_type const& __y)
3268{
3269 return !(__x < __y);
3270}
3271
3272template <class _BiIter>
3273inline _LIBCPP_INLINE_VISIBILITY
3274bool
3275operator<=(const sub_match<_BiIter>& __x,
3276 typename iterator_traits<_BiIter>::value_type const& __y)
3277{
3278 return !(__y < __x);
3279}
3280
3281template <class _CharT, class _ST, class _BiIter>
3282inline _LIBCPP_INLINE_VISIBILITY
3283basic_ostream<_CharT, _ST>&
3284operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m)
3285{
3286 return __os << __m.str();
3287}
3288
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003289template <class _BidirectionalIterator,
3290 class _Allocator = allocator<sub_match<_BidirectionalIterator> > >
3291class match_results
3292{
3293public:
3294 typedef _Allocator allocator_type;
3295 typedef sub_match<_BidirectionalIterator> value_type;
3296private:
3297 typedef vector<value_type, allocator_type> __container_type;
3298
3299 __container_type __matches_;
3300 value_type __unmatched_;
3301 value_type __prefix_;
3302 value_type __suffix_;
3303public:
3304 typedef const value_type& const_reference;
3305 typedef const_reference reference;
3306 typedef typename __container_type::const_iterator const_iterator;
3307 typedef const_iterator iterator;
3308 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
3309 typedef typename allocator_traits<allocator_type>::size_type size_type;
3310 typedef typename iterator_traits<_BidirectionalIterator>::value_type char_type;
3311 typedef basic_string<char_type> string_type;
3312
3313 // construct/copy/destroy:
3314 explicit match_results(const allocator_type& __a = allocator_type());
3315// match_results(const match_results&) = default;
3316// match_results& operator=(const match_results&) = default;
3317#ifdef _LIBCPP_MOVE
3318// match_results(match_results&& __m) = default;
3319// match_results& operator=(match_results&& __m) = default;
3320#endif
3321// ~match_results() = default;
3322
3323 // size:
3324 size_type size() const {return __matches_.size();}
3325 size_type max_size() const {return __matches_.max_size();}
3326 bool empty() const {return size() == 0;}
3327
3328 // element access:
3329 difference_type length(size_type __sub = 0) const
3330 {return (*this)[__sub].length();}
3331 difference_type position(size_type __sub = 0) const
3332 {return _STD::distance(__prefix_.first, (*this)[__sub].first);}
3333 string_type str(size_type __sub = 0) const
3334 {return (*this)[__sub].str();}
3335 const_reference operator[](size_type __n) const
3336 {return __n < __matches_.size() ? __matches_[__n] : __unmatched_;}
3337
3338 const_reference prefix() const {return __prefix_;}
3339 const_reference suffix() const {return __suffix_;}
3340
3341 const_iterator begin() const {return empty() ? __matches_.end() : __matches_.begin() + 1;}
3342 const_iterator end() const {return __matches_.end();}
3343 const_iterator cbegin() const {return empty() ? __matches_.end() : __matches_.begin() + 1;}
3344 const_iterator cend() const {return __matches_.end();}
3345
3346 // format:
3347 template <class _OutputIter>
3348 _OutputIter
3349 format(_OutputIter __out, const char_type* __fmt_first,
3350 const char_type* __fmt_last,
3351 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
3352 template <class _OutputIter, class _ST, class _SA>
3353 _OutputIter
3354 format(_OutputIter __out, const basic_string<char_type, _ST, _SA>& __fmt,
3355 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
3356 template <class _ST, class _SA>
3357 basic_string<char_type, _ST, _SA>
3358 format(const basic_string<char_type, _ST, _SA>& __fmt,
3359 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
3360 string_type
3361 format(const char_type* __fmt,
3362 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
3363
3364 // allocator:
3365 allocator_type get_allocator() const {return __matches_.get_allocator();}
3366
3367 // swap:
3368 void swap(match_results& __m);
3369
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003370private:
3371 void __init(unsigned __s,
3372 _BidirectionalIterator __f, _BidirectionalIterator __l);
3373
3374 template <class, class> friend class basic_regex;
3375
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003376 template <class _B, class _A, class _C, class _T>
3377 friend
3378 bool
3379 regex_match(_B, _B, match_results<_B, _A>&, const basic_regex<_C, _T>&,
3380 regex_constants::match_flag_type);
3381};
3382
3383template <class _BidirectionalIterator, class _Allocator>
3384match_results<_BidirectionalIterator, _Allocator>::match_results(
3385 const allocator_type& __a)
3386 : __matches_(__a),
3387 __unmatched_(),
3388 __prefix_(),
3389 __suffix_()
3390{
3391}
3392
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003393template <class _BidirectionalIterator, class _Allocator>
3394void
3395match_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s,
3396 _BidirectionalIterator __f, _BidirectionalIterator __l)
3397{
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003398 __unmatched_.first = __l;
3399 __unmatched_.second = __l;
3400 __unmatched_.matched = false;
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003401 __matches_.assign(__s, __unmatched_);
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003402 __prefix_.first = __f;
3403 __prefix_.second = __f;
3404 __prefix_.matched = false;
3405 __suffix_.first = __l;
3406 __suffix_.second = __l;
3407 __suffix_.matched = false;
3408}
3409
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003410typedef match_results<const char*> cmatch;
3411typedef match_results<const wchar_t*> wcmatch;
3412typedef match_results<string::const_iterator> smatch;
3413typedef match_results<wstring::const_iterator> wsmatch;
3414
3415template <class _BidirectionalIterator, class _Allocator>
3416 bool
3417 operator==(const match_results<_BidirectionalIterator, _Allocator>& __x,
3418 const match_results<_BidirectionalIterator, _Allocator>& __y);
3419
3420template <class _BidirectionalIterator, class _Allocator>
3421 bool
3422 operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x,
3423 const match_results<_BidirectionalIterator, _Allocator>& __y);
3424
3425template <class _BidirectionalIterator, class _Allocator>
3426 void
3427 swap(match_results<_BidirectionalIterator, _Allocator>& __x,
3428 match_results<_BidirectionalIterator, _Allocator>& __y);
3429
3430// regex_search
3431
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003432template <class _CharT, class _Traits>
3433template <class _BidirectionalIterator, class _Allocator>
3434bool
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003435basic_regex<_CharT, _Traits>::__match_at_start_ecma(
3436 _BidirectionalIterator __first, _BidirectionalIterator __last,
3437 match_results<_BidirectionalIterator, _Allocator>& __m,
3438 regex_constants::match_flag_type __flags) const
3439{
3440 return false;
3441}
3442
3443template <class _CharT, class _Traits>
3444template <class _BidirectionalIterator, class _Allocator>
3445bool
3446basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
3447 const _CharT* __first, const _CharT* __last,
3448 match_results<_BidirectionalIterator, _Allocator>& __m,
3449 vector<size_t>& __lc,
3450 regex_constants::match_flag_type __flags) const
3451{
3452/*
3453 How do you set __m.__matches[i].first and second?
3454 With const _CharT* [__first, __last), we need a reference
3455 _BidirectionalIterator to bounce off of. Something like:
3456 __m.__matches_[0].second = next(__m.__matches_[0].first, __current - __first_);
3457
3458 Pre: __m.__matches_[0].first <-> __first ? or
3459 __m.__prefix_.first <-> first and
3460 __m.__suffix_.second <-> last ?
3461*/
3462 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
3463 __split_buffer<__command> __commands;
3464 difference_type __j = 0;
3465 difference_type __highest_j = 0;
3466 difference_type _N = _STD::distance(__first, __last);
3467 __state* __st = __start_.get();
3468 if (__st)
3469 {
3470 __commands.push_front(__command(__st));
3471 __commands.push_front(__command(__command::__consume_input));
3472 _BidirectionalIterator __current = __first;
3473 do
3474 {
3475 __command __cmd = __commands.back();
3476 __commands.pop_back();
3477 if (__cmd.first != nullptr)
3478 __cmd = __cmd.first->__test(__first, __current, __last, __lc,
3479 __m.__matches_.data(), __flags);
3480 switch (__cmd.__do_)
3481 {
3482 case __command::__end_state:
3483 __highest_j = _STD::max(__highest_j, __j);
3484 break;
3485 case __command::__consume_input:
3486 if (__j == _N)
3487 return false;
3488 ++__current;
3489 if (++__j != _N && !__commands.empty())
3490 __commands.push_front(__command(__command::__consume_input));
3491 break;
3492 case __command::__accept_and_consume:
3493 __commands.push_front(__command(__cmd.first));
3494 if (__cmd.second != nullptr)
3495 __commands.push_front(__command(__cmd.second));
3496 break;
3497 case __command::__accept_but_not_consume:
3498 __commands.push_back(__command(__cmd.first));
3499 if (__cmd.second != nullptr)
3500 __commands.push_back(__command(__cmd.second));
3501 break;
3502 case __command::__reject:
3503 break;
3504 default:
3505 throw regex_error(regex_constants::error_temp);
3506 break;
3507 }
3508 } while (!__commands.empty());
3509 if (__highest_j != 0)
3510 {
3511 __m.__matches_[0].first = __first;
3512 __m.__matches_[0].second = _STD::next(__first, __highest_j);
3513 __m.__matches_[0].matched = true;
3514 return true;
3515 }
3516 }
3517 return false;
3518}
3519
3520template <class _CharT, class _Traits>
3521template <class _BidirectionalIterator, class _Allocator>
3522bool
3523basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
3524 _BidirectionalIterator __first, _BidirectionalIterator __last,
3525 match_results<_BidirectionalIterator, _Allocator>& __m,
3526 regex_constants::match_flag_type __flags) const
3527{
3528 return false;
3529}
3530
3531template <class _CharT, class _Traits>
3532template <class _BidirectionalIterator, class _Allocator>
3533bool
3534basic_regex<_CharT, _Traits>::__match_at_start(
3535 _BidirectionalIterator __first, _BidirectionalIterator __last,
3536 match_results<_BidirectionalIterator, _Allocator>& __m,
3537 vector<size_t>& __lc,
3538 regex_constants::match_flag_type __flags) const
3539{
3540 if (__flags_ & ECMAScript)
3541 return __match_at_start_ecma(__first, __last, __m, __flags);
3542 if (mark_count() == 0)
3543 return __match_at_start_posix_nosubs(__first, __last, __m, __lc, __flags);
3544 return __match_at_start_posix_subs(__first, __last, __m, __flags);
3545}
3546
3547template <class _CharT, class _Traits>
3548template <class _BidirectionalIterator, class _Allocator>
3549bool
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003550basic_regex<_CharT, _Traits>::__search(
3551 _BidirectionalIterator __first, _BidirectionalIterator __last,
3552 match_results<_BidirectionalIterator, _Allocator>& __m,
3553 regex_constants::match_flag_type __flags) const
3554{
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003555 __m.__init(1 + mark_count(), __first, __last);
3556 vector<size_t> __lc(__loop_count());
3557 if (__match_at_start(__first, __last, __m, __lc, __flags))
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003558 {
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003559 __m.__prefix_.second = __m[0].first;
3560 __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
3561 __m.__suffix_.first = __m[0].second;
3562 __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
3563 return true;
3564 }
3565 if (!(__flags & regex_constants::match_continuous))
3566 {
3567 __m.__matches_.assign(__m.size(), __m.__unmatched_);
3568 for (++__first; __first != __last; ++__first)
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003569 {
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003570 if (__match_at_start(__first, __last, __m, __lc, __flags))
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003571 {
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003572 __m.__prefix_.second = __m[0].first;
3573 __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
3574 __m.__suffix_.first = __m[0].second;
3575 __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
3576 return true;
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003577 }
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003578 __m.__matches_.assign(__m.size(), __m.__unmatched_);
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003579 }
3580 }
Howard Hinnantf8ce4592010-07-07 19:14:52 +00003581 __m.__matches_.clear();
3582 return false;
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003583}
3584
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003585template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003586inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003587bool
3588regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,
3589 match_results<_BidirectionalIterator, _Allocator>& __m,
3590 const basic_regex<_CharT, _Traits>& __e,
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003591 regex_constants::match_flag_type __flags = regex_constants::match_default)
3592{
3593 return __e.__search(__first, __last, __m, __flags);
3594}
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003595
3596template <class _BidirectionalIterator, class _CharT, class _Traits>
3597inline _LIBCPP_INLINE_VISIBILITY
3598bool
3599regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,
3600 const basic_regex<_CharT, _Traits>& __e,
3601 regex_constants::match_flag_type __flags = regex_constants::match_default)
3602{
3603 match_results<_BidirectionalIterator> __m;
3604 return _STD::regex_search(__first, __last, __m, __e, __flags);
3605}
3606
3607template <class _CharT, class _Allocator, class _Traits>
3608inline _LIBCPP_INLINE_VISIBILITY
3609bool
3610regex_search(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,
3611 const basic_regex<_CharT, _Traits>& __e,
3612 regex_constants::match_flag_type __flags = regex_constants::match_default)
3613{
3614 return _STD::regex_search(__str, __str + _Traits::length(__str), __m, __e, __flags);
3615}
3616
3617template <class _CharT, class _Traits>
3618inline _LIBCPP_INLINE_VISIBILITY
3619bool
3620regex_search(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,
3621 regex_constants::match_flag_type __flags = regex_constants::match_default)
3622{
3623 return _STD::regex_search(__str, __str + _Traits::length(__str), __e, __flags);
3624}
3625
3626template <class _ST, class _SA, class _CharT, class _Traits>
3627inline _LIBCPP_INLINE_VISIBILITY
3628bool
3629regex_search(const basic_string<_CharT, _ST, _SA>& __s,
3630 const basic_regex<_CharT, _Traits>& __e,
3631 regex_constants::match_flag_type __flags = regex_constants::match_default)
3632{
3633 return _STD::regex_search(__s.begin(), __s.end(), __e, __flags);
3634}
3635
3636template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
3637inline _LIBCPP_INLINE_VISIBILITY
3638bool
3639regex_search(const basic_string<_CharT, _ST, _SA>& __s,
3640 match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
3641 const basic_regex<_CharT, _Traits>& __e,
3642 regex_constants::match_flag_type __flags = regex_constants::match_default)
3643{
3644 return _STD::regex_search(__s.begin(), __s.end(), __m, __e, __flags);
3645}
3646
3647// regex_match
3648
3649template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
3650bool
3651regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,
3652 match_results<_BidirectionalIterator, _Allocator>& __m,
3653 const basic_regex<_CharT, _Traits>& __e,
3654 regex_constants::match_flag_type __flags = regex_constants::match_default)
3655{
3656 bool __r = _STD::regex_search(__first, __last, __m, __e,
3657 __flags | regex_constants::match_continuous);
3658 if (__r)
3659 {
3660 __r = !__m.suffix().matched;
3661 if (!__r)
3662 __m.__matches_.clear();
3663 }
3664 return __r;
3665}
3666
3667template <class _BidirectionalIterator, class _CharT, class _Traits>
3668inline _LIBCPP_INLINE_VISIBILITY
3669bool
3670regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,
3671 const basic_regex<_CharT, _Traits>& __e,
3672 regex_constants::match_flag_type __flags = regex_constants::match_default)
3673{
3674 match_results<_BidirectionalIterator> __m;
3675 return _STD::regex_match(__first, __last, __m, __e, __flags);
3676}
3677
3678template <class _CharT, class _Allocator, class _Traits>
3679inline _LIBCPP_INLINE_VISIBILITY
3680bool
3681regex_match(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,
3682 const basic_regex<_CharT, _Traits>& __e,
3683 regex_constants::match_flag_type __flags = regex_constants::match_default)
3684{
3685 return _STD::regex_match(__str, __str + _Traits::length(__str), __m, __e, __flags);
3686}
3687
3688template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
3689inline _LIBCPP_INLINE_VISIBILITY
3690bool
3691regex_match(const basic_string<_CharT, _ST, _SA>& __s,
3692 match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
3693 const basic_regex<_CharT, _Traits>& __e,
3694 regex_constants::match_flag_type __flags = regex_constants::match_default)
3695{
3696 return _STD::regex_match(__s.begin(), __s.end(), __m, __e, __flags);
3697}
3698
3699template <class _CharT, class _Traits>
3700inline _LIBCPP_INLINE_VISIBILITY
3701bool
3702regex_match(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,
3703 regex_constants::match_flag_type __flags = regex_constants::match_default)
3704{
3705 return _STD::regex_match(__str, __str + _Traits::length(__str), __e, __flags);
3706}
3707
3708template <class _ST, class _SA, class _CharT, class _Traits>
3709inline _LIBCPP_INLINE_VISIBILITY
3710bool
3711regex_match(const basic_string<_CharT, _ST, _SA>& __s,
3712 const basic_regex<_CharT, _Traits>& __e,
3713 regex_constants::match_flag_type __flags = regex_constants::match_default)
3714{
3715 return _STD::regex_match(__s.begin(), __s.end(), __e, __flags);
3716}
3717
Howard Hinnant3257c982010-06-17 00:34:59 +00003718_LIBCPP_END_NAMESPACE_STD
3719
3720#endif // _LIBCPP_REGEX