From 0c958d70f1e18d65dea06d9ec181126f92bdfde1 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 12 Aug 2025 15:01:08 -0700 Subject: [PATCH 1/4] ` == static_cast<_Elem>\(static_cast\((\w+)\)\)` => ` == static_cast($1)` --- stl/inc/regex | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 3753efd523d..03976455580 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -4343,11 +4343,9 @@ template bool _Parser2<_FwdIt, _Elem, _RxTraits>::_Is_esc(_FwdIt _Ch0) const { // assumes _Ch0 != _End return _Mode == _Lex_mode::_Default && ++_Ch0 != _End && ((!(_L_flags & _L_nex_grp) - && (*_Ch0 == static_cast<_Elem>(static_cast(_Meta_lpar)) - || *_Ch0 == static_cast<_Elem>(static_cast(_Meta_rpar)))) + && (*_Ch0 == static_cast(_Meta_lpar) || *_Ch0 == static_cast(_Meta_rpar))) || (!(_L_flags & _L_nex_rep) - && (*_Ch0 == static_cast<_Elem>(static_cast(_Meta_lbr)) - || *_Ch0 == static_cast<_Elem>(static_cast(_Meta_rbr))))); + && (*_Ch0 == static_cast(_Meta_lbr) || *_Ch0 == static_cast(_Meta_rbr)))); } template @@ -4418,7 +4416,7 @@ void _Parser2<_FwdIt, _Elem, _RxTraits>::_Trans() { // map character to meta-cha { // check if $ is special _FwdIt _Next = _Pat; if ((_L_flags & _L_anch_rstr) && ++_Next != _End) { - const bool _Escaped = *_Next == static_cast<_Elem>(static_cast(_Meta_esc)) && _Is_esc(_Next); + const bool _Escaped = *_Next == static_cast(_Meta_esc) && _Is_esc(_Next); if (_Escaped) { ++_Next; } @@ -4430,9 +4428,9 @@ void _Parser2<_FwdIt, _Elem, _RxTraits>::_Trans() { // map character to meta-cha const _Elem _Ch = *_Next; const bool _Is_end_of_alternative = - ((_L_flags & _L_alt_nl) && _Ch == static_cast<_Elem>(static_cast(_Meta_nl)) + ((_L_flags & _L_alt_nl) && _Ch == static_cast(_Meta_nl) && _Disj_count == 0) // dollar followed by newline '\n' for alternation - || (_Escaped && _Ch == static_cast<_Elem>(static_cast(_Meta_rpar)) + || (_Escaped && _Ch == static_cast(_Meta_rpar) && _Disj_count != 0); // dollar followed by (escaped) right parenthesis ')' closing a group if (!_Is_end_of_alternative) { @@ -4466,7 +4464,7 @@ void _Parser2<_FwdIt, _Elem, _RxTraits>::_Trans() { // map character to meta-cha template void _Parser2<_FwdIt, _Elem, _RxTraits>::_Next() { // advance to next input character if (_Pat != _End) { // advance - if (*_Pat == static_cast<_Elem>(static_cast(_Meta_esc)) && _Is_esc(_Pat)) { + if (*_Pat == static_cast(_Meta_esc) && _Is_esc(_Pat)) { ++_Pat; } @@ -4620,8 +4618,7 @@ bool _Parser2<_FwdIt, _Elem, _RxTraits>::_CharacterClassEscape(bool _Addit) { // template _Prs_ret _Parser2<_FwdIt, _Elem, _RxTraits>::_ClassEscape() { // check for class escape - if ((_L_flags & _L_esc_bsp) - && _Char == static_cast<_Elem>(static_cast(_Esc_ctrl_b))) { // handle backspace escape + if ((_L_flags & _L_esc_bsp) && _Char == static_cast(_Esc_ctrl_b)) { // handle backspace escape _Next(); _Unescaped_char = static_cast<_Elem>(static_cast(_Meta_bsp)); return _Prs_chr; @@ -4870,15 +4867,15 @@ bool _Parser2<_FwdIt, _Elem, _RxTraits>::_IdentityEscape(bool _In_character_clas template bool _Parser2<_FwdIt, _Elem, _RxTraits>::_Do_ffn(_Elem _Ch) { // check for limited file format escape characters - if (_Ch == static_cast<_Elem>(static_cast(_Esc_ctrl_f))) { + if (_Ch == static_cast(_Esc_ctrl_f)) { _Val = '\f'; - } else if (_Ch == static_cast<_Elem>(static_cast(_Esc_ctrl_n))) { + } else if (_Ch == static_cast(_Esc_ctrl_n)) { _Val = '\n'; - } else if (_Ch == static_cast<_Elem>(static_cast(_Esc_ctrl_r))) { + } else if (_Ch == static_cast(_Esc_ctrl_r)) { _Val = '\r'; - } else if (_Ch == static_cast<_Elem>(static_cast(_Esc_ctrl_t))) { + } else if (_Ch == static_cast(_Esc_ctrl_t)) { _Val = '\t'; - } else if (_Ch == static_cast<_Elem>(static_cast(_Esc_ctrl_v))) { + } else if (_Ch == static_cast(_Esc_ctrl_v)) { _Val = '\v'; } else { return false; @@ -4889,9 +4886,9 @@ bool _Parser2<_FwdIt, _Elem, _RxTraits>::_Do_ffn(_Elem _Ch) { // check for limit template bool _Parser2<_FwdIt, _Elem, _RxTraits>::_Do_ffnx(_Elem _Ch) { // check for the remaining file format escape characters - if (_Ch == static_cast<_Elem>(static_cast(_Esc_ctrl_a))) { + if (_Ch == static_cast(_Esc_ctrl_a)) { _Val = '\a'; - } else if (_Ch == static_cast<_Elem>(static_cast(_Esc_ctrl_b))) { + } else if (_Ch == static_cast(_Esc_ctrl_b)) { _Val = '\b'; } else { return false; @@ -4909,8 +4906,7 @@ bool _Parser2<_FwdIt, _Elem, _RxTraits>::_CharacterEscape(bool _In_character_cla if ((_L_flags & _L_esc_ffn && _Do_ffn(_Char)) || (_L_flags & _L_esc_ffnx && _Do_ffnx(_Char))) { _Next(); - } else if (_Char == static_cast<_Elem>(static_cast(_Esc_ctrl)) - && (_L_flags & _L_esc_ctrl)) { // handle control escape sequence + } else if (_Char == static_cast(_Esc_ctrl) && (_L_flags & _L_esc_ctrl)) { // handle control escape sequence _Next(); using _Char_traits_type = typename _RxTraits::string_type::traits_type; @@ -4923,12 +4919,10 @@ bool _Parser2<_FwdIt, _Elem, _RxTraits>::_CharacterEscape(bool _In_character_cla _Val = static_cast(_Char) % 32; _Next(); - } else if (_Char == static_cast<_Elem>(static_cast(_Esc_hex)) - && (_L_flags & _L_esc_hex)) { // handle hexadecimal escape sequence + } else if (_Char == static_cast(_Esc_hex) && (_L_flags & _L_esc_hex)) { // handle hexadecimal escape sequence _Next(); _HexDigits(2); - } else if (_Char == static_cast<_Elem>(static_cast(_Esc_uni)) - && (_L_flags & _L_esc_uni)) { // handle Unicode escape sequence + } else if (_Char == static_cast(_Esc_uni) && (_L_flags & _L_esc_uni)) { // handle Unicode escape sequence _Next(); _HexDigits(4); } else if ((_L_flags & _L_esc_oct) && _OctalDigits()) { // handle octal escape sequence @@ -5044,13 +5038,11 @@ bool _Parser2<_FwdIt, _Elem, _RxTraits>::_Alternative() { // check for valid alt _Next(); } else if (_Mchar == _Meta_esc) { // check for valid escape sequence _Next(); - if ((_L_flags & _L_asrt_wrd) - && _Char == static_cast<_Elem>(static_cast(_Esc_word))) { // add word assert + if ((_L_flags & _L_asrt_wrd) && _Char == static_cast(_Esc_word)) { // add word assert _Nfa._Add_wbound(); _Next(); _Quant = false; - } else if ((_L_flags & _L_asrt_wrd) - && _Char == static_cast<_Elem>(static_cast(_Esc_not_word))) { // add not-word assert + } else if ((_L_flags & _L_asrt_wrd) && _Char == static_cast(_Esc_not_word)) { // add not-word assert _Nfa._Add_wbound(); _Nfa._Negate(); _Next(); From 5fd081c6fb9f6a99c6eb556a93d5b05b16329abf Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 12 Aug 2025 15:02:34 -0700 Subject: [PATCH 2/4] ` == static_cast<_Elem>\(('\w')\)` => ` == $1` --- stl/inc/regex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 03976455580..afe28f3bc98 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -4595,10 +4595,10 @@ bool _Parser2<_FwdIt, _Elem, _RxTraits>::_CharacterClassEscape(bool _Addit) { // return false; } - auto _Kind = (_Char == static_cast<_Elem>('W') ? _Rx_char_class_kind::_Negated_w - : _Char == static_cast<_Elem>('S') ? _Rx_char_class_kind::_Negated_s - : _Char == static_cast<_Elem>('D') ? _Rx_char_class_kind::_Negated_d - : _Rx_char_class_kind::_Positive); + auto _Kind = (_Char == 'W' ? _Rx_char_class_kind::_Negated_w + : _Char == 'S' ? _Rx_char_class_kind::_Negated_s + : _Char == 'D' ? _Rx_char_class_kind::_Negated_d + : _Rx_char_class_kind::_Positive); if (_Addit) { _Nfa._Add_class(); From 47351a25768a6a60b65c9efef1453c4678fa9c3c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 12 Aug 2025 22:45:31 -0700 Subject: [PATCH 3/4] Support heterogeneous comparisons with char. --- .../test.cpp | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp b/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp index c9409259f64..e98ca7384d7 100644 --- a/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp +++ b/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp @@ -101,7 +101,29 @@ class test_regex_traits { rx_traits inner; }; -enum class signed_wchar_enum : short {}; +namespace signed_wchar_ns { + enum class signed_wchar_enum : short {}; + + bool operator==(const signed_wchar_enum left, const char right) { + return static_cast(left) == right; + } + +#if !_HAS_CXX20 + bool operator!=(const signed_wchar_enum left, const char right) { + return static_cast(left) != right; + } + + bool operator==(const char left, const signed_wchar_enum right) { + return left == static_cast(right); + } + + bool operator!=(const char left, const signed_wchar_enum right) { + return left != static_cast(right); + } +#endif // !_HAS_CXX20 +} // namespace signed_wchar_ns + +using signed_wchar_ns::signed_wchar_enum; class wrapped_wchar { public: @@ -132,14 +154,32 @@ class wrapped_wchar { return lhs.character == rhs.character; } + friend bool operator==(const wrapped_wchar& lhs, const char rhs) { + return lhs.character == static_cast(rhs); + } + +#if !_HAS_CXX20 + friend bool operator!=(const wrapped_wchar& lhs, const wrapped_wchar& rhs) { + return lhs.character != rhs.character; + } + + friend bool operator!=(const wrapped_wchar& lhs, const char rhs) { + return lhs.character != static_cast(rhs); + } + + friend bool operator==(const char lhs, const wrapped_wchar& rhs) { + return static_cast(lhs) == rhs.character; + } + + friend bool operator!=(const char lhs, const wrapped_wchar& rhs) { + return static_cast(lhs) != rhs.character; + } +#endif // !_HAS_CXX20 + private: wchar_t character; }; -bool operator!=(const wrapped_wchar& lhs, const wrapped_wchar& rhs) { - return !(lhs == rhs); -} - template struct custom_char_traits { using char_type = Elem; From 0c47754e50af380d8be9c3d24eefcc2ec1f3835e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 13 Aug 2025 12:20:52 -0700 Subject: [PATCH 4/4] Centralize operators with more cromulent casts. --- .../GH_000995_regex_custom_char_types/test.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp b/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp index e98ca7384d7..d453f5283e1 100644 --- a/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp +++ b/tests/std/tests/GH_000995_regex_custom_char_types/test.cpp @@ -104,21 +104,21 @@ class test_regex_traits { namespace signed_wchar_ns { enum class signed_wchar_enum : short {}; - bool operator==(const signed_wchar_enum left, const char right) { - return static_cast(left) == right; + bool operator==(const signed_wchar_enum swe, const char ch) { + return static_cast(swe) == static_cast(ch); } #if !_HAS_CXX20 - bool operator!=(const signed_wchar_enum left, const char right) { - return static_cast(left) != right; + bool operator!=(const signed_wchar_enum swe, const char ch) { + return !(swe == ch); } - bool operator==(const char left, const signed_wchar_enum right) { - return left == static_cast(right); + bool operator==(const char ch, const signed_wchar_enum swe) { + return swe == ch; } - bool operator!=(const char left, const signed_wchar_enum right) { - return left != static_cast(right); + bool operator!=(const char ch, const signed_wchar_enum swe) { + return !(swe == ch); } #endif // !_HAS_CXX20 } // namespace signed_wchar_ns