Skip to content

Commit

Permalink
Untag dispatch find (#2380)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Schellenberger Costa <[email protected]>
Co-authored-by: S. B. Tam <[email protected]>
Co-authored-by: Stephan T. Lavavej <[email protected]>
Co-authored-by: Casey Carter <[email protected]>
  • Loading branch information
5 people committed Jan 6, 2022
1 parent 16251e3 commit 69541fa
Showing 1 changed file with 58 additions and 82 deletions.
140 changes: 58 additions & 82 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -5087,61 +5087,46 @@ _NODISCARD constexpr auto lexicographical_compare_three_way(
}
#endif // __cpp_lib_concepts

template <class _Ty>
_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 <class _Ty>
_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 <class _Ty>
_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 <class _Ty>
_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 <class _Ty>
_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 <class _Ty>
_NODISCARD constexpr bool _Within_limits(const _Ty& _Val, _Any_tag, _Any_tag, _Any_tag, true_type) {
// bool _Elem
return _Val == true || _Val == false;
}

template <class _InIt, class _Ty>
_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<is_signed_v<_Elem>>{}, bool_constant<is_signed_v<_Ty>>{},
bool_constant<-1 == static_cast<_Ty>(-1)>{}, bool_constant<is_same_v<_Elem, bool>>{});
}

template <class _InIt>
_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 <class _InIt>
_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 <class _Iter, class _Ty>
_INLINE_VAR constexpr bool _Memchr_in_find_is_safe =
Expand All @@ -5154,8 +5139,29 @@ _INLINE_VAR constexpr bool _Memchr_in_find_is_safe =
> && !is_volatile_v<remove_reference_t<_Iter_ref_t<_Iter>>>;

template <class _InIt, class _Ty>
_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<remove_reference_t<_Iter_ref_t<_InIt>>*>(
_CSTD memchr(_First_ptr, static_cast<unsigned char>(_Val), static_cast<size_t>(_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;
Expand All @@ -5165,36 +5171,6 @@ _NODISCARD constexpr _InIt _Find_unchecked1(_InIt _First, const _InIt _Last, con
return _First;
}

template <class _InIt, class _Ty>
_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<remove_reference_t<_Iter_ref_t<_InIt>>*>(
_CSTD memchr(_First_ptr, static_cast<unsigned char>(_Val), static_cast<size_t>(_Last - _First)));
if constexpr (is_pointer_v<_InIt>) {
return _Result ? _Result : _Last;
} else {
return _Result ? _First + (_Result - _First_ptr) : _Last;
}
}

template <class _InIt, class _Ty>
_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 <class _InIt, class _Ty>
_NODISCARD _CONSTEXPR20 _InIt find(_InIt _First, const _InIt _Last, const _Ty& _Val) { // find first matching _Val
_Adl_verify_range(_First, _Last);
Expand Down

0 comments on commit 69541fa

Please sign in to comment.