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

View File

@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Predicate> 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) { all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
for (; __first != __last; ++__first) for (; __first != __last; ++__first)
if (!__pred(*__first)) if (!__pred(*__first))

View File

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

View File

@ -19,14 +19,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14 #if _LIBCPP_STD_VER >= 17
template<class _Tp, class _Compare> template<class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY constexpr _LIBCPP_INLINE_VISIBILITY constexpr
const _Tp& const _Tp&
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) 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; return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
} }
@ -37,7 +37,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr
const _Tp& const _Tp&
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) 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 #endif

View File

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

View File

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

View File

@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_COPY_H #define _LIBCPP___ALGORITHM_COPY_H
#include <__algorithm/copy_move_common.h> #include <__algorithm/copy_move_common.h>
#include <__algorithm/for_each_segment.h>
#include <__algorithm/iterator_operations.h> #include <__algorithm/iterator_operations.h>
#include <__algorithm/min.h> #include <__algorithm/min.h>
#include <__config> #include <__config>
@ -44,36 +45,34 @@ struct __copy_loop {
return std::make_pair(std::move(__first), std::move(__result)); 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> 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> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const { operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_InIter>; std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
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;
return std::make_pair(__last, std::move(__result)); return std::make_pair(__last, std::move(__result));
} }
template <class _InIter, template <class _InIter,
class _OutIter, 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, !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0> int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> _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 _Traits = __segmented_iterator_traits<_OutIter>;
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
@ -98,8 +97,7 @@ struct __copy_loop {
struct __copy_trivial { struct __copy_trivial {
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
template <class _In, class _Out, template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
__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*> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
operator()(_In* __first, _In* __last, _Out* __result) const { operator()(_In* __first, _In* __last, _Out* __result) const {
return std::__copy_trivial_impl(__first, __last, __result); return std::__copy_trivial_impl(__first, __last, __result);

View File

@ -76,11 +76,11 @@ struct __copy_backward_loop {
template <class _InIter, template <class _InIter,
class _OutIter, 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, !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0> int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> _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 _Traits = __segmented_iterator_traits<_OutIter>;
auto __orig_last = __last; auto __orig_last = __last;
auto __segment_iterator = _Traits::__segment(__result); auto __segment_iterator = _Traits::__segment(__result);

View File

@ -15,6 +15,7 @@
#include <__config> #include <__config>
#include <__iterator/iterator_traits.h> #include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h> #include <__memory/pointer_traits.h>
#include <__string/constexpr_c_functions.h>
#include <__type_traits/enable_if.h> #include <__type_traits/enable_if.h>
#include <__type_traits/is_always_bitcastable.h> #include <__type_traits/is_always_bitcastable.h>
#include <__type_traits/is_constant_evaluated.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*> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) { __copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
const size_t __n = static_cast<size_t>(__last - __first); 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); 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); const size_t __n = static_cast<size_t>(__last - __first);
__result -= __n; __result -= __n;
::__builtin_memmove(__result, __first, __n * sizeof(_Out)); std::__constexpr_memmove(__result, __first, __element_count(__n));
return std::make_pair(__last, __result); 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)); 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, template <class _AlgPolicy,
class _NaiveAlgorithm, class _NaiveAlgorithm,
class _OptimizedAlgorithm, class _OptimizedAlgorithm,
@ -137,23 +129,6 @@ template <class _AlgPolicy,
class _OutIter> class _OutIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) { __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>; using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>;
return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first)); 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 <__algorithm/copy.h>
#include <__config> #include <__config>
#include <__iterator/iterator_traits.h> #include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__utility/convert_to_integral.h> #include <__utility/convert_to_integral.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC 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 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
typename enable_if typename enable_if
< <
__is_cpp17_input_iterator<_InputIterator>::value && __has_input_iterator_category<_InputIterator>::value &&
!__is_cpp17_random_access_iterator<_InputIterator>::value, !__has_random_access_iterator_category<_InputIterator>::value,
_OutputIterator _OutputIterator
>::type >::type
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 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 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
typename enable_if typename enable_if
< <
__is_cpp17_random_access_iterator<_InputIterator>::value, __has_random_access_iterator_category<_InputIterator>::value,
_OutputIterator _OutputIterator
>::type >::type
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)

View File

@ -11,9 +11,20 @@
#define _LIBCPP___ALGORITHM_EQUAL_H #define _LIBCPP___ALGORITHM_EQUAL_H
#include <__algorithm/comp.h> #include <__algorithm/comp.h>
#include <__algorithm/unwrap_iter.h>
#include <__config> #include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__iterator/distance.h> #include <__iterator/distance.h>
#include <__iterator/iterator_traits.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) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header # pragma GCC system_header
@ -22,23 +33,42 @@
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
for (; __first1 != __last1; ++__first1, (void)++__first2) for (; __first1 != __last1; ++__first1, (void)++__first2)
if (!__pred(*__first1, *__first2)) if (!__pred(*__first1, *__first2))
return false; return false;
return true; 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> 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) { equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
return std::equal(__first1, __last1, __first2, __equal_to()); 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> 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, __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
_BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) {
for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2)
@ -47,19 +77,52 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fir
return __first1 == __last1 && __first2 == __last2; 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> 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, __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
_RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag,
random_access_iterator_tag) { random_access_iterator_tag) {
if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
return false; return false;
return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, __identity __proj;
_BinaryPredicate&>(__first1, __last1, __first2, __pred); 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> 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, equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
_BinaryPredicate __pred) { _BinaryPredicate __pred) {
return _VSTD::__equal<_BinaryPredicate&>( return _VSTD::__equal<_BinaryPredicate&>(
@ -68,7 +131,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
} }
template <class _InputIterator1, class _InputIterator2> 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) { equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
return std::__equal( return std::__equal(
__first1, __first1,

View File

@ -50,7 +50,7 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
} else { } else {
_Iter __mp1 = __mid; _Iter __mp1 = __mid;
return pair<_Iter, _Iter>( 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)); 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> template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
return std::equal_range( return std::equal_range(std::move(__first), std::move(__last), __value, __less<>());
std::move(__first),
std::move(__last),
__value,
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

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

View File

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

View File

@ -10,7 +10,16 @@
#ifndef _LIBCPP___ALGORITHM_FIND_H #ifndef _LIBCPP___ALGORITHM_FIND_H
#define _LIBCPP___ALGORITHM_FIND_H #define _LIBCPP___ALGORITHM_FIND_H
#include <__algorithm/unwrap_iter.h>
#include <__config> #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) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header # pragma GCC system_header
@ -18,13 +27,49 @@
_LIBCPP_BEGIN_NAMESPACE_STD _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> template <class _InputIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
for (; __first != __last; ++__first) __identity __proj;
if (*__first == __value) return std::__rewrap_iter(
break; __first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
return __first;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

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

View File

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

View File

@ -10,7 +10,9 @@
#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H #define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
#include <__config> #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) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header # pragma GCC system_header

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,9 +18,12 @@
# pragma GCC system_header # pragma GCC system_header
#endif #endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17 #if _LIBCPP_STD_VER >= 20
namespace ranges { namespace ranges {
@ -46,8 +49,10 @@ struct in_out_result {
} // namespace ranges } // namespace ranges
#endif // _LIBCPP_STD_VER > 17 #endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H #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> template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
return std::includes( return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>());
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>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

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

View File

@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) 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 _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 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) 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 _LIBCPP_END_NAMESPACE_STD

View File

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

View File

@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool bool
is_sorted(_ForwardIterator __first, _ForwardIterator __last) 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 _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 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) 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 _LIBCPP_END_NAMESPACE_STD

View File

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

View File

@ -52,9 +52,7 @@ bool
lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2) _InputIterator2 __first2, _InputIterator2 __last2)
{ {
return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
__less<typename iterator_traits<_InputIterator1>::value_type,
typename iterator_traits<_InputIterator2>::value_type>());
} }
_LIBCPP_END_NAMESPACE_STD _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 <__iterator/iterator_traits.h>
#include <__type_traits/is_callable.h> #include <__type_traits/is_callable.h>
#include <__type_traits/remove_reference.h> #include <__type_traits/remove_reference.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC 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> template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _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); auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
while (__len != 0) { while (__len != 0) {
@ -53,14 +52,13 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last,
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
"The comparator has to be callable"); "The comparator has to be callable");
auto __proj = std::__identity(); 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> template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
return std::lower_bound(__first, __last, __value, return std::lower_bound(__first, __last, __value, __less<>());
__less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

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

View File

@ -32,13 +32,14 @@ struct _ProjectedPred {
_Pred& __pred; // Can be a unary or a binary predicate. _Pred& __pred; // Can be a unary or a binary predicate.
_Proj& __proj; _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> template <class _Tp>
typename __invoke_of<_Pred&, typename __invoke_of<_Pred&,
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))
>::type >::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))); 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<_T1>())),
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>())) decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))
>::type >::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, return std::__invoke(__pred,
std::__invoke(__proj, std::forward<_T1>(__lhs)), std::__invoke(__proj, std::forward<_T1>(__lhs)),
std::__invoke(__proj, std::forward<_T2>(__rhs))); std::__invoke(__proj, std::forward<_T2>(__rhs)));
@ -55,25 +56,12 @@ struct _ProjectedPred {
}; };
template <class _Pred, class _Proj, class = void> template <class _Pred,
struct __can_use_pristine_comp : false_type {}; class _Proj,
__enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value &&
template <class _Pred, class _Proj> __is_identity<__decay_t<_Proj> >::value),
struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t< int> = 0>
!is_member_pointer<typename decay<_Pred>::type>::value && ( _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj>
#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>
>
__make_projected(_Pred& __pred, _Proj& __proj) { __make_projected(_Pred& __pred, _Proj& __proj) {
return _ProjectedPred<_Pred, _Proj>(__pred, __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 // 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 // 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. // the call stack when the comparator is invoked, even in an unoptimized build.
template <class _Pred, class _Proj> template <class _Pred,
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static class _Proj,
__enable_if_t< __enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value &&
__can_use_pristine_comp<_Pred, _Proj>::value, __is_identity<__decay_t<_Proj> >::value,
_Pred& int> = 0>
> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) {
__make_projected(_Pred& __pred, _Proj&) {
return __pred; return __pred;
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17 #if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges { namespace ranges {
template <class _Comp, class _Proj1, class _Proj2> 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) { 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>>) { !is_member_pointer_v<decay_t<_Comp>>) {
// Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable // 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. // 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 _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17 #endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H #endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H

View File

@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp& 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; return __comp(__a, __b) ? __b : __a;
} }
@ -37,9 +37,9 @@ template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp& 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 #ifndef _LIBCPP_CXX03_LANG
@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp _Tp
max(initializer_list<_Tp> __t) 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 #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 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) __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"); "std::max_element requires a ForwardIterator");
if (__first != __last) if (__first != __last)
{ {
@ -48,8 +48,7 @@ template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last) max_element(_ForwardIterator __first, _ForwardIterator __last)
{ {
return _VSTD::max_element(__first, __last, return _VSTD::max_element(__first, __last, __less<>());
__less<typename iterator_traits<_ForwardIterator>::value_type>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

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

View File

@ -28,7 +28,7 @@ template <class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp& 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; return __comp(__b, __a) ? __b : __a;
} }
@ -37,9 +37,9 @@ template <class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp& 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 #ifndef _LIBCPP_CXX03_LANG
@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp _Tp
min(initializer_list<_Tp> __t) 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 #endif // _LIBCPP_CXX03_LANG

View File

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

View File

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

View File

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

View File

@ -12,9 +12,10 @@
#include <__algorithm/comp.h> #include <__algorithm/comp.h>
#include <__config> #include <__config>
#include <__functional/identity.h> #include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__iterator/iterator_traits.h> #include <__iterator/iterator_traits.h>
#include <__type_traits/is_callable.h>
#include <__utility/pair.h> #include <__utility/pair.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC 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 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_ForwardIterator, _ForwardIterator> pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { 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"); "std::minmax_element requires a ForwardIterator");
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value,
"The comparator has to be callable"); "The comparator has to be callable");
@ -93,7 +94,7 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com
template <class _ForwardIterator> template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { 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 _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()); 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> template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>

View File

@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_MOVE_H #define _LIBCPP___ALGORITHM_MOVE_H
#include <__algorithm/copy_move_common.h> #include <__algorithm/copy_move_common.h>
#include <__algorithm/for_each_segment.h>
#include <__algorithm/iterator_operations.h> #include <__algorithm/iterator_operations.h>
#include <__algorithm/min.h> #include <__algorithm/min.h>
#include <__config> #include <__config>
@ -45,36 +46,34 @@ struct __move_loop {
return std::make_pair(std::move(__first), std::move(__result)); 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> 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> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
operator()(_InIter __first, _InIter __last, _OutIter __result) const { operator()(_InIter __first, _InIter __last, _OutIter __result) const {
using _Traits = __segmented_iterator_traits<_InIter>; std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
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;
return std::make_pair(__last, std::move(__result)); return std::make_pair(__last, std::move(__result));
} }
template <class _InIter, template <class _InIter,
class _OutIter, 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, !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0> int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> _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 _Traits = __segmented_iterator_traits<_OutIter>;
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; 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, template <class _InIter,
class _OutIter, 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, !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
int> = 0> int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> _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 _Traits = __segmented_iterator_traits<_OutIter>;
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; 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 bool
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{ {
return _VSTD::next_permutation(__first, __last, return _VSTD::next_permutation(__first, __last, __less<>());
__less<typename iterator_traits<_BidirectionalIterator>::value_type>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

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

View File

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

View File

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

View File

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

View File

@ -17,20 +17,24 @@
#include <__assert> #include <__assert>
#include <__config> #include <__config>
#include <__iterator/iterator_traits.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 <__utility/move.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header # pragma GCC system_header
#endif #endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) { 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; __comp_ref_type<_Compare> __comp_ref = __comp;
@ -64,10 +68,11 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::pop_heap(std::move(__first), std::move(__last), std::pop_heap(std::move(__first), std::move(__last), __less<>());
__less<typename iterator_traits<_RandomAccessIterator>::value_type>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_POP_HEAP_H #endif // _LIBCPP___ALGORITHM_POP_HEAP_H

View File

@ -70,8 +70,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool bool
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{ {
return _VSTD::prev_permutation(__first, __last, return _VSTD::prev_permutation(__first, __last, __less<>());
__less<typename iterator_traits<_BidirectionalIterator>::value_type>());
} }
_LIBCPP_END_NAMESPACE_STD _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 <__algorithm/iterator_operations.h>
#include <__config> #include <__config>
#include <__iterator/iterator_traits.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 <__utility/move.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header # pragma GCC system_header
#endif #endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
@ -68,10 +72,11 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
template <class _RandomAccessIterator> template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::push_heap(std::move(__first), std::move(__last), std::push_heap(std::move(__first), std::move(__last), __less<>());
__less<typename iterator_traits<_RandomAccessIterator>::value_type>());
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H #endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,21 +24,19 @@
# pragma GCC system_header # pragma GCC system_header
#endif #endif
#if _LIBCPP_STD_VER > 17 #if _LIBCPP_STD_VER >= 20
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges { namespace ranges {
template<class _Ip, class _Op> template <class _Ip, class _Op>
using copy_if_result = in_out_result<_Ip, _Op>; using copy_if_result = in_out_result<_Ip, _Op>;
namespace __copy_if { namespace __copy_if {
struct __fn { struct __fn {
template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred> template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI static constexpr _LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter>
copy_if_result <_InIter, _OutIter>
__copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) { for (; __first != __last; ++__first) {
if (std::invoke(__pred, std::invoke(__proj, *__first))) { if (std::invoke(__pred, std::invoke(__proj, *__first))) {
@ -49,20 +47,23 @@ struct __fn {
return {std::move(__first), std::move(__result)}; 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> indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
requires indirectly_copyable<_Iter, _OutIter> requires indirectly_copyable<_Iter, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter>
copy_if_result<_Iter, _OutIter>
operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { 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); 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> indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
requires indirectly_copyable<iterator_t<_Range>, _OutIter> requires indirectly_copyable<iterator_t<_Range>, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { 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); return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
} }
@ -70,12 +71,12 @@ struct __fn {
} // namespace __copy_if } // namespace __copy_if
inline namespace __cpo { inline namespace __cpo {
inline constexpr auto copy_if = __copy_if::__fn{}; inline constexpr auto copy_if = __copy_if::__fn{};
} // namespace __cpo } // namespace __cpo
} // namespace ranges } // namespace ranges
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17 #endif // _LIBCPP_STD_VER >= 20
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H #endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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