]>
Commit | Line | Data |
---|---|---|
c2ba9709 JS |
1 | // -*- C++ -*- |
2 | ||
a5544970 | 3 | // Copyright (C) 2007-2019 Free Software Foundation, Inc. |
c2ba9709 JS |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the terms | |
7 | // of the GNU General Public License as published by the Free Software | |
748086b7 | 8 | // Foundation; either version 3, or (at your option) any later |
c2ba9709 JS |
9 | // version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, but | |
12 | // WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | // General Public License for more details. | |
15 | ||
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
c2ba9709 JS |
24 | |
25 | /** @file parallel/for_each_selectors.h | |
26 | * @brief Functors representing different tasks to be plugged into the | |
27 | * generic parallelization methods for embarrassingly parallel functions. | |
28 | * This file is a GNU parallel extension to the Standard C++ Library. | |
29 | */ | |
30 | ||
31 | // Written by Felix Putze. | |
32 | ||
33 | #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H | |
34 | #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1 | |
35 | ||
36 | #include <parallel/basic_iterator.h> | |
37 | ||
38 | namespace __gnu_parallel | |
39 | { | |
1acba85b JS |
40 | /** @brief Generic __selector for embarrassingly parallel functions. */ |
41 | template<typename _It> | |
a018595e PC |
42 | struct __generic_for_each_selector |
43 | { | |
44 | /** @brief _Iterator on last element processed; needed for some | |
45 | * algorithms (e. g. std::transform()). | |
46 | */ | |
47 | _It _M_finish_iterator; | |
48 | }; | |
c2ba9709 JS |
49 | |
50 | /** @brief std::for_each() selector. */ | |
1acba85b JS |
51 | template<typename _It> |
52 | struct __for_each_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
53 | { |
54 | /** @brief Functor execution. | |
1acba85b JS |
55 | * @param __o Operator. |
56 | * @param __i iterator referencing object. */ | |
57 | template<typename _Op> | |
5817ff8e | 58 | bool |
1acba85b | 59 | operator()(_Op& __o, _It __i) |
15ac3c72 JS |
60 | { |
61 | __o(*__i); | |
62 | return true; | |
63 | } | |
5817ff8e | 64 | }; |
c2ba9709 JS |
65 | |
66 | /** @brief std::generate() selector. */ | |
1acba85b JS |
67 | template<typename _It> |
68 | struct __generate_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
69 | { |
70 | /** @brief Functor execution. | |
1acba85b JS |
71 | * @param __o Operator. |
72 | * @param __i iterator referencing object. */ | |
73 | template<typename _Op> | |
5817ff8e | 74 | bool |
1acba85b | 75 | operator()(_Op& __o, _It __i) |
5817ff8e | 76 | { |
15ac3c72 JS |
77 | *__i = __o(); |
78 | return true; | |
79 | } | |
5817ff8e | 80 | }; |
c2ba9709 JS |
81 | |
82 | /** @brief std::fill() selector. */ | |
1acba85b JS |
83 | template<typename _It> |
84 | struct __fill_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
85 | { |
86 | /** @brief Functor execution. | |
1acba85b JS |
87 | * @param __v Current value. |
88 | * @param __i iterator referencing object. */ | |
4459d22e | 89 | template<typename _ValueType> |
5817ff8e | 90 | bool |
4459d22e | 91 | operator()(_ValueType& __v, _It __i) |
15ac3c72 JS |
92 | { |
93 | *__i = __v; | |
94 | return true; | |
95 | } | |
5817ff8e | 96 | }; |
c2ba9709 | 97 | |
1acba85b JS |
98 | /** @brief std::transform() __selector, one input sequence variant. */ |
99 | template<typename _It> | |
100 | struct __transform1_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
101 | { |
102 | /** @brief Functor execution. | |
1acba85b JS |
103 | * @param __o Operator. |
104 | * @param __i iterator referencing object. */ | |
105 | template<typename _Op> | |
5817ff8e | 106 | bool |
1acba85b | 107 | operator()(_Op& __o, _It __i) |
15ac3c72 JS |
108 | { |
109 | *__i.second = __o(*__i.first); | |
110 | return true; | |
111 | } | |
5817ff8e | 112 | }; |
c2ba9709 | 113 | |
1acba85b JS |
114 | /** @brief std::transform() __selector, two input sequences variant. */ |
115 | template<typename _It> | |
116 | struct __transform2_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
117 | { |
118 | /** @brief Functor execution. | |
1acba85b JS |
119 | * @param __o Operator. |
120 | * @param __i iterator referencing object. */ | |
121 | template<typename _Op> | |
5817ff8e | 122 | bool |
1acba85b | 123 | operator()(_Op& __o, _It __i) |
15ac3c72 JS |
124 | { |
125 | *__i._M_third = __o(*__i._M_first, *__i._M_second); | |
126 | return true; | |
127 | } | |
5817ff8e | 128 | }; |
c2ba9709 JS |
129 | |
130 | /** @brief std::replace() selector. */ | |
1acba85b JS |
131 | template<typename _It, typename _Tp> |
132 | struct __replace_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
133 | { |
134 | /** @brief Value to replace with. */ | |
1acba85b | 135 | const _Tp& __new_val; |
c2ba9709 | 136 | |
5817ff8e | 137 | /** @brief Constructor |
1acba85b | 138 | * @param __new_val Value to replace with. */ |
5817ff8e | 139 | explicit |
1acba85b | 140 | __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {} |
c2ba9709 | 141 | |
5817ff8e | 142 | /** @brief Functor execution. |
1acba85b JS |
143 | * @param __v Current value. |
144 | * @param __i iterator referencing object. */ | |
5817ff8e | 145 | bool |
1acba85b | 146 | operator()(_Tp& __v, _It __i) |
5817ff8e | 147 | { |
15ac3c72 JS |
148 | if (*__i == __v) |
149 | *__i = __new_val; | |
150 | return true; | |
5817ff8e PC |
151 | } |
152 | }; | |
c2ba9709 JS |
153 | |
154 | /** @brief std::replace() selector. */ | |
1acba85b JS |
155 | template<typename _It, typename _Op, typename _Tp> |
156 | struct __replace_if_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
157 | { |
158 | /** @brief Value to replace with. */ | |
1acba85b | 159 | const _Tp& __new_val; |
c2ba9709 | 160 | |
5817ff8e | 161 | /** @brief Constructor. |
1acba85b | 162 | * @param __new_val Value to replace with. */ |
5817ff8e | 163 | explicit |
1acba85b | 164 | __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { } |
c2ba9709 | 165 | |
5817ff8e | 166 | /** @brief Functor execution. |
1acba85b JS |
167 | * @param __o Operator. |
168 | * @param __i iterator referencing object. */ | |
5817ff8e | 169 | bool |
1acba85b | 170 | operator()(_Op& __o, _It __i) |
5817ff8e | 171 | { |
15ac3c72 JS |
172 | if (__o(*__i)) |
173 | *__i = __new_val; | |
174 | return true; | |
5817ff8e PC |
175 | } |
176 | }; | |
c2ba9709 JS |
177 | |
178 | /** @brief std::count() selector. */ | |
1acba85b JS |
179 | template<typename _It, typename _Diff> |
180 | struct __count_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
181 | { |
182 | /** @brief Functor execution. | |
1acba85b JS |
183 | * @param __v Current value. |
184 | * @param __i iterator referencing object. | |
5817ff8e | 185 | * @return 1 if count, 0 if does not count. */ |
4459d22e | 186 | template<typename _ValueType> |
1acba85b | 187 | _Diff |
4459d22e | 188 | operator()(_ValueType& __v, _It __i) |
15ac3c72 | 189 | { return (__v == *__i) ? 1 : 0; } |
5817ff8e | 190 | }; |
c2ba9709 JS |
191 | |
192 | /** @brief std::count_if () selector. */ | |
1acba85b JS |
193 | template<typename _It, typename _Diff> |
194 | struct __count_if_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
195 | { |
196 | /** @brief Functor execution. | |
1acba85b JS |
197 | * @param __o Operator. |
198 | * @param __i iterator referencing object. | |
5817ff8e | 199 | * @return 1 if count, 0 if does not count. */ |
1acba85b JS |
200 | template<typename _Op> |
201 | _Diff | |
202 | operator()(_Op& __o, _It __i) | |
15ac3c72 | 203 | { return (__o(*__i)) ? 1 : 0; } |
5817ff8e | 204 | }; |
c2ba9709 JS |
205 | |
206 | /** @brief std::accumulate() selector. */ | |
1acba85b JS |
207 | template<typename _It> |
208 | struct __accumulate_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
209 | { |
210 | /** @brief Functor execution. | |
1acba85b JS |
211 | * @param __o Operator (unused). |
212 | * @param __i iterator referencing object. | |
5817ff8e | 213 | * @return The current value. */ |
1acba85b | 214 | template<typename _Op> |
15ac3c72 JS |
215 | typename std::iterator_traits<_It>::value_type |
216 | operator()(_Op __o, _It __i) | |
217 | { return *__i; } | |
5817ff8e | 218 | }; |
c2ba9709 JS |
219 | |
220 | /** @brief std::inner_product() selector. */ | |
a018595e | 221 | template<typename _It, typename _It2, typename _Tp> |
1acba85b | 222 | struct __inner_product_selector : public __generic_for_each_selector<_It> |
5817ff8e PC |
223 | { |
224 | /** @brief Begin iterator of first sequence. */ | |
a018595e | 225 | _It __begin1_iterator; |
5817ff8e PC |
226 | |
227 | /** @brief Begin iterator of second sequence. */ | |
a018595e | 228 | _It2 __begin2_iterator; |
5817ff8e PC |
229 | |
230 | /** @brief Constructor. | |
93c66bc6 BK |
231 | * @param __b1 Begin iterator of first sequence. |
232 | * @param __b2 Begin iterator of second sequence. */ | |
5817ff8e | 233 | explicit |
a018595e PC |
234 | __inner_product_selector(_It __b1, _It2 __b2) |
235 | : __begin1_iterator(__b1), __begin2_iterator(__b2) { } | |
5817ff8e PC |
236 | |
237 | /** @brief Functor execution. | |
1acba85b JS |
238 | * @param __mult Multiplication functor. |
239 | * @param __current iterator referencing object. | |
240 | * @return Inner product elemental __result. */ | |
241 | template<typename _Op> | |
242 | _Tp | |
243 | operator()(_Op __mult, _It __current) | |
15ac3c72 JS |
244 | { |
245 | typename std::iterator_traits<_It>::difference_type __position | |
246 | = __current - __begin1_iterator; | |
a018595e | 247 | return __mult(*__current, *(__begin2_iterator + __position)); |
15ac3c72 | 248 | } |
5817ff8e | 249 | }; |
c2ba9709 JS |
250 | |
251 | /** @brief Selector that just returns the passed iterator. */ | |
1acba85b JS |
252 | template<typename _It> |
253 | struct __identity_selector : public __generic_for_each_selector<_It> | |
5817ff8e PC |
254 | { |
255 | /** @brief Functor execution. | |
1acba85b JS |
256 | * @param __o Operator (unused). |
257 | * @param __i iterator referencing object. | |
5817ff8e | 258 | * @return Passed iterator. */ |
1acba85b JS |
259 | template<typename _Op> |
260 | _It | |
261 | operator()(_Op __o, _It __i) | |
15ac3c72 | 262 | { return __i; } |
5817ff8e | 263 | }; |
c2ba9709 JS |
264 | |
265 | /** @brief Selector that returns the difference between two adjacent | |
1acba85b | 266 | * __elements. |
c2ba9709 | 267 | */ |
1acba85b | 268 | template<typename _It> |
a018595e PC |
269 | struct __adjacent_difference_selector |
270 | : public __generic_for_each_selector<_It> | |
5817ff8e | 271 | { |
1acba85b | 272 | template<typename _Op> |
5817ff8e | 273 | bool |
1acba85b | 274 | operator()(_Op& __o, _It __i) |
15ac3c72 JS |
275 | { |
276 | typename _It::first_type __go_back_one = __i.first; | |
277 | --__go_back_one; | |
6aa7cd49 | 278 | *__i.second = __o(*__i.first, *__go_back_one); |
15ac3c72 JS |
279 | return true; |
280 | } | |
5817ff8e | 281 | }; |
c2ba9709 | 282 | |
c2ba9709 JS |
283 | /** @brief Functor doing nothing |
284 | * | |
1acba85b JS |
285 | * For some __reduction tasks (this is not a function object, but is |
286 | * passed as __selector __dummy parameter. | |
c2ba9709 | 287 | */ |
1acba85b | 288 | struct _Nothing |
c2ba9709 JS |
289 | { |
290 | /** @brief Functor execution. | |
1acba85b JS |
291 | * @param __i iterator referencing object. */ |
292 | template<typename _It> | |
531898c3 | 293 | void |
93c66bc6 | 294 | operator()(_It __i) { } |
c2ba9709 JS |
295 | }; |
296 | ||
297 | /** @brief Reduction function doing nothing. */ | |
1acba85b | 298 | struct _DummyReduct |
c2ba9709 | 299 | { |
531898c3 | 300 | bool |
a018595e | 301 | operator()(bool, bool) const |
c2ba9709 JS |
302 | { return true; } |
303 | }; | |
304 | ||
305 | /** @brief Reduction for finding the maximum element, using a comparator. */ | |
1acba85b JS |
306 | template<typename _Compare, typename _It> |
307 | struct __min_element_reduct | |
5817ff8e | 308 | { |
1acba85b | 309 | _Compare& __comp; |
c2ba9709 | 310 | |
5817ff8e | 311 | explicit |
1acba85b | 312 | __min_element_reduct(_Compare &__c) : __comp(__c) { } |
c2ba9709 | 313 | |
1acba85b JS |
314 | _It |
315 | operator()(_It __x, _It __y) | |
a018595e | 316 | { return (__comp(*__x, *__y)) ? __x : __y; } |
5817ff8e | 317 | }; |
c2ba9709 JS |
318 | |
319 | /** @brief Reduction for finding the maximum element, using a comparator. */ | |
1acba85b JS |
320 | template<typename _Compare, typename _It> |
321 | struct __max_element_reduct | |
5817ff8e | 322 | { |
1acba85b | 323 | _Compare& __comp; |
c2ba9709 | 324 | |
5817ff8e | 325 | explicit |
1acba85b | 326 | __max_element_reduct(_Compare& __c) : __comp(__c) { } |
c2ba9709 | 327 | |
1acba85b JS |
328 | _It |
329 | operator()(_It __x, _It __y) | |
a018595e | 330 | { return (__comp(*__x, *__y)) ? __y : __x; } |
5817ff8e | 331 | }; |
c2ba9709 JS |
332 | |
333 | /** @brief General reduction, using a binary operator. */ | |
1acba85b JS |
334 | template<typename _BinOp> |
335 | struct __accumulate_binop_reduct | |
5817ff8e | 336 | { |
1acba85b | 337 | _BinOp& __binop; |
c2ba9709 | 338 | |
5817ff8e | 339 | explicit |
1acba85b | 340 | __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { } |
c2ba9709 | 341 | |
1acba85b JS |
342 | template<typename _Result, typename _Addend> |
343 | _Result | |
344 | operator()(const _Result& __x, const _Addend& __y) | |
15ac3c72 | 345 | { return __binop(__x, __y); } |
5817ff8e | 346 | }; |
c2ba9709 JS |
347 | } |
348 | ||
cbcd1e45 | 349 | #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */ |