@@ -27,13 +27,14 @@ TODO: Documentation of how backends work
27
27
A PSTL parallel backend is a tag type to which the following functions are associated, at minimum:
28
28
29
29
template <class _ExecutionPolicy, class _Iterator, class _Func>
30
- void __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
30
+ optional<__empty> __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f);
31
31
32
32
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
33
- _Iterator __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
33
+ optional< _Iterator> __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
34
34
35
35
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp>
36
- void __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
36
+ optional<__empty>
37
+ __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp);
37
38
38
39
template <class _ExecutionPolicy,
39
40
class _ForwardIterator1,
@@ -49,42 +50,38 @@ A PSTL parallel backend is a tag type to which the following functions are assoc
49
50
_Comp __comp);
50
51
51
52
template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation>
52
- _OutIterator __pstl_transform(_Backend,
53
- _InIterator __first,
54
- _InIterator __last,
55
- _OutIterator __result,
56
- _UnaryOperation __op);
53
+ optional<_OutIterator>
54
+ __pstl_transform(_Backend, _InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op);
57
55
58
56
template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation>
59
- _OutIterator __pstl_transform(_Backend,
60
- _InIterator1 __first1,
61
- _InIterator1 __last1,
62
- _InIterator2 __first2,
63
- _OutIterator __result,
64
- _BinaryOperation __op);
57
+ optional<_OutIterator> __pstl_transform(_InIterator1 __first1,
58
+ _InIterator2 __first2,
59
+ _InIterator1 __last1,
60
+ _OutIterator __result,
61
+ _BinaryOperation __op);
65
62
66
63
template <class _ExecutionPolicy,
67
64
class _Iterator1,
68
65
class _Iterator2,
69
66
class _Tp,
70
67
class _BinaryOperation1,
71
68
class _BinaryOperation2>
72
- _Tp __pstl_transform_reduce(_Backend,
73
- _Iterator1 __first1,
74
- _Iterator1 __last1,
75
- _Iterator2 __first2,
76
- _Iterator2 __last2,
77
- _Tp __init,
78
- _BinaryOperation1 __reduce,
79
- _BinaryOperation2 __transform);
69
+ optional< _Tp> __pstl_transform_reduce(_Backend,
70
+ _Iterator1 __first1,
71
+ _Iterator1 __last1,
72
+ _Iterator2 __first2,
73
+ _Iterator2 __last2,
74
+ _Tp __init,
75
+ _BinaryOperation1 __reduce,
76
+ _BinaryOperation2 __transform);
80
77
81
78
template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
82
- _Tp __pstl_transform_reduce(_Backend,
83
- _Iterator __first,
84
- _Iterator __last,
85
- _Tp __init,
86
- _BinaryOperation __reduce,
87
- _UnaryOperation __transform);
79
+ optional< _Tp> __pstl_transform_reduce(_Backend,
80
+ _Iterator __first,
81
+ _Iterator __last,
82
+ _Tp __init,
83
+ _BinaryOperation __reduce,
84
+ _UnaryOperation __transform);
88
85
89
86
// TODO: Complete this list
90
87
@@ -93,86 +90,95 @@ algorithms, otherwise they are implemented in terms of other algorithms. If none
93
90
implemented, all the algorithms will eventually forward to the basis algorithms listed above:
94
91
95
92
template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func>
96
- void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
93
+ optional<__empty> __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f);
97
94
98
95
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
99
- bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
96
+ optional< bool> __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
100
97
101
98
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
102
- bool __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
99
+ optional< bool> __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
103
100
104
101
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
105
- bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
102
+ optional< bool> __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred);
106
103
107
104
template <class _ExecutionPolicy, class _Iterator, class _Tp>
108
- _Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
105
+ optional< _Iterator> __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
109
106
110
107
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
111
- _Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
108
+ optional< _Iterator> __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
112
109
113
110
template <class _ExecutionPolicy, class _Iterator, class _Tp>
114
- void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
111
+ optional<__empty> __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
115
112
116
113
template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp>
117
- void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
114
+ optional<__empty> __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value);
118
115
119
116
template <class _ExecutionPolicy, class _Iterator, class _Generator>
120
- void __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
117
+ optional<__empty> __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen);
121
118
122
119
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
123
- void __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
120
+ optional<__empty> __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
124
121
125
122
template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator>
126
- void __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
123
+ optional<__empty> __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen);
127
124
128
125
template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp>
129
- _OutIterator __pstl_merge(_Backend,
130
- _Iterator1 __first1,
131
- _Iterator1 __last1,
132
- _Iterator2 __first2,
133
- _Iterator2 __last2,
134
- _OutIterator __result,
135
- _Comp __comp);
126
+ optional< _OutIterator> __pstl_merge(_Backend,
127
+ _Iterator1 __first1,
128
+ _Iterator1 __last1,
129
+ _Iterator2 __first2,
130
+ _Iterator2 __last2,
131
+ _OutIterator __result,
132
+ _Comp __comp);
136
133
137
134
template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation>
138
- _Tp __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
135
+ optional< _Tp> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op);
139
136
140
137
temlate <class _ExecutionPolicy, class _Iterator>
141
- __iter_value_type<_Iterator> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
138
+ optional< __iter_value_type<_Iterator> > __pstl_reduce(_Backend, _Iterator __first, _Iterator __last);
142
139
143
140
template <class _ExecuitonPolicy, class _Iterator, class _Tp>
144
- __iter_diff_t<_Iterator> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
141
+ optional< __iter_diff_t<_Iterator> > __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value);
145
142
146
143
template <class _ExecutionPolicy, class _Iterator, class _Predicate>
147
- __iter_diff_t<_Iterator> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
144
+ optional< __iter_diff_t<_Iterator> > __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred);
148
145
149
146
template <class _ExecutionPolicy, class _Iterator, class _Tp>
150
- void __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
147
+ optional<__empty>
148
+ __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value);
151
149
152
150
template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp>
153
- void __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
151
+ optional<__empty>
152
+ __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value);
154
153
155
154
template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp>
156
- void __pstl_replace_copy(_Backend,
157
- _Iterator __first,
158
- _Iterator __last,
159
- _OutIterator __result,
160
- const _Tp& __old_value,
161
- const _Tp& __new_value);
155
+ optional<__empty> __pstl_replace_copy(_Backend,
156
+ _Iterator __first,
157
+ _Iterator __last,
158
+ _OutIterator __result,
159
+ const _Tp& __old_value,
160
+ const _Tp& __new_value);
162
161
163
162
template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp>
164
- void __pstl_replace_copy_if(_Backend,
165
- _Iterator __first,
166
- _Iterator __last,
167
- _OutIterator __result,
168
- _Pred __pred,
169
- const _Tp& __new_value);
163
+ optional<__empty> __pstl_replace_copy_if(_Backend,
164
+ _Iterator __first,
165
+ _Iterator __last,
166
+ _OutIterator __result,
167
+ _Pred __pred,
168
+ const _Tp& __new_value);
170
169
171
170
template <class _ExecutionPolicy, class _Iterator, class _Comp>
172
- void __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
171
+ optional<__empty> __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp);
173
172
174
173
// TODO: Complete this list
175
174
175
+ Exception handling
176
+ ==================
177
+
178
+ PSTL backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from their
179
+ implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are turned
180
+ into a program termination at the front-end level. When a backend returns a disengaged `optional` to the frontend, the
181
+ frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to the user.
176
182
*/
177
183
178
184
template <class _ExecutionPolicy >
0 commit comments