From 703982fc2d5ec34ddced3db2af31fefd9106f5bc Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 9 Oct 2024 14:37:50 -0700 Subject: [PATCH 01/10] Replace unnecessarily confusing `break`s with immediate `return`s. Except in `_Traits_find_last_of`, which is being changed by GH 4934. --- stl/inc/__msvc_string_view.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 0f0ba41e20..ba681d267d 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -635,7 +635,7 @@ constexpr size_t _Traits_rfind(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits } if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + return static_cast(-1); // at beginning, no more chance for match } } } @@ -654,7 +654,7 @@ constexpr size_t _Traits_rfind_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_Tra } if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + return static_cast(-1); // at beginning, no more chance for match } } } @@ -882,7 +882,7 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt } if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + return static_cast(-1); // at beginning, no more chance for match } } } else { @@ -892,7 +892,7 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt } if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + return static_cast(-1); // at beginning, no more chance for match } } } @@ -912,7 +912,7 @@ constexpr size_t _Traits_rfind_not_ch(_In_reads_(_Hay_size) const _Traits_ptr_t< } if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + return static_cast(-1); // at beginning, no more chance for match } } } From e2918bb8f833bb502e8de67f46b78ffc366fdc30 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 9 Oct 2024 14:40:46 -0700 Subject: [PATCH 02/10] Add a `return` instead of relying on fall-through. This will simplify the following transformation. --- stl/inc/__msvc_string_view.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index ba681d267d..c6c4f7782f 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -834,6 +834,7 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p return static_cast(_Match_try - _Haystack); // found a match } } + return static_cast(-1); // no match } else { const auto _End = _Haystack + _Hay_size; for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { From e968071f2e5f8e5ef9186d6e7c06b6d8d3f654ad Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 9 Oct 2024 14:45:43 -0700 Subject: [PATCH 03/10] Flip `!_Matches._Mark` tests. Both sides unconditionally return, allowing us to flip them. (One case is a forever loop where the only ways out are returns.) --- stl/inc/__msvc_string_view.hpp | 43 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index c6c4f7782f..bd7b491872 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -822,19 +822,18 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p if (_Start_at < _Hay_size) { // room for match, look for it if constexpr (_Special) { _String_bitmap _Matches; - if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the - // bitmap, fall back to the serial algorithm - return _Traits_find_first_not_of<_Traits, false>( - _Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); - } - - const auto _End = _Haystack + _Hay_size; - for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { - if (!_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match + if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { + const auto _End = _Haystack + _Hay_size; + for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { + if (!_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } } + return static_cast(-1); // no match } - return static_cast(-1); // no match + + // couldn't put one of the characters into the bitmap, fall back to the serial algorithm + return _Traits_find_first_not_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); } else { const auto _End = _Haystack + _Hay_size; for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { @@ -872,20 +871,20 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt if (_Hay_size != 0) { // worth searching, do it if constexpr (_Special) { _String_bitmap _Matches; - if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the - // bitmap, fall back to the serial algorithm - return _Traits_find_last_not_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); - } - - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (!_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (!_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } - if (_Match_try == _Haystack) { - return static_cast(-1); // at beginning, no more chance for match + if (_Match_try == _Haystack) { + return static_cast(-1); // at beginning, no more chance for match + } } } + + // couldn't put one of the characters into the bitmap, fall back to the serial algorithm + return _Traits_find_last_not_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); } else { for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { From d892ca8b1b21e13aa0eec1b1b22872c1488b10c6 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 9 Oct 2024 14:53:36 -0700 Subject: [PATCH 04/10] Transform "call self with `_Special=false`" to fall-through. --- stl/inc/__msvc_string_view.hpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index bd7b491872..147b33924a 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -833,13 +833,12 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p } // couldn't put one of the characters into the bitmap, fall back to the serial algorithm - return _Traits_find_first_not_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); - } else { - const auto _End = _Haystack + _Hay_size; - for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { - if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + } + + const auto _End = _Haystack + _Hay_size; + for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { + if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match } } } @@ -884,16 +883,15 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt } // couldn't put one of the characters into the bitmap, fall back to the serial algorithm - return _Traits_find_last_not_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); - } else { - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + } - if (_Match_try == _Haystack) { - return static_cast(-1); // at beginning, no more chance for match - } + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } + + if (_Match_try == _Haystack) { + return static_cast(-1); // at beginning, no more chance for match } } } From d11acd07a0a384b1c575751864f748e1da13364c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 9 Oct 2024 14:57:17 -0700 Subject: [PATCH 05/10] Extract `_Elem`. --- stl/inc/__msvc_string_view.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 147b33924a..f803245b82 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -821,7 +821,8 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), at/after _Start_at if (_Start_at < _Hay_size) { // room for match, look for it if constexpr (_Special) { - _String_bitmap _Matches; + using _Elem = typename _Traits::char_type; + _String_bitmap<_Elem> _Matches; if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { const auto _End = _Haystack + _Hay_size; for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { @@ -869,7 +870,8 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), before _Start_at if (_Hay_size != 0) { // worth searching, do it if constexpr (_Special) { - _String_bitmap _Matches; + using _Elem = typename _Traits::char_type; + _String_bitmap<_Elem> _Matches; if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { if (!_Matches._Match(*_Match_try)) { From 5b2d81ad00f261ecfc29a061996327a76a6395fd Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 9 Oct 2024 20:38:11 -0700 Subject: [PATCH 06/10] Extract `_Hay_start`, `_Hay_end`. --- stl/inc/__msvc_string_view.hpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index f803245b82..49ffd67c97 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -820,12 +820,14 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), at/after _Start_at if (_Start_at < _Hay_size) { // room for match, look for it + const auto _Hay_start = _Haystack + _Start_at; + const auto _Hay_end = _Haystack + _Hay_size; + if constexpr (_Special) { using _Elem = typename _Traits::char_type; _String_bitmap<_Elem> _Matches; if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { - const auto _End = _Haystack + _Hay_size; - for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { + for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { if (!_Matches._Match(*_Match_try)) { return static_cast(_Match_try - _Haystack); // found a match } @@ -836,8 +838,7 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p // couldn't put one of the characters into the bitmap, fall back to the serial algorithm } - const auto _End = _Haystack + _Hay_size; - for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) { + for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { return static_cast(_Match_try - _Haystack); // found a match } @@ -869,11 +870,13 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), before _Start_at if (_Hay_size != 0) { // worth searching, do it + const auto _Hay_start = (_STD min)(_Start_at, _Hay_size - 1); + if constexpr (_Special) { using _Elem = typename _Traits::char_type; _String_bitmap<_Elem> _Matches; if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + for (auto _Match_try = _Haystack + _Hay_start;; --_Match_try) { if (!_Matches._Match(*_Match_try)) { return static_cast(_Match_try - _Haystack); // found a match } @@ -887,7 +890,7 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt // couldn't put one of the characters into the bitmap, fall back to the serial algorithm } - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + for (auto _Match_try = _Haystack + _Hay_start;; --_Match_try) { if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { return static_cast(_Match_try - _Haystack); // found a match } From e22295fae66b97811a18d050e7c04a3606771224 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 9 Oct 2024 21:15:14 -0700 Subject: [PATCH 07/10] Fuse `bool _Special` into its usage. --- stl/inc/__msvc_string_view.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 49ffd67c97..e15f678b3a 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -714,7 +714,7 @@ class _String_bitmap<_Elem, false> { // _String_bitmap for wchar_t/unsigned shor bool _Matches[256] = {}; }; -template > +template constexpr size_t _Traits_find_first_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { @@ -723,7 +723,7 @@ constexpr size_t _Traits_find_first_of(_In_reads_(_Hay_size) const _Traits_ptr_t const auto _Hay_start = _Haystack + _Start_at; const auto _Hay_end = _Haystack + _Hay_size; - if constexpr (_Special) { + if constexpr (_Is_implementation_handled_char_traits<_Traits>) { if (!_STD _Is_constant_evaluated()) { using _Elem = typename _Traits::char_type; @@ -814,7 +814,7 @@ constexpr size_t _Traits_find_last_of(_In_reads_(_Hay_size) const _Traits_ptr_t< return static_cast(-1); // no match } -template > +template constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { @@ -823,7 +823,7 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p const auto _Hay_start = _Haystack + _Start_at; const auto _Hay_end = _Haystack + _Hay_size; - if constexpr (_Special) { + if constexpr (_Is_implementation_handled_char_traits<_Traits>) { using _Elem = typename _Traits::char_type; _String_bitmap<_Elem> _Matches; if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { @@ -864,7 +864,7 @@ constexpr size_t _Traits_find_not_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_ return static_cast(-1); // no match } -template > +template constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { @@ -872,7 +872,7 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt if (_Hay_size != 0) { // worth searching, do it const auto _Hay_start = (_STD min)(_Start_at, _Hay_size - 1); - if constexpr (_Special) { + if constexpr (_Is_implementation_handled_char_traits<_Traits>) { using _Elem = typename _Traits::char_type; _String_bitmap<_Elem> _Matches; if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { From 8d902d943e5fca56e19cf63f85c0ed3091d6f9f9 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Thu, 10 Oct 2024 08:36:31 -0700 Subject: [PATCH 08/10] Use early returns to reduce indentation In `_Traits_meow` functions with `if (condition) { woof; } return;` where `woof` is a `for` containing at least two `if`s. --- stl/inc/__msvc_string_view.hpp | 255 +++++++++++++++++---------------- 1 file changed, 135 insertions(+), 120 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index e15f678b3a..5fc0addfac 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -628,15 +628,17 @@ constexpr size_t _Traits_rfind(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits return (_STD min)(_Start_at, _Hay_size); // empty string always matches } - if (_Needle_size <= _Hay_size) { // room for match, look for it - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - _Needle_size);; --_Match_try) { - if (_Traits::eq(*_Match_try, *_Needle) && _Traits::compare(_Match_try, _Needle, _Needle_size) == 0) { - return static_cast(_Match_try - _Haystack); // found a match - } + if (_Needle_size > _Hay_size) { // no room for match + return static_cast(-1); + } - if (_Match_try == _Haystack) { - return static_cast(-1); // at beginning, no more chance for match - } + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - _Needle_size);; --_Match_try) { + if (_Traits::eq(*_Match_try, *_Needle) && _Traits::compare(_Match_try, _Needle, _Needle_size) == 0) { + return static_cast(_Match_try - _Haystack); // found a match + } + + if (_Match_try == _Haystack) { + return static_cast(-1); // at beginning, no more chance for match } } @@ -647,15 +649,18 @@ template constexpr size_t _Traits_rfind_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, const _Traits_ch_t<_Traits> _Ch) noexcept { // search [_Haystack, _Haystack + _Hay_size) for _Ch before _Start_at - if (_Hay_size != 0) { // room for match, look for it - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (_Traits::eq(*_Match_try, _Ch)) { - return static_cast(_Match_try - _Haystack); // found a match - } - if (_Match_try == _Haystack) { - return static_cast(-1); // at beginning, no more chance for match - } + if (_Hay_size == 0) { // no room for match + return static_cast(-1); + } + + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (_Traits::eq(*_Match_try, _Ch)) { + return static_cast(_Match_try - _Haystack); // found a match + } + + if (_Match_try == _Haystack) { + return static_cast(-1); // at beginning, no more chance for match } } @@ -719,57 +724,59 @@ constexpr size_t _Traits_find_first_of(_In_reads_(_Hay_size) const _Traits_ptr_t const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for one of [_Needle, _Needle + _Needle_size), at/after _Start_at - if (_Needle_size != 0 && _Start_at < _Hay_size) { // room for match, look for it - const auto _Hay_start = _Haystack + _Start_at; - const auto _Hay_end = _Haystack + _Hay_size; + if (_Needle_size == 0 || _Start_at >= _Hay_size) { // no match possible + return static_cast(-1); + } + + const auto _Hay_start = _Haystack + _Start_at; + const auto _Hay_end = _Haystack + _Hay_size; - if constexpr (_Is_implementation_handled_char_traits<_Traits>) { - if (!_STD _Is_constant_evaluated()) { - using _Elem = typename _Traits::char_type; + if constexpr (_Is_implementation_handled_char_traits<_Traits>) { + if (!_STD _Is_constant_evaluated()) { + using _Elem = typename _Traits::char_type; #if _USE_STD_VECTOR_ALGORITHMS - const bool _Try_vectorize = _Hay_size - _Start_at > _Threshold_find_first_of; + const bool _Try_vectorize = _Hay_size - _Start_at > _Threshold_find_first_of; - // Additional condition for when the vectorization outperforms the table lookup - const bool _Use_bitmap = !_Try_vectorize || (sizeof(_Elem) > 1 && sizeof(_Elem) * _Needle_size > 16); + // Additional condition for when the vectorization outperforms the table lookup + const bool _Use_bitmap = !_Try_vectorize || (sizeof(_Elem) > 1 && sizeof(_Elem) * _Needle_size > 16); #else - const bool _Use_bitmap = true; + const bool _Use_bitmap = true; #endif // _USE_STD_VECTOR_ALGORITHMS - if (_Use_bitmap) { - _String_bitmap<_Elem> _Matches; + if (_Use_bitmap) { + _String_bitmap<_Elem> _Matches; - if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { - for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { - if (_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { + for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { + if (_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match } - return static_cast(-1); // no match } - - // couldn't put one of the characters into the bitmap, fall back to vectorized or serial algorithms + return static_cast(-1); // no match } + // couldn't put one of the characters into the bitmap, fall back to vectorized or serial algorithms + } + #if _USE_STD_VECTOR_ALGORITHMS - if (_Try_vectorize) { - const _Traits_ptr_t<_Traits> _Found = - _STD _Find_first_of_vectorized(_Hay_start, _Hay_end, _Needle, _Needle + _Needle_size); - - if (_Found != _Hay_end) { - return static_cast(_Found - _Haystack); // found a match - } else { - return static_cast(-1); // no match - } + if (_Try_vectorize) { + const _Traits_ptr_t<_Traits> _Found = + _STD _Find_first_of_vectorized(_Hay_start, _Hay_end, _Needle, _Needle + _Needle_size); + + if (_Found != _Hay_end) { + return static_cast(_Found - _Haystack); // found a match + } else { + return static_cast(-1); // no match } -#endif // _USE_STD_VECTOR_ALGORITHMS } +#endif // _USE_STD_VECTOR_ALGORITHMS } + } - for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { - if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { + if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match } } @@ -781,32 +788,34 @@ constexpr size_t _Traits_find_last_of(_In_reads_(_Hay_size) const _Traits_ptr_t< const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for last of [_Needle, _Needle + _Needle_size), before _Start_at - if (_Needle_size != 0 && _Hay_size != 0) { // worth searching, do it - if constexpr (_Special) { - _String_bitmap _Matches; - if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the - // bitmap, fall back to the serial algorithm - return _Traits_find_last_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); - } + if (_Needle_size == 0 || _Hay_size == 0) { // not worth searching + return static_cast(-1); + } - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + if constexpr (_Special) { + _String_bitmap _Matches; + if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the + // bitmap, fall back to the serial algorithm + return _Traits_find_last_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); + } - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match - } + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match } - } else { - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match - } + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match + } + } + } else { + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } + + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match } } } @@ -819,29 +828,31 @@ constexpr size_t _Traits_find_first_not_of(_In_reads_(_Hay_size) const _Traits_p const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), at/after _Start_at - if (_Start_at < _Hay_size) { // room for match, look for it - const auto _Hay_start = _Haystack + _Start_at; - const auto _Hay_end = _Haystack + _Hay_size; + if (_Start_at >= _Hay_size) { // no room for match + return static_cast(-1); + } - if constexpr (_Is_implementation_handled_char_traits<_Traits>) { - using _Elem = typename _Traits::char_type; - _String_bitmap<_Elem> _Matches; - if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { - for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { - if (!_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + const auto _Hay_start = _Haystack + _Start_at; + const auto _Hay_end = _Haystack + _Hay_size; + + if constexpr (_Is_implementation_handled_char_traits<_Traits>) { + using _Elem = typename _Traits::char_type; + _String_bitmap<_Elem> _Matches; + if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { + for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { + if (!_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match } - return static_cast(-1); // no match } - - // couldn't put one of the characters into the bitmap, fall back to the serial algorithm + return static_cast(-1); // no match } - for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { - if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + // couldn't put one of the characters into the bitmap, fall back to the serial algorithm + } + + for (auto _Match_try = _Hay_start; _Match_try < _Hay_end; ++_Match_try) { + if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match } } @@ -869,35 +880,37 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for none of [_Needle, _Needle + _Needle_size), before _Start_at - if (_Hay_size != 0) { // worth searching, do it - const auto _Hay_start = (_STD min)(_Start_at, _Hay_size - 1); + if (_Hay_size == 0) { // no match possible + return static_cast(-1); + } - if constexpr (_Is_implementation_handled_char_traits<_Traits>) { - using _Elem = typename _Traits::char_type; - _String_bitmap<_Elem> _Matches; - if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { - for (auto _Match_try = _Haystack + _Hay_start;; --_Match_try) { - if (!_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + const auto _Hay_start = (_STD min)(_Start_at, _Hay_size - 1); - if (_Match_try == _Haystack) { - return static_cast(-1); // at beginning, no more chance for match - } + if constexpr (_Is_implementation_handled_char_traits<_Traits>) { + using _Elem = typename _Traits::char_type; + _String_bitmap<_Elem> _Matches; + if (_Matches._Mark(_Needle, _Needle + _Needle_size)) { + for (auto _Match_try = _Haystack + _Hay_start;; --_Match_try) { + if (!_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match } - } - // couldn't put one of the characters into the bitmap, fall back to the serial algorithm + if (_Match_try == _Haystack) { + return static_cast(-1); // at beginning, no more chance for match + } + } } - for (auto _Match_try = _Haystack + _Hay_start;; --_Match_try) { - if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match - } + // couldn't put one of the characters into the bitmap, fall back to the serial algorithm + } - if (_Match_try == _Haystack) { - return static_cast(-1); // at beginning, no more chance for match - } + for (auto _Match_try = _Haystack + _Hay_start;; --_Match_try) { + if (!_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } + + if (_Match_try == _Haystack) { + return static_cast(-1); // at beginning, no more chance for match } } @@ -908,15 +921,17 @@ template constexpr size_t _Traits_rfind_not_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size, const size_t _Start_at, const _Traits_ch_t<_Traits> _Ch) noexcept { // search [_Haystack, _Haystack + _Hay_size) for any value other than _Ch before _Start_at - if (_Hay_size != 0) { // room for match, look for it - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (!_Traits::eq(*_Match_try, _Ch)) { - return static_cast(_Match_try - _Haystack); // found a match - } + if (_Hay_size == 0) { // no room for match + return static_cast(-1); + } - if (_Match_try == _Haystack) { - return static_cast(-1); // at beginning, no more chance for match - } + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (!_Traits::eq(*_Match_try, _Ch)) { + return static_cast(_Match_try - _Haystack); // found a match + } + + if (_Match_try == _Haystack) { + return static_cast(-1); // at beginning, no more chance for match } } From 9a248c31360144d48a2f1ca81fa84ed78055bd80 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Thu, 10 Oct 2024 12:04:22 -0700 Subject: [PATCH 09/10] Revert changes to `_Traits_find_last_of` ... to avoid merge conflicts with GH-4934. This partially reverts commit 8d902d943e5fca56e19cf63f85c0ed3091d6f9f9. --- stl/inc/__msvc_string_view.hpp | 46 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 5fc0addfac..1d0d3db76f 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -788,34 +788,32 @@ constexpr size_t _Traits_find_last_of(_In_reads_(_Hay_size) const _Traits_ptr_t< const size_t _Hay_size, const size_t _Start_at, _In_reads_(_Needle_size) const _Traits_ptr_t<_Traits> _Needle, const size_t _Needle_size) noexcept { // in [_Haystack, _Haystack + _Hay_size), look for last of [_Needle, _Needle + _Needle_size), before _Start_at - if (_Needle_size == 0 || _Hay_size == 0) { // not worth searching - return static_cast(-1); - } - - if constexpr (_Special) { - _String_bitmap _Matches; - if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the - // bitmap, fall back to the serial algorithm - return _Traits_find_last_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); - } - - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (_Matches._Match(*_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match + if (_Needle_size != 0 && _Hay_size != 0) { // worth searching, do it + if constexpr (_Special) { + _String_bitmap _Matches; + if (!_Matches._Mark(_Needle, _Needle + _Needle_size)) { // couldn't put one of the characters into the + // bitmap, fall back to the serial algorithm + return _Traits_find_last_of<_Traits, false>(_Haystack, _Hay_size, _Start_at, _Needle, _Needle_size); } - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match - } - } - } else { - for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { - if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { - return static_cast(_Match_try - _Haystack); // found a match + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (_Matches._Match(*_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } + + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match + } } + } else { + for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1);; --_Match_try) { + if (_Traits::find(_Needle, _Needle_size, *_Match_try)) { + return static_cast(_Match_try - _Haystack); // found a match + } - if (_Match_try == _Haystack) { - break; // at beginning, no more chance for match + if (_Match_try == _Haystack) { + break; // at beginning, no more chance for match + } } } } From f7a8c35ff0533cd7b272b2692af996ad54c54322 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Thu, 10 Oct 2024 12:13:25 -0700 Subject: [PATCH 10/10] Elide dead returns These return statements are never reached. --- stl/inc/__msvc_string_view.hpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 1d0d3db76f..12a66f55ce 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -641,8 +641,6 @@ constexpr size_t _Traits_rfind(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits return static_cast(-1); // at beginning, no more chance for match } } - - return static_cast(-1); // no match } template @@ -663,8 +661,6 @@ constexpr size_t _Traits_rfind_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_Tra return static_cast(-1); // at beginning, no more chance for match } } - - return static_cast(-1); // no match } template ::value> @@ -911,8 +907,6 @@ constexpr size_t _Traits_find_last_not_of(_In_reads_(_Hay_size) const _Traits_pt return static_cast(-1); // at beginning, no more chance for match } } - - return static_cast(-1); // no match } template @@ -932,8 +926,6 @@ constexpr size_t _Traits_rfind_not_ch(_In_reads_(_Hay_size) const _Traits_ptr_t< return static_cast(-1); // at beginning, no more chance for match } } - - return static_cast(-1); // no match } template