OSDN Git Service

ae12c945d3ce37c1b99acb11c43b010a8ca88705
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / parallel / for_each_selectors.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
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
8 // Foundation; either version 3, or (at your option) any later
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
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/>.
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 {
40
41   /** @brief Generic __selector for embarrassingly parallel functions. */
42   template<typename _It>
43   struct __generic_for_each_selector
44   {
45     /** @brief _Iterator on last element processed; needed for some
46      *  algorithms (e. g. std::transform()).
47      */
48     _It _M_finish_iterator;
49   };
50
51
52   /** @brief std::for_each() selector. */
53   template<typename _It>
54     struct __for_each_selector : public __generic_for_each_selector<_It>
55     {
56       /** @brief Functor execution.
57        *  @param __o Operator.
58        *  @param __i iterator referencing object. */
59       template<typename _Op>
60         bool
61         operator()(_Op& __o, _It __i)
62         {
63           __o(*__i);
64           return true;
65         }
66     };
67
68   /** @brief std::generate() selector. */
69   template<typename _It>
70     struct __generate_selector : public __generic_for_each_selector<_It>
71     {
72       /** @brief Functor execution.
73        *  @param __o Operator.
74        *  @param __i iterator referencing object. */
75       template<typename _Op>
76         bool
77         operator()(_Op& __o, _It __i)
78         {
79           *__i = __o();
80           return true;
81         }
82     };
83
84   /** @brief std::fill() selector. */
85   template<typename _It>
86     struct __fill_selector : public __generic_for_each_selector<_It>
87     {
88       /** @brief Functor execution.
89        *  @param __v Current value.
90        *  @param __i iterator referencing object. */
91       template<typename Val>
92         bool
93         operator()(Val& __v, _It __i)
94         {
95           *__i = __v;
96           return true;
97         }
98     };
99
100   /** @brief std::transform() __selector, one input sequence variant. */
101   template<typename _It>
102     struct __transform1_selector : public __generic_for_each_selector<_It>
103     {
104       /** @brief Functor execution.
105        *  @param __o Operator.
106        *  @param __i iterator referencing object. */
107       template<typename _Op>
108         bool
109         operator()(_Op& __o, _It __i)
110         {
111           *__i.second = __o(*__i.first);
112           return true;
113         }
114     };
115
116   /** @brief std::transform() __selector, two input sequences variant. */
117   template<typename _It>
118     struct __transform2_selector : public __generic_for_each_selector<_It>
119     {
120       /** @brief Functor execution.
121        *  @param __o Operator.
122        *  @param __i iterator referencing object. */
123       template<typename _Op>
124         bool
125         operator()(_Op& __o, _It __i)
126         {
127           *__i._M_third = __o(*__i._M_first, *__i._M_second);
128           return true;
129         }
130     };
131
132   /** @brief std::replace() selector. */
133   template<typename _It, typename _Tp>
134     struct __replace_selector : public __generic_for_each_selector<_It>
135     {
136       /** @brief Value to replace with. */
137       const _Tp& __new_val;
138
139       /** @brief Constructor
140        *  @param __new_val Value to replace with. */
141       explicit
142       __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {}
143
144       /** @brief Functor execution.
145        *  @param __v Current value.
146        *  @param __i iterator referencing object. */
147       bool
148       operator()(_Tp& __v, _It __i)
149       {
150         if (*__i == __v)
151           *__i = __new_val;
152         return true;
153       }
154     };
155
156   /** @brief std::replace() selector. */
157   template<typename _It, typename _Op, typename _Tp>
158     struct __replace_if_selector : public __generic_for_each_selector<_It>
159     {
160       /** @brief Value to replace with. */
161       const _Tp& __new_val;
162
163       /** @brief Constructor.
164        *  @param __new_val Value to replace with. */
165       explicit
166       __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { }
167
168       /** @brief Functor execution.
169        *  @param __o Operator.
170        *  @param __i iterator referencing object. */
171       bool
172       operator()(_Op& __o, _It __i)
173       {
174         if (__o(*__i))
175           *__i = __new_val;
176         return true;
177       }
178     };
179
180   /** @brief std::count() selector. */
181   template<typename _It, typename _Diff>
182     struct __count_selector : public __generic_for_each_selector<_It>
183     {
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>
189         _Diff
190         operator()(Val& __v, _It __i)
191         { return (__v == *__i) ? 1 : 0; }
192     };
193
194   /** @brief std::count_if () selector. */
195   template<typename _It, typename _Diff>
196     struct __count_if_selector : public __generic_for_each_selector<_It>
197     {
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>
203         _Diff
204         operator()(_Op& __o, _It __i)
205         { return (__o(*__i)) ? 1 : 0; }
206     };
207
208   /** @brief std::accumulate() selector. */
209   template<typename _It>
210     struct __accumulate_selector : public __generic_for_each_selector<_It>
211     {
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)
218         { return *__i; }
219     };
220
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>
224     {
225       /** @brief Begin iterator of first sequence. */
226       _It __begin1_iterator;
227
228       /** @brief Begin iterator of second sequence. */
229       It2 begin2_iterator;
230
231       /** @brief Constructor.
232        *  @param b1 Begin iterator of first sequence.
233        *  @param b2 Begin iterator of second sequence. */
234       explicit
235       __inner_product_selector(_It b1, It2 b2)
236       : __begin1_iterator(b1), begin2_iterator(b2) { }
237
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>
243         _Tp
244         operator()(_Op __mult, _It __current)
245         {
246           typename std::iterator_traits<_It>::difference_type __position
247             = __current - __begin1_iterator;
248           return __mult(*__current, *(begin2_iterator + __position));
249         }
250     };
251
252   /** @brief Selector that just returns the passed iterator. */
253   template<typename _It>
254     struct __identity_selector : public __generic_for_each_selector<_It>
255     {
256       /** @brief Functor execution.
257        *  @param __o Operator (unused).
258        *  @param __i iterator referencing object.
259        *  @return Passed iterator. */
260       template<typename _Op>
261         _It
262         operator()(_Op __o, _It __i)
263         { return __i; }
264     };
265
266   /** @brief Selector that returns the difference between two adjacent
267    *  __elements.
268    */
269   template<typename _It>
270     struct __adjacent_difference_selector : public __generic_for_each_selector<_It>
271     {
272       template<typename _Op>
273         bool
274         operator()(_Op& __o, _It __i)
275         {
276           typename _It::first_type __go_back_one = __i.first;
277           --__go_back_one;
278           *__i.__second = __o(*__i.__first, *__go_back_one);
279           return true;
280         }
281     };
282
283   // XXX move into type_traits?
284   /** @brief Functor doing nothing
285    *
286    *  For some __reduction tasks (this is not a function object, but is
287    *  passed as __selector __dummy parameter.
288    */
289   struct _Nothing
290   {
291     /** @brief Functor execution.
292      *  @param __i iterator referencing object. */
293     template<typename _It>
294       void
295       operator()(_It __i) { }
296   };
297
298   /** @brief Reduction function doing nothing. */
299   struct _DummyReduct
300   {
301     bool
302     operator()(bool /*__x*/, bool /*__y*/) const
303     { return true; }
304   };
305
306   /** @brief Reduction for finding the maximum element, using a comparator. */
307   template<typename _Compare, typename _It>
308     struct __min_element_reduct
309     {
310       _Compare& __comp;
311
312       explicit
313       __min_element_reduct(_Compare &__c) : __comp(__c) { }
314
315       _It
316       operator()(_It __x, _It __y)
317       {
318         if (__comp(*__x, *__y))
319           return __x;
320         else
321           return __y;
322       }
323     };
324
325   /** @brief Reduction for finding the maximum element, using a comparator. */
326   template<typename _Compare, typename _It>
327     struct __max_element_reduct
328     {
329       _Compare& __comp;
330
331       explicit
332       __max_element_reduct(_Compare& __c) : __comp(__c) { }
333
334       _It
335       operator()(_It __x, _It __y)
336       {
337         if (__comp(*__x, *__y))
338           return __y;
339         else
340           return __x;
341       }
342     };
343
344   /** @brief General reduction, using a binary operator. */
345   template<typename _BinOp>
346     struct __accumulate_binop_reduct
347     {
348       _BinOp& __binop;
349
350       explicit
351       __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { }
352
353       template<typename _Result, typename _Addend>
354         _Result
355         operator()(const _Result& __x, const _Addend& __y)
356         { return __binop(__x, __y); }
357     };
358 }
359
360 #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */