diff --git a/benchmarks/src/find_and_count.cpp b/benchmarks/src/find_and_count.cpp index 448e67ac7ab..d17fd0e6df2 100644 --- a/benchmarks/src/find_and_count.cpp +++ b/benchmarks/src/find_and_count.cpp @@ -25,7 +25,7 @@ enum class Op { using namespace std; -template class Alloc, Op Operation> +template class Alloc, Op Operation, T FillVal = T{'0'}, T FoundVal = T{'1'}> void bm(benchmark::State& state) { const auto size = static_cast(state.range(0)); const auto pos = static_cast(state.range(1)); @@ -33,13 +33,13 @@ void bm(benchmark::State& state) { using Container = conditional_t= Op::StringFind, basic_string, Alloc>, vector>>; - Container a(size, T{'0'}); + Container a(size, FillVal); if (pos < size) { if constexpr (Operation == Op::StringRFind || Operation == Op::StringFindNotLastOne) { - a[size - pos - 1] = T{'1'}; + a[size - pos - 1] = FoundVal; } else { - a[pos] = T{'1'}; + a[pos] = FoundVal; } } else { if constexpr (Operation == Op::FindUnsized) { @@ -49,19 +49,19 @@ void bm(benchmark::State& state) { for (auto _ : state) { if constexpr (Operation == Op::FindSized) { - benchmark::DoNotOptimize(ranges::find(a.begin(), a.end(), T{'1'})); + benchmark::DoNotOptimize(ranges::find(a.begin(), a.end(), FoundVal)); } else if constexpr (Operation == Op::FindUnsized) { - benchmark::DoNotOptimize(ranges::find(a.begin(), unreachable_sentinel, T{'1'})); + benchmark::DoNotOptimize(ranges::find(a.begin(), unreachable_sentinel, FoundVal)); } else if constexpr (Operation == Op::Count) { - benchmark::DoNotOptimize(ranges::count(a.begin(), a.end(), T{'1'})); + benchmark::DoNotOptimize(ranges::count(a.begin(), a.end(), FoundVal)); } else if constexpr (Operation == Op::StringFind) { - benchmark::DoNotOptimize(a.find(T{'1'})); + benchmark::DoNotOptimize(a.find(FoundVal)); } else if constexpr (Operation == Op::StringRFind) { - benchmark::DoNotOptimize(a.rfind(T{'1'})); + benchmark::DoNotOptimize(a.rfind(FoundVal)); } else if constexpr (Operation == Op::StringFindNotFirstOne) { - benchmark::DoNotOptimize(a.find_first_not_of(T{'0'})); + benchmark::DoNotOptimize(a.find_first_not_of(FillVal)); } else if constexpr (Operation == Op::StringFindNotLastOne) { - benchmark::DoNotOptimize(a.find_last_not_of(T{'0'})); + benchmark::DoNotOptimize(a.find_last_not_of(FillVal)); } } } @@ -72,6 +72,13 @@ void common_args(auto bm) { bm->Args({63, 62})->Args({31, 30})->Args({15, 14})->Args({7, 6}); } +struct point { + int16_t x; + int16_t y; + + bool operator==(const point&) const = default; +}; + BENCHMARK(bm)->Apply(common_args); BENCHMARK(bm)->Apply(common_args); BENCHMARK(bm)->Apply(common_args); @@ -99,4 +106,7 @@ BENCHMARK(bm)- BENCHMARK(bm)->Apply(common_args); BENCHMARK(bm)->Apply(common_args); +BENCHMARK(bm)->Apply(common_args); +BENCHMARK(bm)->Apply(common_args); + BENCHMARK_MAIN(); diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 1ceda78079b..a5a6f257255 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -259,16 +259,12 @@ _Ty* _Is_sorted_until_vectorized(_Ty* const _First, _Ty* const _Last, const bool template __declspec(noalias) void _Replace_vectorized( _Ty* const _First, _Ty* const _Last, const _TVal1 _Old_val, const _TVal2 _New_val) noexcept { - if constexpr (is_pointer_v<_Ty>) { -#ifdef _WIN64 - ::__std_replace_8(_First, _Last, reinterpret_cast(_Old_val), reinterpret_cast(_New_val)); -#else // ^^^ defined(_WIN64) / !defined(_WIN64) vvv - ::__std_replace_4(_First, _Last, reinterpret_cast(_Old_val), reinterpret_cast(_New_val)); -#endif // ^^^ !defined(_WIN64) ^^^ - } else if constexpr (sizeof(_Ty) == 4) { - ::__std_replace_4(_First, _Last, static_cast(_Old_val), static_cast(_New_val)); + if constexpr (sizeof(_Ty) == 4) { + ::__std_replace_4( + _First, _Last, _STD _Find_arg_cast(_Old_val), _STD _Find_arg_cast(_New_val)); } else if constexpr (sizeof(_Ty) == 8) { - ::__std_replace_8(_First, _Last, static_cast(_Old_val), static_cast(_New_val)); + ::__std_replace_8( + _First, _Last, _STD _Find_arg_cast(_Old_val), _STD _Find_arg_cast(_New_val)); } else { _STL_INTERNAL_STATIC_ASSERT(false); // unexpected size } @@ -276,26 +272,18 @@ __declspec(noalias) void _Replace_vectorized( template _Ty* _Search_n_vectorized(_Ty* const _First, _Ty* const _Last, const size_t _Count, const _TVal _Val) noexcept { - if constexpr (is_pointer_v<_Ty>) { -#ifdef _WIN64 - return const_cast<_Ty*>( - static_cast(::__std_search_n_8(_First, _Last, _Count, reinterpret_cast(_Val)))); -#else // ^^^ defined(_WIN64) / !defined(_WIN64) vvv - return const_cast<_Ty*>( - static_cast(::__std_search_n_4(_First, _Last, _Count, reinterpret_cast(_Val)))); -#endif // ^^^ !defined(_WIN64) ^^^ - } else if constexpr (sizeof(_Ty) == 1) { + if constexpr (sizeof(_Ty) == 1) { return const_cast<_Ty*>( - static_cast(::__std_search_n_1(_First, _Last, _Count, static_cast(_Val)))); + static_cast(::__std_search_n_1(_First, _Last, _Count, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 2) { return const_cast<_Ty*>( - static_cast(::__std_search_n_2(_First, _Last, _Count, static_cast(_Val)))); + static_cast(::__std_search_n_2(_First, _Last, _Count, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 4) { return const_cast<_Ty*>( - static_cast(::__std_search_n_4(_First, _Last, _Count, static_cast(_Val)))); + static_cast(::__std_search_n_4(_First, _Last, _Count, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 8) { return const_cast<_Ty*>( - static_cast(::__std_search_n_8(_First, _Last, _Count, static_cast(_Val)))); + static_cast(::__std_search_n_8(_First, _Last, _Count, _STD _Find_arg_cast(_Val)))); } else { _STL_INTERNAL_STATIC_ASSERT(false); // unexpected size } @@ -319,20 +307,14 @@ _Ty* _Unique_vectorized(_Ty* const _First, _Ty* const _Last) noexcept { template _Ty* _Remove_copy_vectorized( const _Ty* const _First, const _Ty* const _Last, _Ty* const _Dest, const _TVal _Val) noexcept { - if constexpr (is_pointer_v<_Ty>) { -#ifdef _WIN64 - return reinterpret_cast<_Ty*>(::__std_remove_copy_8(_First, _Last, _Dest, reinterpret_cast(_Val))); -#else // ^^^ defined(_WIN64) / !defined(_WIN64) vvv - return reinterpret_cast<_Ty*>(::__std_remove_copy_4(_First, _Last, _Dest, reinterpret_cast(_Val))); -#endif // ^^^ !defined(_WIN64) ^^^ - } else if constexpr (sizeof(_Ty) == 1) { - return reinterpret_cast<_Ty*>(::__std_remove_copy_1(_First, _Last, _Dest, static_cast(_Val))); + if constexpr (sizeof(_Ty) == 1) { + return reinterpret_cast<_Ty*>(::__std_remove_copy_1(_First, _Last, _Dest, _STD _Find_arg_cast(_Val))); } else if constexpr (sizeof(_Ty) == 2) { - return reinterpret_cast<_Ty*>(::__std_remove_copy_2(_First, _Last, _Dest, static_cast(_Val))); + return reinterpret_cast<_Ty*>(::__std_remove_copy_2(_First, _Last, _Dest, _STD _Find_arg_cast(_Val))); } else if constexpr (sizeof(_Ty) == 4) { - return reinterpret_cast<_Ty*>(::__std_remove_copy_4(_First, _Last, _Dest, static_cast(_Val))); + return reinterpret_cast<_Ty*>(::__std_remove_copy_4(_First, _Last, _Dest, _STD _Find_arg_cast(_Val))); } else if constexpr (sizeof(_Ty) == 8) { - return reinterpret_cast<_Ty*>(::__std_remove_copy_8(_First, _Last, _Dest, static_cast(_Val))); + return reinterpret_cast<_Ty*>(::__std_remove_copy_8(_First, _Last, _Dest, _STD _Find_arg_cast(_Val))); } else { _STL_INTERNAL_STATIC_ASSERT(false); // Unexpected size } diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 3ce7ca8ec42..5305b74b45a 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -42,20 +42,14 @@ void* __stdcall __std_remove_8(void* _First, void* _Last, uint64_t _Val) noexcep _STD_BEGIN template _Ty* _Remove_vectorized(_Ty* const _First, _Ty* const _Last, const _TVal _Val) noexcept { - if constexpr (is_pointer_v<_Ty>) { -#ifdef _WIN64 - return reinterpret_cast<_Ty*>(::__std_remove_8(_First, _Last, reinterpret_cast(_Val))); -#else - return reinterpret_cast<_Ty*>(::__std_remove_4(_First, _Last, reinterpret_cast(_Val))); -#endif - } else if constexpr (sizeof(_Ty) == 1) { - return reinterpret_cast<_Ty*>(::__std_remove_1(_First, _Last, static_cast(_Val))); + if constexpr (sizeof(_Ty) == 1) { + return reinterpret_cast<_Ty*>(::__std_remove_1(_First, _Last, _STD _Find_arg_cast(_Val))); } else if constexpr (sizeof(_Ty) == 2) { - return reinterpret_cast<_Ty*>(::__std_remove_2(_First, _Last, static_cast(_Val))); + return reinterpret_cast<_Ty*>(::__std_remove_2(_First, _Last, _STD _Find_arg_cast(_Val))); } else if constexpr (sizeof(_Ty) == 4) { - return reinterpret_cast<_Ty*>(::__std_remove_4(_First, _Last, static_cast(_Val))); + return reinterpret_cast<_Ty*>(::__std_remove_4(_First, _Last, _STD _Find_arg_cast(_Val))); } else if constexpr (sizeof(_Ty) == 8) { - return reinterpret_cast<_Ty*>(::__std_remove_8(_First, _Last, static_cast(_Val))); + return reinterpret_cast<_Ty*>(::__std_remove_8(_First, _Last, _STD _Find_arg_cast(_Val))); } else { _STL_INTERNAL_STATIC_ASSERT(false); // Unexpected size } diff --git a/stl/inc/xutility b/stl/inc/xutility index 43d6fc306d9..20658c5595e 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -174,8 +174,20 @@ __declspec(noalias) size_t __stdcall __std_mismatch_2(const void* _First1, const __declspec(noalias) size_t __stdcall __std_mismatch_4(const void* _First1, const void* _First2, size_t _Count) noexcept; __declspec(noalias) size_t __stdcall __std_mismatch_8(const void* _First1, const void* _First2, size_t _Count) noexcept; } // extern "C" +#endif // _USE_STD_VECTOR_ALGORITHMS _STD_BEGIN + +template +_Target _Find_arg_cast(const _Source _Val) noexcept { + if constexpr (is_integral_v<_Source>) { + return static_cast<_Target>(_Val); + } else { + return _STD _Bit_cast<_Target>(_Val); + } +} + +#if _USE_STD_VECTOR_ALGORITHMS template __declspec(noalias) void _Reverse_vectorized(void* _First, void* _Last) noexcept { if constexpr (_Nx == 1) { @@ -193,20 +205,14 @@ __declspec(noalias) void _Reverse_vectorized(void* _First, void* _Last) noexcept template __declspec(noalias) size_t _Count_vectorized(_Ty* const _First, _Ty* const _Last, const _TVal _Val) noexcept { - if constexpr (is_pointer_v<_TVal> || is_null_pointer_v<_TVal>) { -#ifdef _WIN64 - return ::__std_count_trivial_8(_First, _Last, reinterpret_cast(_Val)); -#else - return ::__std_count_trivial_4(_First, _Last, reinterpret_cast(_Val)); -#endif - } else if constexpr (sizeof(_Ty) == 1) { - return ::__std_count_trivial_1(_First, _Last, static_cast(_Val)); + if constexpr (sizeof(_Ty) == 1) { + return ::__std_count_trivial_1(_First, _Last, _STD _Find_arg_cast(_Val)); } else if constexpr (sizeof(_Ty) == 2) { - return ::__std_count_trivial_2(_First, _Last, static_cast(_Val)); + return ::__std_count_trivial_2(_First, _Last, _STD _Find_arg_cast(_Val)); } else if constexpr (sizeof(_Ty) == 4) { - return ::__std_count_trivial_4(_First, _Last, static_cast(_Val)); + return ::__std_count_trivial_4(_First, _Last, _STD _Find_arg_cast(_Val)); } else if constexpr (sizeof(_Ty) == 8) { - return ::__std_count_trivial_8(_First, _Last, static_cast(_Val)); + return ::__std_count_trivial_8(_First, _Last, _STD _Find_arg_cast(_Val)); } else { _STL_INTERNAL_STATIC_ASSERT(false); // unexpected size } @@ -214,26 +220,18 @@ __declspec(noalias) size_t _Count_vectorized(_Ty* const _First, _Ty* const _Last template _Ty* _Find_vectorized(_Ty* const _First, _Ty* const _Last, const _TVal _Val) noexcept { - if constexpr (is_pointer_v<_TVal> || is_null_pointer_v<_TVal>) { -#ifdef _WIN64 - return const_cast<_Ty*>( - static_cast(::__std_find_trivial_8(_First, _Last, reinterpret_cast(_Val)))); -#else - return const_cast<_Ty*>( - static_cast(::__std_find_trivial_4(_First, _Last, reinterpret_cast(_Val)))); -#endif - } else if constexpr (sizeof(_Ty) == 1) { + if constexpr (sizeof(_Ty) == 1) { return const_cast<_Ty*>( - static_cast(::__std_find_trivial_1(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_trivial_1(_First, _Last, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 2) { return const_cast<_Ty*>( - static_cast(::__std_find_trivial_2(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_trivial_2(_First, _Last, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 4) { return const_cast<_Ty*>( - static_cast(::__std_find_trivial_4(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_trivial_4(_First, _Last, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 8) { return const_cast<_Ty*>( - static_cast(::__std_find_trivial_8(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_trivial_8(_First, _Last, _STD _Find_arg_cast(_Val)))); } else { _STL_INTERNAL_STATIC_ASSERT(false); // unexpected size } @@ -241,26 +239,18 @@ _Ty* _Find_vectorized(_Ty* const _First, _Ty* const _Last, const _TVal _Val) noe template _Ty* _Find_last_vectorized(_Ty* const _First, _Ty* const _Last, const _TVal _Val) noexcept { - if constexpr (is_pointer_v<_TVal> || is_null_pointer_v<_TVal>) { -#ifdef _WIN64 - return const_cast<_Ty*>( - static_cast(::__std_find_last_trivial_8(_First, _Last, reinterpret_cast(_Val)))); -#else - return const_cast<_Ty*>( - static_cast(::__std_find_last_trivial_4(_First, _Last, reinterpret_cast(_Val)))); -#endif - } else if constexpr (sizeof(_Ty) == 1) { + if constexpr (sizeof(_Ty) == 1) { return const_cast<_Ty*>( - static_cast(::__std_find_last_trivial_1(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_last_trivial_1(_First, _Last, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 2) { return const_cast<_Ty*>( - static_cast(::__std_find_last_trivial_2(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_last_trivial_2(_First, _Last, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 4) { return const_cast<_Ty*>( - static_cast(::__std_find_last_trivial_4(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_last_trivial_4(_First, _Last, _STD _Find_arg_cast(_Val)))); } else if constexpr (sizeof(_Ty) == 8) { return const_cast<_Ty*>( - static_cast(::__std_find_last_trivial_8(_First, _Last, static_cast(_Val)))); + static_cast(::__std_find_last_trivial_8(_First, _Last, _STD _Find_arg_cast(_Val)))); } else { _STL_INTERNAL_STATIC_ASSERT(false); // unexpected size } @@ -457,12 +447,8 @@ size_t _Mismatch_vectorized(const void* const _First1, const void* const _First2 return __std_mismatch_1(_First1, _First2, _Count * _Element_size) / _Element_size; } } -_STD_END - #endif // _USE_STD_VECTOR_ALGORITHMS -_STD_BEGIN - template struct _Get_first_parameter; @@ -5555,13 +5541,17 @@ constexpr bool _Can_memcmp_elements<_Ty1*, _Ty2*, false> = _Is_pointer_address_c #if _USE_BUILTIN_IS_TRIVIALLY_EQUALITY_COMPARABLE template -constexpr bool _Can_memcmp_elements<_Elem1, _Elem2, false> = +constexpr bool _Is_same_and_builtin_trivially_equality_comparable = is_same_v<_Elem1, _Elem2> && __is_trivially_equality_comparable(_Elem1); #else // ^^^ _USE_BUILTIN_IS_TRIVIALLY_EQUALITY_COMPARABLE / !_USE_BUILTIN_IS_TRIVIALLY_EQUALITY_COMPARABLE vvv template -constexpr bool _Can_memcmp_elements<_Elem1, _Elem2, false> = false; +constexpr bool _Is_same_and_builtin_trivially_equality_comparable = false; #endif // ^^^ !_USE_BUILTIN_IS_TRIVIALLY_EQUALITY_COMPARABLE ^^^ +template +constexpr bool _Can_memcmp_elements<_Elem1, _Elem2, false> = + _Is_same_and_builtin_trivially_equality_comparable<_Elem1, _Elem2>; + // _Can_memcmp_elements_with_pred<_Elem1, _Elem2, _Pr> reports whether the memcmp optimization is applicable, // given contiguously stored elements. (This avoids having to repeat the metaprogramming that finds the element types.) // _Elem1 and _Elem2 aren't top-level const here. @@ -6144,22 +6134,24 @@ struct _Vector_alg_in_find_is_safe_object_pointers<_Ty1*, _Ty2*> // Can we activate the vector algorithms to find a value in a range of elements? template -constexpr bool _Vector_alg_in_find_is_safe_elem = disjunction_v< +constexpr bool _Vector_alg_in_find_is_safe_elem = + _Is_same_and_builtin_trivially_equality_comparable<_Ty, _Elem> + || disjunction_v< #ifdef __cpp_lib_byte - // We're finding a std::byte in a range of std::byte. - conjunction, is_same<_Elem, byte>>, + // We're finding a std::byte in a range of std::byte. + conjunction, is_same<_Elem, byte>>, #endif // defined(__cpp_lib_byte) - // We're finding an integer in a range of integers. - // This case is the one that requires careful runtime handling in _Could_compare_equal_to_value_type. - conjunction, is_integral<_Elem>>, - // We're finding an (object or function) pointer in a range of pointers of the same type. - conjunction, is_same<_Ty, _Elem>>, - // We're finding a nullptr in a range of (object or function) pointers. - conjunction, is_pointer<_Elem>>, - // We're finding an object pointer in a range of object pointers, and: - // - One of the pointer types is a cv void*. - // - One of the pointer types is a cv1 U* and the other is a cv2 U*. - _Vector_alg_in_find_is_safe_object_pointers<_Ty, _Elem>>; + // We're finding an integer in a range of integers. + // This case is the one that requires careful runtime handling in _Could_compare_equal_to_value_type. + conjunction, is_integral<_Elem>>, + // We're finding an (object or function) pointer in a range of pointers of the same type. + conjunction, is_same<_Ty, _Elem>>, + // We're finding a nullptr in a range of (object or function) pointers. + conjunction, is_pointer<_Elem>>, + // We're finding an object pointer in a range of object pointers, and: + // - One of the pointer types is a cv void*. + // - One of the pointer types is a cv1 U* and the other is a cv2 U*. + _Vector_alg_in_find_is_safe_object_pointers<_Ty, _Elem>>; // Can we activate the vector algorithms for find/count? template @@ -6176,14 +6168,15 @@ _NODISCARD constexpr bool _Could_compare_equal_to_value_type(const _Ty& _Val) { // check whether _Val is within the limits of _Elem _STL_INTERNAL_STATIC_ASSERT(_Vector_alg_in_find_is_safe<_InIt, _Ty>); - if constexpr (disjunction_v< -#ifdef __cpp_lib_byte - is_same<_Ty, byte>, -#endif // defined(__cpp_lib_byte) - is_same<_Ty, bool>, is_pointer<_Ty>, is_same<_Ty, nullptr_t>>) { + using _Elem = _Iter_value_t<_InIt>; + + if constexpr (disjunction_v, // If types are the same, _Val can compare equal to _Elem + is_same<_Ty, bool>, // true or false can be represented in any integer type + is_pointer<_Ty>, // we only compare pointers vs. other pointers with the same representation + is_same<_Ty, nullptr_t> // we only compare nullptr_t against pointers; any pointer can be null + >) { return true; } else { - using _Elem = _Iter_value_t<_InIt>; _STL_INTERNAL_STATIC_ASSERT(is_integral_v<_Elem> && is_integral_v<_Ty>); if constexpr (is_same_v<_Elem, bool>) { @@ -6254,11 +6247,12 @@ _NODISCARD _CONSTEXPR20 _InIt _Find_unchecked(_InIt _First, const _InIt _Last, c _Ptr_t _Result; if constexpr (sizeof(_Iter_value_t<_InIt>) == 1) { - _Result = static_cast<_Ptr_t>(_CSTD memchr(_First_ptr, static_cast(_Val), _Count)); + _Result = + static_cast<_Ptr_t>(_CSTD memchr(_First_ptr, _STD _Find_arg_cast(_Val), _Count)); } else { _STL_INTERNAL_STATIC_ASSERT(sizeof(_Iter_value_t<_InIt>) == 2); _Result = reinterpret_cast<_Ptr_t>(const_cast(_CSTD wmemchr( - reinterpret_cast(_First_ptr), static_cast(_Val), _Count))); + reinterpret_cast(_First_ptr), _STD _Find_arg_cast(_Val), _Count))); } if constexpr (is_pointer_v<_InIt>) { @@ -6343,7 +6337,7 @@ namespace ranges { _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)))); + _STD _Find_arg_cast(_Val), static_cast(_Last - _First)))); } else { _STL_INTERNAL_STATIC_ASSERT(_Elements_are_1_byte); size_t _Count; @@ -6357,8 +6351,8 @@ namespace ranges { // 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)); + _Result = static_cast<_Ptr_t>( + _CSTD memchr(_First_ptr, _STD _Find_arg_cast(_Val), _Count)); } if constexpr (_Is_sized) {