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