3 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 // MA 02111-1307, USA.
21 // As a special exception, you may use this file as part of a free
22 // software library without restriction. Specifically, if other files
23 // instantiate templates or use macros or inline functions from this
24 // file, or you compile this file and link it with other files to
25 // produce an executable, this file does not by itself cause the
26 // resulting executable to be covered by the GNU General Public
27 // License. This exception does not however invalidate any other
28 // reasons why the executable file might be covered by the GNU General
31 /** @file parallel/for_each_selectors.h
32 * @brief Functors representing different tasks to be plugged into the
33 * generic parallelization methods for embarrassingly parallel functions.
34 * This file is a GNU parallel extension to the Standard C++ Library.
37 // Written by Felix Putze.
39 #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H
40 #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1
42 #include <parallel/basic_iterator.h>
44 namespace __gnu_parallel
47 /** @brief Generic selector for embarrassingly parallel functions. */
49 struct generic_for_each_selector
51 /** @brief Iterator on last element processed; needed for some
52 * algorithms (e. g. std::transform()).
58 /** @brief std::for_each() selector. */
60 struct for_each_selector
: public generic_for_each_selector
<It
>
62 /** @brief Functor execution.
64 * @param i Iterator referencing object. */
67 operator()(Op
& o
, It i
)
74 /** @brief std::generate() selector. */
76 struct generate_selector
: public generic_for_each_selector
<It
>
78 /** @brief Functor execution.
80 * @param i Iterator referencing object. */
83 operator()(Op
& o
, It i
)
90 /** @brief std::fill() selector. */
92 struct fill_selector
: public generic_for_each_selector
<It
>
94 /** @brief Functor execution.
95 * @param v Current value.
96 * @param i Iterator referencing object. */
97 template<typename Val
>
99 operator()(Val
& v
, It i
)
106 /** @brief std::transform() selector, one input sequence variant. */
107 template<typename It
>
108 struct transform1_selector
: public generic_for_each_selector
<It
>
110 /** @brief Functor execution.
112 * @param i Iterator referencing object. */
113 template<typename Op
>
115 operator()(Op
& o
, It i
)
117 *i
.second
= o(*i
.first
);
122 /** @brief std::transform() selector, two input sequences variant. */
123 template<typename It
>
124 struct transform2_selector
: public generic_for_each_selector
<It
>
126 /** @brief Functor execution.
128 * @param i Iterator referencing object. */
129 template<typename Op
>
131 operator()(Op
& o
, It i
)
133 *i
.third
= o(*i
.first
, *i
.second
);
138 /** @brief std::replace() selector. */
139 template<typename It
, typename T
>
140 struct replace_selector
: public generic_for_each_selector
<It
>
142 /** @brief Value to replace with. */
145 /** @brief Constructor
146 * @param new_val Value to replace with. */
148 replace_selector(const T
&new_val
) : new_val(new_val
) {}
150 /** @brief Functor execution.
151 * @param v Current value.
152 * @param i Iterator referencing object. */
154 operator()(T
& v
, It i
)
162 /** @brief std::replace() selector. */
163 template<typename It
, typename Op
, typename T
>
164 struct replace_if_selector
: public generic_for_each_selector
<It
>
166 /** @brief Value to replace with. */
169 /** @brief Constructor.
170 * @param new_val Value to replace with. */
172 replace_if_selector(const T
&new_val
) : new_val(new_val
) { }
174 /** @brief Functor execution.
176 * @param i Iterator referencing object. */
178 operator()(Op
& o
, It i
)
186 /** @brief std::count() selector. */
187 template<typename It
, typename Diff
>
188 struct count_selector
: public generic_for_each_selector
<It
>
190 /** @brief Functor execution.
191 * @param v Current value.
192 * @param i Iterator referencing object.
193 * @return 1 if count, 0 if does not count. */
194 template<typename Val
>
196 operator()(Val
& v
, It i
)
197 { return (v
== *i
) ? 1 : 0; }
200 /** @brief std::count_if () selector. */
201 template<typename It
, typename Diff
>
202 struct count_if_selector
: public generic_for_each_selector
<It
>
204 /** @brief Functor execution.
206 * @param i Iterator referencing object.
207 * @return 1 if count, 0 if does not count. */
208 template<typename Op
>
210 operator()(Op
& o
, It i
)
211 { return (o(*i
)) ? 1 : 0; }
214 /** @brief std::accumulate() selector. */
215 template<typename It
>
216 struct accumulate_selector
: public generic_for_each_selector
<It
>
218 /** @brief Functor execution.
219 * @param o Operator (unused).
220 * @param i Iterator referencing object.
221 * @return The current value. */
222 template<typename Op
>
223 typename
std::iterator_traits
<It
>::value_type
operator()(Op o
, It i
)
227 /** @brief std::inner_product() selector. */
228 template<typename It
, typename It2
, typename T
>
229 struct inner_product_selector
: public generic_for_each_selector
<It
>
231 /** @brief Begin iterator of first sequence. */
234 /** @brief Begin iterator of second sequence. */
237 /** @brief Constructor.
238 * @param b1 Begin iterator of first sequence.
239 * @param b2 Begin iterator of second sequence. */
241 inner_product_selector(It b1
, It2 b2
)
242 : begin1_iterator(b1
), begin2_iterator(b2
) { }
244 /** @brief Functor execution.
245 * @param mult Multiplication functor.
246 * @param current Iterator referencing object.
247 * @return Inner product elemental result. */
248 template<typename Op
>
250 operator()(Op mult
, It current
)
252 typename
std::iterator_traits
<It
>::difference_type position
253 = current
- begin1_iterator
;
254 return mult(*current
, *(begin2_iterator
+ position
));
258 /** @brief Selector that just returns the passed iterator. */
259 template<typename It
>
260 struct identity_selector
: public generic_for_each_selector
<It
>
262 /** @brief Functor execution.
263 * @param o Operator (unused).
264 * @param i Iterator referencing object.
265 * @return Passed iterator. */
266 template<typename Op
>
268 operator()(Op o
, It i
)
272 /** @brief Selector that returns the difference between two adjacent
275 template<typename It
>
276 struct adjacent_difference_selector
: public generic_for_each_selector
<It
>
278 template<typename Op
>
280 operator()(Op
& o
, It i
)
282 typename
It::first_type go_back_one
= i
.first
;
284 *i
.second
= o(*i
.first
, *go_back_one
);
289 // XXX move into type_traits?
290 /** @brief Functor doing nothing
292 * For some reduction tasks (this is not a function object, but is
293 * passed as selector dummy parameter.
297 /** @brief Functor execution.
298 * @param i Iterator referencing object. */
299 template<typename It
>
304 /** @brief Reduction function doing nothing. */
308 operator()(bool /*x*/, bool /*y*/) const
312 /** @brief Reduction for finding the maximum element, using a comparator. */
313 template<typename Comp
, typename It
>
314 struct min_element_reduct
319 min_element_reduct(Comp
&c
) : comp(c
) { }
322 operator()(It x
, It y
)
331 /** @brief Reduction for finding the maximum element, using a comparator. */
332 template<typename Comp
, typename It
>
333 struct max_element_reduct
338 max_element_reduct(Comp
& c
) : comp(c
) { }
341 operator()(It x
, It y
)
350 /** @brief General reduction, using a binary operator. */
351 template<typename BinOp
>
352 struct accumulate_binop_reduct
357 accumulate_binop_reduct(BinOp
& b
) : binop(b
) { }
359 template<typename Result
, typename Addend
>
361 operator()(const Result
& x
, const Addend
& y
)
362 { return binop(x
, y
); }