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