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 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;
82 unsigned char _M_count : 2;
85 unsigned char _M_end : 1;
86 unsigned char _M_matched : 1;
89 unsigned char _M_bytes[6];
90 _StateIdT _M_state_id;
93 template<
typename _BiIter,
bool _Trivial >
94 struct _ExecutorFrame : _ExecutorFrameBase
96 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i)
97 : _ExecutorFrameBase(__op, __i)
100 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i, _BiIter __p)
101 : _ExecutorFrameBase(__op, __i), _M_pos(__p)
104 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i,
long __v)
105 : _ExecutorFrameBase(__op, __i), _M_val(__v)
110 _BiIter _M_pos = _BiIter();
116 template<
typename _BiIter>
117 struct _ExecutorFrame<_BiIter, true> : _ExecutorFrameBase
119 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i)
120 : _ExecutorFrameBase(__op, __i)
123 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i, _BiIter __p)
124 : _ExecutorFrameBase(__op, __i), _M_pos(__p)
127 _ExecutorFrame(_ExecutorFrameOpcode __op, _StateIdT __i,
long __v)
128 : _ExecutorFrameBase(__op, __i), _M_val(__v)
160 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
166 *_M_states._M_get_sol_pos() = _BiIter();
167 _M_cur_results = _M_results;
168 _M_dfs(__match_mode, _M_states._M_start);
194 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
199 _M_states._M_queue(_M_states._M_start, _M_results);
204 if (_M_states._M_match_queue.empty())
206 std::fill_n(_M_states._M_visited_states, _M_nfa.size(),
false);
207 auto __old_queue =
std::move(_M_states._M_match_queue);
208 auto __alloc = _M_cur_results.get_allocator();
209 for (
auto& __task : __old_queue)
211 _M_cur_results = _ResultsVec(
std::move(__task.second), __alloc);
212 _M_dfs(__match_mode, __task.first);
214 if (__match_mode == _Match_mode::_Prefix)
216 if (_M_current == _M_end)
220 if (__match_mode == _Match_mode::_Exact)
222 _M_states._M_match_queue.clear();
227 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
235 _ResultsVec __what(_M_cur_results);
236 _Executor __sub(_M_current, _M_end, __what, _M_re, _M_flags);
237 __sub._M_states._M_start = __next;
238 if (__sub._M_search_from_first())
240 for (
size_t __i = 0; __i < __what.size(); __i++)
241 if (__what[__i].matched)
242 _M_cur_results[__i] = __what[__i];
254 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
259 const auto& __state = _M_nfa[__i];
260 auto& __rep_count = _M_rep_count[__i];
261 if (__rep_count.second == 0 || __rep_count.first != _M_current)
263 _M_frames.emplace_back(_S_fopcode_restore_rep_count,
264 __i, __rep_count.first);
265 _M_frames.back()._M_count = __rep_count.second;
266 __rep_count.first = _M_current;
267 __rep_count.second = 1;
268 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
272 if (__rep_count.second < 2)
274 __rep_count.second++;
275 _M_frames.emplace_back(_S_fopcode_decrement_rep_count, __i);
276 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
285 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
290 const auto& __state = _M_nfa[__i];
294 if constexpr (__dfs_mode)
296 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
299 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
300 _M_frames.emplace_back(_S_fopcode_rep_once_more, __i);
304 if constexpr (__dfs_mode)
307 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i,
309 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
321 _M_frames.emplace_back(_S_fopcode_fallback_rep_once_more, __i);
322 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
328 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
333 const auto& __state = _M_nfa[__i];
334 auto& __res = _M_cur_results[__state._M_subexpr];
335 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
336 static_cast<_StateIdT
>(__state._M_subexpr),
338 _M_frames.back()._M_end =
false;
339 __res.first = _M_current;
340 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
343 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
348 const auto& __state = _M_nfa[__i];
349 auto& __res = _M_cur_results[__state._M_subexpr];
350 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
351 static_cast<_StateIdT
>(__state._M_subexpr),
353 _M_frames.back()._M_end =
true;
354 _M_frames.back()._M_matched = __res.matched;
355 __res.second = _M_current;
356 __res.matched =
true;
357 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
360 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
365 const auto& __state = _M_nfa[__i];
367 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
370 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
375 const auto& __state = _M_nfa[__i];
377 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
380 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
385 const auto& __state = _M_nfa[__i];
386 if (_M_word_boundary() == !__state._M_neg)
387 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
392 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
397 const auto& __state = _M_nfa[__i];
398 if (_M_lookahead(__state._M_alt) == !__state._M_neg)
399 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
402 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
407 const auto& __state = _M_nfa[__i];
408 if (_M_current == _M_end)
410 if constexpr (__dfs_mode)
412 if (__state._M_matches(*_M_current))
415 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
419 if (__state._M_matches(*_M_current))
420 _M_states._M_queue(__state._M_next, _M_cur_results);
423 template<
typename _BiIter,
typename _TraitsT>
424 struct _Backref_matcher
426 _Backref_matcher(
bool ,
const _TraitsT& __traits)
427 : _M_traits(__traits) { }
430 _M_apply(_BiIter __expected_begin,
431 _BiIter __expected_end, _BiIter __actual_begin,
432 _BiIter __actual_end)
434 return _M_traits.transform(__expected_begin, __expected_end)
435 == _M_traits.transform(__actual_begin, __actual_end);
438 const _TraitsT& _M_traits;
441 template<
typename _BiIter,
typename _CharT>
442 struct _Backref_matcher<_BiIter, std::regex_traits<_CharT>>
444 using _TraitsT = std::regex_traits<_CharT>;
445 _Backref_matcher(
bool __icase,
const _TraitsT& __traits)
446 : _M_icase(__icase), _M_traits(__traits) { }
449 _M_apply(_BiIter __expected_begin,
450 _BiIter __expected_end, _BiIter __actual_begin,
451 _BiIter __actual_end)
454 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
455 __actual_begin, __actual_end);
456 typedef std::ctype<_CharT> __ctype_type;
458 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
459 __actual_begin, __actual_end,
460 [
this, &__fctyp](_CharT __lhs, _CharT __rhs)
462 return __fctyp.tolower(__lhs)
463 == __fctyp.tolower(__rhs);
468 const _TraitsT& _M_traits;
475 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
480 static_assert(__dfs_mode,
"this should never be instantiated");
482 const auto& __state = _M_nfa[__i];
483 auto& __submatch = _M_cur_results[__state._M_backref_index];
484 if (!__submatch.matched)
486 auto __last = _M_current;
487 for (
auto __tmp = __submatch.first;
488 __last != _M_end && __tmp != __submatch.second;
491 if (_Backref_matcher<_BiIter, _TraitsT>(
493 _M_re._M_automaton->_M_traits)._M_apply(
494 __submatch.first, __submatch.second, _M_current, __last))
497 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
501 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
506 if constexpr (__dfs_mode)
508 __glibcxx_assert(!_M_has_sol);
509 if (__match_mode == _Match_mode::_Exact)
510 _M_has_sol = _M_current == _M_end;
513 if (_M_current == _M_begin
519 _M_results = _M_cur_results;
522 __glibcxx_assert(_M_states._M_get_sol_pos());
530 if (*_M_states._M_get_sol_pos() == _BiIter()
532 *_M_states._M_get_sol_pos())
535 *_M_states._M_get_sol_pos() = _M_current;
536 _M_results = _M_cur_results;
543 if (_M_current == _M_begin
546 if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end)
550 _M_results = _M_cur_results;
555 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
560 const auto& __state = _M_nfa[__i];
565 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
567 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
573 _M_frames.emplace_back(_S_fopcode_posix_alternative, __state._M_next,
575 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
579 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
582 [[__gnu__::__always_inline__]]
585 _M_node(_Match_mode __match_mode, _StateIdT __i)
587 if (_M_states._M_visited(__i))
590 switch (_M_nfa[__i]._M_opcode())
592 case _S_opcode_repeat:
593 _M_handle_repeat(__match_mode, __i);
break;
594 case _S_opcode_subexpr_begin:
595 _M_handle_subexpr_begin(__match_mode, __i);
break;
596 case _S_opcode_subexpr_end:
597 _M_handle_subexpr_end(__match_mode, __i);
break;
598 case _S_opcode_line_begin_assertion:
599 _M_handle_line_begin_assertion(__match_mode, __i);
break;
600 case _S_opcode_line_end_assertion:
601 _M_handle_line_end_assertion(__match_mode, __i);
break;
602 case _S_opcode_word_boundary:
603 _M_handle_word_boundary(__match_mode, __i);
break;
604 case _S_opcode_subexpr_lookahead:
605 _M_handle_subexpr_lookahead(__match_mode, __i);
break;
606 case _S_opcode_match:
607 _M_handle_match(__match_mode, __i);
break;
608 case _S_opcode_backref:
609 if constexpr (__dfs_mode)
610 _M_handle_backref(__match_mode, __i);
612 __builtin_unreachable();
614 case _S_opcode_accept:
615 _M_handle_accept(__match_mode, __i);
break;
616 case _S_opcode_alternative:
617 _M_handle_alternative(__match_mode, __i);
break;
619 __glibcxx_assert(
false);
623 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
626 _M_dfs(_Match_mode __match_mode, _StateIdT __start)
628 _M_frames.emplace_back(_S_fopcode_next, __start);
630 while (!_M_frames.empty())
632 _ExecutorFrame<_BiIter> __frame =
std::move(_M_frames.back());
633 _M_frames.pop_back();
635 switch (__frame._M_op)
637 case _S_fopcode_fallback_next:
640 if constexpr (__dfs_mode)
641 _M_current = __frame._M_pos;
643 case _S_fopcode_next:
644 _M_node(__match_mode, __frame._M_state_id);
647 case _S_fopcode_fallback_rep_once_more:
650 if constexpr (__dfs_mode)
651 _M_current = __frame._M_pos;
653 case _S_fopcode_rep_once_more:
654 _M_rep_once_more(__match_mode, __frame._M_state_id);
657 case _S_fopcode_posix_alternative:
658 _M_frames.emplace_back(_S_fopcode_merge_sol, 0, _M_has_sol);
659 _M_frames.emplace_back(_S_fopcode_next, __frame._M_state_id);
660 if constexpr (__dfs_mode)
661 _M_current = __frame._M_pos;
665 case _S_fopcode_merge_sol:
666 _M_has_sol |= __frame._M_val;
669 case _S_fopcode_restore_cur_results:
671 _M_cur_results[__frame._M_state_id].first = __frame._M_pos;
674 _M_cur_results[__frame._M_state_id].second = __frame._M_pos;
675 _M_cur_results[__frame._M_state_id].matched = __frame._M_matched;
679 case _S_fopcode_restore_rep_count:
680 _M_rep_count[__frame._M_state_id].first = __frame._M_pos;
681 _M_rep_count[__frame._M_state_id].second = __frame._M_count;
684 case _S_fopcode_decrement_rep_count:
685 _M_rep_count[__frame._M_state_id].second--;
692 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
702 bool __left_is_word =
false;
703 if (_M_current != _M_begin
706 auto __prev = _M_current;
707 if (_M_is_word(*std::prev(__prev)))
708 __left_is_word =
true;
710 bool __right_is_word =
711 _M_current != _M_end && _M_is_word(*_M_current);
713 return __left_is_word != __right_is_word;
715_GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
717#pragma GCC diagnostic pop
719_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.