Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 30 additions & 17 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -6266,12 +6266,13 @@ namespace ranges {
template <input_iterator _It, sentinel_for<_It> _Se, class _Ty, class _Pj = identity>
requires indirect_binary_predicate<ranges::equal_to, projected<_It, _Pj>, 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>;
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>
&& (_Elements_are_1_byte ? _Is_sized || same_as<_Se, unreachable_sentinel_t>
: _Is_sized && _USE_STD_VECTOR_ALGORITHMS)
: _Is_sized && (_Elements_are_2_bytes || _USE_STD_VECTOR_ALGORITHMS))
&& same_as<_Pj, identity>) {
if (!_STD is_constant_evaluated()) {
if (!_STD _Could_compare_equal_to_value_type<_It>(_Val)) {
Expand All @@ -6295,24 +6296,36 @@ namespace ranges {
} else
#endif // ^^^ _USE_STD_VECTOR_ALGORITHMS ^^^
{
_STL_INTERNAL_STATIC_ASSERT(_Elements_are_1_byte);
size_t _Count;
if constexpr (_Is_sized) {
_Count = static_cast<size_t>(_Last - _First);
} else {
_Count = SIZE_MAX;
}
if constexpr (_Elements_are_2_bytes) {
_STL_INTERNAL_STATIC_ASSERT(_Is_sized);
_Result = reinterpret_cast<_Ptr_t>(
const_cast<wchar_t*>(_CSTD wmemchr(reinterpret_cast<const wchar_t*>(_First_ptr),
static_cast<wchar_t>(_Val), static_cast<size_t>(_Last - _First))));

// 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<unsigned char>(_Val), _Count));

if constexpr (_Is_sized) {
if (_Result == nullptr) {
return _RANGES next(_STD move(_First), _Last);
}
} else {
_STL_INTERNAL_STATIC_ASSERT(_Elements_are_1_byte);
size_t _Count;
if constexpr (_Is_sized) {
_Count = static_cast<size_t>(_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<unsigned char>(_Val), _Count));

if constexpr (_Is_sized) {
if (_Result == nullptr) {
return _RANGES next(_STD move(_First), _Last);
}
}
}
}

Expand Down