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 = 0;
84 unsigned char _M_count : 2;
87 unsigned char _M_subexpr_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 __res.first = _M_current;
342 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
345 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
350 const auto& __state = _M_nfa[__i];
351 auto& __res = _M_cur_results[__state._M_subexpr];
352 _M_frames.emplace_back(_S_fopcode_restore_cur_results,
353 static_cast<_StateIdT
>(__state._M_subexpr),
355 _M_frames.back()._M_subexpr_end =
true;
356 _M_frames.back()._M_matched = __res.matched;
357 __res.second = _M_current;
358 __res.matched =
true;
359 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
362 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,
377 const auto& __state = _M_nfa[__i];
379 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
382 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
387 const auto& __state = _M_nfa[__i];
388 if (_M_word_boundary() == !__state._M_neg)
389 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
394 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
399 const auto& __state = _M_nfa[__i];
400 if (_M_lookahead(__state._M_alt) == !__state._M_neg)
401 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
404 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
409 const auto& __state = _M_nfa[__i];
410 if (_M_current == _M_end)
412 if constexpr (__dfs_mode)
414 if (__state._M_matches(*_M_current))
417 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
421 if (__state._M_matches(*_M_current))
422 _M_states._M_queue(__state._M_next, _M_cur_results);
425 template<
typename _BiIter,
typename _TraitsT>
426 struct _Backref_matcher
428 _Backref_matcher(
bool ,
const _TraitsT& __traits)
429 : _M_traits(__traits) { }
432 _M_apply(_BiIter __expected_begin,
433 _BiIter __expected_end, _BiIter __actual_begin,
434 _BiIter __actual_end)
436 return _M_traits.transform(__expected_begin, __expected_end)
437 == _M_traits.transform(__actual_begin, __actual_end);
440 const _TraitsT& _M_traits;
443 template<
typename _BiIter,
typename _CharT>
444 struct _Backref_matcher<_BiIter, std::regex_traits<_CharT>>
446 using _TraitsT = std::regex_traits<_CharT>;
447 _Backref_matcher(
bool __icase,
const _TraitsT& __traits)
448 : _M_icase(__icase), _M_traits(__traits) { }
451 _M_apply(_BiIter __expected_begin,
452 _BiIter __expected_end, _BiIter __actual_begin,
453 _BiIter __actual_end)
456 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
457 __actual_begin, __actual_end);
458 typedef std::ctype<_CharT> __ctype_type;
460 return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end,
461 __actual_begin, __actual_end,
462 [
this, &__fctyp](_CharT __lhs, _CharT __rhs)
464 return __fctyp.tolower(__lhs)
465 == __fctyp.tolower(__rhs);
470 const _TraitsT& _M_traits;
477 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
482 static_assert(__dfs_mode,
"this should never be instantiated");
484 const auto& __state = _M_nfa[__i];
485 auto& __submatch = _M_cur_results[__state._M_backref_index];
486 if (!__submatch.matched)
488 auto __last = _M_current;
489 for (
auto __tmp = __submatch.first;
490 __last != _M_end && __tmp != __submatch.second;
493 if (_Backref_matcher<_BiIter, _TraitsT>(
495 _M_re._M_automaton->_M_traits)._M_apply(
496 __submatch.first, __submatch.second, _M_current, __last))
499 _M_frames.emplace_back(_S_fopcode_next, __state._M_next);
503 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
508 if constexpr (__dfs_mode)
510 __glibcxx_assert(!_M_has_sol);
511 if (__match_mode == _Match_mode::_Exact)
512 _M_has_sol = _M_current == _M_end;
515 if (_M_current == _M_begin
521 _M_results = _M_cur_results;
524 __glibcxx_assert(_M_states._M_get_sol_pos());
532 if (*_M_states._M_get_sol_pos() == _BiIter()
534 *_M_states._M_get_sol_pos())
537 *_M_states._M_get_sol_pos() = _M_current;
538 _M_results = _M_cur_results;
545 if (_M_current == _M_begin
548 if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end)
552 _M_results = _M_cur_results;
557 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
562 const auto& __state = _M_nfa[__i];
567 _M_frames.emplace_back(_S_fopcode_fallback_next, __state._M_next,
569 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
575 _M_frames.emplace_back(_S_fopcode_posix_alternative, __state._M_next,
577 _M_frames.emplace_back(_S_fopcode_next, __state._M_alt);
581 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
584 [[__gnu__::__always_inline__]]
587 _M_node(_Match_mode __match_mode, _StateIdT __i)
589 if (_M_states._M_visited(__i))
592 switch (_M_nfa[__i]._M_opcode())
594 case _S_opcode_repeat:
595 _M_handle_repeat(__match_mode, __i);
break;
596 case _S_opcode_subexpr_begin:
597 _M_handle_subexpr_begin(__match_mode, __i);
break;
598 case _S_opcode_subexpr_end:
599 _M_handle_subexpr_end(__match_mode, __i);
break;
600 case _S_opcode_line_begin_assertion:
601 _M_handle_line_begin_assertion(__match_mode, __i);
break;
602 case _S_opcode_line_end_assertion:
603 _M_handle_line_end_assertion(__match_mode, __i);
break;
604 case _S_opcode_word_boundary:
605 _M_handle_word_boundary(__match_mode, __i);
break;
606 case _S_opcode_subexpr_lookahead:
607 _M_handle_subexpr_lookahead(__match_mode, __i);
break;
608 case _S_opcode_match:
609 _M_handle_match(__match_mode, __i);
break;
610 case _S_opcode_backref:
611 if constexpr (__dfs_mode)
612 _M_handle_backref(__match_mode, __i);
614 __builtin_unreachable();
616 case _S_opcode_accept:
617 _M_handle_accept(__match_mode, __i);
break;
618 case _S_opcode_alternative:
619 _M_handle_alternative(__match_mode, __i);
break;
621 __glibcxx_assert(
false);
625 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
628 _M_dfs(_Match_mode __match_mode, _StateIdT __start)
630 _M_frames.emplace_back(_S_fopcode_next, __start);
632 while (!_M_frames.empty())
634 _ExecutorFrame<_BiIter> __frame =
std::move(_M_frames.back());
635 _M_frames.pop_back();
637 switch (__frame._M_op)
639 case _S_fopcode_fallback_next:
642 if constexpr (__dfs_mode)
643 _M_current = __frame._M_pos;
645 case _S_fopcode_next:
646 _M_node(__match_mode, __frame._M_state_id);
649 case _S_fopcode_fallback_rep_once_more:
652 if constexpr (__dfs_mode)
653 _M_current = __frame._M_pos;
655 case _S_fopcode_rep_once_more:
656 _M_rep_once_more(__match_mode, __frame._M_state_id);
659 case _S_fopcode_posix_alternative:
660 _M_frames.emplace_back(_S_fopcode_merge_sol, 0, _M_has_sol);
661 _M_frames.emplace_back(_S_fopcode_next, __frame._M_state_id);
662 if constexpr (__dfs_mode)
663 _M_current = __frame._M_pos;
667 case _S_fopcode_merge_sol:
668 _M_has_sol |= __frame._M_val;
671 case _S_fopcode_restore_cur_results:
672 if (!__frame._M_subexpr_end)
673 _M_cur_results[__frame._M_state_id].first = __frame._M_pos;
676 _M_cur_results[__frame._M_state_id].second = __frame._M_pos;
677 _M_cur_results[__frame._M_state_id].matched = __frame._M_matched;
681 case _S_fopcode_restore_rep_count:
682 _M_rep_count[__frame._M_state_id].first = __frame._M_pos;
683 _M_rep_count[__frame._M_state_id].second = __frame._M_count;
686 case _S_fopcode_decrement_rep_count:
687 _M_rep_count[__frame._M_state_id].second--;
694 template<
typename _BiIter,
typename _Alloc,
typename _TraitsT,
704 bool __left_is_word =
false;
705 if (_M_current != _M_begin
708 auto __prev = _M_current;
709 if (_M_is_word(*std::prev(__prev)))
710 __left_is_word =
true;
712 bool __right_is_word =
713 _M_current != _M_end && _M_is_word(*_M_current);
715 return __left_is_word != __right_is_word;
717_GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
719#pragma GCC diagnostic pop
721_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.