@@ -1677,6 +1677,8 @@ public:
16771677enum class _Rx_unwind_ops {
16781678 _After_assert = _N_end + 1,
16791679 _After_neg_assert,
1680+ _Disjunction_eval_alt_on_failure,
1681+ _Disjunction_eval_alt_always,
16801682};
16811683
16821684template <class _BidIt>
@@ -1753,7 +1755,7 @@ public:
17531755
17541756 _Matched = false;
17551757
1756- bool _Succeeded = _Match_pat(_Rep);
1758+ bool _Succeeded = _Match_pat(_Rep) || _Matched ;
17571759 _STL_INTERNAL_CHECK(_Frames_count == 0);
17581760
17591761 if (!_Succeeded) {
@@ -1810,7 +1812,6 @@ private:
18101812 void _Increase_stack_usage_count();
18111813 void _Decrease_stack_usage_count();
18121814
1813- bool _Do_if(_Node_if*);
18141815 bool _Do_rep0(_Node_rep*, bool);
18151816 bool _Do_rep(_Node_rep*, bool, int);
18161817 bool _Do_rep_first(_Node_rep*);
@@ -3402,44 +3403,6 @@ void _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Decrease_stack_usage_cou
34023403 }
34033404}
34043405
3405- template <class _BidIt, class _Elem, class _RxTraits, class _It, class _Alloc>
3406- bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_if(_Node_if* _Node) { // apply if node
3407- const size_t _Frame_idx = _Push_frame();
3408-
3409- // look for the first match
3410- for (; _Node; _Node = _Node->_Child) { // process one branch of if
3411- _Tgt_state = _Frames[_Frame_idx]._Match_state; // rewind to where the alternation starts in input
3412- if (_Match_pat(_Node->_Next)) { // try to match this branch
3413- break;
3414- }
3415- }
3416-
3417- // if none of the if branches matched, fail to match
3418- if (!_Node) {
3419- _Pop_frame(_Frame_idx);
3420- return false;
3421- }
3422-
3423- // if we aren't looking for the longest match, that's it
3424- if (!_Longest) {
3425- _Pop_frame(_Frame_idx);
3426- return true;
3427- }
3428-
3429- // see if there is a longer match
3430- for (;;) { // process one branch of if
3431- _Node = _Node->_Child;
3432- if (!_Node) {
3433- break;
3434- }
3435-
3436- _Tgt_state = _Frames[_Frame_idx]._Match_state;
3437- (void) _Match_pat(_Node->_Next);
3438- }
3439- _Pop_frame(_Frame_idx);
3440- return true;
3441- }
3442-
34433406template <class _BidIt, class _Elem, class _RxTraits, class _It, class _Alloc>
34443407bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_rep0(_Node_rep* _Node, bool _Greedy) {
34453408 // apply repetition to loop with no nested if/do
@@ -4175,13 +4138,17 @@ bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
41754138 }
41764139
41774140 case _N_if:
4178- if (!_Do_if(static_cast<_Node_if*>(_Nx))) {
4179- _Failed = true;
4141+ {
4142+ auto _Node = static_cast<_Node_if*>(_Nx);
4143+ if (_Node->_Child) {
4144+ _Push_frame(_Longest ? _Rx_unwind_ops::_Disjunction_eval_alt_always
4145+ : _Rx_unwind_ops::_Disjunction_eval_alt_on_failure,
4146+ _Node->_Child);
4147+ _Increase_stack_usage_count();
4148+ }
4149+ break;
41804150 }
41814151
4182- _Next = nullptr;
4183- break;
4184-
41854152 case _N_endif:
41864153 break;
41874154
@@ -4236,7 +4203,7 @@ bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
42364203 } while (_Nx);
42374204
42384205 while (_Frames_count > _Initial_frames_count && !_Nx) {
4239- const auto& _Frame = _Frames[--_Frames_count];
4206+ auto& _Frame = _Frames[--_Frames_count];
42404207
42414208 switch (_Frame._Code) {
42424209 case _Rx_unwind_ops::_After_assert:
@@ -4261,6 +4228,30 @@ bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
42614228 break;
42624229 }
42634230
4231+ case _Rx_unwind_ops::_Disjunction_eval_alt_on_failure:
4232+ // evaluate next alternative if matching prior alternatives failed
4233+ if (!_Failed) {
4234+ _Decrease_stack_usage_count();
4235+ break;
4236+ }
4237+ _FALLTHROUGH;
4238+
4239+ case _Rx_unwind_ops::_Disjunction_eval_alt_always:
4240+ // evaluate next alternative no matter if matching prior alternatives succeeded
4241+ {
4242+ auto _Node = static_cast<_Node_if*>(_Frame._Node);
4243+ _Nx = _Node->_Next;
4244+ _Tgt_state = _Frame._Match_state;
4245+ _Failed = false;
4246+ if (_Node->_Child) {
4247+ _Frame._Node = _Node->_Child;
4248+ ++_Frames_count;
4249+ } else {
4250+ _Decrease_stack_usage_count();
4251+ }
4252+ break;
4253+ }
4254+
42644255 default:
42654256#if _ITERATOR_DEBUG_LEVEL != 0
42664257 _STL_REPORT_ERROR("internal stack of regex matcher corrupted");
0 commit comments