31 namespace std _GLIBCXX_VISIBILITY(default)
33 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 template<
typename _BiIter,
typename _Alloc,
46 typename _CharT,
typename _TraitsT>
48 __regex_algo_impl(_BiIter __s,
50 match_results<_BiIter, _Alloc>& __m,
51 const basic_regex<_CharT, _TraitsT>& __re,
53 _RegexExecutorPolicy __policy,
56 if (__re._M_automaton ==
nullptr)
59 typename match_results<_BiIter, _Alloc>::_Unchecked& __res = __m;
61 __m._M_resize(__re._M_automaton->_M_sub_count());
64 bool __use_dfs =
true;
66 || (__policy == _RegexExecutorPolicy::_S_alternate
67 && !__re._M_automaton->_M_has_backref))
70 _Executor<_BiIter, _Alloc, _TraitsT>
71 __executor(__s, __e, __res, __re, __flags, __use_dfs);
73 __ret = __executor._M_match();
75 __ret = __executor._M_search();
79 for (
auto& __it : __res)
81 __it.first = __it.second = __e;
82 auto& __pre = __m._M_prefix();
83 auto& __suf = __m._M_suffix();
86 __pre.matched =
false;
89 __suf.matched =
false;
96 __pre.second = __res[0].first;
97 __pre.matched = (__pre.first != __pre.second);
98 __suf.first = __res[0].second;
100 __suf.matched = (__suf.first != __suf.second);
105 __m._M_establish_failed_match(__e);
111 __lookup_collatename(
string& __name) noexcept
113 static const char*
const __collatenames[] =
206 "left-square-bracket",
208 "right-square-bracket",
238 "left-curly-bracket",
240 "right-curly-bracket",
245 for (
const auto& __it : __collatenames)
248 __name.assign(1,
static_cast<char>(&__it - __collatenames));
258 #pragma GCC diagnostic push
259 #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
261 template<
typename _Ch_type>
262 template<
typename _Fwd_iter>
263 typename regex_traits<_Ch_type>::string_type
272 string __s(__first, __last);
273 __detail::__lookup_collatename(__s);
279 const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
282 for (; __first != __last; ++__first)
283 __s += __fctyp.narrow(*__first, 0);
284 __detail::__lookup_collatename(__s);
292 template<
typename _Ch_type>
293 template<
typename _Fwd_iter>
294 typename regex_traits<_Ch_type>::char_class_type
298 if constexpr (__is_any_random_access_iter<_Fwd_iter>::value)
299 if ((__last - __first) > 6) [[__unlikely__]]
303 const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
305 auto __read_ch = [&]() ->
char {
306 if (__first == __last)
308 char __c = __fctyp.narrow(__fctyp.tolower(*__first), 0);
313 auto __match = [&](
const char* __s) ->
bool {
315 if (__read_ch() != *__s)
318 return __first == __last;
324 if (__read_ch() ==
'l')
329 return ctype_base::alnum;
333 return ctype_base::alpha;
339 return ctype_base::blank;
343 return ctype_base::cntrl;
346 if (__first == __last || __match(
"igit"))
347 return ctype_base::digit;
351 return ctype_base::graph;
355 return __icase ? ctype_base::alpha : ctype_base::lower;
362 return ctype_base::print;
366 return ctype_base::punct;
371 if (__first == __last || __match(
"pace"))
372 return ctype_base::space;
376 return __icase ? ctype_base::alpha : ctype_base::upper;
379 if (__first == __last)
380 return {ctype_base::alnum, char_class_type::_S_under};
383 if (__match(
"digit"))
384 return ctype_base::xdigit;
391 template<
typename _Ch_type>
394 isctype(_Ch_type __c, char_class_type __f)
const
397 const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
399 return __fctyp.is(__f._M_base, __c)
401 || ((__f._M_extended & _RegexMask::_S_under)
402 && __c == __fctyp.widen(
'_'));
405 template<
typename _Ch_type>
408 value(_Ch_type __ch,
int __radix)
const
410 if constexpr (
sizeof(_Ch_type) > 1)
412 const auto& __ctyp = std::use_facet<ctype<_Ch_type>>(_M_locale);
413 const char __c = __ctyp.narrow(__ch,
'\0');
418 const char __c =
static_cast<char>(__ch);
419 const char __max_digit = __radix == 8 ?
'7' :
'9';
420 if (
'0' <= __c && __c <= __max_digit)
449 #pragma GCC diagnostic pop
451 template<
typename _Bi_iter,
typename _Alloc>
452 template<
typename _Out_iter>
456 const match_results<_Bi_iter, _Alloc>::char_type* __fmt_first,
457 const match_results<_Bi_iter, _Alloc>::char_type* __fmt_last,
460 __glibcxx_assert( ready() );
464 __fctyp(use_facet<__ctype_type>(__traits.
getloc()));
466 auto __output = [&](
size_t __idx)
468 auto& __sub = (*this)[__idx];
470 __out = std::copy(__sub.first, __sub.second, __out);
475 bool __escaping =
false;
476 for (; __fmt_first != __fmt_last; __fmt_first++)
481 if (__fctyp.is(__ctype_type::digit, *__fmt_first))
482 __output(__traits.
value(*__fmt_first, 10));
484 *__out++ = *__fmt_first;
487 if (*__fmt_first ==
'\\')
492 if (*__fmt_first ==
'&')
497 *__out++ = *__fmt_first;
506 auto __next = std::find(__fmt_first, __fmt_last,
'$');
507 if (__next == __fmt_last)
510 __out = std::copy(__fmt_first, __next, __out);
512 auto __eat = [&](
char __ch) ->
bool
522 if (++__next == __fmt_last)
530 auto& __sub = _M_prefix();
532 __out = std::copy(__sub.first, __sub.second, __out);
534 else if (__eat(
'\''))
536 auto& __sub = _M_suffix();
538 __out = std::copy(__sub.first, __sub.second, __out);
540 else if (__fctyp.is(__ctype_type::digit, *__next))
542 long __num = __traits.
value(*__next, 10);
543 if (++__next != __fmt_last
544 && __fctyp.is(__ctype_type::digit, *__next))
547 __num += __traits.
value(*__next++, 10);
549 if (0 <= __num &&
size_t(__num) < this->
size())
554 __fmt_first = __next;
556 __out = std::copy(__fmt_first, __fmt_last, __out);
561 template<
typename _Out_iter,
typename _Bi_iter,
562 typename _Rx_traits,
typename _Ch_type>
564 __regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
565 const basic_regex<_Ch_type, _Rx_traits>& __e,
566 const _Ch_type* __fmt,
size_t __len,
569 typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT;
570 _IterT __i(__first, __last, __e, __flags);
575 __out = std::copy(__first, __last, __out);
579 sub_match<_Bi_iter> __last;
580 for (; __i != __end; ++__i)
583 __out = std::copy(__i->prefix().first, __i->prefix().second,
585 __out = __i->format(__out, __fmt, __fmt + __len, __flags);
586 __last = __i->suffix();
591 __out = std::copy(__last.first, __last.second, __out);
596 template<
typename _Bi_iter,
603 if (_M_pregex ==
nullptr && __rhs._M_pregex ==
nullptr)
605 return _M_pregex == __rhs._M_pregex
606 && _M_begin == __rhs._M_begin
607 && _M_end == __rhs._M_end
608 && _M_flags == __rhs._M_flags
609 && _M_match[0] == __rhs._M_match[0];
612 template<
typename _Bi_iter,
625 if (_M_match[0].matched)
627 auto __start = _M_match[0].second;
628 auto __prefix_first = _M_match[0].second;
629 if (_M_match[0].first == _M_match[0].second)
631 if (__start == _M_end)
643 __glibcxx_assert(_M_match[0].matched);
644 auto& __prefix = _M_match._M_prefix();
645 __prefix.first = __prefix_first;
646 __prefix.matched = __prefix.first != __prefix.second;
648 _M_match._M_begin = _M_begin;
656 if (
regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
658 __glibcxx_assert(_M_match[0].matched);
659 auto& __prefix = _M_match._M_prefix();
660 __prefix.first = __prefix_first;
661 __prefix.matched = __prefix.first != __prefix.second;
663 _M_match._M_begin = _M_begin;
671 template<
typename _Bi_iter,
678 _M_position = __rhs._M_position;
679 _M_subs = __rhs._M_subs;
681 _M_suffix = __rhs._M_suffix;
682 _M_has_m1 = __rhs._M_has_m1;
683 _M_normalize_result();
687 template<
typename _Bi_iter,
694 if (_M_end_of_seq() && __rhs._M_end_of_seq())
696 if (_M_suffix.matched && __rhs._M_suffix.matched
697 && _M_suffix == __rhs._M_suffix)
699 if (_M_end_of_seq() || _M_suffix.matched
700 || __rhs._M_end_of_seq() || __rhs._M_suffix.matched)
702 return _M_position == __rhs._M_position
703 && _M_n == __rhs._M_n
704 && _M_subs == __rhs._M_subs;
707 template<
typename _Bi_iter,
715 if (_M_suffix.matched)
717 else if (_M_n + 1 < _M_subs.size())
720 _M_result = &_M_current_match();
727 _M_result = &_M_current_match();
728 else if (_M_has_m1 && __prev->
suffix().length() != 0)
730 _M_suffix.matched =
true;
731 _M_suffix.first = __prev->
suffix().first;
732 _M_suffix.second = __prev->
suffix().second;
733 _M_result = &_M_suffix;
741 template<
typename _Bi_iter,
746 _M_init(_Bi_iter __a, _Bi_iter __b)
749 for (
auto __it : _M_subs)
755 if (_M_position != _Position())
756 _M_result = &_M_current_match();
759 _M_suffix.matched =
true;
760 _M_suffix.first = __a;
761 _M_suffix.second = __b;
762 _M_result = &_M_suffix;
768 _GLIBCXX_END_NAMESPACE_VERSION