@@ -1668,7 +1668,7 @@ void __end_marked_subexpression<_CharT>::__exec(__state& __s) const {
16681668
16691669// __back_ref
16701670
1671- template <class _CharT >
1671+ template <class _CharT , bool _UnmatchedAlwaysSucceed >
16721672class __back_ref : public __owns_one_state <_CharT> {
16731673 typedef __owns_one_state<_CharT> base;
16741674
@@ -1682,8 +1682,8 @@ public:
16821682 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec (__state&) const ;
16831683};
16841684
1685- template <class _CharT >
1686- void __back_ref<_CharT>::__exec(__state& __s) const {
1685+ template <class _CharT , bool _UnmatchedAlwaysSucceed >
1686+ void __back_ref<_CharT, _UnmatchedAlwaysSucceed >::__exec(__state& __s) const {
16871687 if (__mexp_ > __s.__sub_matches_ .size ())
16881688 std::__throw_regex_error<regex_constants::error_backref>();
16891689 sub_match<const _CharT*>& __sm = __s.__sub_matches_ [__mexp_ - 1 ];
@@ -1697,6 +1697,9 @@ void __back_ref<_CharT>::__exec(__state& __s) const {
16971697 __s.__do_ = __state::__reject;
16981698 __s.__node_ = nullptr ;
16991699 }
1700+ } else if constexpr (_UnmatchedAlwaysSucceed) {
1701+ __s.__do_ = __state::__accept_but_not_consume;
1702+ __s.__node_ = this ->first ();;
17001703 } else {
17011704 __s.__do_ = __state::__reject;
17021705 __s.__node_ = nullptr ;
@@ -1705,7 +1708,7 @@ void __back_ref<_CharT>::__exec(__state& __s) const {
17051708
17061709// __back_ref_icase
17071710
1708- template <class _CharT , class _Traits >
1711+ template <class _CharT , class _Traits , bool _UnmatchedAlwaysSucceed >
17091712class __back_ref_icase : public __owns_one_state <_CharT> {
17101713 typedef __owns_one_state<_CharT> base;
17111714
@@ -1721,8 +1724,8 @@ public:
17211724 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec (__state&) const ;
17221725};
17231726
1724- template <class _CharT , class _Traits >
1725- void __back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const {
1727+ template <class _CharT , class _Traits , bool _UnmatchedAlwaysSucceed >
1728+ void __back_ref_icase<_CharT, _Traits, _UnmatchedAlwaysSucceed >::__exec(__state& __s) const {
17261729 sub_match<const _CharT*>& __sm = __s.__sub_matches_ [__mexp_ - 1 ];
17271730 if (__sm.matched ) {
17281731 ptrdiff_t __len = __sm.second - __sm.first ;
@@ -1739,6 +1742,11 @@ void __back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const {
17391742 __s.__node_ = nullptr ;
17401743 }
17411744 } else {
1745+ if constexpr (_UnmatchedAlwaysSucceed) {
1746+ __s.__do_ = __state::__accept_but_not_consume;
1747+ __s.__node_ = this ->first ();
1748+ return ;
1749+ }
17421750 __not_equal:
17431751 __s.__do_ = __state::__reject;
17441752 __s.__node_ = nullptr ;
@@ -1747,7 +1755,7 @@ void __back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const {
17471755
17481756// __back_ref_collate
17491757
1750- template <class _CharT , class _Traits >
1758+ template <class _CharT , class _Traits , bool _UnmatchedAlwaysSucceed >
17511759class __back_ref_collate : public __owns_one_state <_CharT> {
17521760 typedef __owns_one_state<_CharT> base;
17531761
@@ -1763,8 +1771,8 @@ public:
17631771 _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec (__state&) const ;
17641772};
17651773
1766- template <class _CharT , class _Traits >
1767- void __back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const {
1774+ template <class _CharT , class _Traits , bool _UnmatchedAlwaysSucceed >
1775+ void __back_ref_collate<_CharT, _Traits, _UnmatchedAlwaysSucceed >::__exec(__state& __s) const {
17681776 sub_match<const _CharT*>& __sm = __s.__sub_matches_ [__mexp_ - 1 ];
17691777 if (__sm.matched ) {
17701778 ptrdiff_t __len = __sm.second - __sm.first ;
@@ -1781,6 +1789,11 @@ void __back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const {
17811789 __s.__node_ = nullptr ;
17821790 }
17831791 } else {
1792+ if constexpr (_UnmatchedAlwaysSucceed) {
1793+ __s.__do_ = __state::__accept_but_not_consume;
1794+ __s.__node_ = this ->first ();
1795+ return ;
1796+ }
17841797 __not_equal:
17851798 __s.__do_ = __state::__reject;
17861799 __s.__node_ = nullptr ;
@@ -2565,6 +2578,7 @@ private:
25652578 bool __greedy = true );
25662579 __bracket_expression<_CharT, _Traits>* __start_matching_list (bool __negate);
25672580 void __push_char (value_type __c);
2581+ template <bool _UnmatchedAlwaysSucceed = false >
25682582 void __push_back_ref (int __i);
25692583 void __push_alternation (__owns_one_state<_CharT>* __sa, __owns_one_state<_CharT>* __sb);
25702584 void __push_begin_marked_subexpression ();
@@ -3807,7 +3821,7 @@ basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first, _
38073821 }
38083822 if (__v == 0 || __v > mark_count ())
38093823 std::__throw_regex_error<regex_constants::error_backref>();
3810- __push_back_ref (__v);
3824+ __push_back_ref< true > (__v);
38113825 }
38123826 }
38133827 return __first;
@@ -4149,13 +4163,14 @@ void basic_regex<_CharT, _Traits>::__push_word_boundary(bool __invert) {
41494163}
41504164
41514165template <class _CharT , class _Traits >
4166+ template <bool _UnmatchedAlwaysSucceed>
41524167void basic_regex<_CharT, _Traits>::__push_back_ref(int __i) {
41534168 if (flags () & icase)
4154- __end_->first () = new __back_ref_icase<_CharT, _Traits>(__traits_, __i, __end_->first ());
4169+ __end_->first () = new __back_ref_icase<_CharT, _Traits, _UnmatchedAlwaysSucceed >(__traits_, __i, __end_->first ());
41554170 else if (flags () & collate)
4156- __end_->first () = new __back_ref_collate<_CharT, _Traits>(__traits_, __i, __end_->first ());
4171+ __end_->first () = new __back_ref_collate<_CharT, _Traits, _UnmatchedAlwaysSucceed >(__traits_, __i, __end_->first ());
41574172 else
4158- __end_->first () = new __back_ref<_CharT>(__i, __end_->first ());
4173+ __end_->first () = new __back_ref<_CharT, _UnmatchedAlwaysSucceed >(__i, __end_->first ());
41594174 __end_ = static_cast <__owns_one_state<_CharT>*>(__end_->first ());
41604175}
41614176
0 commit comments