Skip to content

<algorithm>: unused __find_end implementation details #100569

@hewillk

Description

@hewillk

The two functions named __find_end in find_end.h are not called from anywhere, they are useless and should be removed.

template < class _IterOps,
class _Pred,
class _Iter1,
class _Sent1,
class _Iter2,
class _Sent2,
class _Proj1,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end(
_Iter1 __first1,
_Sent1 __sent1,
_Iter2 __first2,
_Sent2 __sent2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
bidirectional_iterator_tag,
bidirectional_iterator_tag) {
auto __last1 = _IterOps::next(__first1, __sent1);
auto __last2 = _IterOps::next(__first2, __sent2);
// modeled after search algorithm (in reverse)
if (__first2 == __last2)
return __last1; // Everything matches an empty sequence
_Iter1 __l1 = __last1;
_Iter2 __l2 = __last2;
--__l2;
while (true) {
// Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
while (true) {
if (__first1 == __l1) // return __last1 if no element matches *__first2
return __last1;
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
break;
}
// *__l1 matches *__l2, now match elements before here
_Iter1 __m1 = __l1;
_Iter2 __m2 = __l2;
while (true) {
if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
return __m1;
if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
return __last1;
// if there is a mismatch, restart with a new __l1
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
break;
} // else there is a match, check next elements
}
}
}
template < class _AlgPolicy,
class _Pred,
class _Iter1,
class _Sent1,
class _Iter2,
class _Sent2,
class _Proj1,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end(
_Iter1 __first1,
_Sent1 __sent1,
_Iter2 __first2,
_Sent2 __sent2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
random_access_iterator_tag,
random_access_iterator_tag) {
typedef typename iterator_traits<_Iter1>::difference_type _D1;
auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
// Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
auto __len2 = __last2 - __first2;
if (__len2 == 0)
return __last1;
auto __len1 = __last1 - __first1;
if (__len1 < __len2)
return __last1;
const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
_Iter1 __l1 = __last1;
_Iter2 __l2 = __last2;
--__l2;
while (true) {
while (true) {
if (__s == __l1)
return __last1;
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
break;
}
_Iter1 __m1 = __l1;
_Iter2 __m2 = __l2;
while (true) {
if (__m2 == __first2)
return __m1;
// no need to check range on __m1 because __s guarantees we have enough source
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) {
break;
}
}
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions