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 operator()(_Op __o, _It __i)
221 /** @brief std::inner_product() selector. */
222 template<typename _It, typename It2, typename _Tp>
223 struct __inner_product_selector : public __generic_for_each_selector<_It>
225 /** @brief Begin iterator of first sequence. */
226 _It __begin1_iterator;
228 /** @brief Begin iterator of second sequence. */
231 /** @brief Constructor.
232 * @param b1 Begin iterator of first sequence.
233 * @param b2 Begin iterator of second sequence. */
235 __inner_product_selector(_It b1, It2 b2)
236 : __begin1_iterator(b1), begin2_iterator(b2) { }
238 /** @brief Functor execution.
239 * @param __mult Multiplication functor.
240 * @param __current iterator referencing object.
241 * @return Inner product elemental __result. */
242 template<typename _Op>
244 operator()(_Op __mult, _It __current)
246 typename std::iterator_traits<_It>::difference_type __position
247 = __current - __begin1_iterator;
248 return __mult(*__current, *(begin2_iterator + __position));
252 /** @brief Selector that just returns the passed iterator. */
253 template<typename _It>
254 struct __identity_selector : public __generic_for_each_selector<_It>
256 /** @brief Functor execution.
257 * @param __o Operator (unused).
258 * @param __i iterator referencing object.
259 * @return Passed iterator. */
260 template<typename _Op>
262 operator()(_Op __o, _It __i)
266 /** @brief Selector that returns the difference between two adjacent
269 template<typename _It>
270 struct __adjacent_difference_selector : public __generic_for_each_selector<_It>
272 template<typename _Op>
274 operator()(_Op& __o, _It __i)
276 typename _It::first_type __go_back_one = __i.first;
278 *__i.__second = __o(*__i.__first, *__go_back_one);
283 // XXX move into type_traits?
284 /** @brief Functor doing nothing
286 * For some __reduction tasks (this is not a function object, but is
287 * passed as __selector __dummy parameter.
291 /** @brief Functor execution.
292 * @param __i iterator referencing object. */
293 template<typename _It>
295 operator()(_It __i) { }
298 /** @brief Reduction function doing nothing. */
302 operator()(bool /*__x*/, bool /*__y*/) const
306 /** @brief Reduction for finding the maximum element, using a comparator. */
307 template<typename _Compare, typename _It>
308 struct __min_element_reduct
313 __min_element_reduct(_Compare &__c) : __comp(__c) { }
316 operator()(_It __x, _It __y)
318 if (__comp(*__x, *__y))
325 /** @brief Reduction for finding the maximum element, using a comparator. */
326 template<typename _Compare, typename _It>
327 struct __max_element_reduct
332 __max_element_reduct(_Compare& __c) : __comp(__c) { }
335 operator()(_It __x, _It __y)
337 if (__comp(*__x, *__y))
344 /** @brief General reduction, using a binary operator. */
345 template<typename _BinOp>
346 struct __accumulate_binop_reduct
351 __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { }
353 template<typename _Result, typename _Addend>
355 operator()(const _Result& __x, const _Addend& __y)
356 { return __binop(__x, __y); }
360 #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */