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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>>
433 using _TraitsT = 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);
445 typedef std::ctype<_CharT> __ctype_type;
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>
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>
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
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>
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__]]
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>
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>
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 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.