1*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #ifndef _LIBCPP___NUMERIC_PSTL_H 10*0fca6ea1SDimitry Andric #define _LIBCPP___NUMERIC_PSTL_H 11*0fca6ea1SDimitry Andric 12*0fca6ea1SDimitry Andric #include <__config> 13*0fca6ea1SDimitry Andric 14*0fca6ea1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 15*0fca6ea1SDimitry Andric # pragma GCC system_header 16*0fca6ea1SDimitry Andric #endif 17*0fca6ea1SDimitry Andric 18*0fca6ea1SDimitry Andric _LIBCPP_PUSH_MACROS 19*0fca6ea1SDimitry Andric #include <__undef_macros> 20*0fca6ea1SDimitry Andric 21*0fca6ea1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 22*0fca6ea1SDimitry Andric 23*0fca6ea1SDimitry Andric # include <__functional/identity.h> 24*0fca6ea1SDimitry Andric # include <__functional/operations.h> 25*0fca6ea1SDimitry Andric # include <__iterator/cpp17_iterator_concepts.h> 26*0fca6ea1SDimitry Andric # include <__iterator/iterator_traits.h> 27*0fca6ea1SDimitry Andric # include <__pstl/backend.h> 28*0fca6ea1SDimitry Andric # include <__pstl/dispatch.h> 29*0fca6ea1SDimitry Andric # include <__pstl/handle_exception.h> 30*0fca6ea1SDimitry Andric # include <__type_traits/enable_if.h> 31*0fca6ea1SDimitry Andric # include <__type_traits/is_execution_policy.h> 32*0fca6ea1SDimitry Andric # include <__type_traits/remove_cvref.h> 33*0fca6ea1SDimitry Andric # include <__utility/forward.h> 34*0fca6ea1SDimitry Andric # include <__utility/move.h> 35*0fca6ea1SDimitry Andric 36*0fca6ea1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 37*0fca6ea1SDimitry Andric 38*0fca6ea1SDimitry Andric template <class _ExecutionPolicy, 39*0fca6ea1SDimitry Andric class _ForwardIterator, 40*0fca6ea1SDimitry Andric class _Tp, 41*0fca6ea1SDimitry Andric class _BinaryOperation, 42*0fca6ea1SDimitry Andric class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 43*0fca6ea1SDimitry Andric enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 44*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp reduce( 45*0fca6ea1SDimitry Andric _ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __op) { 46*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators"); 47*0fca6ea1SDimitry Andric using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>; 48*0fca6ea1SDimitry Andric return __pstl::__handle_exception<_Implementation>( 49*0fca6ea1SDimitry Andric std::forward<_ExecutionPolicy>(__policy), 50*0fca6ea1SDimitry Andric std::move(__first), 51*0fca6ea1SDimitry Andric std::move(__last), 52*0fca6ea1SDimitry Andric std::move(__init), 53*0fca6ea1SDimitry Andric std::move(__op)); 54*0fca6ea1SDimitry Andric } 55*0fca6ea1SDimitry Andric 56*0fca6ea1SDimitry Andric template <class _ExecutionPolicy, 57*0fca6ea1SDimitry Andric class _ForwardIterator, 58*0fca6ea1SDimitry Andric class _Tp, 59*0fca6ea1SDimitry Andric class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 60*0fca6ea1SDimitry Andric enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 61*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp 62*0fca6ea1SDimitry Andric reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) { 63*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators"); 64*0fca6ea1SDimitry Andric using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>; 65*0fca6ea1SDimitry Andric return __pstl::__handle_exception<_Implementation>( 66*0fca6ea1SDimitry Andric std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__init), plus{}); 67*0fca6ea1SDimitry Andric } 68*0fca6ea1SDimitry Andric 69*0fca6ea1SDimitry Andric template <class _ExecutionPolicy, 70*0fca6ea1SDimitry Andric class _ForwardIterator, 71*0fca6ea1SDimitry Andric class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 72*0fca6ea1SDimitry Andric enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 73*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator> 74*0fca6ea1SDimitry Andric reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) { 75*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "reduce requires ForwardIterators"); 76*0fca6ea1SDimitry Andric using _Implementation = __pstl::__dispatch<__pstl::__reduce, __pstl::__current_configuration, _RawPolicy>; 77*0fca6ea1SDimitry Andric return __pstl::__handle_exception<_Implementation>( 78*0fca6ea1SDimitry Andric std::forward<_ExecutionPolicy>(__policy), 79*0fca6ea1SDimitry Andric std::move(__first), 80*0fca6ea1SDimitry Andric std::move(__last), 81*0fca6ea1SDimitry Andric __iter_value_type<_ForwardIterator>(), 82*0fca6ea1SDimitry Andric plus{}); 83*0fca6ea1SDimitry Andric } 84*0fca6ea1SDimitry Andric 85*0fca6ea1SDimitry Andric template <class _ExecutionPolicy, 86*0fca6ea1SDimitry Andric class _ForwardIterator1, 87*0fca6ea1SDimitry Andric class _ForwardIterator2, 88*0fca6ea1SDimitry Andric class _Tp, 89*0fca6ea1SDimitry Andric class _BinaryOperation1, 90*0fca6ea1SDimitry Andric class _BinaryOperation2, 91*0fca6ea1SDimitry Andric class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 92*0fca6ea1SDimitry Andric enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 93*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce( 94*0fca6ea1SDimitry Andric _ExecutionPolicy&& __policy, 95*0fca6ea1SDimitry Andric _ForwardIterator1 __first1, 96*0fca6ea1SDimitry Andric _ForwardIterator1 __last1, 97*0fca6ea1SDimitry Andric _ForwardIterator2 __first2, 98*0fca6ea1SDimitry Andric _Tp __init, 99*0fca6ea1SDimitry Andric _BinaryOperation1 __reduce, 100*0fca6ea1SDimitry Andric _BinaryOperation2 __transform) { 101*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_reduce requires ForwardIterators"); 102*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_reduce requires ForwardIterators"); 103*0fca6ea1SDimitry Andric using _Implementation = 104*0fca6ea1SDimitry Andric __pstl::__dispatch<__pstl::__transform_reduce_binary, __pstl::__current_configuration, _RawPolicy>; 105*0fca6ea1SDimitry Andric return __pstl::__handle_exception<_Implementation>( 106*0fca6ea1SDimitry Andric std::forward<_ExecutionPolicy>(__policy), 107*0fca6ea1SDimitry Andric std::move(__first1), 108*0fca6ea1SDimitry Andric std::move(__last1), 109*0fca6ea1SDimitry Andric std::move(__first2), 110*0fca6ea1SDimitry Andric std::move(__init), 111*0fca6ea1SDimitry Andric std::move(__reduce), 112*0fca6ea1SDimitry Andric std::move(__transform)); 113*0fca6ea1SDimitry Andric } 114*0fca6ea1SDimitry Andric 115*0fca6ea1SDimitry Andric // This overload doesn't get a customization point because it's trivial to detect (through e.g. 116*0fca6ea1SDimitry Andric // __desugars_to_v) when specializing the more general variant, which should always be preferred 117*0fca6ea1SDimitry Andric template <class _ExecutionPolicy, 118*0fca6ea1SDimitry Andric class _ForwardIterator1, 119*0fca6ea1SDimitry Andric class _ForwardIterator2, 120*0fca6ea1SDimitry Andric class _Tp, 121*0fca6ea1SDimitry Andric class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 122*0fca6ea1SDimitry Andric enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 123*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce( 124*0fca6ea1SDimitry Andric _ExecutionPolicy&& __policy, 125*0fca6ea1SDimitry Andric _ForwardIterator1 __first1, 126*0fca6ea1SDimitry Andric _ForwardIterator1 __last1, 127*0fca6ea1SDimitry Andric _ForwardIterator2 __first2, 128*0fca6ea1SDimitry Andric _Tp __init) { 129*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform_reduce requires ForwardIterators"); 130*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform_reduce requires ForwardIterators"); 131*0fca6ea1SDimitry Andric using _Implementation = 132*0fca6ea1SDimitry Andric __pstl::__dispatch<__pstl::__transform_reduce_binary, __pstl::__current_configuration, _RawPolicy>; 133*0fca6ea1SDimitry Andric return __pstl::__handle_exception<_Implementation>( 134*0fca6ea1SDimitry Andric std::forward<_ExecutionPolicy>(__policy), 135*0fca6ea1SDimitry Andric std::move(__first1), 136*0fca6ea1SDimitry Andric std::move(__last1), 137*0fca6ea1SDimitry Andric std::move(__first2), 138*0fca6ea1SDimitry Andric std::move(__init), 139*0fca6ea1SDimitry Andric plus{}, 140*0fca6ea1SDimitry Andric multiplies{}); 141*0fca6ea1SDimitry Andric } 142*0fca6ea1SDimitry Andric 143*0fca6ea1SDimitry Andric template <class _ExecutionPolicy, 144*0fca6ea1SDimitry Andric class _ForwardIterator, 145*0fca6ea1SDimitry Andric class _Tp, 146*0fca6ea1SDimitry Andric class _BinaryOperation, 147*0fca6ea1SDimitry Andric class _UnaryOperation, 148*0fca6ea1SDimitry Andric class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 149*0fca6ea1SDimitry Andric enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 150*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce( 151*0fca6ea1SDimitry Andric _ExecutionPolicy&& __policy, 152*0fca6ea1SDimitry Andric _ForwardIterator __first, 153*0fca6ea1SDimitry Andric _ForwardIterator __last, 154*0fca6ea1SDimitry Andric _Tp __init, 155*0fca6ea1SDimitry Andric _BinaryOperation __reduce, 156*0fca6ea1SDimitry Andric _UnaryOperation __transform) { 157*0fca6ea1SDimitry Andric _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "transform_reduce requires ForwardIterators"); 158*0fca6ea1SDimitry Andric using _Implementation = __pstl::__dispatch<__pstl::__transform_reduce, __pstl::__current_configuration, _RawPolicy>; 159*0fca6ea1SDimitry Andric return __pstl::__handle_exception<_Implementation>( 160*0fca6ea1SDimitry Andric std::forward<_ExecutionPolicy>(__policy), 161*0fca6ea1SDimitry Andric std::move(__first), 162*0fca6ea1SDimitry Andric std::move(__last), 163*0fca6ea1SDimitry Andric std::move(__init), 164*0fca6ea1SDimitry Andric std::move(__reduce), 165*0fca6ea1SDimitry Andric std::move(__transform)); 166*0fca6ea1SDimitry Andric } 167*0fca6ea1SDimitry Andric 168*0fca6ea1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 169*0fca6ea1SDimitry Andric 170*0fca6ea1SDimitry Andric #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 171*0fca6ea1SDimitry Andric 172*0fca6ea1SDimitry Andric _LIBCPP_POP_MACROS 173*0fca6ea1SDimitry Andric 174*0fca6ea1SDimitry Andric #endif // _LIBCPP___NUMERIC_PSTL_H 175