diff --git a/stl/inc/xutility b/stl/inc/xutility index dbfbad6ce35..c38cab33263 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -6266,13 +6266,14 @@ namespace ranges { template _Se, class _Ty, class _Pj = identity> requires indirect_binary_predicate, const _Ty*> _NODISCARD constexpr _It _Find_unchecked(_It _First, const _Se _Last, const _Ty& _Val, _Pj _Proj = {}) { - constexpr bool _Elements_are_1_byte = sizeof(_Iter_value_t<_It>) == 1; - constexpr bool _Is_sized = sized_sentinel_for<_Se, _It>; - - if constexpr (_Vector_alg_in_find_is_safe<_It, _Ty> - && (_Elements_are_1_byte ? _Is_sized || same_as<_Se, unreachable_sentinel_t> - : _Is_sized && _USE_STD_VECTOR_ALGORITHMS) - && same_as<_Pj, identity>) { + constexpr bool _Elements_are_1_byte = sizeof(_Iter_value_t<_It>) == 1; + constexpr bool _Elements_are_2_bytes = sizeof(_Iter_value_t<_It>) == 2; + constexpr bool _Is_sized = sized_sentinel_for<_Se, _It>; + + if constexpr (_Vector_alg_in_find_is_safe<_It, _Ty> && same_as<_Pj, identity> + && (_Elements_are_1_byte ? _Is_sized || same_as<_Se, unreachable_sentinel_t> + : _Elements_are_2_bytes ? _Is_sized + : _Is_sized && _USE_STD_VECTOR_ALGORITHMS)) { if (!_STD is_constant_evaluated()) { if (!_STD _Could_compare_equal_to_value_type<_It>(_Val)) { if constexpr (_Is_sized) { @@ -6289,25 +6290,33 @@ namespace ranges { _Ptr_t _Result; #if _USE_STD_VECTOR_ALGORITHMS if constexpr (_Is_sized) { - // When _Is_sized && _Elements_are_1_byte, prefer this over memchr() for performance + // Prefer this over memchr()/wmemchr() below for performance const auto _Last_ptr = _First_ptr + static_cast(_Last - _First); _Result = _STD _Find_vectorized(_First_ptr, _Last_ptr, _Val); } else #endif // ^^^ _USE_STD_VECTOR_ALGORITHMS ^^^ { - _STL_INTERNAL_STATIC_ASSERT(_Elements_are_1_byte); - size_t _Count; - if constexpr (_Is_sized) { - _Count = static_cast(_Last - _First); + if constexpr (_Elements_are_2_bytes) { + _STL_INTERNAL_STATIC_ASSERT(_Is_sized); + _Result = reinterpret_cast<_Ptr_t>( + const_cast(_CSTD wmemchr(reinterpret_cast(_First_ptr), + static_cast(_Val), static_cast(_Last - _First)))); } else { - _Count = SIZE_MAX; - } + _STL_INTERNAL_STATIC_ASSERT(_Elements_are_1_byte); + size_t _Count; + if constexpr (_Is_sized) { + _Count = static_cast(_Last - _First); + } else { + _Count = SIZE_MAX; + } - // C23 7.27.5.2 "The memchr generic function"/2 says "The implementation shall behave as if - // it reads the characters sequentially and stops as soon as a matching character is found." - // C23 7.32.4.6.9 "The wmemchr generic function"/2 lacks such wording, - // so we don't use wmemchr(), avoiding issues with unreachable_sentinel_t. - _Result = static_cast<_Ptr_t>(_CSTD memchr(_First_ptr, static_cast(_Val), _Count)); + // C23 7.27.5.2 "The memchr generic function"/2 says "The implementation shall behave as if + // it reads the characters sequentially and stops as soon as a matching character is found." + // C23 7.32.4.6.9 "The wmemchr generic function"/2 lacks such wording, + // so we don't use wmemchr(), avoiding issues with unreachable_sentinel_t. + _Result = + static_cast<_Ptr_t>(_CSTD memchr(_First_ptr, static_cast(_Val), _Count)); + } if constexpr (_Is_sized) { if (_Result == nullptr) {