Skip to content

Commit 126f4eb

Browse files
authored
Vectorize basic_string::find (#5101)
1 parent 2cef491 commit 126f4eb

File tree

2 files changed

+57
-21
lines changed

2 files changed

+57
-21
lines changed

stl/inc/__msvc_string_view.hpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -660,12 +660,29 @@ template <class _Traits>
660660
constexpr size_t _Traits_find_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack, const size_t _Hay_size,
661661
const size_t _Start_at, const _Traits_ch_t<_Traits> _Ch) noexcept {
662662
// search [_Haystack, _Haystack + _Hay_size) for _Ch, at/after _Start_at
663-
if (_Start_at < _Hay_size) {
664-
const auto _Found_at = _Traits::find(_Haystack + _Start_at, _Hay_size - _Start_at, _Ch);
665-
if (_Found_at) {
666-
return static_cast<size_t>(_Found_at - _Haystack);
663+
if (_Start_at >= _Hay_size) {
664+
return static_cast<size_t>(-1); // (npos) no room for match
665+
}
666+
667+
#if _USE_STD_VECTOR_ALGORITHMS
668+
if constexpr (_Is_implementation_handled_char_traits<_Traits>) {
669+
if (!_STD _Is_constant_evaluated()) {
670+
const auto _End = _Haystack + _Hay_size;
671+
const auto _Ptr = _STD _Find_vectorized(_Haystack + _Start_at, _End, _Ch);
672+
673+
if (_Ptr != _End) {
674+
return static_cast<size_t>(_Ptr - _Haystack);
675+
} else {
676+
return static_cast<size_t>(-1); // (npos) no match
677+
}
667678
}
668679
}
680+
#endif // _USE_STD_VECTOR_ALGORITHMS
681+
682+
const auto _Found_at = _Traits::find(_Haystack + _Start_at, _Hay_size - _Start_at, _Ch);
683+
if (_Found_at) {
684+
return static_cast<size_t>(_Found_at - _Haystack);
685+
}
669686

670687
return static_cast<size_t>(-1); // (npos) no match
671688
}

tests/std/tests/VSO_0000000_vector_algorithms/test.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,38 @@ void test_case_string_find_last_of(const basic_string<T>& input_haystack, const
10901090
assert(expected == actual);
10911091
}
10921092

1093+
template <class T>
1094+
void test_case_string_find_ch(const basic_string<T>& input_haystack, const T value) {
1095+
ptrdiff_t expected;
1096+
1097+
const auto expected_iter = last_known_good_find(input_haystack.begin(), input_haystack.end(), value);
1098+
1099+
if (expected_iter != input_haystack.end()) {
1100+
expected = expected_iter - input_haystack.begin();
1101+
} else {
1102+
expected = -1;
1103+
}
1104+
1105+
const auto actual = static_cast<ptrdiff_t>(input_haystack.find(value));
1106+
assert(expected == actual);
1107+
}
1108+
1109+
template <class T>
1110+
void test_case_string_rfind_ch(const basic_string<T>& input_haystack, const T value) {
1111+
ptrdiff_t expected;
1112+
1113+
const auto expected_iter = last_known_good_find_last(input_haystack.begin(), input_haystack.end(), value);
1114+
1115+
if (expected_iter != input_haystack.end()) {
1116+
expected = expected_iter - input_haystack.begin();
1117+
} else {
1118+
expected = -1;
1119+
}
1120+
1121+
const auto actual = static_cast<ptrdiff_t>(input_haystack.rfind(value));
1122+
assert(expected == actual);
1123+
}
1124+
10931125
template <class T>
10941126
void test_case_string_find_str(const basic_string<T>& input_haystack, const basic_string<T>& input_needle) {
10951127
ptrdiff_t expected;
@@ -1128,22 +1160,6 @@ void test_case_string_rfind_str(const basic_string<T>& input_haystack, const bas
11281160
assert(expected == actual);
11291161
}
11301162

1131-
template <class T>
1132-
void test_case_string_rfind_ch(const basic_string<T>& input_haystack, const T value) {
1133-
ptrdiff_t expected;
1134-
1135-
const auto expected_iter = last_known_good_find_last(input_haystack.begin(), input_haystack.end(), value);
1136-
1137-
if (expected_iter != input_haystack.end()) {
1138-
expected = expected_iter - input_haystack.begin();
1139-
} else {
1140-
expected = -1;
1141-
}
1142-
1143-
const auto actual = static_cast<ptrdiff_t>(input_haystack.rfind(value));
1144-
assert(expected == actual);
1145-
}
1146-
11471163
template <class T, class D>
11481164
void test_basic_string_dis(mt19937_64& gen, D& dis) {
11491165
basic_string<T> input_haystack;
@@ -1154,13 +1170,16 @@ void test_basic_string_dis(mt19937_64& gen, D& dis) {
11541170
temp.reserve(needleDataCount);
11551171

11561172
for (;;) {
1173+
const auto input_element = static_cast<T>(dis(gen));
1174+
test_case_string_find_ch(input_haystack, input_element);
1175+
test_case_string_rfind_ch(input_haystack, input_element);
1176+
11571177
input_needle.clear();
11581178

11591179
test_case_string_find_first_of(input_haystack, input_needle);
11601180
test_case_string_find_last_of(input_haystack, input_needle);
11611181
test_case_string_find_str(input_haystack, input_needle);
11621182
test_case_string_rfind_str(input_haystack, input_needle);
1163-
test_case_string_rfind_ch(input_haystack, static_cast<T>(dis(gen)));
11641183

11651184
for (size_t attempts = 0; attempts < needleDataCount; ++attempts) {
11661185
input_needle.push_back(static_cast<T>(dis(gen)));

0 commit comments

Comments
 (0)