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___PSTL_BACKEND_FWD_H
10#define _LIBCPP___PSTL_BACKEND_FWD_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//
22// This header declares available PSTL backends and the functions that must be implemented in order for the
23// PSTL algorithms to be provided.
24//
25// Backends often do not implement the full set of functions themselves -- a configuration of the PSTL is
26// usually a set of backends "stacked" together which each implement some algorithms under some execution
27// policies. It is only necessary for the "stack" of backends to implement all algorithms under all execution
28// policies, but a single backend is not required to implement everything on its own.
29//
30// The signatures used by each backend function are documented below.
31//
32// Exception handling
33// ==================
34//
35// PSTL backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from
36// their implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions
37// are turned into a program termination at the front-end level. When a backend returns a disengaged `optional` to the
38// frontend, the frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to
39// the user.
40//
41
42_LIBCPP_BEGIN_NAMESPACE_STD
43namespace __pstl {
44
45template <class... _Backends>
46struct __backend_configuration;
47
48struct __default_backend_tag;
49struct __libdispatch_backend_tag;
50struct __serial_backend_tag;
51struct __std_thread_backend_tag;
52
53#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
54using __current_configuration = __backend_configuration<__serial_backend_tag, __default_backend_tag>;
55#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
56using __current_configuration = __backend_configuration<__std_thread_backend_tag, __default_backend_tag>;
57#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
58using __current_configuration = __backend_configuration<__libdispatch_backend_tag, __default_backend_tag>;
59#else
60
61// ...New vendors can add parallel backends here...
62
63# error "Invalid PSTL backend configuration"
64#endif
65
66template <class _Backend, class _ExecutionPolicy>
67struct __find_if;
68// template <class _Policy, class _ForwardIterator, class _Predicate>
69// optional<_ForwardIterator>
70// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
71
72template <class _Backend, class _ExecutionPolicy>
73struct __find_if_not;
74// template <class _Policy, class _ForwardIterator, class _Predicate>
75// optional<_ForwardIterator>
76// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
77
78template <class _Backend, class _ExecutionPolicy>
79struct __find;
80// template <class _Policy, class _ForwardIterator, class _Tp>
81// optional<_ForwardIterator>
82// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept;
83
84template <class _Backend, class _ExecutionPolicy>
85struct __any_of;
86// template <class _Policy, class _ForwardIterator, class _Predicate>
87// optional<bool>
88// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
89
90template <class _Backend, class _ExecutionPolicy>
91struct __all_of;
92// template <class _Policy, class _ForwardIterator, class _Predicate>
93// optional<bool>
94// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
95
96template <class _Backend, class _ExecutionPolicy>
97struct __none_of;
98// template <class _Policy, class _ForwardIterator, class _Predicate>
99// optional<bool>
100// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
101
102template <class _Backend, class _ExecutionPolicy>
103struct __is_partitioned;
104// template <class _Policy, class _ForwardIterator, class _Predicate>
105// optional<bool>
106// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
107
108template <class _Backend, class _ExecutionPolicy>
109struct __for_each;
110// template <class _Policy, class _ForwardIterator, class _Function>
111// optional<__empty>
112// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) const noexcept;
113
114template <class _Backend, class _ExecutionPolicy>
115struct __for_each_n;
116// template <class _Policy, class _ForwardIterator, class _Size, class _Function>
117// optional<__empty>
118// operator()(_Policy&&, _ForwardIterator __first, _Size __size, _Function __func) const noexcept;
119
120template <class _Backend, class _ExecutionPolicy>
121struct __fill;
122// template <class _Policy, class _ForwardIterator, class _Tp>
123// optional<__empty>
124// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept;
125
126template <class _Backend, class _ExecutionPolicy>
127struct __fill_n;
128// template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
129// optional<__empty>
130// operator()(_Policy&&, _ForwardIterator __first, _Size __n, _Tp const& __value) const noexcept;
131
132template <class _Backend, class _ExecutionPolicy>
133struct __replace;
134// template <class _Policy, class _ForwardIterator, class _Tp>
135// optional<__empty>
136// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
137// _Tp const& __old, _Tp const& __new) const noexcept;
138
139template <class _Backend, class _ExecutionPolicy>
140struct __replace_if;
141// template <class _Policy, class _ForwardIterator, class _Predicate, class _Tp>
142// optional<__empty>
143// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
144// _Predicate __pred, _Tp const& __new_value) const noexcept;
145
146template <class _Backend, class _ExecutionPolicy>
147struct __generate;
148// template <class _Policy, class _ForwardIterator, class _Generator>
149// optional<__empty>
150// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) const noexcept;
151
152template <class _Backend, class _ExecutionPolicy>
153struct __generate_n;
154// template <class _Policy, class _ForwardIterator, class _Size, class _Generator>
155// optional<__empty>
156// operator()(_Policy&&, _ForwardIterator __first, _Size __n, _Generator __gen) const noexcept;
157
158template <class _Backend, class _ExecutionPolicy>
159struct __merge;
160// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardOutIterator, class _Comp>
161// optional<_ForwardOutIterator>
162// operator()(_Policy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
163// _ForwardIterator2 __first2, _ForwardIterator2 __last2,
164// _ForwardOutIterator __result, _Comp __comp) const noexcept;
165
166template <class _Backend, class _ExecutionPolicy>
167struct __stable_sort;
168// template <class _Policy, class _RandomAccessIterator, class _Comp>
169// optional<__empty>
170// operator()(_Policy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) const noexcept;
171
172template <class _Backend, class _ExecutionPolicy>
173struct __sort;
174// template <class _Policy, class _RandomAccessIterator, class _Comp>
175// optional<__empty>
176// operator()(_Policy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) const noexcept;
177
178template <class _Backend, class _ExecutionPolicy>
179struct __transform;
180// template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
181// optional<_ForwardOutIterator>
182// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
183// _ForwardOutIterator __result,
184// _UnaryOperation __op) const noexcept;
185
186template <class _Backend, class _ExecutionPolicy>
187struct __transform_binary;
188// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2,
189// class _ForwardOutIterator,
190// class _BinaryOperation>
191// optional<_ForwardOutIterator>
192// operator()(_Policy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
193// _ForwardIterator2 __first2,
194// _ForwardOutIterator __result,
195// _BinaryOperation __op) const noexcept;
196
197template <class _Backend, class _ExecutionPolicy>
198struct __replace_copy_if;
199// template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Predicate, class _Tp>
200// optional<__empty>
201// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
202// _ForwardOutIterator __out_it,
203// _Predicate __pred,
204// _Tp const& __new_value) const noexcept;
205
206template <class _Backend, class _ExecutionPolicy>
207struct __replace_copy;
208// template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Tp>
209// optional<__empty>
210// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
211// _ForwardOutIterator __out_it,
212// _Tp const& __old_value,
213// _Tp const& __new_value) const noexcept;
214
215template <class _Backend, class _ExecutionPolicy>
216struct __move;
217// template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
218// optional<_ForwardOutIterator>
219// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
220// _ForwardOutIterator __out_it) const noexcept;
221
222template <class _Backend, class _ExecutionPolicy>
223struct __copy;
224// template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
225// optional<_ForwardOutIterator>
226// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
227// _ForwardOutIterator __out_it) const noexcept;
228
229template <class _Backend, class _ExecutionPolicy>
230struct __copy_n;
231// template <class _Policy, class _ForwardIterator, class _Size, class _ForwardOutIterator>
232// optional<_ForwardOutIterator>
233// operator()(_Policy&&, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out_it) const noexcept;
234
235template <class _Backend, class _ExecutionPolicy>
236struct __rotate_copy;
237// template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
238// optional<_ForwardOutIterator>
239// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
240// _ForwardOutIterator __out_it) const noexcept;
241
242template <class _Backend, class _ExecutionPolicy>
243struct __transform_reduce;
244// template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
245// optional<_Tp>
246// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
247// _Tp __init,
248// _BinaryOperation __reduce,
249// _UnaryOperation __transform) const noexcept;
250
251template <class _Backend, class _ExecutionPolicy>
252struct __transform_reduce_binary;
253// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2,
254// class _Tp, class _BinaryOperation1, class _BinaryOperation2>
255// optional<_Tp> operator()(_Policy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
256// _ForwardIterator2 __first2,
257// _Tp __init,
258// _BinaryOperation1 __reduce,
259// _BinaryOperation2 __transform) const noexcept;
260
261template <class _Backend, class _ExecutionPolicy>
262struct __count_if;
263// template <class _Policy, class _ForwardIterator, class _Predicate>
264// optional<__iter_diff_t<_ForwardIterator>>
265// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept;
266
267template <class _Backend, class _ExecutionPolicy>
268struct __count;
269// template <class _Policy, class _ForwardIterator, class _Tp>
270// optional<__iter_diff_t<_ForwardIterator>>
271// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept;
272
273template <class _Backend, class _ExecutionPolicy>
274struct __equal_3leg;
275// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
276// optional<bool>
277// operator()(_Policy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
278// _ForwardIterator2 __first2,
279// _Predicate __pred) const noexcept;
280
281template <class _Backend, class _ExecutionPolicy>
282struct __equal;
283// template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
284// optional<bool>
285// operator()(_Policy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
286// _ForwardIterator2 __first2, _ForwardIterator2 __last2,
287// _Predicate __pred) const noexcept;
288
289template <class _Backend, class _ExecutionPolicy>
290struct __reduce;
291// template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation>
292// optional<_Tp>
293// operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
294// _Tp __init, _BinaryOperation __op) const noexcept;
295
296} // namespace __pstl
297_LIBCPP_END_NAMESPACE_STD
298
299_LIBCPP_POP_MACROS
300
301#endif // _LIBCPP___PSTL_BACKEND_FWD_H
302