31namespace std _GLIBCXX_VISIBILITY(default)
33_GLIBCXX_BEGIN_NAMESPACE_VERSION
35#pragma GCC diagnostic push
36#pragma GCC diagnostic ignored "-Wc++17-extensions"
39 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
40 bool _Executor<_BiIter, _Alloc, _TraitsT>::
43 if (_M_search_from_first())
48 while (_M_begin != _M_end)
51 if (_M_search_from_first())
57 enum _ExecutorFrameOpcode :
unsigned char
60 _S_fopcode_fallback_next,
61 _S_fopcode_rep_once_more,
62 _S_fopcode_fallback_rep_once_more,
63 _S_fopcode_posix_alternative,
65 _S_fopcode_restore_cur_results,
66 _S_fopcode_restore_rep_count,
67 _S_fopcode_decrement_rep_count,
70#pragma GCC diagnostic push
71#pragma GCC diagnostic ignored "-Wpedantic"
72 struct _ExecutorFrameBase
74 _ExecutorFrameBase(_ExecutorFrameOpcode __op, _StateIdT __i)
75 : _M_op(__op), _M_state_id(__i)
78 _ExecutorFrameOpcode _M_op;
80 unsigned char _M_byte0 = 0;
82 unsigned char _M_count : 2;
85 unsigned char _M_subexpr_end : 1;
86 unsigned char _M_matched : 1;
89 unsigned char _M_bytes[6];
90 _StateIdT _M_state_id;
92#pragma GCC diagnostic pop
94 template<
typename _BiIter,
bool _Trivial >
95 struct _ExecutorFrame : _ExecutorFrameBase
97 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i)
98 : _ExecutorFrameBase(__op, __i)
101 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i, _BiIter __p)
102 : _ExecutorFrameBase(__op, __i), _M_pos(__p)
105 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i,
long __v)
106 : _ExecutorFrameBase(__op, __i), _M_val(__v)
111 _BiIter _M_pos = _BiIter();
117 template<
typename _BiIter>
118 struct _ExecutorFrame<_BiIter, true> : _ExecutorFrameBase
120 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i)
121 : _ExecutorFrameBase(__op, __i)
124 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i, _BiIter __p)
125 : _ExecutorFrameBase(__op, __i), _M_pos(__p)
128 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i,
long __v)
129 : _ExecutorFrameBase(__op, __i), _M_val(__v)
161 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
162 bool _Executor<_BiIter, _Alloc, _TraitsT>::
163 _M_main_dfs(_Match_mode __match_mode)
166 *_M_get_sol_pos() = _BiIter();
167 _M_cur_results = _M_results;
168 _M_dfs<_Search_mode::_Dfs>(__match_mode, _M_start);
191 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
192 bool _Executor<_BiIter, _Alloc, _TraitsT>::
193 _M_maybe_start_match(_StateIdT __i,
size_t __depth)
200 if (__depth > _M_nfa.size())
204 if (__i == _S_invalid_state_id)
207 const auto& __state = _M_nfa[__i];
208 switch (__state._M_opcode())
210 case _S_opcode_match:
211 return __state._M_matches(*_M_current);
213 case _S_opcode_accept:
217 case _S_opcode_subexpr_begin:
218 case _S_opcode_subexpr_end:
219 case _S_opcode_dummy:
223 return _M_maybe_start_match(__state._M_next, __depth + 1);
225 case _S_opcode_line_begin_assertion:
230 && _M_maybe_start_match(__state._M_next, __depth + 1);
232 case _S_opcode_line_end_assertion:
236 && _M_maybe_start_match(__state._M_next, __depth + 1);
238 case _S_opcode_word_boundary:
242 return _M_word_boundary() == !__state._M_neg
243 && _M_maybe_start_match(__state._M_next, __depth + 1);
245 case _S_opcode_alternative:
249 return _M_maybe_start_match(__state._M_alt, __depth + 1)
250 || _M_maybe_start_match(__state._M_next, __depth + 1);
252 case _S_opcode_repeat:
257 return _M_maybe_start_match(__state._M_alt, __depth + 1)
258 || _M_maybe_start_match(__state._M_next, __depth + 1);
260 case _S_opcode_backref:
261 case _S_opcode_subexpr_lookahead:
289 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
290 bool _Executor<_BiIter, _Alloc, _TraitsT>::
291 _M_main_bfs(_Match_mode __match_mode)
293 _M_match_queue.emplace_back(_M_start, _M_results);
298 if (_M_match_queue.empty())
300 std::fill_n(_M_visited_states, _M_nfa.size(),
false);
301 auto __old_queue =
std::move(_M_match_queue);
302 auto __alloc = _M_cur_results.get_allocator();
303 for (
auto& __task : __old_queue)
305 _M_cur_results = _ResultsVec(
std::move(__task.second), __alloc);
306 _M_dfs<_Search_mode::_Bfs>(__match_mode, __task.first);
308 if (__match_mode == _Match_mode::_Prefix)
310 if (_M_current == _M_end)
314 if (__match_mode == _Match_mode::_Exact)
316 _M_match_queue.clear();
321 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
322 bool _Executor<_BiIter, _Alloc, _TraitsT>::
323 _M_lookahead(_StateIdT __next)
328 _ResultsVec __what(_M_cur_results);
329 _Executor __sub(_M_current, _M_end, __what, _M_re, _M_flags,
330 bool(_M_search_mode));
331 __sub._M_start = __next;
332 if (__sub._M_search_from_first())
334 for (
size_t __i = 0; __i < __what.size(); __i++)
335 if (__what[__i].matched)
336 _M_cur_results[__i] = __what[__i];
354 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
355 _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
356 _M_rep_once_more(_Match_mode, _StateIdT __i)
358 const auto& __state = _M_nfa[__i];
359 auto& __rep_count = _M_rep_count[__i];
360 if (__rep_count.second == 0 || __rep_count.first != _M_current)
362 _M_frames.emplace_back(_S_fopcode_restore_rep_count,
363 __i, __rep_count.first);
364 _M_frames.back()._M_count = __rep_count.second;
365 __rep_count.first = _M_current;
366 __rep_count.second = 1;
367 return __state._M_alt;
371 if (__rep_count.second < 2)
373 __rep_count.second++;
374 _M_frames.emplace_back(_S_fopcode_decrement_rep_count, __i);
375 return __state._M_alt;
378 return _S_invalid_state_id;
384 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
386 [[__gnu__::__always_inline__]]
388 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
389 _M_match_simple_repeat_body(_StateIdT __next, _StateIdT __repeat)
391 if (__next == _S_invalid_state_id)
392 return _S_invalid_state_id;
394 const auto& __state = _M_nfa[__next];
395 if (__state._M_opcode() != _S_opcode_match
396 || __state._M_next != __repeat)
399 if (_M_current == _M_end || !__state._M_matches(*_M_current))
400 return _S_invalid_state_id;
410 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
411 template<_Search_mode __search_mode>
413 [[__gnu__::__always_inline__]]
415 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
416 _M_handle_repeat(_Match_mode __match_mode, _StateIdT __i)
418 const auto& __state = _M_nfa[__i];
422 if constexpr (__search_mode == _Search_mode::_Dfs)
424 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
427 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
428 _StateIdT __next = _M_rep_once_more(__match_mode, __i);
429 if constexpr (__search_mode == _Search_mode::_Dfs)
430 return _M_match_simple_repeat_body(__next, __i);
436 if constexpr (__search_mode == _Search_mode::_Dfs)
439 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i,
441 return __state._M_next;
453 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i);
454 return __state._M_next;
458 return _S_invalid_state_id;
461 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
462 template<_Search_mode __search_mode>
464 [[__gnu__::__always_inline__]]
466 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
467 _M_handle_subexpr_begin(_Match_mode, _StateIdT __i)
469 const auto& __state = _M_nfa[__i];
470 auto& __res = _M_cur_results[__state._M_subexpr];
471 if (_M_nfa._M_has_backref
472 || __state._M_subexpr != 0
473 || __search_mode != _Search_mode::_Dfs)
474 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
475 static_cast<_StateIdT
>(__state._M_subexpr),
477 __res.first = _M_current;
478 return __state._M_next;
481 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
482 template<_Search_mode __search_mode>
484 [[__gnu__::__always_inline__]]
486 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
487 _M_handle_subexpr_end(_Match_mode, _StateIdT __i)
489 const auto& __state = _M_nfa[__i];
490 auto& __res = _M_cur_results[__state._M_subexpr];
491 if (_M_nfa._M_has_backref
492 || __state._M_subexpr != 0
493 || __search_mode != _Search_mode::_Dfs)
495 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
496 static_cast<_StateIdT
>(__state._M_subexpr),
498 _M_frames.back()._M_subexpr_end =
true;
499 _M_frames.back()._M_matched = __res.matched;
502 __res.second = _M_current;
503 __res.matched =
true;
504 return __state._M_next;
507 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
508 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
509 _M_handle_line_begin_assertion(_Match_mode, _StateIdT __i)
511 const auto& __state = _M_nfa[__i];
513 return __state._M_next;
514 return _S_invalid_state_id;
517 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
518 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
519 _M_handle_line_end_assertion(_Match_mode, _StateIdT __i)
521 const auto& __state = _M_nfa[__i];
523 return __state._M_next;
524 return _S_invalid_state_id;
527 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
528 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
529 _M_handle_word_boundary(_Match_mode, _StateIdT __i)
531 const auto& __state = _M_nfa[__i];
532 if (_M_word_boundary() == !__state._M_neg)
533 return __state._M_next;
534 return _S_invalid_state_id;
539 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
540 _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
541 _M_handle_subexpr_lookahead(_Match_mode, _StateIdT __i)
543 const auto& __state = _M_nfa[__i];
544 if (_M_lookahead(__state._M_alt) == !__state._M_neg)
545 return __state._M_next;
546 return _S_invalid_state_id;
549 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
550 template<_Search_mode __search_mode>
552 [[__gnu__::__always_inline__]]
554 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
555 _M_handle_match(_Match_mode, _StateIdT __i)
557 const auto& __state = _M_nfa[__i];
558 if (_M_current == _M_end)
559 return _S_invalid_state_id;
560 if constexpr (__search_mode == _Search_mode::_Dfs)
562 if (__state._M_matches(*_M_current))
565 return __state._M_next;
569 if (__state._M_matches(*_M_current))
570 _M_match_queue.emplace_back(__state._M_next, _M_cur_results);
572 return _S_invalid_state_id;
575 template<
typename _BiIter,
typename _TraitsT>
576 struct _Backref_matcher
578 _Backref_matcher(
bool ,
const _TraitsT& __traits)
579 : _M_traits(__traits) { }
582 _M_apply(_BiIter __expected_begin,
583 _BiIter __expected_end, _BiIter __actual_begin,
584 _BiIter __actual_end)
586 return _M_traits.transform(__expected_begin, __expected_end)
587 == _M_traits.transform(__actual_begin, __actual_end);
590 const _TraitsT& _M_traits;
593 template<
typename _BiIter,
typename _CharT>
594 struct _Backref_matcher<_BiIter, std::regex_traits<_CharT>>
596 using _TraitsT = std::regex_traits<_CharT>;
597 _Backref_matcher(
bool __icase,
const _TraitsT& __traits)
598 : _M_icase(__icase), _M_traits(__traits) { }
601 _M_apply(_BiIter __expected_begin,
602 _BiIter __expected_end, _BiIter __actual_begin,
603 _BiIter __actual_end)
606 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
607 __actual_begin, __actual_end);
608 typedef std::ctype<_CharT> __ctype_type;
610 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
611 __actual_begin, __actual_end,
612 [
this, &__fctyp](_CharT __lhs, _CharT __rhs)
614 return __fctyp.tolower(__lhs)
615 == __fctyp.tolower(__rhs);
620 const _TraitsT& _M_traits;
627 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
628 _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
629 _M_handle_backref(_Match_mode, _StateIdT __i)
631 __glibcxx_assert(_M_search_mode == _Search_mode::_Dfs);
633 const auto& __state = _M_nfa[__i];
634 auto& __submatch = _M_cur_results[__state._M_backref_index];
635 if (!__submatch.matched)
636 return _S_invalid_state_id;
637 auto __last = _M_current;
638 for (
auto __tmp = __submatch.first;
639 __last != _M_end && __tmp != __submatch.second;
642 if (_Backref_matcher<_BiIter, _TraitsT>(
644 _M_re._M_automaton->_M_traits)._M_apply(
645 __submatch.first, __submatch.second, _M_current, __last))
648 return __state._M_next;
651 return _S_invalid_state_id;
654 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
655 template<_Search_mode __search_mode>
657 [[__gnu__::__always_inline__]]
659 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
660 _M_handle_accept(_Match_mode __match_mode, _StateIdT)
662 if constexpr (__search_mode == _Search_mode::_Dfs)
664 __glibcxx_assert(!_M_has_sol);
665 if (__match_mode == _Match_mode::_Exact)
666 _M_has_sol = _M_current == _M_end;
669 if (_M_current == _M_begin
675 _M_results = _M_cur_results;
678 __glibcxx_assert(_M_get_sol_pos());
686 if (*_M_get_sol_pos() == _BiIter()
690 *_M_get_sol_pos() = _M_current;
691 _M_results = _M_cur_results;
698 if (_M_current == _M_begin
700 return _S_invalid_state_id;
701 if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end)
705 _M_results = _M_cur_results;
708 return _S_invalid_state_id;
711 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
713 [[__gnu__::__always_inline__]]
715 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
716 _M_handle_alternative(_Match_mode, _StateIdT __i)
718 const auto& __state = _M_nfa[__i];
723 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
725 return __state._M_alt;
731 _M_frames.emplace_back(_S_fopcode_posix_alternative, __state._M_next,
733 return __state._M_alt;
737 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
738 template<_Search_mode __search_mode>
740 [[__gnu__::__always_inline__]]
742 inline _StateIdT _Executor<_BiIter, _Alloc, _TraitsT>::
743 _M_node(_Match_mode __match_mode, _StateIdT __i)
747 if constexpr (__search_mode == _Search_mode::_Bfs)
749 return _S_invalid_state_id;
751 _StateIdT __next = _S_invalid_state_id;
752 switch (_M_nfa[__i]._M_opcode())
754 case _S_opcode_repeat:
755 __next = _M_handle_repeat<__search_mode>(__match_mode, __i);
break;
756 case _S_opcode_subexpr_begin:
757 __next = _M_handle_subexpr_begin<__search_mode>(__match_mode, __i);
759 case _S_opcode_subexpr_end:
760 __next = _M_handle_subexpr_end<__search_mode>(__match_mode, __i);
762 case _S_opcode_line_begin_assertion:
763 __next = _M_handle_line_begin_assertion(__match_mode, __i);
break;
764 case _S_opcode_line_end_assertion:
765 __next = _M_handle_line_end_assertion(__match_mode, __i);
break;
766 case _S_opcode_word_boundary:
767 __next = _M_handle_word_boundary(__match_mode, __i);
break;
768 case _S_opcode_subexpr_lookahead:
769 __next = _M_handle_subexpr_lookahead(__match_mode, __i);
break;
770 case _S_opcode_match:
771 __next = _M_handle_match<__search_mode>(__match_mode, __i);
break;
772 case _S_opcode_backref:
773 if constexpr (__search_mode == _Search_mode::_Dfs)
774 __next = _M_handle_backref(__match_mode, __i);
776 __builtin_unreachable();
778 case _S_opcode_accept:
779 __next = _M_handle_accept<__search_mode>(__match_mode, __i);
break;
780 case _S_opcode_alternative:
781 __next = _M_handle_alternative(__match_mode, __i);
break;
783 __glibcxx_assert(
false);
788 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
789 template<_Search_mode __search_mode>
790 void _Executor<_BiIter, _Alloc, _TraitsT>::
791 _M_dfs(_Match_mode __match_mode, _StateIdT __start)
793 _StateIdT __next = __start;
800 while (__next != _S_invalid_state_id)
801 __next = _M_node<__search_mode>(__match_mode, __next);
803 if (_M_frames.empty())
806 _ExecutorFrame<_BiIter> __frame =
std::move(_M_frames.back());
807 _M_frames.pop_back();
809 switch (__frame._M_op)
811 case _S_fopcode_fallback_next:
814 if constexpr (__search_mode == _Search_mode::_Dfs)
815 _M_current = __frame._M_pos;
817 case _S_fopcode_next:
818 __next = __frame._M_state_id;
821 case _S_fopcode_fallback_rep_once_more:
824 if constexpr (__search_mode == _Search_mode::_Dfs)
825 _M_current = __frame._M_pos;
827 case _S_fopcode_rep_once_more:
828 __next = _M_rep_once_more(__match_mode, __frame._M_state_id);
831 case _S_fopcode_posix_alternative:
832 _M_frames.emplace_back(_S_fopcode_merge_sol, 0, _M_has_sol);
833 __next = __frame._M_state_id;
834 if constexpr (__search_mode == _Search_mode::_Dfs)
835 _M_current = __frame._M_pos;
839 case _S_fopcode_merge_sol:
840 _M_has_sol |= __frame._M_val;
843 case _S_fopcode_restore_cur_results:
844 if (!__frame._M_subexpr_end)
845 _M_cur_results[__frame._M_state_id].first = __frame._M_pos;
848 _M_cur_results[__frame._M_state_id].second = __frame._M_pos;
849 _M_cur_results[__frame._M_state_id].matched = __frame._M_matched;
853 case _S_fopcode_restore_rep_count:
854 _M_rep_count[__frame._M_state_id].first = __frame._M_pos;
855 _M_rep_count[__frame._M_state_id].second = __frame._M_count;
858 case _S_fopcode_decrement_rep_count:
859 _M_rep_count[__frame._M_state_id].second--;
866 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
867 bool _Executor<_BiIter, _Alloc, _TraitsT>::
868 _M_word_boundary()
const
875 bool __left_is_word =
false;
876 if (_M_current != _M_begin
879 auto __prev = _M_current;
880 if (_M_is_word(*std::prev(__prev)))
881 __left_is_word =
true;
883 bool __right_is_word =
884 _M_current != _M_end && _M_is_word(*_M_current);
886 return __left_is_word != __right_is_word;
889#pragma GCC diagnostic pop
891_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