@@ -43,6 +43,20 @@ __declspec(noalias) size_t __stdcall __std_find_last_of_trivial_pos_1(
4343__declspec (noalias) size_t __stdcall __std_find_last_of_trivial_pos_2(
4444 const void * _Haystack, size_t _Haystack_length, const void * _Needle, size_t _Needle_length) noexcept ;
4545
46+ const void * __stdcall __std_find_not_ch_1 (const void * _First, const void * _Last, uint8_t _Val) noexcept ;
47+ const void * __stdcall __std_find_not_ch_2 (const void * _First, const void * _Last, uint16_t _Val) noexcept ;
48+ const void * __stdcall __std_find_not_ch_4 (const void * _First, const void * _Last, uint32_t _Val) noexcept ;
49+ const void * __stdcall __std_find_not_ch_8 (const void * _First, const void * _Last, uint64_t _Val) noexcept ;
50+
51+ __declspec (noalias) size_t __stdcall __std_find_last_not_ch_pos_1(
52+ const void * _First, const void * _Last, uint8_t _Val) noexcept ;
53+ __declspec (noalias) size_t __stdcall __std_find_last_not_ch_pos_2(
54+ const void * _First, const void * _Last, uint16_t _Val) noexcept ;
55+ __declspec (noalias) size_t __stdcall __std_find_last_not_ch_pos_4(
56+ const void * _First, const void * _Last, uint32_t _Val) noexcept ;
57+ __declspec (noalias) size_t __stdcall __std_find_last_not_ch_pos_8(
58+ const void * _First, const void * _Last, uint64_t _Val) noexcept ;
59+
4660} // extern "C"
4761
4862_STD_BEGIN
@@ -77,6 +91,35 @@ size_t _Find_last_of_pos_vectorized(const _Ty1* const _Haystack, const size_t _H
7791 }
7892}
7993
94+ template <class _Ty >
95+ const _Ty* _Find_not_ch_vectorized (const _Ty* const _First, const _Ty* const _Last, const _Ty _Ch) noexcept {
96+ if constexpr (sizeof (_Ty) == 1 ) {
97+ return static_cast <const _Ty*>(::__std_find_not_ch_1 (_First, _Last, static_cast <uint8_t >(_Ch)));
98+ } else if constexpr (sizeof (_Ty) == 2 ) {
99+ return static_cast <const _Ty*>(::__std_find_not_ch_2 (_First, _Last, static_cast <uint16_t >(_Ch)));
100+ } else if constexpr (sizeof (_Ty) == 4 ) {
101+ return static_cast <const _Ty*>(::__std_find_not_ch_4 (_First, _Last, static_cast <uint32_t >(_Ch)));
102+ } else if constexpr (sizeof (_Ty) == 8 ) {
103+ return static_cast <const _Ty*>(::__std_find_not_ch_8 (_First, _Last, static_cast <uint64_t >(_Ch)));
104+ } else {
105+ _STL_INTERNAL_STATIC_ASSERT (false ); // unexpected size
106+ }
107+ }
108+
109+ template <class _Ty >
110+ size_t _Find_last_not_ch_pos_vectorized (const _Ty* const _First, const _Ty* const _Last, const _Ty _Ch) noexcept {
111+ if constexpr (sizeof (_Ty) == 1 ) {
112+ return ::__std_find_last_not_ch_pos_1 (_First, _Last, static_cast <uint8_t >(_Ch));
113+ } else if constexpr (sizeof (_Ty) == 2 ) {
114+ return ::__std_find_last_not_ch_pos_2 (_First, _Last, static_cast <uint16_t >(_Ch));
115+ } else if constexpr (sizeof (_Ty) == 4 ) {
116+ return ::__std_find_last_not_ch_pos_4 (_First, _Last, static_cast <uint32_t >(_Ch));
117+ } else if constexpr (sizeof (_Ty) == 8 ) {
118+ return ::__std_find_last_not_ch_pos_8 (_First, _Last, static_cast <uint64_t >(_Ch));
119+ } else {
120+ _STL_INTERNAL_STATIC_ASSERT (false ); // unexpected size
121+ }
122+ }
80123_STD_END
81124
82125#endif // _USE_STD_VECTOR_ALGORITHMS
@@ -987,14 +1030,30 @@ template <class _Traits>
9871030constexpr size_t _Traits_find_not_ch (_In_reads_(_Hay_size) const _Traits_ptr_t<_Traits> _Haystack,
9881031 const size_t _Hay_size, const size_t _Start_at, const _Traits_ch_t<_Traits> _Ch) noexcept {
9891032 // search [_Haystack, _Haystack + _Hay_size) for any value other than _Ch, at/after _Start_at
990- if (_Start_at < _Hay_size) { // room for match, look for it
991- const auto _End = _Haystack + _Hay_size;
992- for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) {
993- if (!_Traits::eq (*_Match_try, _Ch)) {
994- return static_cast <size_t >(_Match_try - _Haystack); // found a match
1033+ if (_Start_at >= _Hay_size) { // no room for match
1034+ return static_cast <size_t >(-1 ); // no match
1035+ }
1036+
1037+ const auto _End = _Haystack + _Hay_size;
1038+
1039+ #if _USE_STD_VECTOR_ALGORITHMS
1040+ if constexpr (_Is_implementation_handled_char_traits<_Traits>) {
1041+ if (!_STD _Is_constant_evaluated ()) {
1042+ const auto _Result = _STD _Find_not_ch_vectorized (_Haystack + _Start_at, _End, _Ch);
1043+ if (_Result != _End) {
1044+ return static_cast <size_t >(_Result - _Haystack);
1045+ } else {
1046+ return static_cast <size_t >(-1 ); // no match
9951047 }
9961048 }
9971049 }
1050+ #endif // _USE_STD_VECTOR_ALGORITHMS
1051+
1052+ for (auto _Match_try = _Haystack + _Start_at; _Match_try < _End; ++_Match_try) {
1053+ if (!_Traits::eq (*_Match_try, _Ch)) {
1054+ return static_cast <size_t >(_Match_try - _Haystack); // found a match
1055+ }
1056+ }
9981057
9991058 return static_cast <size_t >(-1 ); // no match
10001059}
@@ -1047,7 +1106,17 @@ constexpr size_t _Traits_rfind_not_ch(_In_reads_(_Hay_size) const _Traits_ptr_t<
10471106 return static_cast <size_t >(-1 );
10481107 }
10491108
1050- for (auto _Match_try = _Haystack + (_STD min)(_Start_at, _Hay_size - 1 );; --_Match_try) {
1109+ const size_t _Actual_start_at = (_STD min)(_Start_at, _Hay_size - 1 );
1110+
1111+ #if _USE_STD_VECTOR_ALGORITHMS
1112+ if constexpr (_Is_implementation_handled_char_traits<_Traits>) {
1113+ if (!_STD _Is_constant_evaluated ()) {
1114+ return _STD _Find_last_not_ch_pos_vectorized (_Haystack, _Haystack + _Actual_start_at + 1 , _Ch);
1115+ }
1116+ }
1117+ #endif // _USE_STD_VECTOR_ALGORITHMS
1118+
1119+ for (auto _Match_try = _Haystack + _Actual_start_at;; --_Match_try) {
10511120 if (!_Traits::eq (*_Match_try, _Ch)) {
10521121 return static_cast <size_t >(_Match_try - _Haystack); // found a match
10531122 }
0 commit comments