31 namespace std _GLIBCXX_VISIBILITY(default)
33 _GLIBCXX_BEGIN_NAMESPACE_VERSION
35 #pragma GCC diagnostic push 36 #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr 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" // anon struct 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(__match_mode, _M_start);
194 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
195 bool _Executor<_BiIter, _Alloc, _TraitsT>::
196 _M_main_bfs(_Match_mode __match_mode)
198 _M_match_queue.emplace_back(_M_start, _M_results);
203 if (_M_match_queue.empty())
205 std::fill_n(_M_visited_states, _M_nfa.size(),
false);
206 auto __old_queue =
std::move(_M_match_queue);
207 auto __alloc = _M_cur_results.get_allocator();
208 for (
auto& __task : __old_queue)
210 _M_cur_results = _ResultsVec(
std::move(__task.second), __alloc);
211 _M_dfs(__match_mode, __task.first);
213 if (__match_mode == _Match_mode::_Prefix)
215 if (_M_current == _M_end)
219 if (__match_mode == _Match_mode::_Exact)
221 _M_match_queue.clear();
226 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
227 bool _Executor<_BiIter, _Alloc, _TraitsT>::
228 _M_lookahead(_StateIdT __next)
233 _ResultsVec __what(_M_cur_results);
234 _Executor __sub(_M_current, _M_end, __what, _M_re, _M_flags,
235 bool(_M_search_mode));
236 __sub._M_start = __next;
237 if (__sub._M_search_from_first())
239 for (
size_t __i = 0; __i < __what.size(); __i++)
240 if (__what[__i].matched)
241 _M_cur_results[__i] = __what[__i];
253 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
254 void _Executor<_BiIter, _Alloc, _TraitsT>::
255 _M_rep_once_more(_Match_mode, _StateIdT __i)
257 const auto& __state = _M_nfa[__i];
258 auto& __rep_count = _M_rep_count[__i];
259 if (__rep_count.second == 0 || __rep_count.first != _M_current)
261 _M_frames.emplace_back(_S_fopcode_restore_rep_count,
262 __i, __rep_count.first);
263 _M_frames.back()._M_count = __rep_count.second;
264 __rep_count.first = _M_current;
265 __rep_count.second = 1;
266 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
270 if (__rep_count.second < 2)
272 __rep_count.second++;
273 _M_frames.emplace_back(_S_fopcode_decrement_rep_count, __i);
274 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
283 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
284 void _Executor<_BiIter, _Alloc, _TraitsT>::
285 _M_handle_repeat(_Match_mode, _StateIdT __i)
287 const auto& __state = _M_nfa[__i];
291 if (_M_search_mode == _Search_mode::_DFS)
293 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
296 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
297 _M_frames.emplace_back(_S_fopcode_rep_once_more, __i);
301 if (_M_search_mode == _Search_mode::_DFS)
304 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i,
306 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
318 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i);
319 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
325 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
326 void _Executor<_BiIter, _Alloc, _TraitsT>::
327 _M_handle_subexpr_begin(_Match_mode, _StateIdT __i)
329 const auto& __state = _M_nfa[__i];
330 auto& __res = _M_cur_results[__state._M_subexpr];
331 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
332 static_cast<_StateIdT>(__state._M_subexpr),
334 __res.first = _M_current;
335 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
338 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
339 void _Executor<_BiIter, _Alloc, _TraitsT>::
340 _M_handle_subexpr_end(_Match_mode, _StateIdT __i)
342 const auto& __state = _M_nfa[__i];
343 auto& __res = _M_cur_results[__state._M_subexpr];
344 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
345 static_cast<_StateIdT>(__state._M_subexpr),
347 _M_frames.back()._M_subexpr_end =
true;
348 _M_frames.back()._M_matched = __res.matched;
349 __res.second = _M_current;
350 __res.matched =
true;
351 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
354 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
355 inline void _Executor<_BiIter, _Alloc, _TraitsT>::
356 _M_handle_line_begin_assertion(_Match_mode, _StateIdT __i)
358 const auto& __state = _M_nfa[__i];
360 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
363 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
364 inline void _Executor<_BiIter, _Alloc, _TraitsT>::
365 _M_handle_line_end_assertion(_Match_mode, _StateIdT __i)
367 const auto& __state = _M_nfa[__i];
369 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
372 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
373 inline void _Executor<_BiIter, _Alloc, _TraitsT>::
374 _M_handle_word_boundary(_Match_mode, _StateIdT __i)
376 const auto& __state = _M_nfa[__i];
377 if (_M_word_boundary() == !__state._M_neg)
378 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
383 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
384 void _Executor<_BiIter, _Alloc, _TraitsT>::
385 _M_handle_subexpr_lookahead(_Match_mode, _StateIdT __i)
387 const auto& __state = _M_nfa[__i];
388 if (_M_lookahead(__state._M_alt) == !__state._M_neg)
389 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
392 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
393 void _Executor<_BiIter, _Alloc, _TraitsT>::
394 _M_handle_match(_Match_mode, _StateIdT __i)
396 const auto& __state = _M_nfa[__i];
397 if (_M_current == _M_end)
399 if (_M_search_mode == _Search_mode::_DFS)
401 if (__state._M_matches(*_M_current))
404 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
408 if (__state._M_matches(*_M_current))
409 _M_match_queue.emplace_back(__state._M_next, _M_cur_results);
412 template<
typename _BiIter,
typename _TraitsT>
413 struct _Backref_matcher
415 _Backref_matcher(
bool ,
const _TraitsT& __traits)
416 : _M_traits(__traits) { }
419 _M_apply(_BiIter __expected_begin,
420 _BiIter __expected_end, _BiIter __actual_begin,
421 _BiIter __actual_end)
423 return _M_traits.transform(__expected_begin, __expected_end)
424 == _M_traits.transform(__actual_begin, __actual_end);
427 const _TraitsT& _M_traits;
430 template<
typename _BiIter,
typename _CharT>
431 struct _Backref_matcher<_BiIter,
std::regex_traits<_CharT>>
434 _Backref_matcher(
bool __icase,
const _TraitsT& __traits)
435 : _M_icase(__icase), _M_traits(__traits) { }
438 _M_apply(_BiIter __expected_begin,
439 _BiIter __expected_end, _BiIter __actual_begin,
440 _BiIter __actual_end)
443 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
444 __actual_begin, __actual_end);
446 const auto& __fctyp = use_facet<__ctype_type>(_M_traits.getloc());
447 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
448 __actual_begin, __actual_end,
449 [
this, &__fctyp](_CharT __lhs, _CharT __rhs)
451 return __fctyp.tolower(__lhs)
452 == __fctyp.tolower(__rhs);
457 const _TraitsT& _M_traits;
464 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
465 void _Executor<_BiIter, _Alloc, _TraitsT>::
466 _M_handle_backref(_Match_mode, _StateIdT __i)
468 __glibcxx_assert(_M_search_mode == _Search_mode::_DFS);
470 const auto& __state = _M_nfa[__i];
471 auto& __submatch = _M_cur_results[__state._M_backref_index];
472 if (!__submatch.matched)
474 auto __last = _M_current;
475 for (
auto __tmp = __submatch.first;
476 __last != _M_end && __tmp != __submatch.second;
479 if (_Backref_matcher<_BiIter, _TraitsT>(
481 _M_re._M_automaton->_M_traits)._M_apply(
482 __submatch.first, __submatch.second, _M_current, __last))
485 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
489 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
490 void _Executor<_BiIter, _Alloc, _TraitsT>::
491 _M_handle_accept(_Match_mode __match_mode, _StateIdT)
493 if (_M_search_mode == _Search_mode::_DFS)
495 __glibcxx_assert(!_M_has_sol);
496 if (__match_mode == _Match_mode::_Exact)
497 _M_has_sol = _M_current == _M_end;
500 if (_M_current == _M_begin
506 _M_results = _M_cur_results;
509 __glibcxx_assert(_M_get_sol_pos());
517 if (*_M_get_sol_pos() == _BiIter()
521 *_M_get_sol_pos() = _M_current;
522 _M_results = _M_cur_results;
529 if (_M_current == _M_begin
530 && (_M_flags & regex_constants::match_not_null))
532 if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end)
536 _M_results = _M_cur_results;
541 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
542 void _Executor<_BiIter, _Alloc, _TraitsT>::
543 _M_handle_alternative(_Match_mode, _StateIdT __i)
545 const auto& __state = _M_nfa[__i];
550 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
552 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
558 _M_frames.emplace_back(_S_fopcode_posix_alternative, __state._M_next,
560 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
564 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
566 [[__gnu__::__always_inline__]]
568 inline void _Executor<_BiIter, _Alloc, _TraitsT>::
569 _M_node(_Match_mode __match_mode, _StateIdT __i)
574 switch (_M_nfa[__i]._M_opcode())
576 case _S_opcode_repeat:
577 _M_handle_repeat(__match_mode, __i);
break;
578 case _S_opcode_subexpr_begin:
579 _M_handle_subexpr_begin(__match_mode, __i);
break;
580 case _S_opcode_subexpr_end:
581 _M_handle_subexpr_end(__match_mode, __i);
break;
582 case _S_opcode_line_begin_assertion:
583 _M_handle_line_begin_assertion(__match_mode, __i);
break;
584 case _S_opcode_line_end_assertion:
585 _M_handle_line_end_assertion(__match_mode, __i);
break;
586 case _S_opcode_word_boundary:
587 _M_handle_word_boundary(__match_mode, __i);
break;
588 case _S_opcode_subexpr_lookahead:
589 _M_handle_subexpr_lookahead(__match_mode, __i);
break;
590 case _S_opcode_match:
591 _M_handle_match(__match_mode, __i);
break;
592 case _S_opcode_backref:
593 if (_M_search_mode == _Search_mode::_DFS)
594 _M_handle_backref(__match_mode, __i);
596 __builtin_unreachable();
598 case _S_opcode_accept:
599 _M_handle_accept(__match_mode, __i);
break;
600 case _S_opcode_alternative:
601 _M_handle_alternative(__match_mode, __i);
break;
603 __glibcxx_assert(
false);
607 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
608 void _Executor<_BiIter, _Alloc, _TraitsT>::
609 _M_dfs(_Match_mode __match_mode, _StateIdT __start)
611 const bool __dfs_mode = (_M_search_mode == _Search_mode::_DFS);
612 _M_frames.emplace_back(_S_fopcode_next, __start);
614 while (!_M_frames.empty())
616 _ExecutorFrame<_BiIter> __frame =
std::move(_M_frames.back());
617 _M_frames.pop_back();
619 switch (__frame._M_op)
621 case _S_fopcode_fallback_next:
625 _M_current = __frame._M_pos;
627 case _S_fopcode_next:
628 _M_node(__match_mode, __frame._M_state_id);
631 case _S_fopcode_fallback_rep_once_more:
635 _M_current = __frame._M_pos;
637 case _S_fopcode_rep_once_more:
638 _M_rep_once_more(__match_mode, __frame._M_state_id);
641 case _S_fopcode_posix_alternative:
642 _M_frames.emplace_back(_S_fopcode_merge_sol, 0, _M_has_sol);
643 _M_frames.emplace_back(_S_fopcode_next, __frame._M_state_id);
645 _M_current = __frame._M_pos;
649 case _S_fopcode_merge_sol:
650 _M_has_sol |= __frame._M_val;
653 case _S_fopcode_restore_cur_results:
654 if (!__frame._M_subexpr_end)
655 _M_cur_results[__frame._M_state_id].first = __frame._M_pos;
658 _M_cur_results[__frame._M_state_id].second = __frame._M_pos;
659 _M_cur_results[__frame._M_state_id].matched = __frame._M_matched;
663 case _S_fopcode_restore_rep_count:
664 _M_rep_count[__frame._M_state_id].first = __frame._M_pos;
665 _M_rep_count[__frame._M_state_id].second = __frame._M_count;
668 case _S_fopcode_decrement_rep_count:
669 _M_rep_count[__frame._M_state_id].second--;
676 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT>
677 bool _Executor<_BiIter, _Alloc, _TraitsT>::
678 _M_word_boundary()
const 685 bool __left_is_word =
false;
686 if (_M_current != _M_begin
689 auto __prev = _M_current;
690 if (_M_is_word(*std::prev(__prev)))
691 __left_is_word =
true;
693 bool __right_is_word =
694 _M_current != _M_end && _M_is_word(*_M_current);
696 return __left_is_word != __right_is_word;
699 #pragma GCC diagnostic pop 701 _GLIBCXX_END_NAMESPACE_VERSION
constexpr match_flag_type match_prev_avail
constexpr syntax_option_type icase
constexpr match_flag_type match_not_bow
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
constexpr match_flag_type match_not_null
constexpr _OI fill_n(_OI __first, _Size __n, const _Tp &__value)
Fills the range [first,first+n) with copies of value.
ISO C++ entities toplevel namespace is std.
constexpr syntax_option_type ECMAScript
Primary class template ctype facet.This template class defines classification and conversion function...
constexpr match_flag_type match_not_eow
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr match_flag_type match_continuous
Describes aspects of a regular expression.