libcxx: update to LLVM 17

release/17.x branch, commit 8f4dd44097c9ae25dd203d5ac87f3b48f854bba8

This adds the flag `-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL`. A future
enhancement could possibly pass something different if there is a
compelling parallel implementation. That libdispatch one might be worth
looking into.
This commit is contained in:
Andrew Kelley 2023-08-11 17:34:16 -07:00
parent 9ddfacd8e6
commit 5d4439cc3e
940 changed files with 46811 additions and 22346 deletions

View File

@ -20,6 +20,9 @@
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iter, class _Sent, class _BinaryPredicate>
@ -50,4 +53,6 @@ adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H

View File

@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Predicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_NODISCARD_EXT 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))

View File

@ -37,8 +37,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
return std::binary_search(__first, __last, __value,
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
return std::binary_search(__first, __last, __value, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -19,14 +19,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
#if _LIBCPP_STD_VER >= 17
template<class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY constexpr
const _Tp&
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
{
_LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
_LIBCPP_ASSERT_UNCATEGORIZED(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
}
@ -37,7 +37,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr
const _Tp&
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
{
return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>());
return _VSTD::clamp(__v, __lo, __hi, __less<>());
}
#endif

View File

@ -10,6 +10,8 @@
#define _LIBCPP___ALGORITHM_COMP_H
#include <__config>
#include <__type_traits/integral_constant.h>
#include <__type_traits/predicate_traits.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -24,41 +26,20 @@ struct __equal_to {
}
};
template <class _T1, class _T2 = _T1>
struct __less
{
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
template <class _Lhs, class _Rhs>
struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {};
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
// The definition is required because __less is part of the ABI, but it's empty
// because all comparisons should be transparent.
template <class _T1 = void, class _T2 = _T1>
struct __less {};
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
};
template <class _T1>
struct __less<_T1, _T1>
{
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
};
template <class _T1>
struct __less<const _T1, _T1>
{
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
};
template <class _T1>
struct __less<_T1, const _T1>
{
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
template <>
struct __less<void, void> {
template <class _Tp, class _Up>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const {
return __lhs < __rhs;
}
};
_LIBCPP_END_NAMESPACE_STD

View File

@ -9,8 +9,8 @@
#ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
#include <__assert>
#include <__config>
#include <__debug>
#include <__utility/declval.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@ -23,11 +23,10 @@ template <class _Compare>
struct __debug_less
{
_Compare &__comp_;
_LIBCPP_CONSTEXPR_SINCE_CXX14
__debug_less(_Compare& __c) : __comp_(__c) {}
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {}
template <class _Tp, class _Up>
_LIBCPP_CONSTEXPR_SINCE_CXX14
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
bool operator()(const _Tp& __x, const _Up& __y)
{
bool __r = __comp_(__x, __y);
@ -37,7 +36,7 @@ struct __debug_less
}
template <class _Tp, class _Up>
_LIBCPP_CONSTEXPR_SINCE_CXX14
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
bool operator()(_Tp& __x, _Up& __y)
{
bool __r = __comp_(__x, __y);
@ -52,7 +51,7 @@ struct __debug_less
decltype((void)std::declval<_Compare&>()(
std::declval<_LHS &>(), std::declval<_RHS &>()))
__do_compare_assert(int, _LHS & __l, _RHS & __r) {
_LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r),
_LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r),
"Comparator does not induce a strict weak ordering");
(void)__l;
(void)__r;
@ -66,7 +65,7 @@ struct __debug_less
// Pass the comparator by lvalue reference. Or in debug mode, using a
// debugging wrapper that stores a reference.
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
#if _LIBCPP_ENABLE_DEBUG_MODE
template <class _Comp>
using __comp_ref_type = __debug_less<_Comp>;
#else

View File

@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_COPY_H
#include <__algorithm/copy_move_common.h>
#include <__algorithm/for_each_segment.h>
#include <__algorithm/iterator_operations.h>
#include <__algorithm/min.h>
#include <__config>
@ -44,36 +45,34 @@ struct __copy_loop {
return std::make_pair(std::move(__first), std::move(__result));
}
template <class _InIter, class _OutIter>
struct _CopySegment {
using _Traits = __segmented_iterator_traits<_InIter>;
_OutIter& __result_;
_LIBCPP_HIDE_FROM_ABI _CopySegment(_OutIter& __result) : __result_(__result) {}
_LIBCPP_HIDE_FROM_ABI void
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
__result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
}
};
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_InIter>;
auto __sfirst = _Traits::__segment(__first);
auto __slast = _Traits::__segment(__last);
if (__sfirst == __slast) {
auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
return std::make_pair(__last, std::move(__iters.second));
}
__result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
++__sfirst;
while (__sfirst != __slast) {
__result =
std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
++__sfirst;
}
__result =
std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
return std::make_pair(__last, std::move(__result));
}
template <class _InIter,
class _OutIter,
__enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) {
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_OutIter>;
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
@ -98,8 +97,7 @@ struct __copy_loop {
struct __copy_trivial {
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
template <class _In, class _Out,
__enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
operator()(_In* __first, _In* __last, _Out* __result) const {
return std::__copy_trivial_impl(__first, __last, __result);

View File

@ -76,11 +76,11 @@ struct __copy_backward_loop {
template <class _InIter,
class _OutIter,
__enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) {
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_OutIter>;
auto __orig_last = __last;
auto __segment_iterator = _Traits::__segment(__result);

View File

@ -15,6 +15,7 @@
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
#include <__string/constexpr_c_functions.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_always_bitcastable.h>
#include <__type_traits/is_constant_evaluated.h>
@ -61,7 +62,8 @@ template <class _In, class _Out>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
const size_t __n = static_cast<size_t>(__last - __first);
::__builtin_memmove(__result, __first, __n * sizeof(_Out));
std::__constexpr_memmove(__result, __first, __element_count(__n));
return std::make_pair(__last, __result + __n);
}
@ -72,7 +74,7 @@ __copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
const size_t __n = static_cast<size_t>(__last - __first);
__result -= __n;
::__builtin_memmove(__result, __first, __n * sizeof(_Out));
std::__constexpr_memmove(__result, __first, __element_count(__n));
return std::make_pair(__last, __result);
}
@ -119,16 +121,6 @@ __unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) {
return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
}
template <class _IterOps, class _InValue, class _OutIter, class = void>
struct __can_copy_without_conversion : false_type {};
template <class _IterOps, class _InValue, class _OutIter>
struct __can_copy_without_conversion<
_IterOps,
_InValue,
_OutIter,
__enable_if_t<is_same<_InValue, typename _IterOps::template __value_type<_OutIter> >::value> > : true_type {};
template <class _AlgPolicy,
class _NaiveAlgorithm,
class _OptimizedAlgorithm,
@ -137,23 +129,6 @@ template <class _AlgPolicy,
class _OutIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) {
#ifdef _LIBCPP_COMPILER_GCC
// GCC doesn't support `__builtin_memmove` during constant evaluation.
if (__libcpp_is_constant_evaluated()) {
return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
}
#else
// In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is
// insufficient). Also, conversions are not supported.
if (__libcpp_is_constant_evaluated()) {
using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>;
if (!is_trivially_copyable<_InValue>::value ||
!__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) {
return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first));
}
}
#endif // _LIBCPP_COMPILER_GCC
using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>;
return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first));
}

View File

@ -12,8 +12,8 @@
#include <__algorithm/copy.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__utility/convert_to_integral.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -25,8 +25,8 @@ template<class _InputIterator, class _Size, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
typename enable_if
<
__is_cpp17_input_iterator<_InputIterator>::value &&
!__is_cpp17_random_access_iterator<_InputIterator>::value,
__has_input_iterator_category<_InputIterator>::value &&
!__has_random_access_iterator_category<_InputIterator>::value,
_OutputIterator
>::type
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
@ -51,7 +51,7 @@ template<class _InputIterator, class _Size, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
typename enable_if
<
__is_cpp17_random_access_iterator<_InputIterator>::value,
__has_random_access_iterator_category<_InputIterator>::value,
_OutputIterator
>::type
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)

View File

@ -11,9 +11,20 @@
#define _LIBCPP___ALGORITHM_EQUAL_H
#include <__algorithm/comp.h>
#include <__algorithm/unwrap_iter.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__string/constexpr_c_functions.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_equality_comparable.h>
#include <__type_traits/is_volatile.h>
#include <__type_traits/predicate_traits.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -22,23 +33,42 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
for (; __first1 != __last1; ++__first1, (void)++__first2)
if (!__pred(*__first1, *__first2))
return false;
return true;
}
template <
class _Tp,
class _Up,
class _BinaryPredicate,
__enable_if_t<__is_trivial_equality_predicate<_BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value &&
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
}
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
return std::__equal_iter_impl(
std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred);
}
template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
return std::equal(__first1, __last1, __first2, __equal_to());
}
#if _LIBCPP_STD_VER > 11
#if _LIBCPP_STD_VER >= 14
template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
_BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) {
for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
@ -47,19 +77,52 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fir
return __first1 == __last1 && __first2 == __last2;
}
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
while (__first1 != __last1 && __first2 != __last2) {
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
return false;
++__first1;
++__first2;
}
return __first1 == __last1 && __first2 == __last2;
}
template <class _Tp,
class _Up,
class _Pred,
class _Proj1,
class _Proj2,
__enable_if_t<__is_trivial_equality_predicate<_Pred, _Tp, _Up>::value && __is_identity<_Proj1>::value &&
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
}
template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
_RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
random_access_iterator_tag) {
if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
return false;
return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
_BinaryPredicate&>(__first1, __last1, __first2, __pred);
__identity __proj;
return std::__equal_impl(
std::__unwrap_iter(__first1),
std::__unwrap_iter(__last1),
std::__unwrap_iter(__first2),
std::__unwrap_iter(__last2),
__pred,
__proj,
__proj);
}
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
_BinaryPredicate __pred) {
return _VSTD::__equal<_BinaryPredicate&>(
@ -68,7 +131,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
}
template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
return std::__equal(
__first1,

View File

@ -50,7 +50,7 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
} else {
_Iter __mp1 = __mid;
return pair<_Iter, _Iter>(
std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj));
}
}
@ -75,11 +75,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
return std::equal_range(
std::move(__first),
std::move(__last),
__value,
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
return std::equal_range(std::move(__first), std::move(__last), __value, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -12,7 +12,6 @@
#include <__algorithm/fill_n.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header

View File

@ -12,7 +12,6 @@
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__utility/convert_to_integral.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header

View File

@ -10,7 +10,16 @@
#ifndef _LIBCPP___ALGORITHM_FIND_H
#define _LIBCPP___ALGORITHM_FIND_H
#include <__algorithm/unwrap_iter.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__string/constexpr_c_functions.h>
#include <__type_traits/is_same.h>
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
# include <cwchar>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -18,13 +27,49 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iter, class _Sent, class _Tp, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
__find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
for (; __first != __last; ++__first)
if (std::__invoke(__proj, *__first) == __value)
break;
return __first;
}
template <class _Tp,
class _Up,
class _Proj,
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
sizeof(_Tp) == 1,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
return __ret;
return __last;
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class _Tp,
class _Up,
class _Proj,
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
return __ret;
return __last;
}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class _InputIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
for (; __first != __last; ++__first)
if (*__first == __value)
break;
return __first;
__identity __proj;
return std::__rewrap_iter(
__first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -15,12 +15,12 @@
#include <__algorithm/search.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__iterator/advance.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
#include <__iterator/reverse_iterator.h>
#include <__utility/pair.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header

View File

@ -12,7 +12,6 @@
#include <__config>
#include <__utility/convert_to_integral.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -20,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
#if _LIBCPP_STD_VER >= 17
template <class _InputIterator, class _Size, class _Function>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first,

View File

@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
#define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
#include <__config>
#include <__iterator/segmented_iterator.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// __for_each_segment is a utility function for optimizing iterating over segmented iterators linearly.
// __first and __last are expected to be a segmented range. __func is expected to take a range of local iterators.
// Anything that is returned from __func is ignored.
template <class _SegmentedIterator, class _Functor>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
auto __sfirst = _Traits::__segment(__first);
auto __slast = _Traits::__segment(__last);
// We are in a single segment, so we might not be at the beginning or end
if (__sfirst == __slast) {
__func(_Traits::__local(__first), _Traits::__local(__last));
return;
}
// We have more than one segment. Iterate over the first segment, since we might not start at the beginning
__func(_Traits::__local(__first), _Traits::__end(__sfirst));
++__sfirst;
// iterate over the segments which are guaranteed to be completely in the range
while (__sfirst != __slast) {
__func(_Traits::__begin(__sfirst), _Traits::__end(__sfirst));
++__sfirst;
}
// iterate over the last segment
__func(_Traits::__begin(__sfirst), _Traits::__local(__last));
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H

View File

@ -11,7 +11,6 @@
#include <__config>
#include <__utility/convert_to_integral.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header

View File

@ -10,7 +10,9 @@
#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
#include <__config>
#include <type_traits>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_integral.h>
#include <__type_traits/make_unsigned.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header

View File

@ -18,7 +18,7 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
@ -44,6 +44,6 @@ struct in_found_result {
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H

View File

@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
namespace ranges {
template <class _InIter1, class _Func1>
@ -42,7 +42,7 @@ struct in_fun_result {
};
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD

View File

@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
namespace ranges {
@ -49,7 +49,7 @@ struct in_in_out_result {
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD

View File

@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
namespace ranges {
@ -46,7 +46,7 @@ struct in_in_result {
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD

View File

@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
namespace ranges {
template <class _InIter1, class _OutIter1, class _OutIter2>
@ -47,7 +47,7 @@ struct in_out_out_result {
};
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD

View File

@ -18,9 +18,12 @@
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
namespace ranges {
@ -46,8 +49,10 @@ struct in_out_result {
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H

View File

@ -61,13 +61,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
return std::includes(
std::move(__first1),
std::move(__last1),
std::move(__first2),
std::move(__last2),
__less<typename iterator_traits<_InputIterator1>::value_type,
typename iterator_traits<_InputIterator2>::value_type>());
return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -246,8 +246,7 @@ inline _LIBCPP_HIDE_FROM_ABI
void
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
{
std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last),
__less<typename iterator_traits<_BidirectionalIterator>::value_type>());
std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
return _VSTD::is_heap(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -58,7 +58,7 @@ template<class _RandomAccessIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
return _VSTD::__is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
return _VSTD::__is_heap_until(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -19,19 +19,22 @@
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
#include <__type_traits/is_callable.h>
#include <__utility/move.h>
#include <type_traits>
#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 _Iter1, class _Sent1, class _Iter2, class _Sent2, class = void>
struct _ConstTimeDistance : false_type {};
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2>
struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t<
@ -47,7 +50,7 @@ struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t<
is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value
> > : true_type {};
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
// Internal functions
@ -202,7 +205,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt
return std::is_permutation(__first1, __last1, __first2, __equal_to());
}
#if _LIBCPP_STD_VER > 11
#if _LIBCPP_STD_VER >= 14
// 2+2 iterators
template <class _ForwardIterator1, class _ForwardIterator2>
@ -231,8 +234,10 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt
__pred, __identity(), __identity());
}
#endif // _LIBCPP_STD_VER > 11
#endif // _LIBCPP_STD_VER >= 14
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H

View File

@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
is_sorted(_ForwardIterator __first, _ForwardIterator __last)
{
return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
return _VSTD::is_sorted(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -48,7 +48,7 @@ template<class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
{
return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
return _VSTD::is_sorted_until(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -33,11 +33,14 @@
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy> struct _IterOps;
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
struct _RangeAlgPolicy {};
template <>
@ -172,4 +175,6 @@ struct _IterOps<_ClassicAlgPolicy> {
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H

View File

@ -52,9 +52,7 @@ bool
lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2)
{
return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
__less<typename iterator_traits<_InputIterator1>::value_type,
typename iterator_traits<_InputIterator2>::value_type>());
return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -0,0 +1,125 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
#include <__algorithm/min.h>
#include <__algorithm/three_way_comp_ref_type.h>
#include <__compare/compare_three_way.h>
#include <__compare/ordering.h>
#include <__concepts/arithmetic.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/common_type.h>
#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
// Fast path for random access iterators which computes the number of loop iterations up-front and
// then skips the iterator comparisons inside the loop.
template <class _InputIterator1, class _InputIterator2, class _Cmp>
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
-> decltype(__comp(*__first1, *__first2)) {
static_assert(
signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior.");
static_assert(
signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior.");
using _Len1 = __iter_diff_t<_InputIterator1>;
using _Len2 = __iter_diff_t<_InputIterator2>;
using _Common = common_type_t<_Len1, _Len2>;
_Len1 __len1 = __last1 - __first1;
_Len2 __len2 = __last2 - __first2;
_Common __min_len = std::min<_Common>(__len1, __len2);
for (_Common __i = 0; __i < __min_len; ++__i) {
auto __c = __comp(*__first1, *__first2);
if (__c != 0) {
return __c;
}
++__first1;
++__first2;
}
return __len1 <=> __len2;
}
// Unoptimized implementation which compares the iterators against the end in every loop iteration
template <class _InputIterator1, class _InputIterator2, class _Cmp>
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_path(
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
-> decltype(__comp(*__first1, *__first2)) {
while (true) {
bool __exhausted1 = __first1 == __last1;
bool __exhausted2 = __first2 == __last2;
if (__exhausted1 || __exhausted2) {
if (!__exhausted1)
return strong_ordering::greater;
if (!__exhausted2)
return strong_ordering::less;
return strong_ordering::equal;
}
auto __c = __comp(*__first1, *__first2);
if (__c != 0) {
return __c;
}
++__first1;
++__first2;
}
}
template <class _InputIterator1, class _InputIterator2, class _Cmp>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp)
-> decltype(__comp(*__first1, *__first2)) {
static_assert(__comparison_category<decltype(__comp(*__first1, *__first2))>,
"The comparator passed to lexicographical_compare_three_way must return a comparison category type.");
static_assert(std::is_copy_constructible_v<_InputIterator1>, "Iterators must be copy constructible.");
static_assert(std::is_copy_constructible_v<_InputIterator2>, "Iterators must be copy constructible.");
__three_way_comp_ref_type<_Cmp> __wrapped_comp_ref(__comp);
if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
__has_random_access_iterator_category<_InputIterator2>::value) {
return std::__lexicographical_compare_three_way_fast_path(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
} else {
// Unoptimized implementation which compares the iterators against the end in every loop iteration
return std::__lexicographical_compare_three_way_slow_path(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
}
}
template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
return std::lexicographical_compare_three_way(
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way());
}
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H

View File

@ -20,7 +20,6 @@
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_callable.h>
#include <__type_traits/remove_reference.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -30,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
_Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
while (__len != 0) {
@ -53,14 +52,13 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last,
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
"The comparator has to be callable");
auto __proj = std::__identity();
return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
}
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
return std::lower_bound(__first, __last, __value,
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
return std::lower_bound(__first, __last, __value, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -21,6 +21,9 @@
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
@ -47,10 +50,11 @@ void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::make_heap(std::move(__first), std::move(__last),
__less<typename iterator_traits<_RandomAccessIterator>::value_type>());
std::make_heap(std::move(__first), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H

View File

@ -32,13 +32,14 @@ struct _ProjectedPred {
_Pred& __pred; // Can be a unary or a binary predicate.
_Proj& __proj;
_LIBCPP_CONSTEXPR _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) : __pred(__pred_arg), __proj(__proj_arg) {}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg)
: __pred(__pred_arg), __proj(__proj_arg) {}
template <class _Tp>
typename __invoke_of<_Pred&,
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))
>::type
_LIBCPP_CONSTEXPR operator()(_Tp&& __v) const {
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const {
return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v)));
}
@ -47,7 +48,7 @@ struct _ProjectedPred {
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())),
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))
>::type
_LIBCPP_CONSTEXPR operator()(_T1&& __lhs, _T2&& __rhs) const {
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const {
return std::__invoke(__pred,
std::__invoke(__proj, std::forward<_T1>(__lhs)),
std::__invoke(__proj, std::forward<_T2>(__rhs)));
@ -55,25 +56,12 @@ struct _ProjectedPred {
};
template <class _Pred, class _Proj, class = void>
struct __can_use_pristine_comp : false_type {};
template <class _Pred, class _Proj>
struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t<
!is_member_pointer<typename decay<_Pred>::type>::value && (
#if _LIBCPP_STD_VER > 17
is_same<typename decay<_Proj>::type, identity>::value ||
#endif
is_same<typename decay<_Proj>::type, __identity>::value
)
> > : true_type {};
template <class _Pred, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
__enable_if_t<
!__can_use_pristine_comp<_Pred, _Proj>::value,
_ProjectedPred<_Pred, _Proj>
>
template <class _Pred,
class _Proj,
__enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value &&
__is_identity<__decay_t<_Proj> >::value),
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj>
__make_projected(_Pred& __pred, _Proj& __proj) {
return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
}
@ -81,28 +69,27 @@ __make_projected(_Pred& __pred, _Proj& __proj) {
// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable
// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in
// the call stack when the comparator is invoked, even in an unoptimized build.
template <class _Pred, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
__enable_if_t<
__can_use_pristine_comp<_Pred, _Proj>::value,
_Pred&
>
__make_projected(_Pred& __pred, _Proj&) {
template <class _Pred,
class _Proj,
__enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value &&
__is_identity<__decay_t<_Proj> >::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) {
return __pred;
}
_LIBCPP_END_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
template <class _Comp, class _Proj1, class _Proj2>
_LIBCPP_HIDE_FROM_ABI constexpr static
_LIBCPP_HIDE_FROM_ABI constexpr
decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
if constexpr (same_as<decay_t<_Proj1>, identity> && same_as<decay_t<_Proj2>, identity> &&
if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value &&
!is_member_pointer_v<decay_t<_Comp>>) {
// Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
// optimizations that rely on the type of the comparator.
@ -121,6 +108,6 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H

View File

@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp&
max(const _Tp& __a, const _Tp& __b, _Compare __comp)
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
{
return __comp(__a, __b) ? __b : __a;
}
@ -37,9 +37,9 @@ template <class _Tp>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp&
max(const _Tp& __a, const _Tp& __b)
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
return _VSTD::max(__a, __b, __less<_Tp>());
return _VSTD::max(__a, __b, __less<>());
}
#ifndef _LIBCPP_CXX03_LANG
@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp
max(initializer_list<_Tp> __t)
{
return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
return *_VSTD::max_element(__t.begin(), __t.end(), __less<>());
}
#endif // _LIBCPP_CXX03_LANG

View File

@ -24,7 +24,7 @@ template <class _Compare, class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
"std::max_element requires a ForwardIterator");
if (__first != __last)
{
@ -48,8 +48,7 @@ template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last)
{
return _VSTD::max_element(__first, __last,
__less<typename iterator_traits<_ForwardIterator>::value_type>());
return _VSTD::max_element(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -60,9 +60,7 @@ _OutputIterator
merge(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
{
typedef typename iterator_traits<_InputIterator1>::value_type __v1;
typedef typename iterator_traits<_InputIterator2>::value_type __v2;
return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp&
min(const _Tp& __a, const _Tp& __b, _Compare __comp)
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
{
return __comp(__b, __a) ? __b : __a;
}
@ -37,9 +37,9 @@ template <class _Tp>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp&
min(const _Tp& __a, const _Tp& __b)
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
return _VSTD::min(__a, __b, __less<_Tp>());
return _VSTD::min(__a, __b, __less<>());
}
#ifndef _LIBCPP_CXX03_LANG
@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp
min(initializer_list<_Tp> __t)
{
return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
return *_VSTD::min_element(__t.begin(), __t.end(), __less<>());
}
#endif // _LIBCPP_CXX03_LANG

View File

@ -22,6 +22,9 @@
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Comp, class _Iter, class _Sent, class _Proj>
@ -49,7 +52,7 @@ template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
"std::min_element requires a ForwardIterator");
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
"The comparator has to be callable");
@ -61,10 +64,11 @@ template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last)
{
return _VSTD::min_element(__first, __last,
__less<typename iterator_traits<_ForwardIterator>::value_type>());
return _VSTD::min_element(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H

View File

@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
namespace ranges {
@ -47,7 +47,7 @@ struct min_max_result {
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD

View File

@ -27,7 +27,7 @@ template<class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<const _Tp&, const _Tp&>
minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp)
{
return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
pair<const _Tp&, const _Tp&>(__a, __b);
@ -37,9 +37,9 @@ template<class _Tp>
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<const _Tp&, const _Tp&>
minmax(const _Tp& __a, const _Tp& __b)
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
return std::minmax(__a, __b, __less<_Tp>());
return std::minmax(__a, __b, __less<>());
}
#ifndef _LIBCPP_CXX03_LANG
@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Tp, _Tp>
minmax(initializer_list<_Tp> __t)
{
return std::minmax(__t, __less<_Tp>());
return std::minmax(__t, __less<>());
}
#endif // _LIBCPP_CXX03_LANG

View File

@ -12,9 +12,10 @@
#include <__algorithm/comp.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_callable.h>
#include <__utility/pair.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -82,7 +83,7 @@ template <class _ForwardIterator, class _Compare>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
static_assert(__has_forward_iterator_category<_ForwardIterator>::value,
"std::minmax_element requires a ForwardIterator");
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
"The comparator has to be callable");
@ -93,7 +94,7 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com
template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
return std::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
return std::minmax_element(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -38,7 +38,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
return std::mismatch(__first1, __last1, __first2, __equal_to());
}
#if _LIBCPP_STD_VER > 11
#if _LIBCPP_STD_VER >= 14
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>

View File

@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_MOVE_H
#include <__algorithm/copy_move_common.h>
#include <__algorithm/for_each_segment.h>
#include <__algorithm/iterator_operations.h>
#include <__algorithm/min.h>
#include <__config>
@ -45,36 +46,34 @@ struct __move_loop {
return std::make_pair(std::move(__first), std::move(__result));
}
template <class _InIter, class _OutIter>
struct _MoveSegment {
using _Traits = __segmented_iterator_traits<_InIter>;
_OutIter& __result_;
_LIBCPP_HIDE_FROM_ABI _MoveSegment(_OutIter& __result) : __result_(__result) {}
_LIBCPP_HIDE_FROM_ABI void
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
__result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
}
};
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_InIter>;
auto __sfirst = _Traits::__segment(__first);
auto __slast = _Traits::__segment(__last);
if (__sfirst == __slast) {
auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
return std::make_pair(__last, std::move(__iters.second));
}
__result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
++__sfirst;
while (__sfirst != __slast) {
__result =
std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
++__sfirst;
}
__result =
std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
return std::make_pair(__last, std::move(__result));
}
template <class _InIter,
class _OutIter,
__enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) {
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_OutIter>;
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;

View File

@ -76,11 +76,11 @@ struct __move_backward_loop {
template <class _InIter,
class _OutIter,
__enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) {
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_OutIter>;
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;

View File

@ -69,8 +69,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
return _VSTD::next_permutation(__first, __last,
__less<typename iterator_traits<_BidirectionalIterator>::value_type>());
return _VSTD::next_permutation(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -14,7 +14,6 @@
#include <__algorithm/iterator_operations.h>
#include <__algorithm/sort.h>
#include <__config>
#include <__debug>
#include <__debug_utils/randomize_range.h>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
@ -249,8 +248,7 @@ void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Ra
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<typename
iterator_traits<_RandomAccessIterator>::value_type>());
std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -16,11 +16,11 @@
#include <__algorithm/sift_down.h>
#include <__algorithm/sort_heap.h>
#include <__config>
#include <__debug>
#include <__debug_utils/randomize_range.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_copy_assignable.h>
#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@ -87,8 +87,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
void
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
{
_VSTD::partial_sort(__first, __middle, __last,
__less<typename iterator_traits<_RandomAccessIterator>::value_type>());
_VSTD::partial_sort(__first, __middle, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -79,8 +79,7 @@ _RandomAccessIterator
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
{
return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
__less<typename iterator_traits<_RandomAccessIterator>::value_type>());
return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -14,7 +14,6 @@
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
#include <__utility/pair.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header

View File

@ -17,20 +17,24 @@
#include <__assert>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_copy_assignable.h>
#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <type_traits>
#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 _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
_LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty");
_LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty");
__comp_ref_type<_Compare> __comp_ref = __comp;
@ -64,10 +68,11 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::pop_heap(std::move(__first), std::move(__last),
__less<typename iterator_traits<_RandomAccessIterator>::value_type>());
std::pop_heap(std::move(__first), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_POP_HEAP_H

View File

@ -70,8 +70,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
return _VSTD::prev_permutation(__first, __last,
__less<typename iterator_traits<_BidirectionalIterator>::value_type>());
return _VSTD::prev_permutation(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -0,0 +1,100 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H
#include <__algorithm/pstl_find.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
void __pstl_any_of(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
return std::find_if(__policy, __g_first, __g_last, __g_pred) != __g_last;
},
std::move(__first),
std::move(__last),
std::move(__pred));
}
template <class>
void __pstl_all_of(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Pred,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
return !std::any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
return !__g_pred(__value);
});
},
std::move(__first),
std::move(__last),
std::move(__pred));
}
template <class>
void __pstl_none_of(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Pred,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
return !std::any_of(__policy, __g_first, __g_last, __g_pred);
},
std::move(__first),
std::move(__last),
std::move(__pred));
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H

View File

@ -0,0 +1,198 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKEND_H
#define _LIBCPP___ALGORITHM_PSTL_BACKEND_H
#include <__algorithm/pstl_backends/cpu_backend.h>
#include <__config>
#include <execution>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
/*
TODO: Documentation of how backends work
A PSTL parallel backend is a tag type to which the following functions are associated, at minimum:
template <class _ExecutionPolicy, class _Iterator, class _Func>
void __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
_Iterator __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
void __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation>
_OutIterator __pstl_transform(_InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op);
template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation>
_OutIterator __pstl_transform(_InIterator1 __first1,
_InIterator1 __last1,
_InIterator2 __first2,
_OutIterator __result,
_BinaryOperation __op);
template <class _ExecutionPolicy,
class _Iterator1,
class _Iterator2,
class _Tp,
class _BinaryOperation1,
class _BinaryOperation2>
_Tp __pstl_transform_reduce(_Backend,
_Iterator1 __first1,
_Iterator1 __last1,
_Iterator2 __first2,
_Iterator2 __last2,
_Tp __init,
_BinaryOperation1 __reduce,
_BinaryOperation2 __transform);
template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
_Tp __pstl_transform_reduce(_Backend,
_Iterator __first,
_Iterator __last,
_Tp __init,
_BinaryOperation __reduce,
_UnaryOperation __transform);
// TODO: Complete this list
The following functions are optional but can be provided. If provided, they are used by the corresponding
algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are
implemented, all the algorithms will eventually forward to the basis algorithms listed above:
template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func>
void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
bool __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
template <class _ExecutionPolicy, class _Iterator, class _Tp>
_Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
_Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
template <class _ExecutionPolicy, class _Iterator, class _Tp>
void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp>
void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
template <class _ExecutionPolicy, class _Iterator, class _Generator>
void __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
void __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator>
void __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp>
_OutIterator __pstl_merge(_Backend,
_Iterator1 __first1,
_Iterator1 __last1,
_Iterator2 __first2,
_Iterator2 __last2,
_OutIterator __result,
_Comp __comp);
template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation>
_Tp __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
temlate <class _ExecutionPolicy, class _Iterator>
__iter_value_type<_Iterator> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
template <class _ExecuitonPolicy, class _Iterator, class _Tp>
__iter_diff_t<_Iterator> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
__iter_diff_t<_Iterator> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
template <class _ExecutionPolicy, class _Iterator, class _Tp>
void __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp>
void __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp>
void __pstl_replace_copy(_Backend,
_Iterator __first,
_Iterator __last,
_OutIterator __result,
const _Tp& __old_value,
const _Tp& __new_value);
template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp>
void __pstl_replace_copy_if(_Backend,
_Iterator __first,
_Iterator __last,
_OutIterator __result,
_Pred __pred,
const _Tp& __new_value);
template <class _ExecutionPolicy, class _Iterator, class _Comp>
void __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
// TODO: Complete this list
*/
template <class _ExecutionPolicy>
struct __select_backend;
template <>
struct __select_backend<std::execution::sequenced_policy> {
using type = __cpu_backend_tag;
};
# if _LIBCPP_STD_VER >= 20
template <>
struct __select_backend<std::execution::unsequenced_policy> {
using type = __cpu_backend_tag;
};
# endif
# if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) || defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) || \
defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
template <>
struct __select_backend<std::execution::parallel_policy> {
using type = __cpu_backend_tag;
};
template <>
struct __select_backend<std::execution::parallel_unsequenced_policy> {
using type = __cpu_backend_tag;
};
# else
// ...New vendors can add parallel backends here...
# error "Invalid choice of a PSTL parallel backend"
# endif
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKEND_H

View File

@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H
#include <__config>
/*
// _Functor takes a subrange for [__first, __last) that should be executed in serial
template <class _RandomAccessIterator, class _Functor>
void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func);
template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction>
_Tp __parallel_transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction);
// Cancel the execution of other jobs - they aren't needed anymore
void __cancel_execution();
template <class _RandomAccessIterator1,
class _RandomAccessIterator2,
class _RandomAccessIterator3,
class _Compare,
class _LeafMerge>
void __parallel_merge(
_RandomAccessIterator1 __first1,
_RandomAccessIterator1 __last1,
_RandomAccessIterator2 __first2,
_RandomAccessIterator2 __last2,
_RandomAccessIterator3 __outit,
_Compare __comp,
_LeafMerge __leaf_merge);
template <class _RandomAccessIterator, class _Comp, class _LeafSort>
void __parallel_stable_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Comp __comp,
_LeafSort __leaf_sort);
TODO: Document the parallel backend
*/
#include <__algorithm/pstl_backends/cpu_backends/any_of.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__algorithm/pstl_backends/cpu_backends/fill.h>
#include <__algorithm/pstl_backends/cpu_backends/find_if.h>
#include <__algorithm/pstl_backends/cpu_backends/for_each.h>
#include <__algorithm/pstl_backends/cpu_backends/merge.h>
#include <__algorithm/pstl_backends/cpu_backends/stable_sort.h>
#include <__algorithm/pstl_backends/cpu_backends/transform.h>
#include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h>
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H

View File

@ -0,0 +1,90 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H
#include <__algorithm/any_of.h>
#include <__algorithm/find_if.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__atomic/atomic.h>
#include <__atomic/memory_order.h>
#include <__config>
#include <__functional/operations.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/pair.h>
#include <__utility/terminate_on_exception.h>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Index, class _Brick>
_LIBCPP_HIDE_FROM_ABI bool __parallel_or(_Index __first, _Index __last, _Brick __f) {
std::atomic<bool> __found(false);
__par_backend::__parallel_for(__first, __last, [__f, &__found](_Index __i, _Index __j) {
if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) {
__found.store(true, std::memory_order_relaxed);
__par_backend::__cancel_execution();
}
});
return __found;
}
// TODO: check whether __simd_first() can be used here
template <class _Index, class _DifferenceType, class _Pred>
_LIBCPP_HIDE_FROM_ABI bool __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept {
_DifferenceType __block_size = 4 < __n ? 4 : __n;
const _Index __last = __first + __n;
while (__last != __first) {
int32_t __flag = 1;
_PSTL_PRAGMA_SIMD_REDUCTION(& : __flag)
for (_DifferenceType __i = 0; __i < __block_size; ++__i)
if (__pred(*(__first + __i)))
__flag = 0;
if (!__flag)
return true;
__first += __block_size;
if (__last - __first >= __block_size << 1) {
// Double the block _Size. Any unnecessary iterations can be amortized against work done so far.
__block_size <<= 1;
} else {
__block_size = __last - __first;
}
}
return false;
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
_LIBCPP_HIDE_FROM_ABI bool
__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
return std::__terminate_on_exception([&] {
return std::__parallel_or(
__first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
return std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __pred);
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
return std::__simd_or(__first, __last - __first, __pred);
} else {
return std::any_of(__first, __last, __pred);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H

View File

@ -0,0 +1,41 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H
#include <__config>
#include <cstddef>
#if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL)
# include <__algorithm/pstl_backends/cpu_backends/serial.h>
#elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD)
# include <__algorithm/pstl_backends/cpu_backends/thread.h>
#elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH)
# include <__algorithm/pstl_backends/cpu_backends/libdispatch.h>
#else
# error "Invalid CPU backend choice"
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
struct __cpu_backend_tag {};
inline constexpr size_t __lane_size = 64;
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H

View File

@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H
#include <__algorithm/fill.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Index, class _DifferenceType, class _Tp>
_LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept {
_PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
_PSTL_PRAGMA_SIMD
for (_DifferenceType __i = 0; __i < __n; ++__i)
__first[__i] = __value;
return __first + __n;
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
_LIBCPP_HIDE_FROM_ABI void
__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
std::__terminate_on_exception([&] {
__par_backend::__parallel_for(
__first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __value);
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
std::__simd_fill_n(__first, __last - __first, __value);
} else {
std::fill(__first, __last, __value);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H

View File

@ -0,0 +1,123 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H
#include <__algorithm/find_if.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__atomic/atomic.h>
#include <__config>
#include <__functional/operations.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/pair.h>
#include <__utility/terminate_on_exception.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Index, class _Brick, class _Compare>
_LIBCPP_HIDE_FROM_ABI _Index
__parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) {
typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
const _DifferenceType __n = __last - __first;
_DifferenceType __initial_dist = __b_first ? __n : -1;
std::atomic<_DifferenceType> __extremum(__initial_dist);
// TODO: find out what is better here: parallel_for or parallel_reduce
__par_backend::__parallel_for(__first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
// See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
// why using a shared variable scales fairly well in this situation.
if (__comp(__i - __first, __extremum)) {
_Index __res = __f(__i, __j);
// If not '__last' returned then we found what we want so put this to extremum
if (__res != __j) {
const _DifferenceType __k = __res - __first;
for (_DifferenceType __old = __extremum; __comp(__k, __old); __old = __extremum) {
__extremum.compare_exchange_weak(__old, __k);
}
}
}
});
return __extremum != __initial_dist ? __first + __extremum : __last;
}
template <class _Index, class _DifferenceType, class _Compare>
_LIBCPP_HIDE_FROM_ABI _Index
__simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept {
// Experiments show good block sizes like this
const _DifferenceType __block_size = 8;
alignas(__lane_size) _DifferenceType __lane[__block_size] = {0};
while (__end - __begin >= __block_size) {
_DifferenceType __found = 0;
_PSTL_PRAGMA_SIMD_REDUCTION(| : __found) for (_DifferenceType __i = __begin; __i < __begin + __block_size; ++__i) {
const _DifferenceType __t = __comp(__first, __i);
__lane[__i - __begin] = __t;
__found |= __t;
}
if (__found) {
_DifferenceType __i;
// This will vectorize
for (__i = 0; __i < __block_size; ++__i) {
if (__lane[__i]) {
break;
}
}
return __first + __begin + __i;
}
__begin += __block_size;
}
// Keep remainder scalar
while (__begin != __end) {
if (__comp(__first, __begin)) {
return __first + __begin;
}
++__begin;
}
return __first + __end;
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
return std::__terminate_on_exception([&] {
return std::__parallel_find(
__first,
__last,
[&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
return std::__pstl_find_if<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __pred);
},
less<>{},
true);
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
using __diff_t = __iter_diff_t<_ForwardIterator>;
return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
return __pred(__iter[__i]);
});
} else {
return std::find_if(__first, __last, __pred);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H

View File

@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H
#include <__algorithm/for_each.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iterator, class _DifferenceType, class _Function>
_LIBCPP_HIDE_FROM_ABI _Iterator __simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept {
_PSTL_PRAGMA_SIMD
for (_DifferenceType __i = 0; __i < __n; ++__i)
__f(__first[__i]);
return __first + __n;
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Functor>
_LIBCPP_HIDE_FROM_ABI void
__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
std::__terminate_on_exception([&] {
std::__par_backend::__parallel_for(
__first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __func);
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
std::__simd_walk_1(__first, __last - __first, __func);
} else {
std::for_each(__first, __last, __func);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H

View File

@ -0,0 +1,241 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H
#include <__algorithm/lower_bound.h>
#include <__algorithm/max.h>
#include <__algorithm/upper_bound.h>
#include <__atomic/atomic.h>
#include <__config>
#include <__exception/terminate.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/move_iterator.h>
#include <__memory/allocator.h>
#include <__memory/construct_at.h>
#include <__memory/unique_ptr.h>
#include <__numeric/reduce.h>
#include <__utility/exception_guard.h>
#include <__utility/move.h>
#include <__utility/pair.h>
#include <__utility/terminate_on_exception.h>
#include <cstddef>
#include <new>
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __par_backend {
inline namespace __libdispatch {
// ::dispatch_apply is marked as __attribute__((nothrow)) because it doesn't let exceptions propagate, and neither do
// we.
// TODO: Do we want to add [[_Clang::__callback__(__func, __context, __)]]?
_LIBCPP_EXPORTED_FROM_ABI void
__dispatch_apply(size_t __chunk_count, void* __context, void (*__func)(void* __context, size_t __chunk)) noexcept;
template <class _Func>
_LIBCPP_HIDE_FROM_ABI void __dispatch_apply(size_t __chunk_count, _Func __func) noexcept {
__libdispatch::__dispatch_apply(__chunk_count, &__func, [](void* __context, size_t __chunk) {
(*static_cast<_Func*>(__context))(__chunk);
});
}
struct __chunk_partitions {
ptrdiff_t __chunk_count_; // includes the first chunk
ptrdiff_t __chunk_size_;
ptrdiff_t __first_chunk_size_;
};
[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI __chunk_partitions __partition_chunks(ptrdiff_t __size);
template <class _RandomAccessIterator, class _Functor>
_LIBCPP_HIDE_FROM_ABI void
__parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func) {
auto __partitions = __libdispatch::__partition_chunks(__last - __first);
// Perform the chunked execution.
__libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
auto __index =
__chunk == 0
? 0
: (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
__func(__first + __index, __first + __index + __this_chunk_size);
});
}
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut>
struct __merge_range {
__merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result)
: __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {}
_RandomAccessIterator1 __mid1_;
_RandomAccessIterator2 __mid2_;
_RandomAccessIteratorOut __result_;
};
template <typename _RandomAccessIterator1,
typename _RandomAccessIterator2,
typename _RandomAccessIterator3,
typename _Compare,
typename _LeafMerge>
_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
_RandomAccessIterator1 __first1,
_RandomAccessIterator1 __last1,
_RandomAccessIterator2 __first2,
_RandomAccessIterator2 __last2,
_RandomAccessIterator3 __result,
_Compare __comp,
_LeafMerge __leaf_merge) {
__chunk_partitions __partitions =
__libdispatch::__partition_chunks(std::max<ptrdiff_t>(__last1 - __first1, __last2 - __first2));
if (__partitions.__chunk_count_ == 0)
return;
if (__partitions.__chunk_count_ == 1) {
__leaf_merge(__first1, __last1, __first2, __last2, __result, __comp);
return;
}
using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>;
auto const __n_ranges = __partitions.__chunk_count_ + 1;
// TODO: use __uninitialized_buffer
auto __destroy = [=](__merge_range_t* __ptr) {
std::destroy_n(__ptr, __n_ranges);
std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges);
};
unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges(
std::allocator<__merge_range_t>().allocate(__n_ranges), __destroy);
// TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case
std::__terminate_on_exception([&] {
__merge_range_t* __r = __ranges.get();
std::__construct_at(__r++, __first1, __first2, __result);
bool __iterate_first_range = __last1 - __first1 > __last2 - __first2;
auto __compute_chunk = [&](size_t __chunk_size) -> __merge_range_t {
auto [__mid1, __mid2] = [&] {
if (__iterate_first_range) {
auto __m1 = __first1 + __chunk_size;
auto __m2 = std::lower_bound(__first2, __last2, __m1[-1], __comp);
return std::make_pair(__m1, __m2);
} else {
auto __m2 = __first2 + __chunk_size;
auto __m1 = std::lower_bound(__first1, __last1, __m2[-1], __comp);
return std::make_pair(__m1, __m2);
}
}();
__result += (__mid1 - __first1) + (__mid2 - __first2);
__first1 = __mid1;
__first2 = __mid2;
return {std::move(__mid1), std::move(__mid2), __result};
};
// handle first chunk
std::__construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_));
// handle 2 -> N - 1 chunks
for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i)
std::__construct_at(__r++, __compute_chunk(__partitions.__chunk_size_));
// handle last chunk
std::__construct_at(__r, __last1, __last2, __result);
__libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) {
auto __first_iters = __ranges[__index];
auto __last_iters = __ranges[__index + 1];
__leaf_merge(
__first_iters.__mid1_,
__last_iters.__mid1_,
__first_iters.__mid2_,
__last_iters.__mid2_,
__first_iters.__result_,
__comp);
});
});
}
template <class _RandomAccessIterator, class _Transform, class _Value, class _Combiner, class _Reduction>
_LIBCPP_HIDE_FROM_ABI _Value __parallel_transform_reduce(
_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Transform __transform,
_Value __init,
_Combiner __combiner,
_Reduction __reduction) {
if (__first == __last)
return __init;
auto __partitions = __libdispatch::__partition_chunks(__last - __first);
auto __destroy = [__count = __partitions.__chunk_count_](_Value* __ptr) {
std::destroy_n(__ptr, __count);
std::allocator<_Value>().deallocate(__ptr, __count);
};
// TODO: use __uninitialized_buffer
// TODO: allocate one element per worker instead of one element per chunk
unique_ptr<_Value[], decltype(__destroy)> __values(
std::allocator<_Value>().allocate(__partitions.__chunk_count_), __destroy);
// __dispatch_apply is noexcept
__libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) {
auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_;
auto __index =
__chunk == 0
? 0
: (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_);
if (__this_chunk_size != 1) {
std::__construct_at(
__values.get() + __chunk,
__reduction(__first + __index + 2,
__first + __index + __this_chunk_size,
__combiner(__transform(__first + __index), __transform(__first + __index + 1))));
} else {
std::__construct_at(__values.get() + __chunk, __transform(__first + __index));
}
});
return std::__terminate_on_exception([&] {
return std::reduce(
std::make_move_iterator(__values.get()),
std::make_move_iterator(__values.get() + __partitions.__chunk_count_),
std::move(__init),
__combiner);
});
}
// TODO: parallelize this
template <class _RandomAccessIterator, class _Comp, class _LeafSort>
_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp, _LeafSort __leaf_sort) {
__leaf_sort(__first, __last, __comp);
}
_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
} // namespace __libdispatch
} // namespace __par_backend
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H

View File

@ -0,0 +1,79 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H
#include <__algorithm/merge.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _ForwardOutIterator,
class _Comp>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_merge(
__cpu_backend_tag,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_ForwardOutIterator __result,
_Comp __comp) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
return std::__terminate_on_exception([&] {
__par_backend::__parallel_merge(
__first1,
__last1,
__first2,
__last2,
__result,
__comp,
[](_ForwardIterator1 __g_first1,
_ForwardIterator1 __g_last1,
_ForwardIterator2 __g_first2,
_ForwardIterator2 __g_last2,
_ForwardOutIterator __g_result,
_Comp __g_comp) {
return std::__pstl_merge<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{},
std::move(__g_first1),
std::move(__g_last1),
std::move(__g_first2),
std::move(__g_last2),
std::move(__g_result),
std::move(__g_comp));
});
return __result + (__last1 - __first1) + (__last2 - __first2);
});
} else {
return std::merge(__first1, __last1, __first2, __last2, __result, __comp);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H

View File

@ -0,0 +1,72 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H
#include <__config>
#include <__utility/move.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __par_backend {
inline namespace __serial_cpu_backend {
template <class _RandomAccessIterator, class _Fp>
_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
__f(__first, __last);
}
template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
_LIBCPP_HIDE_FROM_ABI _Tp
__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
return __reduce(std::move(__first), std::move(__last), std::move(__init));
}
template <class _RandomAccessIterator, class _Compare, class _LeafSort>
_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
__leaf_sort(__first, __last, __comp);
}
_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
template <class _RandomAccessIterator1,
class _RandomAccessIterator2,
class _RandomAccessIterator3,
class _Compare,
class _LeafMerge>
_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
_RandomAccessIterator1 __first1,
_RandomAccessIterator1 __last1,
_RandomAccessIterator2 __first2,
_RandomAccessIterator2 __last2,
_RandomAccessIterator3 __outit,
_Compare __comp,
_LeafMerge __leaf_merge) {
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
}
// TODO: Complete this list
} // namespace __serial_cpu_backend
} // namespace __par_backend
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H

View File

@ -0,0 +1,45 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__algorithm/stable_sort.h>
#include <__config>
#include <__type_traits/is_execution_policy.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
_LIBCPP_HIDE_FROM_ABI void
__pstl_stable_sort(__cpu_backend_tag, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy>) {
std::__terminate_on_exception([&] {
__par_backend::__parallel_stable_sort(
__first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
std::stable_sort(__g_first, __g_last, __g_comp);
});
});
} else {
std::stable_sort(__first, __last, __comp);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H

View File

@ -0,0 +1,78 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H
#include <__assert>
#include <__config>
#include <__utility/move.h>
#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
// This backend implementation is for testing purposes only and not meant for production use. This will be replaced
// by a proper implementation once the PSTL implementation is somewhat stable.
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __par_backend {
inline namespace __thread_cpu_backend {
template <class _RandomAccessIterator, class _Fp>
_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) {
__f(__first, __last);
}
template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
_LIBCPP_HIDE_FROM_ABI _Tp
__parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) {
return __reduce(std::move(__first), std::move(__last), std::move(__init));
}
template <class _RandomAccessIterator, class _Compare, class _LeafSort>
_LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort(
_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) {
__leaf_sort(__first, __last, __comp);
}
_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {}
template <class _RandomAccessIterator1,
class _RandomAccessIterator2,
class _RandomAccessIterator3,
class _Compare,
class _LeafMerge>
_LIBCPP_HIDE_FROM_ABI void __parallel_merge(
_RandomAccessIterator1 __first1,
_RandomAccessIterator1 __last1,
_RandomAccessIterator2 __first2,
_RandomAccessIterator2 __last2,
_RandomAccessIterator3 __outit,
_Compare __comp,
_LeafMerge __leaf_merge) {
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
}
} // namespace __thread_cpu_backend
} // namespace __par_backend
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H

View File

@ -0,0 +1,132 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__algorithm/transform.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function>
_LIBCPP_HIDE_FROM_ABI _Iterator2
__simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept {
_PSTL_PRAGMA_SIMD
for (_DifferenceType __i = 0; __i < __n; ++__i)
__f(__first1[__i], __first2[__i]);
return __first2 + __n;
}
template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
__cpu_backend_tag,
_ForwardIterator __first,
_ForwardIterator __last,
_ForwardOutIterator __result,
_UnaryOperation __op) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
std::__terminate_on_exception([&] {
std::__par_backend::__parallel_for(
__first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op);
});
});
return __result + (__last - __first);
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
return std::__simd_walk_2(
__first,
__last - __first,
__result,
[&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) {
__out_value = __op(__in_value);
});
} else {
return std::transform(__first, __last, __result, __op);
}
}
template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function>
_LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_walk_3(
_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept {
_PSTL_PRAGMA_SIMD
for (_DifferenceType __i = 0; __i < __n; ++__i)
__f(__first1[__i], __first2[__i], __first3[__i]);
return __first3 + __n;
}
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _ForwardOutIterator,
class _BinaryOperation,
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
__cpu_backend_tag,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardOutIterator __result,
_BinaryOperation __op) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
std::__terminate_on_exception([&] {
std::__par_backend::__parallel_for(
__first1,
__last1,
[__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) {
return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{},
__brick_first,
__brick_last,
__first2 + (__brick_first - __first1),
__result + (__brick_first - __first1),
__op);
});
});
return __result + (__last1 - __first1);
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
return std::__simd_walk_3(
__first1,
__last1 - __first1,
__first2,
__result,
[&](__iter_reference<_ForwardIterator1> __in1,
__iter_reference<_ForwardIterator2> __in2,
__iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); });
} else {
return std::transform(__first1, __last1, __first2, __result, __op);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H

View File

@ -0,0 +1,194 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__numeric/transform_reduce.h>
#include <__type_traits/is_arithmetic.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/operation_traits.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#include <new>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <
typename _DifferenceType,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
__enable_if_t<__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept {
_PSTL_PRAGMA_SIMD_REDUCTION(+ : __init)
for (_DifferenceType __i = 0; __i < __n; ++__i)
__init += __f(__i);
return __init;
}
template <
typename _Size,
typename _Tp,
typename _BinaryOperation,
typename _UnaryOperation,
__enable_if_t<!(__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>), int> = 0>
_LIBCPP_HIDE_FROM_ABI _Tp
__simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept {
const _Size __block_size = __lane_size / sizeof(_Tp);
if (__n > 2 * __block_size && __block_size > 1) {
alignas(__lane_size) char __lane_buffer[__lane_size];
_Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer);
// initializer
_PSTL_PRAGMA_SIMD
for (_Size __i = 0; __i < __block_size; ++__i) {
::new (__lane + __i) _Tp(__binary_op(__f(__i), __f(__block_size + __i)));
}
// main loop
_Size __i = 2 * __block_size;
const _Size __last_iteration = __block_size * (__n / __block_size);
for (; __i < __last_iteration; __i += __block_size) {
_PSTL_PRAGMA_SIMD
for (_Size __j = 0; __j < __block_size; ++__j) {
__lane[__j] = __binary_op(std::move(__lane[__j]), __f(__i + __j));
}
}
// remainder
_PSTL_PRAGMA_SIMD
for (_Size __j = 0; __j < __n - __last_iteration; ++__j) {
__lane[__j] = __binary_op(std::move(__lane[__j]), __f(__last_iteration + __j));
}
// combiner
for (_Size __j = 0; __j < __block_size; ++__j) {
__init = __binary_op(std::move(__init), std::move(__lane[__j]));
}
// destroyer
_PSTL_PRAGMA_SIMD
for (_Size __j = 0; __j < __block_size; ++__j) {
__lane[__j].~_Tp();
}
} else {
for (_Size __i = 0; __i < __n; ++__i) {
__init = __binary_op(std::move(__init), __f(__i));
}
}
return __init;
}
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _Tp,
class _BinaryOperation1,
class _BinaryOperation2>
_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
__cpu_backend_tag,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_Tp __init,
_BinaryOperation1 __reduce,
_BinaryOperation2 __transform) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value) {
return std::__terminate_on_exception([&] {
return __par_backend::__parallel_transform_reduce(
__first1,
std::move(__last1),
[__first1, __first2, __transform](_ForwardIterator1 __iter) {
return __transform(*__iter, *(__first2 + (__iter - __first1)));
},
std::move(__init),
std::move(__reduce),
[__first1, __first2, __reduce, __transform](
_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last, _Tp __brick_init) {
return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{},
__brick_first,
std::move(__brick_last),
__first2 + (__brick_first - __first1),
std::move(__brick_init),
std::move(__reduce),
std::move(__transform));
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value) {
return std::__simd_transform_reduce(
__last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
return __transform(__first1[__i], __first2[__i]);
});
} else {
return std::transform_reduce(
std::move(__first1),
std::move(__last1),
std::move(__first2),
std::move(__init),
std::move(__reduce),
std::move(__transform));
}
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
_LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
__cpu_backend_tag,
_ForwardIterator __first,
_ForwardIterator __last,
_Tp __init,
_BinaryOperation __reduce,
_UnaryOperation __transform) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
return std::__terminate_on_exception([&] {
return __par_backend::__parallel_transform_reduce(
std::move(__first),
std::move(__last),
[__transform](_ForwardIterator __iter) { return __transform(*__iter); },
std::move(__init),
__reduce,
[__transform, __reduce](auto __brick_first, auto __brick_last, _Tp __brick_init) {
return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>(
__cpu_backend_tag{},
std::move(__brick_first),
std::move(__brick_last),
std::move(__brick_init),
std::move(__reduce),
std::move(__transform));
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
return std::__simd_transform_reduce(
__last - __first,
std::move(__init),
std::move(__reduce),
[=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); });
} else {
return std::transform_reduce(
std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform));
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H

View File

@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H
#define _LIBCPP___ALGORITHM_PSTL_COPY_H
#include <__algorithm/copy_n.h>
#include <__algorithm/pstl_transform.h>
#include <__config>
#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/is_trivially_copyable.h>
#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
// TODO: Use the std::copy/move shenanigans to forward to std::memmove
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
return std::transform(__policy, __first, __last, __result, __identity());
}
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
class _Size,
enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
return std::copy(__policy, __first, __first + __n, __result);
else
return std::copy_n(__first, __n, __result);
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_COPY_H

View File

@ -0,0 +1,89 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_COUNT_H
#define _LIBCPP___ALGORITHM_PSTL_COUNT_H
#include <__algorithm/count.h>
#include <__algorithm/for_each.h>
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_for_each.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__atomic/atomic.h>
#include <__config>
#include <__functional/operations.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/pstl_transform_reduce.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
void __pstl_count_if(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
using __diff_t = __iter_diff_t<_ForwardIterator>;
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count_if),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
return std::transform_reduce(
__policy,
std::move(__g_first),
std::move(__g_last),
__diff_t(),
std::plus{},
[&](__iter_reference<_ForwardIterator> __element) -> bool { return __g_pred(__element); });
},
std::move(__first),
std::move(__last),
std::move(__pred));
}
template <class>
void __pstl_count(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
return std::count_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __v) {
return __v == __g_value;
});
},
std::move(__first),
std::move(__last),
__value);
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_COUNT_H

View File

@ -0,0 +1,84 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_FILL_H
#define _LIBCPP___ALGORITHM_PSTL_FILL_H
#include <__algorithm/fill_n.h>
#include <__algorithm/pstl_for_each.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
void __pstl_fill(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
__element = __g_value;
});
},
std::move(__first),
std::move(__last),
__value);
}
template <class>
void __pstl_fill_n(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _SizeT,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n),
[&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
std::fill(__policy, __g_first, __g_first + __g_n, __g_value);
else
std::fill_n(__g_first, __g_n, __g_value);
},
std::move(__first),
__n,
__value);
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_FILL_H

View File

@ -0,0 +1,95 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_FIND_H
#define _LIBCPP___ALGORITHM_PSTL_FIND_H
#include <__algorithm/comp.h>
#include <__algorithm/find.h>
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
using _Backend = typename __select_backend<_RawPolicy>::type;
return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred));
}
template <class>
void __pstl_find_if_not();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) {
return !__g_pred(__value);
});
},
std::move(__first),
std::move(__last),
std::move(__pred));
}
template <class>
void __pstl_find();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find),
[&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
return __element == __g_value;
});
},
std::move(__first),
std::move(__last),
__value);
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_FIND_H

View File

@ -0,0 +1,76 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
#define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H
#include <__algorithm/for_each.h>
#include <__algorithm/for_each_n.h>
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/void_t.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Function,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
using _Backend = typename __select_backend<_RawPolicy>::type;
std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func));
}
template <class>
void __pstl_for_each_n(); // declaration needed for the frontend dispatch below
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Size,
class _Function,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n),
[&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) {
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func));
} else {
std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func));
}
},
__first,
__size,
std::move(__func));
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H

View File

@ -0,0 +1,45 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
#define _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH
#include <__config>
#include <__type_traits/is_callable.h>
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
# define _LIBCPP_PSTL_CUSTOMIZATION_POINT(name) \
[](auto&&... __args) -> decltype(std::name<_RawPolicy>(typename __select_backend<_RawPolicy>::type{}, \
std::forward<decltype(__args)>(__args)...)) { \
return std::name<_RawPolicy>( \
typename __select_backend<_RawPolicy>::type{}, std::forward<decltype(__args)>(__args)...); \
}
template <class _SpecializedImpl, class _GenericImpl, class... _Args>
_LIBCPP_HIDE_FROM_ABI decltype(auto)
__pstl_frontend_dispatch(_SpecializedImpl __specialized_impl, _GenericImpl __generic_impl, _Args&&... __args) {
if constexpr (__is_callable<_SpecializedImpl, _Args...>::value) {
return __specialized_impl(std::forward<_Args>(__args)...);
} else {
return __generic_impl(std::forward<_Args>(__args)...);
}
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH

View File

@ -0,0 +1,82 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_GENERATE_H
#define _LIBCPP___ALGORITHM_PSTL_GENERATE_H
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_for_each.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
void __pstl_generate();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Generator,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate),
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) {
std::for_each(
__policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) {
__element = __g_gen();
});
},
std::move(__first),
std::move(__last),
std::move(__gen));
}
template <class>
void __pstl_generate_n();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Size,
class _Generator,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n),
[&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) {
std::for_each_n(__policy, std::move(__g_first), __g_n, [&](__iter_reference<_ForwardIterator> __element) {
__element = __g_gen();
});
},
std::move(__first),
__n,
std::move(__gen));
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_GENERATE_H

View File

@ -0,0 +1,58 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
#define _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED
#include <__algorithm/pstl_any_all_none_of.h>
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_find.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
void __pstl_is_partitioned();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Predicate,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned),
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
__g_first = std::find_if_not(__policy, __g_first, __g_last, __g_pred);
if (__g_first == __g_last)
return true;
++__g_first;
return std::none_of(__policy, __g_first, __g_last, __g_pred);
},
std::move(__first),
std::move(__last),
std::move(__pred));
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED

View File

@ -0,0 +1,58 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H
#define _LIBCPP___ALGORITHM_PSTL_MERGE_H
#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__functional/operations.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _ForwardOutIterator,
class _Comp = std::less<>,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
merge(_ExecutionPolicy&&,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_ForwardOutIterator __result,
_Comp __comp = {}) {
using _Backend = typename __select_backend<_RawPolicy>::type;
return std::__pstl_merge<_RawPolicy>(
_Backend{},
std::move(__first1),
std::move(__last1),
std::move(__first2),
std::move(__last2),
std::move(__result),
std::move(__comp));
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_MERGE_H

View File

@ -0,0 +1,167 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_REPLACE_H
#define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_for_each.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__algorithm/pstl_transform.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
void __pstl_replace_if();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Pred,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
replace_if(_ExecutionPolicy&& __policy,
_ForwardIterator __first,
_ForwardIterator __last,
_Pred __pred,
const _Tp& __new_value) {
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if),
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred, const _Tp& __g_new_value) {
std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
if (__g_pred(__element))
__element = __g_new_value;
});
},
std::move(__first),
std::move(__last),
std::move(__pred),
__new_value);
}
template <class>
void __pstl_replace();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
replace(_ExecutionPolicy&& __policy,
_ForwardIterator __first,
_ForwardIterator __last,
const _Tp& __old_value,
const _Tp& __new_value) {
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace),
[&__policy](
_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) {
std::replace_if(
__policy,
std::move(__g_first),
std::move(__g_last),
[&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
__g_new_value);
},
std::move(__first),
std::move(__last),
__old_value,
__new_value);
}
template <class>
void __pstl_replace_copy_if();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
class _Pred,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void replace_copy_if(
_ExecutionPolicy&& __policy,
_ForwardIterator __first,
_ForwardIterator __last,
_ForwardOutIterator __result,
_Pred __pred,
const _Tp& __new_value) {
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if),
[&__policy](_ForwardIterator __g_first,
_ForwardIterator __g_last,
_ForwardOutIterator __g_result,
_Pred __g_pred,
const _Tp& __g_new_value) {
std::transform(__policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) {
return __g_pred(__element) ? __g_new_value : __element;
});
},
std::move(__first),
std::move(__last),
std::move(__result),
std::move(__pred),
__new_value);
}
template <class>
void __pstl_replace_copy();
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
class _Tp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void replace_copy(
_ExecutionPolicy&& __policy,
_ForwardIterator __first,
_ForwardIterator __last,
_ForwardOutIterator __result,
const _Tp& __old_value,
const _Tp& __new_value) {
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy),
[&__policy](_ForwardIterator __g_first,
_ForwardIterator __g_last,
_ForwardOutIterator __g_result,
const _Tp& __g_old_value,
const _Tp& __g_new_value) {
return std::replace_copy_if(
__policy,
std::move(__g_first),
std::move(__g_last),
std::move(__g_result),
[&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
__g_new_value);
},
std::move(__first),
std::move(__last),
std::move(__result),
__old_value,
__new_value);
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H

View File

@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_SORT_H
#define _LIBCPP___ALGORITHM_PSTL_SORT_H
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__algorithm/pstl_stable_sort.h>
#include <__config>
#include <__functional/operations.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class>
void __pstl_sort();
template <class _ExecutionPolicy,
class _RandomAccessIterator,
class _Comp,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort),
[&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) {
std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp));
},
std::move(__first),
std::move(__last),
std::move(__comp));
}
template <class _ExecutionPolicy,
class _RandomAccessIterator,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_SORT_H

View File

@ -0,0 +1,43 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
#define _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H
#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__functional/operations.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _RandomAccessIterator,
class _Comp = less<>,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp = {}) {
using _Backend = typename __select_backend<_RawPolicy>::type;
std::__pstl_stable_sort<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__comp));
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H

View File

@ -0,0 +1,77 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
#define _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H
#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _ExecutionPolicy,
class _ForwardIterator,
class _ForwardOutIterator,
class _UnaryOperation,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
_ExecutionPolicy&&,
_ForwardIterator __first,
_ForwardIterator __last,
_ForwardOutIterator __result,
_UnaryOperation __op) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
using _Backend = typename __select_backend<_RawPolicy>::type;
return std::__pstl_transform<_RawPolicy>(
_Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op));
}
template <class _ExecutionPolicy,
class _ForwardIterator1,
class _ForwardIterator2,
class _ForwardOutIterator,
class _BinaryOperation,
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
_ExecutionPolicy&&,
_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardOutIterator __result,
_BinaryOperation __op) {
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
using _Backend = typename __select_backend<_RawPolicy>::type;
return std::__pstl_transform<_RawPolicy>(
_Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op));
}
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
#endif // _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H

View File

@ -14,13 +14,17 @@
#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_copy_assignable.h>
#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <type_traits>
#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 _AlgPolicy, class _Compare, class _RandomAccessIterator>
@ -68,10 +72,11 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::push_heap(std::move(__first), std::move(__last),
__less<typename iterator_traits<_RandomAccessIterator>::value_type>());
std::push_heap(std::move(__first), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H

View File

@ -24,17 +24,16 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
namespace __adjacent_find {
struct __fn {
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) {
_LIBCPP_HIDE_FROM_ABI constexpr static _Iter
__adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
if (__first == __last)
return __first;
@ -47,32 +46,33 @@ struct __fn {
return __i;
}
template <forward_iterator _Iter, sentinel_for<_Iter> _Sent,
class _Proj = identity,
template <forward_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
_Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _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);
}
template <forward_range _Range,
class _Proj = identity,
indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>,
projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>, projected<iterator_t<_Range>, _Proj>>
_Pred = ranges::equal_to>
_LIBCPP_NODISCARD_EXT _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);
}
};
} // namespace __adjacent_find
inline namespace __cpo {
inline constexpr auto adjacent_find = __adjacent_find::__fn{};
inline constexpr auto adjacent_find = __adjacent_find::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H

View File

@ -22,17 +22,15 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
namespace __all_of {
struct __fn {
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) {
_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;
@ -40,29 +38,32 @@ struct __fn {
return true;
}
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _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);
}
template <input_range _Range, class _Proj = identity,
template <input_range _Range,
class _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _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);
}
};
} // namespace __all_of
inline namespace __cpo {
inline constexpr auto all_of = __all_of::__fn{};
inline constexpr auto all_of = __all_of::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H

View File

@ -22,17 +22,15 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
namespace __any_of {
struct __fn {
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) {
_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;
@ -40,29 +38,32 @@ struct __fn {
return false;
}
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _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);
}
template <input_range _Range, class _Proj = identity,
template <input_range _Range,
class _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _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);
}
};
} // namespace __any_of
inline namespace __cpo {
inline constexpr auto any_of = __any_of::__fn{};
inline constexpr auto any_of = __any_of::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H

View File

@ -24,40 +24,45 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
namespace __binary_search {
struct __fn {
template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity,
template <forward_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Type,
class _Proj = identity,
indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
}
template <forward_range _Range, class _Type, class _Proj = identity,
template <forward_range _Range,
class _Type,
class _Proj = identity,
indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __first = ranges::begin(__r);
auto __last = ranges::end(__r);
auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
auto __last = ranges::end(__r);
auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
}
};
} // namespace __binary_search
inline namespace __cpo {
inline constexpr auto binary_search = __binary_search::__fn{};
inline constexpr auto binary_search = __binary_search::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H

View File

@ -22,25 +22,20 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
namespace __clamp {
struct __fn {
template <class _Type,
class _Proj = identity,
class _Proj = identity,
indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
const _Type& operator()(const _Type& __value,
const _Type& __low,
const _Type& __high,
_Comp __comp = {},
_Proj __proj = {}) const {
_LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
"Bad bounds passed to std::ranges::clamp");
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()(
const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const {
_LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
"Bad bounds passed to std::ranges::clamp");
if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low)))
return __low;
@ -49,17 +44,16 @@ struct __fn {
else
return __value;
}
};
} // namespace __clamp
inline namespace __cpo {
inline constexpr auto clamp = __clamp::__fn{};
inline constexpr auto clamp = __clamp::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H

View File

@ -25,7 +25,7 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
@ -36,19 +36,18 @@ using copy_result = in_out_result<_InIter, _OutIter>;
namespace __copy {
struct __fn {
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
requires indirectly_copyable<_InIter, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const {
_LIBCPP_HIDE_FROM_ABI constexpr copy_result<_InIter, _OutIter>
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
return {std::move(__ret.first), std::move(__ret.second)};
}
template <input_range _Range, weakly_incrementable _OutIter>
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __r, _OutIter __result) const {
_LIBCPP_HIDE_FROM_ABI constexpr copy_result<borrowed_iterator_t<_Range>, _OutIter>
operator()(_Range&& __r, _OutIter __result) const {
auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
return {std::move(__ret.first), std::move(__ret.second)};
}
@ -56,12 +55,12 @@ struct __fn {
} // namespace __copy
inline namespace __cpo {
inline constexpr auto copy = __copy::__fn{};
inline constexpr auto copy = __copy::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H

View File

@ -23,30 +23,29 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
template<class _Ip, class _Op>
template <class _Ip, class _Op>
using copy_backward_result = in_out_result<_Ip, _Op>;
namespace __copy_backward {
struct __fn {
template <bidirectional_iterator _InIter1, sentinel_for<_InIter1> _Sent1, bidirectional_iterator _InIter2>
requires indirectly_copyable<_InIter1, _InIter2>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
_LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<_InIter1, _InIter2>
operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
return {std::move(__ret.first), std::move(__ret.second)};
}
template <bidirectional_range _Range, bidirectional_iterator _Iter>
requires indirectly_copyable<iterator_t<_Range>, _Iter>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __r, _Iter __result) const {
_LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter>
operator()(_Range&& __r, _Iter __result) const {
auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
return {std::move(__ret.first), std::move(__ret.second)};
}
@ -54,12 +53,12 @@ struct __fn {
} // namespace __copy_backward
inline namespace __cpo {
inline constexpr auto copy_backward = __copy_backward::__fn{};
inline constexpr auto copy_backward = __copy_backward::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H

View File

@ -24,21 +24,19 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
template<class _Ip, class _Op>
template <class _Ip, class _Op>
using copy_if_result = in_out_result<_Ip, _Op>;
namespace __copy_if {
struct __fn {
template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI static constexpr
copy_if_result <_InIter, _OutIter>
_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))) {
@ -49,20 +47,23 @@ struct __fn {
return {std::move(__first), std::move(__result)};
}
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Proj = identity,
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
weakly_incrementable _OutIter,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
requires indirectly_copyable<_Iter, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_if_result<_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);
}
template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity,
template <input_range _Range,
weakly_incrementable _OutIter,
class _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_if_result<borrowed_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);
}
@ -70,12 +71,12 @@ struct __fn {
} // namespace __copy_if
inline namespace __cpo {
inline constexpr auto copy_if = __copy_if::__fn{};
inline constexpr auto copy_if = __copy_if::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H

View File

@ -27,7 +27,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
namespace ranges {
@ -36,10 +36,9 @@ using copy_n_result = in_out_result<_Ip, _Op>;
namespace __copy_n {
struct __fn {
template <class _InIter, class _DiffType, class _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr static
copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) {
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
__go(_InIter __first, _DiffType __n, _OutIter __result) {
while (__n != 0) {
*__result = *__first;
++__first;
@ -50,27 +49,27 @@ struct __fn {
}
template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr static
copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) {
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
__go(_InIter __first, _DiffType __n, _OutIter __result) {
auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result);
return {__ret.first, __ret.second};
}
template <input_iterator _Ip, weakly_incrementable _Op>
requires indirectly_copyable<_Ip, _Op>
_LIBCPP_HIDE_FROM_ABI constexpr
copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
_LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
return __go(std::move(__first), __n, std::move(__result));
}
};
} // namespace __copy_n
inline namespace __cpo {
inline constexpr auto copy_n = __copy_n::__fn{};
inline constexpr auto copy_n = __copy_n::__fn{};
} // namespace __cpo
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD

View File

@ -25,7 +25,7 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
@ -34,16 +34,16 @@ namespace __count {
struct __fn {
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
auto __pred = [&](auto&& __e) { return __e == __value; };
return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
}
template <input_range _Range, class _Type, class _Proj = identity>
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
auto __pred = [&](auto&& __e) { return __e == __value; };
return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
}
@ -51,12 +51,12 @@ struct __fn {
} // namespace __count
inline namespace __cpo {
inline constexpr auto count = __count::__fn{};
inline constexpr auto count = __count::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H

View File

@ -25,15 +25,14 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI constexpr
iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last,
_Pred& __pred, _Proj& __proj) {
_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
__count_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
iter_difference_t<_Iter> __counter(0);
for (; __first != __last; ++__first) {
if (std::invoke(__pred, std::invoke(__proj, *__first)))
@ -44,29 +43,32 @@ iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last,
namespace __count_if {
struct __fn {
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity,
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Predicate>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
}
template <input_range _Range, class _Proj = identity,
template <input_range _Range,
class _Proj = identity,
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Predicate>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
}
};
} // namespace __count_if
inline namespace __cpo {
inline constexpr auto count_if = __count_if::__fn{};
inline constexpr auto count_if = __count_if::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H

View File

@ -9,6 +9,8 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_H
#define _LIBCPP___ALGORITHM_RANGES_EQUAL_H
#include <__algorithm/equal.h>
#include <__algorithm/unwrap_range.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
@ -24,92 +26,79 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
namespace __equal {
struct __fn {
private:
template <class _Iter1, class _Sent1,
class _Iter2, class _Sent2,
class _Pred,
class _Proj1,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI constexpr static
bool __equal_impl(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2) {
while (__first1 != __last1 && __first2 != __last2) {
if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
return false;
++__first1;
++__first2;
}
return __first1 == __last1 && __first2 == __last2;
}
public:
template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
class _Pred = ranges::equal_to,
template <input_iterator _Iter1,
sentinel_for<_Iter1> _Sent1,
input_iterator _Iter2,
sentinel_for<_Iter2> _Sent2,
class _Pred = ranges::equal_to,
class _Proj1 = identity,
class _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Pred __pred = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred __pred = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
if (__last1 - __first1 != __last2 - __first2)
return false;
}
return __equal_impl(std::move(__first1), std::move(__last1),
std::move(__first2), std::move(__last2),
__pred,
__proj1,
__proj2);
auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1));
auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2));
return std::__equal_impl(
std::move(__unwrapped1.first),
std::move(__unwrapped1.second),
std::move(__unwrapped2.first),
std::move(__unwrapped2.second),
__pred,
__proj1,
__proj2);
}
template <input_range _Range1,
input_range _Range2,
class _Pred = ranges::equal_to,
class _Pred = ranges::equal_to,
class _Proj1 = identity,
class _Proj2 = identity>
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr
bool operator()(_Range1&& __range1,
_Range2&& __range2,
_Pred __pred = {},
_Proj1 __proj1 = {},
_Proj2 __proj2 = {}) const {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
if (ranges::distance(__range1) != ranges::distance(__range2))
return false;
}
return __equal_impl(ranges::begin(__range1), ranges::end(__range1),
ranges::begin(__range2), ranges::end(__range2),
__pred,
__proj1,
__proj2);
auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
return std::__equal_impl(
std::move(__unwrapped1.first),
std::move(__unwrapped1.second),
std::move(__unwrapped2.first),
std::move(__unwrapped2.second),
__pred,
__proj1,
__proj2);
return false;
}
};
} // namespace __equal
inline namespace __cpo {
inline constexpr auto equal = __equal::__fn{};
inline constexpr auto equal = __equal::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H

View File

@ -30,7 +30,7 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
@ -38,28 +38,25 @@ namespace ranges {
namespace __equal_range {
struct __fn {
template <
forward_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Tp,
class _Proj = identity,
indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
template <forward_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Tp,
class _Proj = identity,
indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__equal_range<_RangeAlgPolicy>(
std::move(__first), std::move(__last), __value, __comp, __proj);
auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj);
return {std::move(__ret.first), std::move(__ret.second)};
}
template <
forward_range _Range,
class _Tp,
class _Proj = identity,
indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
template <forward_range _Range,
class _Tp,
class _Proj = identity,
indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__equal_range<_RangeAlgPolicy>(
ranges::begin(__range), ranges::end(__range), __value, __comp, __proj);
auto __ret =
std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj);
return {std::move(__ret.first), std::move(__ret.second)};
}
};
@ -67,12 +64,12 @@ struct __fn {
} // namespace __equal_range
inline namespace __cpo {
inline constexpr auto equal_range = __equal_range::__fn{};
inline constexpr auto equal_range = __equal_range::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H

View File

@ -20,7 +20,7 @@
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 17
#if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD
@ -28,9 +28,8 @@ namespace ranges {
namespace __fill {
struct __fn {
template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
_LIBCPP_HIDE_FROM_ABI constexpr
_Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
_LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
return ranges::fill_n(__first, __last - __first, __value);
} else {
for (; __first != __last; ++__first)
@ -40,20 +39,19 @@ struct __fn {
}
template <class _Type, output_range<const _Type&> _Range>
_LIBCPP_HIDE_FROM_ABI constexpr
borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
return (*this)(ranges::begin(__range), ranges::end(__range), __value);
}
};
} // namespace __fill
inline namespace __cpo {
inline constexpr auto fill = __fill::__fn{};
inline constexpr auto fill = __fill::__fn{};
} // namespace __cpo
} // namespace ranges
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_FILL_H

Some files were not shown because too many files have changed in this diff Show More