From 95d377691c83515dec533f75257ee2174eb4f0e2 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 19 Nov 2024 14:41:39 +0200 Subject: [PATCH 1/2] Vectorize `basic_string::find` --- stl/inc/__msvc_string_view.hpp | 25 +++++++-- .../VSO_0000000_vector_algorithms/test.cpp | 53 +++++++++++++------ 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index aeae9bd2c08..97c268cab55 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -660,12 +660,29 @@ template constexpr size_t _Traits_find_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, at/after _Start_at - if (_Start_at < _Hay_size) { - const auto _Found_at = _Traits::find(_Haystack + _Start_at, _Hay_size - _Start_at, _Ch); - if (_Found_at) { - return static_cast(_Found_at - _Haystack); + if (_Start_at >= _Hay_size) { + return static_cast(-1); // (npos) no room for match + } + +#if _USE_STD_VECTOR_ALGORITHMS + if constexpr (_Is_implementation_handled_char_traits<_Traits>) { + if (!_STD _Is_constant_evaluated()) { + const auto _End = _Haystack + _Hay_size; + const auto _Ptr = _STD _Find_vectorized(_Haystack, _End, _Ch); + + if (_Ptr != _End) { + return static_cast(_Ptr - _Haystack); + } else { + return static_cast(-1); // (npos) no match + } } } +#endif // _USE_STD_VECTOR_ALGORITHMS + + const auto _Found_at = _Traits::find(_Haystack + _Start_at, _Hay_size - _Start_at, _Ch); + if (_Found_at) { + return static_cast(_Found_at - _Haystack); + } return static_cast(-1); // (npos) no match } diff --git a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp index dcc5c59ec46..27ba7340b3f 100644 --- a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp +++ b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp @@ -1090,6 +1090,38 @@ void test_case_string_find_last_of(const basic_string& input_haystack, const assert(expected == actual); } +template +void test_case_string_find_ch(const basic_string& input_haystack, const T value) { + ptrdiff_t expected; + + const auto expected_iter = last_known_good_find(input_haystack.begin(), input_haystack.end(), value); + + if (expected_iter != input_haystack.end()) { + expected = expected_iter - input_haystack.begin(); + } else { + expected = -1; + } + + const auto actual = static_cast(input_haystack.find(value)); + assert(expected == actual); +} + +template +void test_case_string_rfind_ch(const basic_string& input_haystack, const T value) { + ptrdiff_t expected; + + const auto expected_iter = last_known_good_find_last(input_haystack.begin(), input_haystack.end(), value); + + if (expected_iter != input_haystack.end()) { + expected = expected_iter - input_haystack.begin(); + } else { + expected = -1; + } + + const auto actual = static_cast(input_haystack.rfind(value)); + assert(expected == actual); +} + template void test_case_string_find_str(const basic_string& input_haystack, const basic_string& input_needle) { ptrdiff_t expected; @@ -1128,22 +1160,6 @@ void test_case_string_rfind_str(const basic_string& input_haystack, const bas assert(expected == actual); } -template -void test_case_string_rfind_ch(const basic_string& input_haystack, const T value) { - ptrdiff_t expected; - - const auto expected_iter = last_known_good_find_last(input_haystack.begin(), input_haystack.end(), value); - - if (expected_iter != input_haystack.end()) { - expected = expected_iter - input_haystack.begin(); - } else { - expected = -1; - } - - const auto actual = static_cast(input_haystack.rfind(value)); - assert(expected == actual); -} - template void test_basic_string_dis(mt19937_64& gen, D& dis) { basic_string input_haystack; @@ -1154,13 +1170,16 @@ void test_basic_string_dis(mt19937_64& gen, D& dis) { temp.reserve(needleDataCount); for (;;) { + const auto input_element = static_cast(dis(gen)); + test_case_string_find_ch(input_haystack, input_element); + test_case_string_rfind_ch(input_haystack, input_element); + input_needle.clear(); test_case_string_find_first_of(input_haystack, input_needle); test_case_string_find_last_of(input_haystack, input_needle); test_case_string_find_str(input_haystack, input_needle); test_case_string_rfind_str(input_haystack, input_needle); - test_case_string_rfind_ch(input_haystack, static_cast(dis(gen))); for (size_t attempts = 0; attempts < needleDataCount; ++attempts) { input_needle.push_back(static_cast(dis(gen))); From 97b4cfacbaaac9d6ead422fba2f8d1137e5b1749 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 19 Nov 2024 15:42:29 +0200 Subject: [PATCH 2/2] start at --- stl/inc/__msvc_string_view.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 97c268cab55..468378cbc78 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -668,7 +668,7 @@ constexpr size_t _Traits_find_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_Trai if constexpr (_Is_implementation_handled_char_traits<_Traits>) { if (!_STD _Is_constant_evaluated()) { const auto _End = _Haystack + _Hay_size; - const auto _Ptr = _STD _Find_vectorized(_Haystack, _End, _Ch); + const auto _Ptr = _STD _Find_vectorized(_Haystack + _Start_at, _End, _Ch); if (_Ptr != _End) { return static_cast(_Ptr - _Haystack);