diff --git a/stl/inc/xutility b/stl/inc/xutility index a8f41b14b5..0d22298ef5 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -5087,61 +5087,46 @@ _NODISCARD constexpr auto lexicographical_compare_three_way( } #endif // __cpp_lib_concepts -template -_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, true_type, true_type, _Any_tag, false_type) { - // signed _Elem, signed _Ty - return SCHAR_MIN <= _Val && _Val <= SCHAR_MAX; -} - -template -_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, true_type, false_type, true_type, false_type) { - // signed _Elem, unsigned _Ty, -1 == static_cast<_Ty>(-1) - return _Val <= SCHAR_MAX || static_cast<_Ty>(SCHAR_MIN) <= _Val; -} - -template -_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, true_type, false_type, false_type, false_type) { - // signed _Elem, unsigned _Ty, -1 != static_cast<_Ty>(-1) - return _Val <= SCHAR_MAX; -} - -template -_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, false_type, true_type, _Any_tag, false_type) { - // unsigned _Elem, signed _Ty - return 0 <= _Val && _Val <= UCHAR_MAX; -} - -template -_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, false_type, false_type, _Any_tag, false_type) { - // unsigned _Elem, unsigned _Ty - return _Val <= UCHAR_MAX; -} - -template -_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, _Any_tag, _Any_tag, _Any_tag, true_type) { - // bool _Elem - return _Val == true || _Val == false; -} - template _NODISCARD constexpr bool _Within_limits(const _InIt&, const _Ty& _Val) { // check whether _Val is within the limits of _Elem - using _Elem = _Iter_value_t<_InIt>; - return _Within_limits(_Val, bool_constant>{}, bool_constant>{}, - bool_constant<-1 == static_cast<_Ty>(-1)>{}, bool_constant>{}); -} - -template -_NODISCARD constexpr bool _Within_limits(const _InIt&, const bool&) { // bools are always within the limits of _Elem - return true; -} - + if constexpr (is_same_v<_Ty, bool>) { + return true; + } #ifdef __cpp_lib_byte -template -_NODISCARD constexpr bool _Within_limits(const _InIt&, const byte&) { // bytes are only comparable with other bytes - return true; -} + else if constexpr (is_same_v<_Ty, byte>) { + return true; + } #endif // __cpp_lib_byte + else { + using _Elem = _Iter_value_t<_InIt>; + _STL_INTERNAL_STATIC_ASSERT(sizeof(_Elem) == 1); + if constexpr (is_same_v<_Elem, bool>) { + return _Val == true || _Val == false; + } else if constexpr (is_signed_v<_Elem>) { + if constexpr (is_signed_v<_Ty>) { + // signed _Elem, signed _Ty + return SCHAR_MIN <= _Val && _Val <= SCHAR_MAX; + } else { + if constexpr (-1 == static_cast<_Ty>(-1)) { + // signed _Elem, unsigned _Ty, -1 == static_cast<_Ty>(-1) + return _Val <= SCHAR_MAX || static_cast<_Ty>(SCHAR_MIN) <= _Val; + } else { + // signed _Elem, unsigned _Ty, -1 != static_cast<_Ty>(-1) + return _Val <= SCHAR_MAX; + } + } + } else { + if constexpr (is_signed_v<_Ty>) { + // unsigned _Elem, signed _Ty + return 0 <= _Val && _Val <= UCHAR_MAX; + } else { + // unsigned _Elem, unsigned _Ty + return _Val <= UCHAR_MAX; + } + } + } +} template _INLINE_VAR constexpr bool _Memchr_in_find_is_safe = @@ -5154,8 +5139,29 @@ _INLINE_VAR constexpr bool _Memchr_in_find_is_safe = > && !is_volatile_v>>; template -_NODISCARD constexpr _InIt _Find_unchecked1(_InIt _First, const _InIt _Last, const _Ty& _Val, false_type) { - // find first matching _Val +_NODISCARD _CONSTEXPR20 _InIt _Find_unchecked(_InIt _First, const _InIt _Last, const _Ty& _Val) { + // find first matching _Val; choose optimization + // activate optimization for contiguous iterators to (const) bytes and integral values +#if _HAS_CXX20 + if (!_STD is_constant_evaluated()) +#endif // _HAS_CXX20 + { + if constexpr (_Memchr_in_find_is_safe<_InIt, _Ty>) { + // find first byte matching integral _Val + if (!_Within_limits(_First, _Val)) { + return _Last; + } + const auto _First_ptr = _To_address(_First); + const auto _Result = static_cast>*>( + _CSTD memchr(_First_ptr, static_cast(_Val), static_cast(_Last - _First))); + if constexpr (is_pointer_v<_InIt>) { + return _Result ? _Result : _Last; + } else { + return _Result ? _First + (_Result - _First_ptr) : _Last; + } + } + } + for (; _First != _Last; ++_First) { if (*_First == _Val) { break; @@ -5165,36 +5171,6 @@ _NODISCARD constexpr _InIt _Find_unchecked1(_InIt _First, const _InIt _Last, con return _First; } -template -_NODISCARD _CONSTEXPR20 _InIt _Find_unchecked1(_InIt _First, const _InIt _Last, const _Ty& _Val, true_type) { - // find first byte matching integral _Val - if (!_Within_limits(_First, _Val)) { - return _Last; - } - -#if _HAS_CXX20 - if (_STD is_constant_evaluated()) { - using _Elem = _Iter_value_t<_InIt>; - return _Find_unchecked1(_First, _Last, static_cast<_Elem>(_Val), false_type{}); - } -#endif // _HAS_CXX20 - const auto _First_ptr = _To_address(_First); - const auto _Result = static_cast>*>( - _CSTD memchr(_First_ptr, static_cast(_Val), static_cast(_Last - _First))); - if constexpr (is_pointer_v<_InIt>) { - return _Result ? _Result : _Last; - } else { - return _Result ? _First + (_Result - _First_ptr) : _Last; - } -} - -template -_NODISCARD _CONSTEXPR20 _InIt _Find_unchecked(const _InIt _First, const _InIt _Last, const _Ty& _Val) { - // find first matching _Val; choose optimization - // activate optimization for contiguous iterators to (const) bytes and integral values - return _Find_unchecked1(_First, _Last, _Val, bool_constant<_Memchr_in_find_is_safe<_InIt, _Ty>>{}); -} - template _NODISCARD _CONSTEXPR20 _InIt find(_InIt _First, const _InIt _Last, const _Ty& _Val) { // find first matching _Val _Adl_verify_range(_First, _Last);