Skip to content

Commit

Permalink
[libc++] Forward more algorithms to the classic algorithms (#114674)
Browse files Browse the repository at this point in the history
This partially addresses #105687.
  • Loading branch information
philnik777 authored Nov 6, 2024
1 parent 56077e5 commit eab7be5
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 97 deletions.
12 changes: 8 additions & 4 deletions libcxx/include/__algorithm/adjacent_find.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#include <__algorithm/comp.h>
#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/invoke.h>
#include <__utility/move.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand All @@ -25,14 +27,15 @@ _LIBCPP_PUSH_MACROS

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Iter, class _Sent, class _BinaryPredicate>
template <class _Iter, class _Sent, class _Pred, class _Proj>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter
__adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
__adjacent_find(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
if (__first == __last)
return __first;

_Iter __i = __first;
while (++__i != __last) {
if (__pred(*__first, *__i))
if (std::__invoke(__pred, std::__invoke(__proj, *__first), std::__invoke(__proj, *__i)))
return __first;
__first = __i;
}
Expand All @@ -42,7 +45,8 @@ __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
template <class _ForwardIterator, class _BinaryPredicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
return std::__adjacent_find(std::move(__first), std::move(__last), __pred);
__identity __proj;
return std::__adjacent_find(std::move(__first), std::move(__last), __pred, __proj);
}

template <class _ForwardIterator>
Expand Down
18 changes: 14 additions & 4 deletions libcxx/include/__algorithm/all_of.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,30 @@
#define _LIBCPP___ALGORITHM_ALL_OF_H

#include <__config>
#include <__functional/identity.h>
#include <__type_traits/invoke.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
return false;
}
return true;
}

template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
for (; __first != __last; ++__first)
if (!__pred(*__first))
return false;
return true;
__identity __proj;
return std::__all_of(__first, __last, __pred, __proj);
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
18 changes: 14 additions & 4 deletions libcxx/include/__algorithm/any_of.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,30 @@
#define _LIBCPP___ALGORITHM_ANY_OF_H

#include <__config>
#include <__functional/identity.h>
#include <__type_traits/invoke.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__any_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
return true;
}
return false;
}

template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
for (; __first != __last; ++__first)
if (__pred(*__first))
return true;
return false;
__identity __proj;
return std::__any_of(__first, __last, __pred, __proj);
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
26 changes: 21 additions & 5 deletions libcxx/include/__algorithm/copy_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,41 @@
#define _LIBCPP___ALGORITHM_COPY_IF_H

#include <__config>
#include <__functional/identity.h>
#include <__type_traits/invoke.h>
#include <__utility/move.h>
#include <__utility/pair.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _OutputIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
__copy_if(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
if (__pred(*__first)) {
if (std::__invoke(__pred, std::__invoke(__proj, *__first))) {
*__result = *__first;
++__result;
}
}
return __result;
return std::make_pair(std::move(__first), std::move(__result));
}

template <class _InputIterator, class _OutputIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
__identity __proj;
return std::__copy_if(__first, __last, __result, __pred, __proj).second;
}

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___ALGORITHM_COPY_IF_H
21 changes: 16 additions & 5 deletions libcxx/include/__algorithm/count_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,35 @@
#ifndef _LIBCPP___ALGORITHM_COUNT_IF_H
#define _LIBCPP___ALGORITHM_COUNT_IF_H

#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/invoke.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __policy_iter_diff_t<_AlgPolicy, _Iter>
__count_if(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
__policy_iter_diff_t<_AlgPolicy, _Iter> __counter(0);
for (; __first != __last; ++__first) {
if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
++__counter;
}
return __counter;
}

template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
typename iterator_traits<_InputIterator>::difference_type
count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
typename iterator_traits<_InputIterator>::difference_type __r(0);
for (; __first != __last; ++__first)
if (__pred(*__first))
++__r;
return __r;
__identity __proj;
return std::__count_if<_ClassicAlgPolicy>(__first, __last, __pred, __proj);
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
3 changes: 3 additions & 0 deletions libcxx/include/__algorithm/iterator_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ struct _IterOps<_ClassicAlgPolicy> {
}
};

template <class _AlgPolicy, class _Iter>
using __policy_iter_diff_t = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS
Expand Down
21 changes: 3 additions & 18 deletions libcxx/include/__algorithm/ranges_adjacent_find.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H

#include <__algorithm/adjacent_find.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
Expand All @@ -33,28 +33,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD

namespace ranges {
struct __adjacent_find {
template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI constexpr static _Iter
__adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
if (__first == __last)
return __first;

auto __i = __first;
while (++__i != __last) {
if (std::invoke(__pred, std::invoke(__proj, *__first), std::invoke(__proj, *__i)))
return __first;
__first = __i;
}
return __i;
}

template <forward_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter
operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj);
return std::__adjacent_find(std::move(__first), std::move(__last), __pred, __proj);
}

template <forward_range _Range,
Expand All @@ -63,7 +48,7 @@ struct __adjacent_find {
_Pred = ranges::equal_to>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
return std::__adjacent_find(ranges::begin(__range), ranges::end(__range), __pred, __proj);
}
};

Expand Down
14 changes: 3 additions & 11 deletions libcxx/include/__algorithm/ranges_all_of.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
#define _LIBCPP___ALGORITHM_RANGES_ALL_OF_H

#include <__algorithm/all_of.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
Expand All @@ -31,30 +32,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD

namespace ranges {
struct __all_of {
template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI constexpr static bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
if (!std::invoke(__pred, std::invoke(__proj, *__first)))
return false;
}
return true;
}

template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj);
return std::__all_of(std::move(__first), std::move(__last), __pred, __proj);
}

template <input_range _Range,
class _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
return std::__all_of(ranges::begin(__range), ranges::end(__range), __pred, __proj);
}
};

Expand Down
15 changes: 3 additions & 12 deletions libcxx/include/__algorithm/ranges_any_of.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
#define _LIBCPP___ALGORITHM_RANGES_ANY_OF_H

#include <__algorithm/any_of.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
#include <__ranges/access.h>
Expand All @@ -31,30 +31,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD

namespace ranges {
struct __any_of {
template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
if (std::invoke(__pred, std::invoke(__proj, *__first)))
return true;
}
return false;
}

template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj);
return std::__any_of(std::move(__first), std::move(__last), __pred, __proj);
}

template <input_range _Range,
class _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
return std::__any_of(ranges::begin(__range), ranges::end(__range), __pred, __proj);
}
};

Expand Down
19 changes: 5 additions & 14 deletions libcxx/include/__algorithm/ranges_copy_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H

#include <__algorithm/copy_if.h>
#include <__algorithm/in_out_result.h>
#include <__config>
#include <__functional/identity.h>
Expand Down Expand Up @@ -37,18 +38,6 @@ template <class _Ip, class _Op>
using copy_if_result = in_out_result<_Ip, _Op>;

struct __copy_if {
template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter>
__copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
if (std::invoke(__pred, std::invoke(__proj, *__first))) {
*__result = *__first;
++__result;
}
}
return {std::move(__first), std::move(__result)};
}

template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
weakly_incrementable _OutIter,
Expand All @@ -57,7 +46,8 @@ struct __copy_if {
requires indirectly_copyable<_Iter, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter>
operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
auto __res = std::__copy_if(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
return {std::move(__res.first), std::move(__res.second)};
}

template <input_range _Range,
Expand All @@ -67,7 +57,8 @@ struct __copy_if {
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
auto __res = std::__copy_if(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
return {std::move(__res.first), std::move(__res.second)};
}
};

Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__algorithm/ranges_copy_n.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace ranges {
template <class _Ip, class _Op>
using copy_n_result = in_out_result<_Ip, _Op>;

// TODO: Merge this with copy_n
struct __copy_n {
template <class _InIter, class _DiffType, class _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
Expand Down
Loading

0 comments on commit eab7be5

Please sign in to comment.