3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
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
8 // Foundation; either version 3, or (at your option) any later
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.
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.
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/>.
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.
31 // Written by Felix Putze.
33 #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H
34 #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1
36 #include <parallel/basic_iterator.h>
38 namespace __gnu_parallel
41 /** @brief Generic __selector for embarrassingly parallel functions. */
42 template<typename _It>
43 struct __generic_for_each_selector
45 /** @brief _Iterator on last element processed; needed for some
46 * algorithms (e. g. std::transform()).
48 _It _M_finish_iterator;
52 /** @brief std::for_each() selector. */
53 template<typename _It>
54 struct __for_each_selector : public __generic_for_each_selector<_It>
56 /** @brief Functor execution.
57 * @param __o Operator.
58 * @param __i iterator referencing object. */
59 template<typename _Op>
61 operator()(_Op& __o, _It __i)
68 /** @brief std::generate() selector. */
69 template<typename _It>
70 struct __generate_selector : public __generic_for_each_selector<_It>
72 /** @brief Functor execution.
73 * @param __o Operator.
74 * @param __i iterator referencing object. */
75 template<typename _Op>
77 operator()(_Op& __o, _It __i)
84 /** @brief std::fill() selector. */
85 template<typename _It>
86 struct __fill_selector : public __generic_for_each_selector<_It>
88 /** @brief Functor execution.
89 * @param __v Current value.
90 * @param __i iterator referencing object. */
91 template<typename Val>
93 operator()(Val& __v, _It __i)
100 /** @brief std::transform() __selector, one input sequence variant. */
101 template<typename _It>
102 struct __transform1_selector : public __generic_for_each_selector<_It>
104 /** @brief Functor execution.
105 * @param __o Operator.
106 * @param __i iterator referencing object. */
107 template<typename _Op>
109 operator()(_Op& __o, _It __i)
111 *__i.second = __o(*__i.first);
116 /** @brief std::transform() __selector, two input sequences variant. */
117 template<typename _It>
118 struct __transform2_selector : public __generic_for_each_selector<_It>
120 /** @brief Functor execution.
121 * @param __o Operator.
122 * @param __i iterator referencing object. */
123 template<typename _Op>
125 operator()(_Op& __o, _It __i)
127 *__i._M_third = __o(*__i._M_first, *__i._M_second);
132 /** @brief std::replace() selector. */
133 template<typename _It, typename _Tp>
134 struct __replace_selector : public __generic_for_each_selector<_It>
136 /** @brief Value to replace with. */
137 const _Tp& __new_val;
139 /** @brief Constructor
140 * @param __new_val Value to replace with. */
142 __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {}
144 /** @brief Functor execution.
145 * @param __v Current value.
146 * @param __i iterator referencing object. */
148 operator()(_Tp& __v, _It __i)
156 /** @brief std::replace() selector. */
157 template<typename _It, typename _Op, typename _Tp>
158 struct __replace_if_selector : public __generic_for_each_selector<_It>
160 /** @brief Value to replace with. */
161 const _Tp& __new_val;
163 /** @brief Constructor.
164 * @param __new_val Value to replace with. */
166 __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { }
168 /** @brief Functor execution.
169 * @param __o Operator.
170 * @param __i iterator referencing object. */
172 operator()(_Op& __o, _It __i)
180 /** @brief std::count() selector. */
181 template<typename _It, typename _Diff>
182 struct __count_selector : public __generic_for_each_selector<_It>
184 /** @brief Functor execution.
185 * @param __v Current value.
186 * @param __i iterator referencing object.
187 * @return 1 if count, 0 if does not count. */
188 template<typename Val>
190 operator()(Val& __v, _It __i)
191 { return (__v == *__i) ? 1 : 0; }
194 /** @brief std::count_if () selector. */
195 template<typename _It, typename _Diff>
196 struct __count_if_selector : public __generic_for_each_selector<_It>
198 /** @brief Functor execution.
199 * @param __o Operator.
200 * @param __i iterator referencing object.
201 * @return 1 if count, 0 if does not count. */
202 template<typename _Op>
204 operator()(_Op& __o, _It __i)
205 { return (__o(*__i)) ? 1 : 0; }
208 /** @brief std::accumulate() selector. */
209 template<typename _It>
210 struct __accumulate_selector : public __generic_for_each_selector<_It>
212 /** @brief Functor execution.
213 * @param __o Operator (unused).
214 * @param __i iterator referencing object.
215 * @return The current value. */
216 template<typename _Op>
217 typename std::iterator_traits<_It>::value_type
218 operator()(_Op __o, _It __i)
222 /** @brief std::inner_product() selector. */
223 template<typename _It, typename It2, typename _Tp>
224 struct __inner_product_selector : public __generic_for_each_selector<_It>
226 /** @brief Begin iterator of first sequence. */
227 _It __begin1_iterator;
229 /** @brief Begin iterator of second sequence. */
232 /** @brief Constructor.
233 * @param b1 Begin iterator of first sequence.
234 * @param b2 Begin iterator of second sequence. */
236 __inner_product_selector(_It b1, It2 b2)
237 : __begin1_iterator(b1), begin2_iterator(b2) { }
239 /** @brief Functor execution.
240 * @param __mult Multiplication functor.
241 * @param __current iterator referencing object.
242 * @return Inner product elemental __result. */
243 template<typename _Op>
245 operator()(_Op __mult, _It __current)
247 typename std::iterator_traits<_It>::difference_type __position
248 = __current - __begin1_iterator;
249 return __mult(*__current, *(begin2_iterator + __position));
253 /** @brief Selector that just returns the passed iterator. */
254 template<typename _It>
255 struct __identity_selector : public __generic_for_each_selector<_It>
257 /** @brief Functor execution.
258 * @param __o Operator (unused).
259 * @param __i iterator referencing object.
260 * @return Passed iterator. */
261 template<typename _Op>
263 operator()(_Op __o, _It __i)
267 /** @brief Selector that returns the difference between two adjacent
270 template<typename _It>
271 struct __adjacent_difference_selector :
272 public __generic_for_each_selector<_It>
274 template<typename _Op>
276 operator()(_Op& __o, _It __i)
278 typename _It::first_type __go_back_one = __i.first;
280 *__i.__second = __o(*__i.__first, *__go_back_one);
285 // XXX move into type_traits?
286 /** @brief Functor doing nothing
288 * For some __reduction tasks (this is not a function object, but is
289 * passed as __selector __dummy parameter.
293 /** @brief Functor execution.
294 * @param __i iterator referencing object. */
295 template<typename _It>
297 operator()(_It __i) { }
300 /** @brief Reduction function doing nothing. */
304 operator()(bool /*__x*/, bool /*__y*/) const
308 /** @brief Reduction for finding the maximum element, using a comparator. */
309 template<typename _Compare, typename _It>
310 struct __min_element_reduct
315 __min_element_reduct(_Compare &__c) : __comp(__c) { }
318 operator()(_It __x, _It __y)
320 if (__comp(*__x, *__y))
327 /** @brief Reduction for finding the maximum element, using a comparator. */
328 template<typename _Compare, typename _It>
329 struct __max_element_reduct
334 __max_element_reduct(_Compare& __c) : __comp(__c) { }
337 operator()(_It __x, _It __y)
339 if (__comp(*__x, *__y))
346 /** @brief General reduction, using a binary operator. */
347 template<typename _BinOp>
348 struct __accumulate_binop_reduct
353 __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { }
355 template<typename _Result, typename _Addend>
357 operator()(const _Result& __x, const _Addend& __y)
358 { return __binop(__x, __y); }
362 #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */