31namespace std _GLIBCXX_VISIBILITY(default)
33_GLIBCXX_BEGIN_NAMESPACE_VERSION
35#pragma GCC diagnostic push
36#pragma GCC diagnostic ignored "-Wc++17-extensions"
39_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2)
40 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
45 if (_M_search_from_first())
50 while (_M_begin != _M_end)
53 if (_M_search_from_first())
59 enum _ExecutorFrameOpcode :
unsigned char
62 _S_fopcode_fallback_next,
63 _S_fopcode_rep_once_more,
64 _S_fopcode_fallback_rep_once_more,
65 _S_fopcode_posix_alternative,
67 _S_fopcode_restore_cur_results,
68 _S_fopcode_restore_rep_count,
69 _S_fopcode_decrement_rep_count,
72#pragma GCC diagnostic push
73#pragma GCC diagnostic ignored "-Wpedantic"
74 struct _ExecutorFrameBase
76 _ExecutorFrameBase(_ExecutorFrameOpcode __op, _StateIdT __i)
77 : _M_op(__op), _M_state_id(__i)
80 _ExecutorFrameOpcode _M_op;
82 unsigned char _M_byte0;
84 unsigned char _M_count : 2;
87 unsigned char _M_end : 1;
88 unsigned char _M_matched : 1;
91 unsigned char _M_bytes[6];
92 _StateIdT _M_state_id;
94#pragma GCC diagnostic pop
96 template<
typename _BiIter,
bool _Trivial >
97 struct _ExecutorFrame : _ExecutorFrameBase
99 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i)
100 : _ExecutorFrameBase(__op, __i)
103 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i, _BiIter __p)
104 : _ExecutorFrameBase(__op, __i), _M_pos(__p)
107 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i,
long __v)
108 : _ExecutorFrameBase(__op, __i), _M_val(__v)
113 _BiIter _M_pos = _BiIter();
119 template<
typename _BiIter>
120 struct _ExecutorFrame<_BiIter, true> : _ExecutorFrameBase
122 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i)
123 : _ExecutorFrameBase(__op, __i)
126 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i, _BiIter __p)
127 : _ExecutorFrameBase(__op, __i), _M_pos(__p)
130 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i,
long __v)
131 : _ExecutorFrameBase(__op, __i), _M_val(__v)
163 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
169 *_M_states._M_get_sol_pos() = _BiIter();
170 _M_cur_results = _M_results;
171 _M_dfs(__match_mode, _M_states._M_start);
197 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
202 _M_states._M_queue(_M_states._M_start, _M_results);
207 if (_M_states._M_match_queue.empty())
209 std::fill_n(_M_states._M_visited_states, _M_nfa.size(),
false);
210 auto __old_queue =
std::move(_M_states._M_match_queue);
211 auto __alloc = _M_cur_results.get_allocator();
212 for (
auto& __task : __old_queue)
214 _M_cur_results = _ResultsVec(
std::move(__task.second), __alloc);
215 _M_dfs(__match_mode, __task.first);
217 if (__match_mode == _Match_mode::_Prefix)
219 if (_M_current == _M_end)
223 if (__match_mode == _Match_mode::_Exact)
225 _M_states._M_match_queue.clear();
230 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
238 _ResultsVec __what(_M_cur_results);
239 _Executor __sub(_M_current, _M_end, __what, _M_re, _M_flags);
240 __sub._M_states._M_start = __next;
241 if (__sub._M_search_from_first())
243 for (
size_t __i = 0; __i < __what.size(); __i++)
244 if (__what[__i].matched)
245 _M_cur_results[__i] = __what[__i];
257 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
262 const auto& __state = _M_nfa[__i];
263 auto& __rep_count = _M_rep_count[__i];
264 if (__rep_count.second == 0 || __rep_count.first != _M_current)
266 _M_frames.emplace_back(_S_fopcode_restore_rep_count,
267 __i, __rep_count.first);
268 _M_frames.back()._M_count = __rep_count.second;
269 __rep_count.first = _M_current;
270 __rep_count.second = 1;
271 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
275 if (__rep_count.second < 2)
277 __rep_count.second++;
278 _M_frames.emplace_back(_S_fopcode_decrement_rep_count, __i);
279 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
288 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
293 const auto& __state = _M_nfa[__i];
297 if constexpr (__dfs_mode)
299 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
302 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
303 _M_frames.emplace_back(_S_fopcode_rep_once_more, __i);
307 if constexpr (__dfs_mode)
310 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i,
312 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
324 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i);
325 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
331 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
336 const auto& __state = _M_nfa[__i];
337 auto& __res = _M_cur_results[__state._M_subexpr];
338 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
339 static_cast<_StateIdT
>(__state._M_subexpr),
341 _M_frames.back()._M_end =
false;
342 __res.first = _M_current;
343 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
346 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
351 const auto& __state = _M_nfa[__i];
352 auto& __res = _M_cur_results[__state._M_subexpr];
353 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
354 static_cast<_StateIdT
>(__state._M_subexpr),
356 _M_frames.back()._M_end =
true;
357 _M_frames.back()._M_matched = __res.matched;
358 __res.second = _M_current;
359 __res.matched =
true;
360 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
363 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
368 const auto& __state = _M_nfa[__i];
370 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
373 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
378 const auto& __state = _M_nfa[__i];
380 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
383 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
388 const auto& __state = _M_nfa[__i];
389 if (_M_word_boundary() == !__state._M_neg)
390 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
395 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
400 const auto& __state = _M_nfa[__i];
401 if (_M_lookahead(__state._M_alt) == !__state._M_neg)
402 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
405 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
410 const auto& __state = _M_nfa[__i];
411 if (_M_current == _M_end)
413 if constexpr (__dfs_mode)
415 if (__state._M_matches(*_M_current))
418 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
422 if (__state._M_matches(*_M_current))
423 _M_states._M_queue(__state._M_next, _M_cur_results);
426 template<
typename _BiIter,
typename _TraitsT>
427 struct _Backref_matcher
429 _Backref_matcher(
bool ,
const _TraitsT& __traits)
430 : _M_traits(__traits) { }
433 _M_apply(_BiIter __expected_begin,
434 _BiIter __expected_end, _BiIter __actual_begin,
435 _BiIter __actual_end)
437 return _M_traits.transform(__expected_begin, __expected_end)
438 == _M_traits.transform(__actual_begin, __actual_end);
441 const _TraitsT& _M_traits;
444 template<
typename _BiIter,
typename _CharT>
445 struct _Backref_matcher<_BiIter, std::regex_traits<_CharT>>
447 using _TraitsT = std::regex_traits<_CharT>;
448 _Backref_matcher(
bool __icase,
const _TraitsT& __traits)
449 : _M_icase(__icase), _M_traits(__traits) { }
452 _M_apply(_BiIter __expected_begin,
453 _BiIter __expected_end, _BiIter __actual_begin,
454 _BiIter __actual_end)
457 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
458 __actual_begin, __actual_end);
459 typedef std::ctype<_CharT> __ctype_type;
461 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
462 __actual_begin, __actual_end,
463 [
this, &__fctyp](_CharT __lhs, _CharT __rhs)
465 return __fctyp.tolower(__lhs)
466 == __fctyp.tolower(__rhs);
471 const _TraitsT& _M_traits;
478 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
483 static_assert(__dfs_mode,
"this should never be instantiated");
485 const auto& __state = _M_nfa[__i];
486 auto& __submatch = _M_cur_results[__state._M_backref_index];
487 if (!__submatch.matched)
489 auto __last = _M_current;
490 for (
auto __tmp = __submatch.first;
491 __last != _M_end && __tmp != __submatch.second;
494 if (_Backref_matcher<_BiIter, _TraitsT>(
496 _M_re._M_automaton->_M_traits)._M_apply(
497 __submatch.first, __submatch.second, _M_current, __last))
500 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
504 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
509 if constexpr (__dfs_mode)
511 __glibcxx_assert(!_M_has_sol);
512 if (__match_mode == _Match_mode::_Exact)
513 _M_has_sol = _M_current == _M_end;
516 if (_M_current == _M_begin
522 _M_results = _M_cur_results;
525 __glibcxx_assert(_M_states._M_get_sol_pos());
533 if (*_M_states._M_get_sol_pos() == _BiIter()
535 *_M_states._M_get_sol_pos())
538 *_M_states._M_get_sol_pos() = _M_current;
539 _M_results = _M_cur_results;
546 if (_M_current == _M_begin
549 if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end)
553 _M_results = _M_cur_results;
558 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
563 const auto& __state = _M_nfa[__i];
568 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
570 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
576 _M_frames.emplace_back(_S_fopcode_posix_alternative, __state._M_next,
578 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
582 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
585 [[__gnu__::__always_inline__]]
588 _M_node(_Match_mode __match_mode, _StateIdT __i)
590 if (_M_states._M_visited(__i))
593 switch (_M_nfa[__i]._M_opcode())
595 case _S_opcode_repeat:
596 _M_handle_repeat(__match_mode, __i);
break;
597 case _S_opcode_subexpr_begin:
598 _M_handle_subexpr_begin(__match_mode, __i);
break;
599 case _S_opcode_subexpr_end:
600 _M_handle_subexpr_end(__match_mode, __i);
break;
601 case _S_opcode_line_begin_assertion:
602 _M_handle_line_begin_assertion(__match_mode, __i);
break;
603 case _S_opcode_line_end_assertion:
604 _M_handle_line_end_assertion(__match_mode, __i);
break;
605 case _S_opcode_word_boundary:
606 _M_handle_word_boundary(__match_mode, __i);
break;
607 case _S_opcode_subexpr_lookahead:
608 _M_handle_subexpr_lookahead(__match_mode, __i);
break;
609 case _S_opcode_match:
610 _M_handle_match(__match_mode, __i);
break;
611 case _S_opcode_backref:
612 if constexpr (__dfs_mode)
613 _M_handle_backref(__match_mode, __i);
615 __builtin_unreachable();
617 case _S_opcode_accept:
618 _M_handle_accept(__match_mode, __i);
break;
619 case _S_opcode_alternative:
620 _M_handle_alternative(__match_mode, __i);
break;
622 __glibcxx_assert(
false);
626 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
629 _M_dfs(_Match_mode __match_mode, _StateIdT __start)
631 _M_frames.emplace_back(_S_fopcode_next, __start);
633 while (!_M_frames.empty())
635 _ExecutorFrame<_BiIter> __frame =
std::move(_M_frames.back());
636 _M_frames.pop_back();
638 switch (__frame._M_op)
640 case _S_fopcode_fallback_next:
643 if constexpr (__dfs_mode)
644 _M_current = __frame._M_pos;
646 case _S_fopcode_next:
647 _M_node(__match_mode, __frame._M_state_id);
650 case _S_fopcode_fallback_rep_once_more:
653 if constexpr (__dfs_mode)
654 _M_current = __frame._M_pos;
656 case _S_fopcode_rep_once_more:
657 _M_rep_once_more(__match_mode, __frame._M_state_id);
660 case _S_fopcode_posix_alternative:
661 _M_frames.emplace_back(_S_fopcode_merge_sol, 0, _M_has_sol);
662 _M_frames.emplace_back(_S_fopcode_next, __frame._M_state_id);
663 if constexpr (__dfs_mode)
664 _M_current = __frame._M_pos;
668 case _S_fopcode_merge_sol:
669 _M_has_sol |= __frame._M_val;
672 case _S_fopcode_restore_cur_results:
674 _M_cur_results[__frame._M_state_id].first = __frame._M_pos;
677 _M_cur_results[__frame._M_state_id].second = __frame._M_pos;
678 _M_cur_results[__frame._M_state_id].matched = __frame._M_matched;
682 case _S_fopcode_restore_rep_count:
683 _M_rep_count[__frame._M_state_id].first = __frame._M_pos;
684 _M_rep_count[__frame._M_state_id].second = __frame._M_count;
687 case _S_fopcode_decrement_rep_count:
688 _M_rep_count[__frame._M_state_id].second--;
695 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
705 bool __left_is_word =
false;
706 if (_M_current != _M_begin
709 auto __prev = _M_current;
710 if (_M_is_word(*std::prev(__prev)))
711 __left_is_word =
true;
713 bool __right_is_word =
714 _M_current != _M_end && _M_is_word(*_M_current);
716 return __left_is_word != __right_is_word;
718_GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
720#pragma GCC diagnostic pop
722_GLIBCXX_END_NAMESPACE_VERSION
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
const _Facet & use_facet(const locale &__loc)
Return a facet.
ISO C++ entities toplevel namespace is std.
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
Implementation details not part of the namespace std interface.
constexpr match_flag_type match_not_bow
constexpr syntax_option_type ECMAScript
constexpr match_flag_type match_continuous
constexpr syntax_option_type icase
constexpr match_flag_type match_prev_avail
constexpr match_flag_type match_not_eow
constexpr match_flag_type match_not_null
Takes a regex and an input string and does the matching.