blob: b13a7733ef6bf95485a1de7484a002dfca44e998 [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 Hinnant3257c982010-06-17 00:34:59 +0000729
730#pragma GCC system_header
731
732_LIBCPP_BEGIN_NAMESPACE_STD
733
734namespace regex_constants
735{
736
737// syntax_option_type
738
739enum syntax_option_type
740{
741 icase = 1 << 0,
742 nosubs = 1 << 1,
743 optimize = 1 << 2,
744 collate = 1 << 3,
745 ECMAScript = 1 << 4,
746 basic = 1 << 5,
747 extended = 1 << 6,
748 awk = 1 << 7,
749 grep = 1 << 8,
750 egrep = 1 << 9
751};
752
753inline
754/*constexpr*/
755syntax_option_type
756operator~(syntax_option_type __x)
757{
758 return syntax_option_type(~int(__x));
759}
760
761inline
762/*constexpr*/
763syntax_option_type
764operator&(syntax_option_type __x, syntax_option_type __y)
765{
766 return syntax_option_type(int(__x) & int(__y));
767}
768
769inline
770/*constexpr*/
771syntax_option_type
772operator|(syntax_option_type __x, syntax_option_type __y)
773{
774 return syntax_option_type(int(__x) | int(__y));
775}
776
777inline
778/*constexpr*/
779syntax_option_type
780operator^(syntax_option_type __x, syntax_option_type __y)
781{
782 return syntax_option_type(int(__x) ^ int(__y));
783}
784
785inline
786/*constexpr*/
787syntax_option_type&
788operator&=(syntax_option_type& __x, syntax_option_type __y)
789{
790 __x = __x & __y;
791 return __x;
792}
793
794inline
795/*constexpr*/
796syntax_option_type&
797operator|=(syntax_option_type& __x, syntax_option_type __y)
798{
799 __x = __x | __y;
800 return __x;
801}
802
803inline
804/*constexpr*/
805syntax_option_type&
806operator^=(syntax_option_type& __x, syntax_option_type __y)
807{
808 __x = __x ^ __y;
809 return __x;
810}
811
812// match_flag_type
813
814enum match_flag_type
815{
816 match_default = 0,
817 match_not_bol = 1 << 0,
818 match_not_eol = 1 << 1,
819 match_not_bow = 1 << 2,
820 match_not_eow = 1 << 3,
821 match_any = 1 << 4,
822 match_not_null = 1 << 5,
823 match_continuous = 1 << 6,
824 match_prev_avail = 1 << 7,
825 format_default = 0,
826 format_sed = 1 << 8,
827 format_no_copy = 1 << 9,
828 format_first_only = 1 << 10
829};
830
831inline
832/*constexpr*/
833match_flag_type
834operator~(match_flag_type __x)
835{
836 return match_flag_type(~int(__x));
837}
838
839inline
840/*constexpr*/
841match_flag_type
842operator&(match_flag_type __x, match_flag_type __y)
843{
844 return match_flag_type(int(__x) & int(__y));
845}
846
847inline
848/*constexpr*/
849match_flag_type
850operator|(match_flag_type __x, match_flag_type __y)
851{
852 return match_flag_type(int(__x) | int(__y));
853}
854
855inline
856/*constexpr*/
857match_flag_type
858operator^(match_flag_type __x, match_flag_type __y)
859{
860 return match_flag_type(int(__x) ^ int(__y));
861}
862
863inline
864/*constexpr*/
865match_flag_type&
866operator&=(match_flag_type& __x, match_flag_type __y)
867{
868 __x = __x & __y;
869 return __x;
870}
871
872inline
873/*constexpr*/
874match_flag_type&
875operator|=(match_flag_type& __x, match_flag_type __y)
876{
877 __x = __x | __y;
878 return __x;
879}
880
881inline
882/*constexpr*/
883match_flag_type&
884operator^=(match_flag_type& __x, match_flag_type __y)
885{
886 __x = __x ^ __y;
887 return __x;
888}
889
890enum error_type
891{
892 error_collate = 1,
893 error_ctype,
894 error_escape,
895 error_backref,
896 error_brack,
897 error_paren,
898 error_brace,
899 error_badbrace,
900 error_range,
901 error_space,
902 error_badrepeat,
903 error_complexity,
Howard Hinnant8c2c18d2010-06-24 21:28:00 +0000904 error_stack,
905 error_temp
Howard Hinnant3257c982010-06-17 00:34:59 +0000906};
907
908} // regex_constants
909
910class _LIBCPP_EXCEPTION_ABI regex_error
911 : public runtime_error
912{
913 regex_constants::error_type __code_;
914public:
915 explicit regex_error(regex_constants::error_type __ecode);
916 virtual ~regex_error() throw();
917 regex_constants::error_type code() const {return __code_;}
918};
919
920template <class _CharT>
921struct regex_traits
922{
923public:
924 typedef _CharT char_type;
925 typedef basic_string<char_type> string_type;
926 typedef locale locale_type;
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000927 typedef ctype_base::mask char_class_type;
Howard Hinnant3257c982010-06-17 00:34:59 +0000928
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000929 static const char_class_type __regex_word = 0x80;
Howard Hinnant3257c982010-06-17 00:34:59 +0000930private:
931 locale __loc_;
932 const ctype<char_type>* __ct_;
933 const collate<char_type>* __col_;
934
935public:
936 regex_traits();
937
938 static size_t length(const char_type* __p)
939 {return char_traits<char_type>::length(__p);}
940 char_type translate(char_type __c) const {return __c;}
941 char_type translate_nocase(char_type __c) const;
942 template <class _ForwardIterator>
943 string_type
944 transform(_ForwardIterator __f, _ForwardIterator __l) const;
945 template <class _ForwardIterator>
946 string_type
947 transform_primary( _ForwardIterator __f, _ForwardIterator __l) const
948 {return __transform_primary(__f, __l, char_type());}
949 template <class _ForwardIterator>
950 string_type
951 lookup_collatename(_ForwardIterator __f, _ForwardIterator __l) const
952 {return __lookup_collatename(__f, __l, char_type());}
953 template <class _ForwardIterator>
954 char_class_type
955 lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000956 bool __icase = false) const
957 {return __lookup_classname(__f, __l, __icase, char_type());}
958 bool isctype(char_type __c, char_class_type __m) const;
959 int value(char_type __ch, int __radix) const
960 {return __value(__ch, __radix);}
Howard Hinnant3257c982010-06-17 00:34:59 +0000961 locale_type imbue(locale_type __l);
962 locale_type getloc()const {return __loc_;}
963
964private:
965 void __init();
966
967 template <class _ForwardIterator>
968 string_type
969 __transform_primary(_ForwardIterator __f, _ForwardIterator __l, char) const;
970 template <class _ForwardIterator>
971 string_type
972 __transform_primary(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
973
974 template <class _ForwardIterator>
975 string_type
976 __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, char) const;
977 template <class _ForwardIterator>
978 string_type
979 __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
Howard Hinnantf409d2f2010-06-21 21:01:43 +0000980
981 template <class _ForwardIterator>
982 char_class_type
983 __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
984 bool __icase, char) const;
985 template <class _ForwardIterator>
986 char_class_type
987 __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
988 bool __icase, wchar_t) const;
989
990 static int __value(unsigned char __ch, int __radix);
991 int __value(char __ch, int __radix) const
992 {return __value(static_cast<unsigned char>(__ch), __radix);}
993 int __value(wchar_t __ch, int __radix) const;
Howard Hinnant3257c982010-06-17 00:34:59 +0000994};
995
996template <class _CharT>
997regex_traits<_CharT>::regex_traits()
998{
999 __init();
1000}
1001
1002template <class _CharT>
1003typename regex_traits<_CharT>::char_type
1004regex_traits<_CharT>::translate_nocase(char_type __c) const
1005{
1006 return __ct_->tolower(__c);
1007}
1008
1009template <class _CharT>
1010template <class _ForwardIterator>
1011typename regex_traits<_CharT>::string_type
1012regex_traits<_CharT>::transform(_ForwardIterator __f, _ForwardIterator __l) const
1013{
1014 string_type __s(__f, __l);
1015 return __col_->transform(__s.data(), __s.data() + __s.size());
1016}
1017
1018template <class _CharT>
1019void
1020regex_traits<_CharT>::__init()
1021{
1022 __ct_ = &use_facet<ctype<char_type> >(__loc_);
1023 __col_ = &use_facet<collate<char_type> >(__loc_);
1024}
1025
1026template <class _CharT>
1027typename regex_traits<_CharT>::locale_type
1028regex_traits<_CharT>::imbue(locale_type __l)
1029{
1030 locale __r = __loc_;
1031 __loc_ = __l;
1032 __init();
1033 return __r;
1034}
1035
1036// transform_primary is very FreeBSD-specific
1037
1038template <class _CharT>
1039template <class _ForwardIterator>
1040typename regex_traits<_CharT>::string_type
1041regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
1042 _ForwardIterator __l, char) const
1043{
1044 const string_type __s(__f, __l);
1045 string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
1046 switch (__d.size())
1047 {
1048 case 1:
1049 break;
1050 case 12:
1051 __d[11] = __d[3];
1052 break;
1053 default:
1054 __d.clear();
1055 break;
1056 }
1057 return __d;
1058}
1059
1060template <class _CharT>
1061template <class _ForwardIterator>
1062typename regex_traits<_CharT>::string_type
1063regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
1064 _ForwardIterator __l, wchar_t) const
1065{
1066 const string_type __s(__f, __l);
1067 string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
1068 switch (__d.size())
1069 {
1070 case 1:
1071 break;
1072 case 3:
1073 __d[2] = __d[0];
1074 break;
1075 default:
1076 __d.clear();
1077 break;
1078 }
1079 return __d;
1080}
1081
1082// lookup_collatename is very FreeBSD-specific
1083
Howard Hinnantf409d2f2010-06-21 21:01:43 +00001084string __get_collation_name(const char* __s);
Howard Hinnant3257c982010-06-17 00:34:59 +00001085
1086template <class _CharT>
1087template <class _ForwardIterator>
1088typename regex_traits<_CharT>::string_type
1089regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
1090 _ForwardIterator __l, char) const
1091{
1092 string_type __s(__f, __l);
1093 string_type __r;
1094 if (!__s.empty())
1095 {
1096 __r = __get_collation_name(__s.c_str());
1097 if (__r.empty() && __s.size() <= 2)
1098 {
1099 __r = __col_->transform(__s.data(), __s.data() + __s.size());
1100 if (__r.size() == 1 || __r.size() == 12)
1101 __r = __s;
1102 else
1103 __r.clear();
1104 }
1105 }
1106 return __r;
1107}
1108
1109template <class _CharT>
1110template <class _ForwardIterator>
1111typename regex_traits<_CharT>::string_type
1112regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
1113 _ForwardIterator __l, wchar_t) const
1114{
1115 string_type __s(__f, __l);
1116 string __n;
1117 __n.reserve(__s.size());
1118 for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();
1119 __i != __e; ++__i)
1120 {
1121 if (static_cast<unsigned>(*__i) >= 127)
1122 return string_type();
1123 __n.push_back(char(*__i));
1124 }
1125 string_type __r;
1126 if (!__s.empty())
1127 {
1128 __n = __get_collation_name(__n.c_str());
1129 if (!__n.empty())
1130 __r.assign(__n.begin(), __n.end());
1131 else if (__s.size() <= 2)
1132 {
1133 __r = __col_->transform(__s.data(), __s.data() + __s.size());
1134 if (__r.size() == 1 || __r.size() == 3)
1135 __r = __s;
1136 else
1137 __r.clear();
1138 }
1139 }
1140 return __r;
1141}
1142
Howard Hinnantf409d2f2010-06-21 21:01:43 +00001143// lookup_classname
1144
1145ctype_base::mask __get_classname(const char* __s, bool __icase);
1146
1147template <class _CharT>
1148template <class _ForwardIterator>
1149typename regex_traits<_CharT>::char_class_type
1150regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,
1151 _ForwardIterator __l,
1152 bool __icase, char) const
1153{
1154 string_type __s(__f, __l);
1155 __ct_->tolower(&__s[0], &__s[0] + __s.size());
1156 return __get_classname(__s.c_str(), __icase);
1157}
1158
1159template <class _CharT>
1160template <class _ForwardIterator>
1161typename regex_traits<_CharT>::char_class_type
1162regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,
1163 _ForwardIterator __l,
1164 bool __icase, wchar_t) const
1165{
1166 string_type __s(__f, __l);
1167 __ct_->tolower(&__s[0], &__s[0] + __s.size());
1168 string __n;
1169 __n.reserve(__s.size());
1170 for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();
1171 __i != __e; ++__i)
1172 {
1173 if (static_cast<unsigned>(*__i) >= 127)
1174 return char_class_type();
1175 __n.push_back(char(*__i));
1176 }
1177 return __get_classname(__n.c_str(), __icase);
1178}
1179
1180template <class _CharT>
1181bool
1182regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const
1183{
1184 if (__ct_->is(__m, __c))
1185 return true;
1186 return (__c == '_' && (__m & __regex_word));
1187}
1188
1189template <class _CharT>
1190int
1191regex_traits<_CharT>::__value(unsigned char __ch, int __radix)
1192{
1193 if ((__ch & 0xF8u) == 0x30) // '0' <= __ch && __ch <= '7'
1194 return __ch - '0';
1195 if (__radix != 8)
1196 {
1197 if ((__ch & 0xFEu) == 0x38) // '8' <= __ch && __ch <= '9'
1198 return __ch - '0';
1199 if (__radix == 16)
1200 {
1201 __ch |= 0x20; // tolower
1202 if ('a' <= __ch && __ch <= 'f')
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001203 return __ch - ('a' - 10);
Howard Hinnantf409d2f2010-06-21 21:01:43 +00001204 }
1205 }
1206 return -1;
1207}
1208
1209template <class _CharT>
1210inline
1211int
1212regex_traits<_CharT>::__value(wchar_t __ch, int __radix) const
1213{
1214 return __value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
1215}
1216
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001217template <class _CharT> class __transition;
1218
1219template <class _CharT>
1220class __state
1221{
1222 typedef __transition<_CharT> __transition;
1223 __transition* __t1_;
1224 __transition* __t2_;
1225 int __state_;
1226 enum
1227 {
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001228 __not_tried = 0,
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001229 __1_succeded = 1,
1230 __1_failed = 2,
1231 __2_not_tried = 0,
1232 __2_succeded = 4,
1233 __2_failed = 8
1234 };
1235
1236 __state(const __state&);
1237 __state& operator=(const __state&);
1238public:
1239 __state()
1240 : __t1_(), __t2_(), __state_() {}
1241 ~__state();
1242
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001243 __state* operator()(_CharT __c);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001244
1245 void __add_one(__transition* __t) {__t1_ = __t;}
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001246
1247 void __reset_state();
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001248};
1249
1250template <class _CharT>
1251__state<_CharT>::~__state()
1252{
1253 delete __t1_;
1254 delete __t2_;
1255}
1256
1257template <class _CharT>
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001258__state<_CharT>*
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001259__state<_CharT>::operator()(_CharT __c)
1260{
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001261 __state* __r = nullptr;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001262 if ((__state_ & 3) == 0)
1263 {
1264 if (__t1_)
1265 {
1266 __r = (*__t1_)(__c);
1267 if (__r)
1268 __state_ |= __1_succeded;
1269 else
1270 __state_ |= __1_failed;
1271 }
1272 else
1273 __state_ |= __1_failed;
1274 }
1275 else if ((__state_ & 0xC) == 0)
1276 {
1277 if (__t2_)
1278 {
1279 __r = (*__t2_)(__c);
1280 if (__r)
1281 __state_ |= __2_succeded;
1282 else
1283 __state_ |= __2_failed;
1284 }
1285 else
1286 __state_ |= __2_failed;
1287 }
1288 return __r;
1289}
1290
1291template <class _CharT>
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001292void
1293__state<_CharT>::__reset_state()
1294{
1295 __state_ = __not_tried;
1296 if (__t1_)
1297 __t1_->__reset_state();
1298 if (__t2_)
1299 __t2_->__reset_state();
1300}
1301
1302template <class _CharT>
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001303class __transition
1304{
1305 __transition(const __transition&);
1306 __transition& operator=(const __transition&);
1307
1308 typedef __state<_CharT> __state;
1309 typedef unique_ptr<__state, void(*)(__state*)> __sptr;
1310
1311 static void __delete_state(__state* __p) {delete __p;}
1312 static void __ignore_state(__state*) {}
1313
1314protected:
1315 __sptr __sptr_;
1316public:
1317 __transition(bool __owns, __state* __st)
1318 : __sptr_(__st, __owns ? &__delete_state : &__ignore_state) {}
1319 virtual ~__transition() {}
1320
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001321 virtual __state* operator()(_CharT) const {return __sptr_.get();}
1322
1323 void __reset_state();
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001324};
1325
1326template <class _CharT>
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001327void
1328__transition<_CharT>::__reset_state()
1329{
1330 if (__sptr_.get_deleter() == &__delete_state)
1331 __sptr_->__reset_state();
1332}
1333
1334template <class _CharT>
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001335class __match_char
1336 : public __transition<_CharT>
1337{
1338 typedef __transition<_CharT> base;
1339 _CharT __c_;
1340public:
1341 __match_char(_CharT __c, bool __owns, __state<_CharT>* __st)
1342 : base(__owns, __st), __c_(__c) {}
1343
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001344 virtual __state<_CharT>* operator()(_CharT __c) const
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001345 {return __c == __c_ ? base::__sptr_.get() : nullptr;}
1346};
1347
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001348template <class, class> class match_results;
1349
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001350template <class _CharT, class _Traits = regex_traits<_CharT> >
1351class basic_regex
1352{
1353public:
1354 // types:
1355 typedef _CharT value_type;
1356 typedef regex_constants::syntax_option_type flag_type;
1357 typedef typename _Traits::locale_type locale_type;
1358
1359private:
1360 _Traits __traits_;
1361 flag_type __flags_;
1362 unsigned __marked_count_;
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001363 int __open_count_;
1364 shared_ptr<__state<_CharT> > __start_;
1365 __state<_CharT>* __end_;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001366
1367public:
1368 // constants:
1369 static const/*expr*/ regex_constants::syntax_option_type icase = regex_constants::icase;
1370 static const/*expr*/ regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
1371 static const/*expr*/ regex_constants::syntax_option_type optimize = regex_constants::optimize;
1372 static const/*expr*/ regex_constants::syntax_option_type collate = regex_constants::collate;
1373 static const/*expr*/ regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
1374 static const/*expr*/ regex_constants::syntax_option_type basic = regex_constants::basic;
1375 static const/*expr*/ regex_constants::syntax_option_type extended = regex_constants::extended;
1376 static const/*expr*/ regex_constants::syntax_option_type awk = regex_constants::awk;
1377 static const/*expr*/ regex_constants::syntax_option_type grep = regex_constants::grep;
1378 static const/*expr*/ regex_constants::syntax_option_type egrep = regex_constants::egrep;
1379
1380 // construct/copy/destroy:
1381 basic_regex();
1382 explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001383 : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001384 {__parse(__p, __p + __traits_.length(__p));}
1385 basic_regex(const value_type* __p, size_t __len, flag_type __f)
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001386 : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001387 {__parse(__p, __p + __len);}
1388 basic_regex(const basic_regex&);
1389#ifdef _LIBCPP_MOVE
1390 basic_regex(basic_regex&&);
1391#endif
1392 template <class _ST, class _SA>
1393 explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
1394 flag_type __f = regex_constants::ECMAScript)
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001395 : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001396 {__parse(__p.begin(), __p.end());}
1397 template <class _ForwardIterator>
1398 basic_regex(_ForwardIterator __first, _ForwardIterator __last,
1399 flag_type __f = regex_constants::ECMAScript)
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001400 : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001401 {__parse(__first, __last);}
1402 basic_regex(initializer_list<value_type> __il,
1403 flag_type __f = regex_constants::ECMAScript)
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001404 : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001405 {__parse(__il.begin(), __il.end());}
1406
1407 ~basic_regex();
1408
1409 basic_regex& operator=(const basic_regex&);
1410#ifdef _LIBCPP_MOVE
1411 basic_regex& operator=(basic_regex&&);
1412#endif
1413 basic_regex& operator=(const value_type* __p);
1414 basic_regex& operator=(initializer_list<value_type> __il);
1415 template <class _ST, class _SA>
1416 basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p);
1417
1418 // assign:
1419 basic_regex& assign(const basic_regex& __that);
1420#ifdef _LIBCPP_MOVE
1421 basic_regex& assign(basic_regex&& __that);
1422#endif
1423 basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript);
1424 basic_regex& assign(const value_type* __p, size_t __len, flag_type __f);
1425 template <class _ST, class _SA>
1426 basic_regex& assign(const basic_string<value_type, _ST, _SA>& __s,
1427 flag_type __f = regex_constants::ECMAScript);
1428 template <class _InputIterator>
1429 basic_regex& assign(_InputIterator __first, _InputIterator __last,
1430 flag_type __f = regex_constants::ECMAScript);
1431 basic_regex& assign(initializer_list<value_type> __il,
1432 flag_type = regex_constants::ECMAScript);
1433
1434 // const operations:
1435 unsigned mark_count() const {return __marked_count_;}
1436 flag_type flags() const {return __flags_;}
1437
1438 // locale:
1439 locale_type imbue(locale_type __loc) {return __traits_.imbue(__loc);}
1440 locale_type getloc() const {return __traits_.getloc();}
1441
1442 // swap:
1443 void swap(basic_regex&);
1444
1445private:
1446 template <class _ForwardIterator>
1447 void __parse(_ForwardIterator __first, _ForwardIterator __last);
1448 template <class _ForwardIterator>
1449 _ForwardIterator
1450 __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
1451 template <class _ForwardIterator>
1452 _ForwardIterator
1453 __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last);
1454 template <class _ForwardIterator>
1455 _ForwardIterator
1456 __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last);
1457 template <class _ForwardIterator>
1458 _ForwardIterator
1459 __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last);
1460 template <class _ForwardIterator>
1461 _ForwardIterator
1462 __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last);
1463 template <class _ForwardIterator>
1464 _ForwardIterator
1465 __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last);
1466 template <class _ForwardIterator>
1467 _ForwardIterator
1468 __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last);
1469 template <class _ForwardIterator>
1470 _ForwardIterator
1471 __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last);
1472 template <class _ForwardIterator>
1473 _ForwardIterator
1474 __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last);
1475 template <class _ForwardIterator>
1476 _ForwardIterator
1477 __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last);
1478 template <class _ForwardIterator>
1479 _ForwardIterator
1480 __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last);
1481 template <class _ForwardIterator>
1482 _ForwardIterator
1483 __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);
1484 template <class _ForwardIterator>
1485 _ForwardIterator
1486 __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last);
Howard Hinnant0de86b62010-06-25 20:56:08 +00001487 template <class _ForwardIterator>
1488 _ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001489 __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last);
1490 template <class _ForwardIterator>
1491 _ForwardIterator
Howard Hinnant0de86b62010-06-25 20:56:08 +00001492 __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last);
1493 template <class _ForwardIterator>
1494 _ForwardIterator
1495 __parse_follow_list(_ForwardIterator __first, _ForwardIterator __last);
1496 template <class _ForwardIterator>
1497 _ForwardIterator
1498 __parse_expression_term(_ForwardIterator __first, _ForwardIterator __last);
1499 template <class _ForwardIterator>
1500 _ForwardIterator
1501 __parse_equivalence_class(_ForwardIterator __first, _ForwardIterator __last);
1502 template <class _ForwardIterator>
1503 _ForwardIterator
1504 __parse_character_class(_ForwardIterator __first, _ForwardIterator __last);
1505 template <class _ForwardIterator>
1506 _ForwardIterator
1507 __parse_collating_symbol(_ForwardIterator __first, _ForwardIterator __last);
1508 template <class _ForwardIterator>
1509 _ForwardIterator
1510 __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c);
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001511 template <class _ForwardIterator>
1512 _ForwardIterator
1513 __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
1514 template <class _ForwardIterator>
1515 _ForwardIterator
1516 __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last);
1517 template <class _ForwardIterator>
1518 _ForwardIterator
1519 __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last);
1520 template <class _ForwardIterator>
1521 _ForwardIterator
1522 __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last);
1523 template <class _ForwardIterator>
1524 _ForwardIterator
1525 __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
1526 template <class _ForwardIterator>
1527 _ForwardIterator
1528 __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001529
Howard Hinnant0de86b62010-06-25 20:56:08 +00001530 void __push_l_anchor() {}
1531 void __push_r_anchor() {}
1532 void __push_match_any() {}
1533 void __push_greedy_inf_repeat(int __min) {}
1534 void __push_exact_repeat(int __count) {}
1535 void __push_repeat(int __min, int __max) {}
1536 void __start_nonmatching_list() {}
1537 void __start_matching_list() {}
1538 void __end_nonmatching_list() {}
1539 void __end_matching_list() {}
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001540 void __push_char(value_type __c);
Howard Hinnant0de86b62010-06-25 20:56:08 +00001541 void __push_char(const typename _Traits::string_type& __c) {}
1542 void __push_range() {}
1543 void __push_class_type(typename _Traits::char_class_type) {}
1544 void __push_back_ref(int __i) {}
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001545 void __push_alternation() {}
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00001546
1547 template <class _BidirectionalIterator, class _Allocator>
1548 bool
1549 __search(_BidirectionalIterator __first, _BidirectionalIterator __last,
1550 match_results<_BidirectionalIterator, _Allocator>& __m,
1551 regex_constants::match_flag_type __flags) const;
1552
1553 template <class _B, class _A, class _C, class _T>
1554 friend
1555 bool
1556 regex_search(_B, _B, match_results<_B, _A>&, const basic_regex<_C, _T>&,
1557 regex_constants::match_flag_type);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001558};
1559
1560template <class _CharT, class _Traits>
1561inline
1562basic_regex<_CharT, _Traits>::basic_regex()
1563 : __traits_(), __flags_(), __marked_count_(0)
1564{
1565}
1566
1567template <class _CharT, class _Traits>
1568basic_regex<_CharT, _Traits>::~basic_regex()
1569{
1570}
1571
1572template <class _CharT, class _Traits>
1573template <class _ForwardIterator>
1574void
1575basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
1576 _ForwardIterator __last)
1577{
1578 switch (__flags_ & 0x3F0)
1579 {
1580 case ECMAScript:
1581 break;
1582 case basic:
1583 __parse_basic_reg_exp(__first, __last);
1584 break;
1585 case extended:
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001586 __parse_extended_reg_exp(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001587 break;
1588 case awk:
1589 break;
1590 case grep:
1591 break;
1592 case egrep:
1593 break;
1594 default:
1595 throw regex_error(regex_constants::error_temp);
1596 }
1597}
1598
1599template <class _CharT, class _Traits>
1600template <class _ForwardIterator>
1601_ForwardIterator
1602basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first,
1603 _ForwardIterator __last)
1604{
1605 if (__first != __last)
1606 {
1607 if (*__first == '^')
1608 {
1609 __push_l_anchor();
1610 ++__first;
1611 }
1612 if (__first != __last)
1613 {
1614 __first = __parse_RE_expression(__first, __last);
1615 if (__first != __last)
1616 {
1617 _ForwardIterator __temp = next(__first);
1618 if (__temp == __last && *__first == '$')
1619 {
1620 __push_r_anchor();
1621 ++__first;
1622 }
1623 }
1624 }
1625 if (__first != __last)
1626 throw regex_error(regex_constants::error_temp);
1627 }
1628 return __first;
1629}
1630
1631template <class _CharT, class _Traits>
1632template <class _ForwardIterator>
1633_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001634basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first,
1635 _ForwardIterator __last)
1636{
1637 while (true)
1638 {
1639 _ForwardIterator __temp = __parse_ERE_branch(__first, __last);
1640 if (__temp == __first)
1641 throw regex_error(regex_constants::error_temp);
1642 __first = __temp;
1643 if (__first == __last)
1644 break;
1645 if (*__first != '|')
1646 throw regex_error(regex_constants::error_temp);
1647 __push_alternation();
1648 ++__first;
1649 }
1650 return __first;
1651}
1652
1653template <class _CharT, class _Traits>
1654template <class _ForwardIterator>
1655_ForwardIterator
1656basic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first,
1657 _ForwardIterator __last)
1658{
1659 _ForwardIterator __temp = __parse_ERE_expression(__first, __last);
1660 if (__temp == __first)
1661 throw regex_error(regex_constants::error_temp);
1662 do
1663 {
1664 __first = __temp;
1665 __temp = __parse_ERE_expression(__first, __last);
1666 } while (__temp != __first);
1667 return __first;
1668}
1669
1670template <class _CharT, class _Traits>
1671template <class _ForwardIterator>
1672_ForwardIterator
1673basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first,
1674 _ForwardIterator __last)
1675{
1676 _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last);
1677 if (__temp == __first && __temp != __last)
1678 {
1679 switch (*__temp)
1680 {
1681 case '^':
1682 __push_l_anchor();
1683 ++__temp;
1684 break;
1685 case '$':
1686 __push_r_anchor();
1687 ++__temp;
1688 break;
1689 case '(':
1690 ++__marked_count_;
1691 ++__open_count_;
1692 __temp = __parse_extended_reg_exp(++__temp, __last);
1693 if (__temp == __last || *__temp != ')')
1694 throw regex_error(regex_constants::error_paren);
1695 --__open_count_;
1696 ++__temp;
1697 break;
1698 }
1699 }
1700 if (__temp != __first)
1701 __temp = __parse_ERE_dupl_symbol(__temp, __last);
1702 __first = __temp;
1703 return __first;
1704}
1705
1706template <class _CharT, class _Traits>
1707template <class _ForwardIterator>
1708_ForwardIterator
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001709basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first,
1710 _ForwardIterator __last)
1711{
1712 while (true)
1713 {
1714 _ForwardIterator __temp = __parse_simple_RE(__first, __last);
1715 if (__temp == __first)
1716 break;
1717 __first = __temp;
1718 }
1719 return __first;
1720}
1721
1722template <class _CharT, class _Traits>
1723template <class _ForwardIterator>
1724_ForwardIterator
1725basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first,
1726 _ForwardIterator __last)
1727{
1728 if (__first != __last)
1729 {
1730 _ForwardIterator __temp = __parse_nondupl_RE(__first, __last);
1731 if (__temp != __first)
1732 {
1733 __first = __temp;
1734 __first = __parse_RE_dupl_symbol(__first, __last);
1735 }
1736 }
1737 return __first;
1738}
1739
1740template <class _CharT, class _Traits>
1741template <class _ForwardIterator>
1742_ForwardIterator
1743basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first,
1744 _ForwardIterator __last)
1745{
1746 _ForwardIterator __temp = __first;
1747 __first = __parse_one_char_or_coll_elem_RE(__first, __last);
1748 if (__temp == __first)
1749 {
1750 __temp = __parse_Back_open_paren(__first, __last);
1751 if (__temp != __first)
1752 {
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001753 ++__marked_count_;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001754 __first = __parse_RE_expression(__temp, __last);
1755 __temp = __parse_Back_close_paren(__first, __last);
1756 if (__temp == __first)
1757 throw regex_error(regex_constants::error_paren);
1758 __first = __temp;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001759 }
1760 else
1761 __first = __parse_BACKREF(__first, __last);
1762 }
1763 return __first;
1764}
1765
1766template <class _CharT, class _Traits>
1767template <class _ForwardIterator>
1768_ForwardIterator
1769basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE(
1770 _ForwardIterator __first,
1771 _ForwardIterator __last)
1772{
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001773 _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001774 if (__temp == __first)
1775 {
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001776 __temp = __parse_QUOTED_CHAR(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001777 if (__temp == __first)
1778 {
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001779 if (__temp != __last && *__temp == '.')
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001780 {
1781 __push_match_any();
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001782 ++__temp;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001783 }
1784 else
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001785 __temp = __parse_bracket_expression(__first, __last);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001786 }
1787 }
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001788 __first = __temp;
1789 return __first;
1790}
1791
1792template <class _CharT, class _Traits>
1793template <class _ForwardIterator>
1794_ForwardIterator
1795basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE(
1796 _ForwardIterator __first,
1797 _ForwardIterator __last)
1798{
1799 _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last);
1800 if (__temp == __first)
1801 {
1802 __temp = __parse_QUOTED_CHAR_ERE(__first, __last);
1803 if (__temp == __first)
1804 {
1805 if (__temp != __last && *__temp == '.')
1806 {
1807 __push_match_any();
1808 ++__temp;
1809 }
1810 else
1811 __temp = __parse_bracket_expression(__first, __last);
1812 }
1813 }
1814 __first = __temp;
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001815 return __first;
1816}
1817
1818template <class _CharT, class _Traits>
1819template <class _ForwardIterator>
1820_ForwardIterator
1821basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first,
1822 _ForwardIterator __last)
1823{
1824 if (__first != __last)
1825 {
1826 _ForwardIterator __temp = next(__first);
1827 if (__temp != __last)
1828 {
1829 if (*__first == '\\' && *__temp == '(')
1830 __first = ++__temp;
1831 }
1832 }
1833 return __first;
1834}
1835
1836template <class _CharT, class _Traits>
1837template <class _ForwardIterator>
1838_ForwardIterator
1839basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first,
1840 _ForwardIterator __last)
1841{
1842 if (__first != __last)
1843 {
1844 _ForwardIterator __temp = next(__first);
1845 if (__temp != __last)
1846 {
1847 if (*__first == '\\' && *__temp == ')')
1848 __first = ++__temp;
1849 }
1850 }
1851 return __first;
1852}
1853
1854template <class _CharT, class _Traits>
1855template <class _ForwardIterator>
1856_ForwardIterator
1857basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first,
1858 _ForwardIterator __last)
1859{
1860 if (__first != __last)
1861 {
1862 _ForwardIterator __temp = next(__first);
1863 if (__temp != __last)
1864 {
1865 if (*__first == '\\' && *__temp == '{')
1866 __first = ++__temp;
1867 }
1868 }
1869 return __first;
1870}
1871
1872template <class _CharT, class _Traits>
1873template <class _ForwardIterator>
1874_ForwardIterator
1875basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first,
1876 _ForwardIterator __last)
1877{
1878 if (__first != __last)
1879 {
1880 _ForwardIterator __temp = next(__first);
1881 if (__temp != __last)
1882 {
1883 if (*__first == '\\' && *__temp == '}')
1884 __first = ++__temp;
1885 }
1886 }
1887 return __first;
1888}
1889
1890template <class _CharT, class _Traits>
1891template <class _ForwardIterator>
1892_ForwardIterator
1893basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,
1894 _ForwardIterator __last)
1895{
1896 if (__first != __last)
1897 {
1898 _ForwardIterator __temp = next(__first);
1899 if (__temp != __last)
1900 {
1901 if (*__first == '\\' && '1' <= *__temp && *__temp <= '9')
1902 {
1903 __push_back_ref(*__temp - '0');
1904 __first = ++__temp;
1905 }
1906 }
1907 }
1908 return __first;
1909}
1910
1911template <class _CharT, class _Traits>
1912template <class _ForwardIterator>
1913_ForwardIterator
1914basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first,
1915 _ForwardIterator __last)
1916{
1917 if (__first != __last)
1918 {
1919 _ForwardIterator __temp = next(__first);
1920 if (__temp == __last && *__first == '$')
1921 return __first;
1922 // Not called inside a bracket
1923 if (*__first == '.' || *__first == '\\' || *__first == '[')
1924 return __first;
Howard Hinnant0de86b62010-06-25 20:56:08 +00001925 __push_char(*__first);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001926 ++__first;
1927 }
1928 return __first;
1929}
1930
1931template <class _CharT, class _Traits>
1932template <class _ForwardIterator>
1933_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00001934basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first,
1935 _ForwardIterator __last)
1936{
1937 if (__first != __last)
1938 {
1939 switch (*__first)
1940 {
1941 case '^':
1942 case '.':
1943 case '[':
1944 case '$':
1945 case '(':
1946 case '|':
1947 case '*':
1948 case '+':
1949 case '?':
1950 case '{':
1951 case '\\':
1952 break;
1953 case ')':
1954 if (__open_count_ == 0)
1955 {
1956 __push_char(*__first);
1957 ++__first;
1958 }
1959 break;
1960 default:
1961 __push_char(*__first);
1962 ++__first;
1963 break;
1964 }
1965 }
1966 return __first;
1967}
1968
1969template <class _CharT, class _Traits>
1970template <class _ForwardIterator>
1971_ForwardIterator
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001972basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first,
1973 _ForwardIterator __last)
1974{
1975 if (__first != __last)
1976 {
1977 _ForwardIterator __temp = next(__first);
1978 if (__temp != __last)
1979 {
1980 if (*__first == '\\')
1981 {
1982 switch (*__temp)
1983 {
1984 case '^':
1985 case '.':
1986 case '*':
1987 case '[':
1988 case '$':
1989 case '\\':
Howard Hinnant0de86b62010-06-25 20:56:08 +00001990 __push_char(*__temp);
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00001991 __first = ++__temp;
1992 break;
1993 }
1994 }
1995 }
1996 }
1997 return __first;
1998}
1999
2000template <class _CharT, class _Traits>
2001template <class _ForwardIterator>
2002_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002003basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,
2004 _ForwardIterator __last)
2005{
2006 if (__first != __last)
2007 {
2008 _ForwardIterator __temp = next(__first);
2009 if (__temp != __last)
2010 {
2011 if (*__first == '\\')
2012 {
2013 switch (*__temp)
2014 {
2015 case '^':
2016 case '.':
2017 case '*':
2018 case '[':
2019 case '$':
2020 case '\\':
2021 case '(':
2022 case ')':
2023 case '|':
2024 case '+':
2025 case '?':
2026 case '{':
2027 __push_char(*__temp);
2028 __first = ++__temp;
2029 break;
2030 }
2031 }
2032 }
2033 }
2034 return __first;
2035}
2036
2037template <class _CharT, class _Traits>
2038template <class _ForwardIterator>
2039_ForwardIterator
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002040basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first,
2041 _ForwardIterator __last)
2042{
2043 if (__first != __last)
2044 {
Howard Hinnant0de86b62010-06-25 20:56:08 +00002045 if (*__first == '*')
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002046 {
2047 __push_greedy_inf_repeat(0);
2048 ++__first;
2049 }
2050 else
2051 {
2052 _ForwardIterator __temp = __parse_Back_open_brace(__first, __last);
2053 if (__temp != __first)
2054 {
2055 int __min = 0;
2056 __first = __temp;
2057 __temp = __parse_DUP_COUNT(__first, __last, __min);
2058 if (__temp == __first)
2059 throw regex_error(regex_constants::error_badbrace);
2060 __first = __temp;
2061 if (__first == __last)
2062 throw regex_error(regex_constants::error_brace);
2063 if (*__first != ',')
2064 {
2065 __temp = __parse_Back_close_brace(__first, __last);
2066 if (__temp == __first)
2067 throw regex_error(regex_constants::error_brace);
2068 __push_exact_repeat(__min);
2069 __first = __temp;
2070 }
2071 else
2072 {
2073 ++__first; // consume ','
2074 int __max = -1;
2075 __first = __parse_DUP_COUNT(__first, __last, __max);
2076 __temp = __parse_Back_close_brace(__first, __last);
2077 if (__temp == __first)
2078 throw regex_error(regex_constants::error_brace);
2079 if (__max == -1)
2080 __push_greedy_inf_repeat(__min);
2081 else
2082 {
2083 if (__max < __min)
2084 throw regex_error(regex_constants::error_badbrace);
2085 __push_repeat(__min, __max);
2086 }
2087 __first = __temp;
2088 }
2089 }
2090 }
2091 }
2092 return __first;
2093}
2094
Howard Hinnant0de86b62010-06-25 20:56:08 +00002095template <class _CharT, class _Traits>
2096template <class _ForwardIterator>
2097_ForwardIterator
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002098basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first,
2099 _ForwardIterator __last)
2100{
2101 if (__first != __last)
2102 {
2103 switch (*__first)
2104 {
2105 case '*':
2106 __push_greedy_inf_repeat(0);
2107 ++__first;
2108 break;
2109 case '+':
2110 __push_greedy_inf_repeat(1);
2111 ++__first;
2112 break;
2113 case '?':
2114 __push_repeat(0, 1);
2115 ++__first;
2116 break;
2117 case '{':
2118 {
2119 int __min;
2120 _ForwardIterator __temp = __parse_DUP_COUNT(__first, __last, __min);
2121 if (__temp == __first)
2122 throw regex_error(regex_constants::error_badbrace);
2123 __first = __temp;
2124 if (__first == __last)
2125 throw regex_error(regex_constants::error_brace);
2126 switch (*__first)
2127 {
2128 case '}':
2129 __push_exact_repeat(__min);
2130 ++__first;
2131 break;
2132 case ',':
2133 if (++__first == __last)
2134 throw regex_error(regex_constants::error_badbrace);
2135 if (*__first == '}')
2136 {
2137 __push_greedy_inf_repeat(__min);
2138 ++__first;
2139 }
2140 else
2141 {
2142 int __max;
2143 __temp = __parse_DUP_COUNT(__first, __last, __max);
2144 if (__temp == __first)
2145 throw regex_error(regex_constants::error_brace);
2146 __first = __temp;
2147 if (__first == __last || *__first != '}')
2148 throw regex_error(regex_constants::error_brace);
2149 ++__first;
2150 if (__max < __min)
2151 throw regex_error(regex_constants::error_badbrace);
2152 __push_repeat(__min, __max);
2153 }
2154 default:
2155 throw regex_error(regex_constants::error_badbrace);
2156 }
2157 }
2158 break;
2159 }
2160 }
2161 return __first;
2162}
2163
2164template <class _CharT, class _Traits>
2165template <class _ForwardIterator>
2166_ForwardIterator
Howard Hinnant0de86b62010-06-25 20:56:08 +00002167basic_regex<_CharT, _Traits>::__parse_bracket_expression(_ForwardIterator __first,
2168 _ForwardIterator __last)
2169{
2170 if (__first != __last && *__first == '[')
2171 {
2172 if (++__first == __last)
2173 throw regex_error(regex_constants::error_brack);
2174 bool __non_matching = false;
2175 if (*__first == '^')
2176 {
2177 ++__first;
2178 __non_matching = true;
2179 __start_nonmatching_list();
2180 }
2181 else
2182 __start_matching_list();
2183 if (__first == __last)
2184 throw regex_error(regex_constants::error_brack);
2185 if (*__first == ']')
2186 {
2187 __push_char(']');
2188 ++__first;
2189 }
2190 __first = __parse_follow_list(__first, __last);
2191 if (__first == __last)
2192 throw regex_error(regex_constants::error_brack);
2193 if (*__first == '-')
2194 {
2195 __push_char('-');
2196 ++__first;
2197 }
2198 if (__first == __last || *__first != ']')
2199 throw regex_error(regex_constants::error_brack);
2200 if (__non_matching)
2201 __end_nonmatching_list();
2202 else
2203 __end_matching_list();
2204 ++__first;
2205 }
2206 return __first;
2207}
2208
2209template <class _CharT, class _Traits>
2210template <class _ForwardIterator>
2211_ForwardIterator
2212basic_regex<_CharT, _Traits>::__parse_follow_list(_ForwardIterator __first,
2213 _ForwardIterator __last)
2214{
2215 if (__first != __last)
2216 {
2217 while (true)
2218 {
2219 _ForwardIterator __temp = __parse_expression_term(__first, __last);
2220 if (__temp == __first)
2221 break;
2222 __first = __temp;
2223 }
2224 }
2225 return __first;
2226}
2227
2228template <class _CharT, class _Traits>
2229template <class _ForwardIterator>
2230_ForwardIterator
2231basic_regex<_CharT, _Traits>::__parse_expression_term(_ForwardIterator __first,
2232 _ForwardIterator __last)
2233{
2234 if (__first != __last && *__first != ']')
2235 {
2236 bool __parsed_one = false;
2237 _ForwardIterator __temp = next(__first);
2238 if (__temp != __last && *__first == '[')
2239 {
2240 if (*__temp == '=')
2241 return __parse_equivalence_class(++__temp, __last);
2242 else if (*__temp == ':')
2243 return __parse_character_class(++__temp, __last);
2244 else if (*__temp == '.')
2245 {
2246 __first = __parse_collating_symbol(++__temp, __last);
2247 __parsed_one = true;
2248 }
2249 }
2250 if (!__parsed_one)
2251 {
2252 __push_char(*__first);
2253 ++__first;
2254 }
2255 if (__first != __last && *__first != ']')
2256 {
2257 __temp = next(__first);
2258 if (__temp != __last && *__first == '-' && *__temp != ']')
2259 {
2260 // parse a range
2261 __first = __temp;
2262 ++__temp;
2263 if (__temp != __last && *__first == '[' && *__temp == '.')
2264 __first = __parse_collating_symbol(++__temp, __last);
2265 else
2266 {
2267 __push_char(*__first);
2268 ++__first;
2269 }
2270 __push_range();
2271 }
2272 }
2273 }
2274 return __first;
2275}
2276
2277template <class _CharT, class _Traits>
2278template <class _ForwardIterator>
2279_ForwardIterator
2280basic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first,
2281 _ForwardIterator __last)
2282{
2283 // Found [=
2284 // This means =] must exist
2285 value_type _Equal_close[2] = {'=', ']'};
2286 _ForwardIterator __temp = _STD::search(__first, __last, _Equal_close,
2287 _Equal_close+2);
2288 if (__temp == __last)
2289 throw regex_error(regex_constants::error_brack);
2290 // [__first, __temp) contains all text in [= ... =]
2291 typedef typename _Traits::string_type string_type;
2292 string_type __collate_name =
2293 __traits_.lookup_collatename(__first, __temp);
2294 if (__collate_name.empty())
2295 throw regex_error(regex_constants::error_brack);
2296 string_type __equiv_name =
2297 __traits_.transform_primary(__collate_name.begin(),
2298 __collate_name.end());
2299 if (!__equiv_name.empty())
2300 __push_char(__equiv_name);
2301 else
2302 __push_char(__collate_name);
2303 __first = next(__temp, 2);
2304 return __first;
2305}
2306
2307template <class _CharT, class _Traits>
2308template <class _ForwardIterator>
2309_ForwardIterator
2310basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first,
2311 _ForwardIterator __last)
2312{
2313 // Found [:
2314 // This means :] must exist
2315 value_type _Colon_close[2] = {':', ']'};
2316 _ForwardIterator __temp = _STD::search(__first, __last, _Colon_close,
2317 _Colon_close+2);
2318 if (__temp == __last)
2319 throw regex_error(regex_constants::error_brack);
2320 // [__first, __temp) contains all text in [: ... :]
2321 typedef typename _Traits::char_class_type char_class_type;
2322 char_class_type __class_type =
2323 __traits_.lookup_classname(__first, __temp, __flags_ & icase);
2324 if (__class_type == 0)
2325 throw regex_error(regex_constants::error_brack);
2326 __push_class_type(__class_type);
2327 __first = next(__temp, 2);
2328 return __first;
2329}
2330
2331template <class _CharT, class _Traits>
2332template <class _ForwardIterator>
2333_ForwardIterator
2334basic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first,
2335 _ForwardIterator __last)
2336{
2337 // Found [.
2338 // This means .] must exist
2339 value_type _Dot_close[2] = {'.', ']'};
2340 _ForwardIterator __temp = _STD::search(__first, __last, _Dot_close,
2341 _Dot_close+2);
2342 if (__temp == __last)
2343 throw regex_error(regex_constants::error_brack);
2344 // [__first, __temp) contains all text in [. ... .]
2345 typedef typename _Traits::string_type string_type;
2346 string_type __collate_name =
2347 __traits_.lookup_collatename(__first, __temp);
2348 if (__collate_name.empty())
2349 throw regex_error(regex_constants::error_brack);
2350 __push_char(__collate_name);
2351 __first = next(__temp, 2);
2352 return __first;
2353}
2354
2355template <class _CharT, class _Traits>
2356template <class _ForwardIterator>
2357_ForwardIterator
2358basic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first,
2359 _ForwardIterator __last,
2360 int& __c)
2361{
2362 if (__first != __last && '0' <= *__first && *__first <= '9')
2363 {
2364 __c = *__first - '0';
2365 for (++__first; __first != __last && '0' <= *__first && *__first <= '9';
2366 ++__first)
2367 {
2368 __c *= 10;
2369 __c += *__first - '0';
2370 }
2371 }
2372 return __first;
2373}
2374
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002375template <class _CharT, class _Traits>
2376void
2377basic_regex<_CharT, _Traits>::__push_char(value_type __c)
2378{
2379 unique_ptr<__state<_CharT> > __new_end(new __state<_CharT>);
2380 unique_ptr<__transition<_CharT> > __new_transition(
2381 new __match_char<_CharT>(__c, true, __new_end.get()));
2382 __state<_CharT>* __e = __new_end.release();
2383 if (__end_ == nullptr)
2384 {
2385 __start_.reset(new __state<_CharT>);
2386 __end_ = __start_.get();
2387 }
2388 __end_->__add_one(__new_transition.release());
2389 __end_ = __e;
2390}
2391
Howard Hinnant8c2c18d2010-06-24 21:28:00 +00002392typedef basic_regex<char> regex;
2393typedef basic_regex<wchar_t> wregex;
2394
Howard Hinnantcd85b9e2010-06-29 18:37:43 +00002395// sub_match
2396
2397template <class _BidirectionalIterator>
2398class sub_match
2399 : public pair<_BidirectionalIterator, _BidirectionalIterator>
2400{
2401public:
2402 typedef _BidirectionalIterator iterator;
2403 typedef typename iterator_traits<iterator>::value_type value_type;
2404 typedef typename iterator_traits<iterator>::difference_type difference_type;
2405 typedef basic_string<value_type> string_type;
2406
2407 bool matched;
2408
2409 difference_type length() const
2410 {return matched ? _STD::distance(this->first, this->second) : 0;}
2411 string_type str() const
2412 {return matched ? string_type(this->first, this->second) : string_type();}
2413 operator string_type() const
2414 {return str();}
2415
2416 int compare(const sub_match& __s) const
2417 {return str().compare(__s.str());}
2418 int compare(const string_type& __s) const
2419 {return str().compare(__s);}
2420 int compare(const value_type* __s) const
2421 {return str().compare(__s);}
2422};
2423
2424typedef sub_match<const char*> csub_match;
2425typedef sub_match<const wchar_t*> wcsub_match;
2426typedef sub_match<string::const_iterator> ssub_match;
2427typedef sub_match<wstring::const_iterator> wssub_match;
2428
2429template <class _BiIter>
2430inline _LIBCPP_INLINE_VISIBILITY
2431bool
2432operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2433{
2434 return __x.compare(__y) == 0;
2435}
2436
2437template <class _BiIter>
2438inline _LIBCPP_INLINE_VISIBILITY
2439bool
2440operator!=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2441{
2442 return !(__x == __y);
2443}
2444
2445template <class _BiIter>
2446inline _LIBCPP_INLINE_VISIBILITY
2447bool
2448operator<(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2449{
2450 return __x.compare(__y) < 0;
2451}
2452
2453template <class _BiIter>
2454inline _LIBCPP_INLINE_VISIBILITY
2455bool
2456operator<=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2457{
2458 return !(__y < __x);
2459}
2460
2461template <class _BiIter>
2462inline _LIBCPP_INLINE_VISIBILITY
2463bool
2464operator>=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2465{
2466 return !(__x < __y);
2467}
2468
2469template <class _BiIter>
2470inline _LIBCPP_INLINE_VISIBILITY
2471bool
2472operator>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
2473{
2474 return __y < __x;
2475}
2476
2477template <class _BiIter, class _ST, class _SA>
2478inline _LIBCPP_INLINE_VISIBILITY
2479bool
2480operator==(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2481 const sub_match<_BiIter>& __y)
2482{
2483 return __y.compare(__x.c_str()) == 0;
2484}
2485
2486template <class _BiIter, class _ST, class _SA>
2487inline _LIBCPP_INLINE_VISIBILITY
2488bool
2489operator!=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2490 const sub_match<_BiIter>& __y)
2491{
2492 return !(__x == __y);
2493}
2494
2495template <class _BiIter, class _ST, class _SA>
2496inline _LIBCPP_INLINE_VISIBILITY
2497bool
2498operator<(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2499 const sub_match<_BiIter>& __y)
2500{
2501 return __y.compare(__x.c_str()) > 0;
2502}
2503
2504template <class _BiIter, class _ST, class _SA>
2505inline _LIBCPP_INLINE_VISIBILITY
2506bool
2507operator>(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2508 const sub_match<_BiIter>& __y)
2509{
2510 return __y < __x;
2511}
2512
2513template <class _BiIter, class _ST, class _SA>
2514inline _LIBCPP_INLINE_VISIBILITY
2515bool operator>=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2516 const sub_match<_BiIter>& __y)
2517{
2518 return !(__x < __y);
2519}
2520
2521template <class _BiIter, class _ST, class _SA>
2522inline _LIBCPP_INLINE_VISIBILITY
2523bool
2524operator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
2525 const sub_match<_BiIter>& __y)
2526{
2527 return !(__y < __x);
2528}
2529
2530template <class _BiIter, class _ST, class _SA>
2531inline _LIBCPP_INLINE_VISIBILITY
2532bool
2533operator==(const sub_match<_BiIter>& __x,
2534 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
2535{
2536 return __x.compare(__y.c_str()) == 0;
2537}
2538
2539template <class _BiIter, class _ST, class _SA>
2540inline _LIBCPP_INLINE_VISIBILITY
2541bool
2542operator!=(const sub_match<_BiIter>& __x,
2543 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
2544{
2545 return !(__x == __y);
2546}
2547
2548template <class _BiIter, class _ST, class _SA>
2549inline _LIBCPP_INLINE_VISIBILITY
2550bool
2551operator<(const sub_match<_BiIter>& __x,
2552 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
2553{
2554 return __x.compare(__y.c_str()) < 0;
2555}
2556
2557template <class _BiIter, class _ST, class _SA>
2558inline _LIBCPP_INLINE_VISIBILITY
2559bool operator>(const sub_match<_BiIter>& __x,
2560 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
2561{
2562 return __y < __x;
2563}
2564
2565template <class _BiIter, class _ST, class _SA>
2566inline _LIBCPP_INLINE_VISIBILITY
2567bool
2568operator>=(const sub_match<_BiIter>& __x,
2569 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
2570{
2571 return !(__x < __y);
2572}
2573
2574template <class _BiIter, class _ST, class _SA>
2575inline _LIBCPP_INLINE_VISIBILITY
2576bool
2577operator<=(const sub_match<_BiIter>& __x,
2578 const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
2579{
2580 return !(__y < __x);
2581}
2582
2583template <class _BiIter>
2584inline _LIBCPP_INLINE_VISIBILITY
2585bool
2586operator==(typename iterator_traits<_BiIter>::value_type const* __x,
2587 const sub_match<_BiIter>& __y)
2588{
2589 return __y.compare(__x) == 0;
2590}
2591
2592template <class _BiIter>
2593inline _LIBCPP_INLINE_VISIBILITY
2594bool
2595operator!=(typename iterator_traits<_BiIter>::value_type const* __x,
2596 const sub_match<_BiIter>& __y)
2597{
2598 return !(__x == __y);
2599}
2600
2601template <class _BiIter>
2602inline _LIBCPP_INLINE_VISIBILITY
2603bool
2604operator<(typename iterator_traits<_BiIter>::value_type const* __x,
2605 const sub_match<_BiIter>& __y)
2606{
2607 return __y.compare(__x) > 0;
2608}
2609
2610template <class _BiIter>
2611inline _LIBCPP_INLINE_VISIBILITY
2612bool
2613operator>(typename iterator_traits<_BiIter>::value_type const* __x,
2614 const sub_match<_BiIter>& __y)
2615{
2616 return __y < __x;
2617}
2618
2619template <class _BiIter>
2620inline _LIBCPP_INLINE_VISIBILITY
2621bool
2622operator>=(typename iterator_traits<_BiIter>::value_type const* __x,
2623 const sub_match<_BiIter>& __y)
2624{
2625 return !(__x < __y);
2626}
2627
2628template <class _BiIter>
2629inline _LIBCPP_INLINE_VISIBILITY
2630bool
2631operator<=(typename iterator_traits<_BiIter>::value_type const* __x,
2632 const sub_match<_BiIter>& __y)
2633{
2634 return !(__y < __x);
2635}
2636
2637template <class _BiIter>
2638inline _LIBCPP_INLINE_VISIBILITY
2639bool
2640operator==(const sub_match<_BiIter>& __x,
2641 typename iterator_traits<_BiIter>::value_type const* __y)
2642{
2643 return __x.compare(__y) == 0;
2644}
2645
2646template <class _BiIter>
2647inline _LIBCPP_INLINE_VISIBILITY
2648bool
2649operator!=(const sub_match<_BiIter>& __x,
2650 typename iterator_traits<_BiIter>::value_type const* __y)
2651{
2652 return !(__x == __y);
2653}
2654
2655template <class _BiIter>
2656inline _LIBCPP_INLINE_VISIBILITY
2657bool
2658operator<(const sub_match<_BiIter>& __x,
2659 typename iterator_traits<_BiIter>::value_type const* __y)
2660{
2661 return __x.compare(__y) < 0;
2662}
2663
2664template <class _BiIter>
2665inline _LIBCPP_INLINE_VISIBILITY
2666bool
2667operator>(const sub_match<_BiIter>& __x,
2668 typename iterator_traits<_BiIter>::value_type const* __y)
2669{
2670 return __y < __x;
2671}
2672
2673template <class _BiIter>
2674inline _LIBCPP_INLINE_VISIBILITY
2675bool
2676operator>=(const sub_match<_BiIter>& __x,
2677 typename iterator_traits<_BiIter>::value_type const* __y)
2678{
2679 return !(__x < __y);
2680}
2681
2682template <class _BiIter>
2683inline _LIBCPP_INLINE_VISIBILITY
2684bool
2685operator<=(const sub_match<_BiIter>& __x,
2686 typename iterator_traits<_BiIter>::value_type const* __y)
2687{
2688 return !(__y < __x);
2689}
2690
2691template <class _BiIter>
2692inline _LIBCPP_INLINE_VISIBILITY
2693bool
2694operator==(typename iterator_traits<_BiIter>::value_type const& __x,
2695 const sub_match<_BiIter>& __y)
2696{
2697 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
2698 return __y.compare(string_type(1, __x)) == 0;
2699}
2700
2701template <class _BiIter>
2702inline _LIBCPP_INLINE_VISIBILITY
2703bool
2704operator!=(typename iterator_traits<_BiIter>::value_type const& __x,
2705 const sub_match<_BiIter>& __y)
2706{
2707 return !(__x == __y);
2708}
2709
2710template <class _BiIter>
2711inline _LIBCPP_INLINE_VISIBILITY
2712bool
2713operator<(typename iterator_traits<_BiIter>::value_type const& __x,
2714 const sub_match<_BiIter>& __y)
2715{
2716 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
2717 return __y.compare(string_type(1, __x)) > 0;
2718}
2719
2720template <class _BiIter>
2721inline _LIBCPP_INLINE_VISIBILITY
2722bool
2723operator>(typename iterator_traits<_BiIter>::value_type const& __x,
2724 const sub_match<_BiIter>& __y)
2725{
2726 return __y < __x;
2727}
2728
2729template <class _BiIter>
2730inline _LIBCPP_INLINE_VISIBILITY
2731bool
2732operator>=(typename iterator_traits<_BiIter>::value_type const& __x,
2733 const sub_match<_BiIter>& __y)
2734{
2735 return !(__x < __y);
2736}
2737
2738template <class _BiIter>
2739inline _LIBCPP_INLINE_VISIBILITY
2740bool
2741operator<=(typename iterator_traits<_BiIter>::value_type const& __x,
2742 const sub_match<_BiIter>& __y)
2743{
2744 return !(__y < __x);
2745}
2746
2747template <class _BiIter>
2748inline _LIBCPP_INLINE_VISIBILITY
2749bool
2750operator==(const sub_match<_BiIter>& __x,
2751 typename iterator_traits<_BiIter>::value_type const& __y)
2752{
2753 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
2754 return __x.compare(string_type(1, __y)) == 0;
2755}
2756
2757template <class _BiIter>
2758inline _LIBCPP_INLINE_VISIBILITY
2759bool
2760operator!=(const sub_match<_BiIter>& __x,
2761 typename iterator_traits<_BiIter>::value_type const& __y)
2762{
2763 return !(__x == __y);
2764}
2765
2766template <class _BiIter>
2767inline _LIBCPP_INLINE_VISIBILITY
2768bool
2769operator<(const sub_match<_BiIter>& __x,
2770 typename iterator_traits<_BiIter>::value_type const& __y)
2771{
2772 typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
2773 return __x.compare(string_type(1, __y)) < 0;
2774}
2775
2776template <class _BiIter>
2777inline _LIBCPP_INLINE_VISIBILITY
2778bool
2779operator>(const sub_match<_BiIter>& __x,
2780 typename iterator_traits<_BiIter>::value_type const& __y)
2781{
2782 return __y < __x;
2783}
2784
2785template <class _BiIter>
2786inline _LIBCPP_INLINE_VISIBILITY
2787bool
2788operator>=(const sub_match<_BiIter>& __x,
2789 typename iterator_traits<_BiIter>::value_type const& __y)
2790{
2791 return !(__x < __y);
2792}
2793
2794template <class _BiIter>
2795inline _LIBCPP_INLINE_VISIBILITY
2796bool
2797operator<=(const sub_match<_BiIter>& __x,
2798 typename iterator_traits<_BiIter>::value_type const& __y)
2799{
2800 return !(__y < __x);
2801}
2802
2803template <class _CharT, class _ST, class _BiIter>
2804inline _LIBCPP_INLINE_VISIBILITY
2805basic_ostream<_CharT, _ST>&
2806operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m)
2807{
2808 return __os << __m.str();
2809}
2810
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00002811template <class _BidirectionalIterator,
2812 class _Allocator = allocator<sub_match<_BidirectionalIterator> > >
2813class match_results
2814{
2815public:
2816 typedef _Allocator allocator_type;
2817 typedef sub_match<_BidirectionalIterator> value_type;
2818private:
2819 typedef vector<value_type, allocator_type> __container_type;
2820
2821 __container_type __matches_;
2822 value_type __unmatched_;
2823 value_type __prefix_;
2824 value_type __suffix_;
2825public:
2826 typedef const value_type& const_reference;
2827 typedef const_reference reference;
2828 typedef typename __container_type::const_iterator const_iterator;
2829 typedef const_iterator iterator;
2830 typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
2831 typedef typename allocator_traits<allocator_type>::size_type size_type;
2832 typedef typename iterator_traits<_BidirectionalIterator>::value_type char_type;
2833 typedef basic_string<char_type> string_type;
2834
2835 // construct/copy/destroy:
2836 explicit match_results(const allocator_type& __a = allocator_type());
2837// match_results(const match_results&) = default;
2838// match_results& operator=(const match_results&) = default;
2839#ifdef _LIBCPP_MOVE
2840// match_results(match_results&& __m) = default;
2841// match_results& operator=(match_results&& __m) = default;
2842#endif
2843// ~match_results() = default;
2844
2845 // size:
2846 size_type size() const {return __matches_.size();}
2847 size_type max_size() const {return __matches_.max_size();}
2848 bool empty() const {return size() == 0;}
2849
2850 // element access:
2851 difference_type length(size_type __sub = 0) const
2852 {return (*this)[__sub].length();}
2853 difference_type position(size_type __sub = 0) const
2854 {return _STD::distance(__prefix_.first, (*this)[__sub].first);}
2855 string_type str(size_type __sub = 0) const
2856 {return (*this)[__sub].str();}
2857 const_reference operator[](size_type __n) const
2858 {return __n < __matches_.size() ? __matches_[__n] : __unmatched_;}
2859
2860 const_reference prefix() const {return __prefix_;}
2861 const_reference suffix() const {return __suffix_;}
2862
2863 const_iterator begin() const {return empty() ? __matches_.end() : __matches_.begin() + 1;}
2864 const_iterator end() const {return __matches_.end();}
2865 const_iterator cbegin() const {return empty() ? __matches_.end() : __matches_.begin() + 1;}
2866 const_iterator cend() const {return __matches_.end();}
2867
2868 // format:
2869 template <class _OutputIter>
2870 _OutputIter
2871 format(_OutputIter __out, const char_type* __fmt_first,
2872 const char_type* __fmt_last,
2873 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
2874 template <class _OutputIter, class _ST, class _SA>
2875 _OutputIter
2876 format(_OutputIter __out, const basic_string<char_type, _ST, _SA>& __fmt,
2877 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
2878 template <class _ST, class _SA>
2879 basic_string<char_type, _ST, _SA>
2880 format(const basic_string<char_type, _ST, _SA>& __fmt,
2881 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
2882 string_type
2883 format(const char_type* __fmt,
2884 regex_constants::match_flag_type __flags = regex_constants::format_default) const;
2885
2886 // allocator:
2887 allocator_type get_allocator() const {return __matches_.get_allocator();}
2888
2889 // swap:
2890 void swap(match_results& __m);
2891
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00002892private:
2893 void __init(unsigned __s,
2894 _BidirectionalIterator __f, _BidirectionalIterator __l);
2895
2896 template <class, class> friend class basic_regex;
2897
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00002898 template <class _B, class _A, class _C, class _T>
2899 friend
2900 bool
2901 regex_match(_B, _B, match_results<_B, _A>&, const basic_regex<_C, _T>&,
2902 regex_constants::match_flag_type);
2903};
2904
2905template <class _BidirectionalIterator, class _Allocator>
2906match_results<_BidirectionalIterator, _Allocator>::match_results(
2907 const allocator_type& __a)
2908 : __matches_(__a),
2909 __unmatched_(),
2910 __prefix_(),
2911 __suffix_()
2912{
2913}
2914
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00002915template <class _BidirectionalIterator, class _Allocator>
2916void
2917match_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s,
2918 _BidirectionalIterator __f, _BidirectionalIterator __l)
2919{
2920 __matches_.resize(__s);
2921 for (unsigned __i = 0; __i < __s; ++__i)
2922 {
2923 __matches_[__i].first = __l;
2924 __matches_[__i].second = __l;
2925 __matches_[__i].matched = false;
2926 }
2927 __unmatched_.first = __l;
2928 __unmatched_.second = __l;
2929 __unmatched_.matched = false;
2930 __prefix_.first = __f;
2931 __prefix_.second = __f;
2932 __prefix_.matched = false;
2933 __suffix_.first = __l;
2934 __suffix_.second = __l;
2935 __suffix_.matched = false;
2936}
2937
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00002938typedef match_results<const char*> cmatch;
2939typedef match_results<const wchar_t*> wcmatch;
2940typedef match_results<string::const_iterator> smatch;
2941typedef match_results<wstring::const_iterator> wsmatch;
2942
2943template <class _BidirectionalIterator, class _Allocator>
2944 bool
2945 operator==(const match_results<_BidirectionalIterator, _Allocator>& __x,
2946 const match_results<_BidirectionalIterator, _Allocator>& __y);
2947
2948template <class _BidirectionalIterator, class _Allocator>
2949 bool
2950 operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x,
2951 const match_results<_BidirectionalIterator, _Allocator>& __y);
2952
2953template <class _BidirectionalIterator, class _Allocator>
2954 void
2955 swap(match_results<_BidirectionalIterator, _Allocator>& __x,
2956 match_results<_BidirectionalIterator, _Allocator>& __y);
2957
2958// regex_search
2959
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00002960template <class _CharT, class _Traits>
2961template <class _BidirectionalIterator, class _Allocator>
2962bool
2963basic_regex<_CharT, _Traits>::__search(
2964 _BidirectionalIterator __first, _BidirectionalIterator __last,
2965 match_results<_BidirectionalIterator, _Allocator>& __m,
2966 regex_constants::match_flag_type __flags) const
2967{
2968 bool __r = false;
2969 if (__start_)
2970 {
2971 __m.__init(1 + mark_count(), __first, __last);
2972 for (; __first != __last; ++__first)
2973 {
2974 __start_->__reset_state();
2975 __state<_CharT>* __st = (*__start_)(*__first);
2976 if (__st)
2977 {
2978 _BidirectionalIterator& __f = __m.__matches_[0].first;
2979 _BidirectionalIterator& __l = __m.__matches_[0].second;
2980 __m.__matches_[0].matched = false;
2981 __f = __l = __first;
2982 ++__l;
2983 for (; __l != __last && __st != nullptr && __st != __end_; ++__l)
2984 __st = (*__st)(*__l);
2985 if (__st == __end_)
2986 {
2987 __r = __m.__matches_[0].matched = true;
2988 __m.__prefix_.second = __first;
2989 __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
2990 __m.__suffix_.first = __l;
2991 __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
2992 }
2993 }
2994 if (__flags & regex_constants::match_continuous)
2995 break;
2996 }
2997 }
2998 if (!__r)
2999 __m.__matches_.clear();
3000 return __r;
3001}
3002
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003003template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003004inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003005bool
3006regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,
3007 match_results<_BidirectionalIterator, _Allocator>& __m,
3008 const basic_regex<_CharT, _Traits>& __e,
Howard Hinnant9b80f2b2010-06-30 17:22:19 +00003009 regex_constants::match_flag_type __flags = regex_constants::match_default)
3010{
3011 return __e.__search(__first, __last, __m, __flags);
3012}
Howard Hinnant7e9d84b2010-06-30 00:21:42 +00003013
3014template <class _BidirectionalIterator, class _CharT, class _Traits>
3015inline _LIBCPP_INLINE_VISIBILITY
3016bool
3017regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,
3018 const basic_regex<_CharT, _Traits>& __e,
3019 regex_constants::match_flag_type __flags = regex_constants::match_default)
3020{
3021 match_results<_BidirectionalIterator> __m;
3022 return _STD::regex_search(__first, __last, __m, __e, __flags);
3023}
3024
3025template <class _CharT, class _Allocator, class _Traits>
3026inline _LIBCPP_INLINE_VISIBILITY
3027bool
3028regex_search(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,
3029 const basic_regex<_CharT, _Traits>& __e,
3030 regex_constants::match_flag_type __flags = regex_constants::match_default)
3031{
3032 return _STD::regex_search(__str, __str + _Traits::length(__str), __m, __e, __flags);
3033}
3034
3035template <class _CharT, class _Traits>
3036inline _LIBCPP_INLINE_VISIBILITY
3037bool
3038regex_search(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,
3039 regex_constants::match_flag_type __flags = regex_constants::match_default)
3040{
3041 return _STD::regex_search(__str, __str + _Traits::length(__str), __e, __flags);
3042}
3043
3044template <class _ST, class _SA, class _CharT, class _Traits>
3045inline _LIBCPP_INLINE_VISIBILITY
3046bool
3047regex_search(const basic_string<_CharT, _ST, _SA>& __s,
3048 const basic_regex<_CharT, _Traits>& __e,
3049 regex_constants::match_flag_type __flags = regex_constants::match_default)
3050{
3051 return _STD::regex_search(__s.begin(), __s.end(), __e, __flags);
3052}
3053
3054template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
3055inline _LIBCPP_INLINE_VISIBILITY
3056bool
3057regex_search(const basic_string<_CharT, _ST, _SA>& __s,
3058 match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
3059 const basic_regex<_CharT, _Traits>& __e,
3060 regex_constants::match_flag_type __flags = regex_constants::match_default)
3061{
3062 return _STD::regex_search(__s.begin(), __s.end(), __m, __e, __flags);
3063}
3064
3065// regex_match
3066
3067template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
3068bool
3069regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,
3070 match_results<_BidirectionalIterator, _Allocator>& __m,
3071 const basic_regex<_CharT, _Traits>& __e,
3072 regex_constants::match_flag_type __flags = regex_constants::match_default)
3073{
3074 bool __r = _STD::regex_search(__first, __last, __m, __e,
3075 __flags | regex_constants::match_continuous);
3076 if (__r)
3077 {
3078 __r = !__m.suffix().matched;
3079 if (!__r)
3080 __m.__matches_.clear();
3081 }
3082 return __r;
3083}
3084
3085template <class _BidirectionalIterator, class _CharT, class _Traits>
3086inline _LIBCPP_INLINE_VISIBILITY
3087bool
3088regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,
3089 const basic_regex<_CharT, _Traits>& __e,
3090 regex_constants::match_flag_type __flags = regex_constants::match_default)
3091{
3092 match_results<_BidirectionalIterator> __m;
3093 return _STD::regex_match(__first, __last, __m, __e, __flags);
3094}
3095
3096template <class _CharT, class _Allocator, class _Traits>
3097inline _LIBCPP_INLINE_VISIBILITY
3098bool
3099regex_match(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,
3100 const basic_regex<_CharT, _Traits>& __e,
3101 regex_constants::match_flag_type __flags = regex_constants::match_default)
3102{
3103 return _STD::regex_match(__str, __str + _Traits::length(__str), __m, __e, __flags);
3104}
3105
3106template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
3107inline _LIBCPP_INLINE_VISIBILITY
3108bool
3109regex_match(const basic_string<_CharT, _ST, _SA>& __s,
3110 match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
3111 const basic_regex<_CharT, _Traits>& __e,
3112 regex_constants::match_flag_type __flags = regex_constants::match_default)
3113{
3114 return _STD::regex_match(__s.begin(), __s.end(), __m, __e, __flags);
3115}
3116
3117template <class _CharT, class _Traits>
3118inline _LIBCPP_INLINE_VISIBILITY
3119bool
3120regex_match(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,
3121 regex_constants::match_flag_type __flags = regex_constants::match_default)
3122{
3123 return _STD::regex_match(__str, __str + _Traits::length(__str), __e, __flags);
3124}
3125
3126template <class _ST, class _SA, class _CharT, class _Traits>
3127inline _LIBCPP_INLINE_VISIBILITY
3128bool
3129regex_match(const basic_string<_CharT, _ST, _SA>& __s,
3130 const basic_regex<_CharT, _Traits>& __e,
3131 regex_constants::match_flag_type __flags = regex_constants::match_default)
3132{
3133 return _STD::regex_match(__s.begin(), __s.end(), __e, __flags);
3134}
3135
Howard Hinnant3257c982010-06-17 00:34:59 +00003136_LIBCPP_END_NAMESPACE_STD
3137
3138#endif // _LIBCPP_REGEX