OSDN Git Service

2009-09-17 Johannes Singler <singler@ira.uka.de>
[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
218         operator()(_Op __o, _It __i)
219         { return *__i; }
220     };
221
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>
225     {
226       /** @brief Begin iterator of first sequence. */
227       _It __begin1_iterator;
228
229       /** @brief Begin iterator of second sequence. */
230       It2 begin2_iterator;
231
232       /** @brief Constructor.
233        *  @param b1 Begin iterator of first sequence.
234        *  @param b2 Begin iterator of second sequence. */
235       explicit
236       __inner_product_selector(_It b1, It2 b2)
237       : __begin1_iterator(b1), begin2_iterator(b2) { }
238
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>
244         _Tp
245         operator()(_Op __mult, _It __current)
246         {
247           typename std::iterator_traits<_It>::difference_type __position
248             = __current - __begin1_iterator;
249           return __mult(*__current, *(begin2_iterator + __position));
250         }
251     };
252
253   /** @brief Selector that just returns the passed iterator. */
254   template<typename _It>
255     struct __identity_selector : public __generic_for_each_selector<_It>
256     {
257       /** @brief Functor execution.
258        *  @param __o Operator (unused).
259        *  @param __i iterator referencing object.
260        *  @return Passed iterator. */
261       template<typename _Op>
262         _It
263         operator()(_Op __o, _It __i)
264         { return __i; }
265     };
266
267   /** @brief Selector that returns the difference between two adjacent
268    *  __elements.
269    */
270   template<typename _It>
271     struct __adjacent_difference_selector :
272            public __generic_for_each_selector<_It>
273     {
274       template<typename _Op>
275         bool
276         operator()(_Op& __o, _It __i)
277         {
278           typename _It::first_type __go_back_one = __i.first;
279           --__go_back_one;
280           *__i.__second = __o(*__i.__first, *__go_back_one);
281           return true;
282         }
283     };
284
285   // XXX move into type_traits?
286   /** @brief Functor doing nothing
287    *
288    *  For some __reduction tasks (this is not a function object, but is
289    *  passed as __selector __dummy parameter.
290    */
291   struct _Nothing
292   {
293     /** @brief Functor execution.
294      *  @param __i iterator referencing object. */
295     template<typename _It>
296       void
297       operator()(_It __i) { }
298   };
299
300   /** @brief Reduction function doing nothing. */
301   struct _DummyReduct
302   {
303     bool
304     operator()(bool /*__x*/, bool /*__y*/) const
305     { return true; }
306   };
307
308   /** @brief Reduction for finding the maximum element, using a comparator. */
309   template<typename _Compare, typename _It>
310     struct __min_element_reduct
311     {
312       _Compare& __comp;
313
314       explicit
315       __min_element_reduct(_Compare &__c) : __comp(__c) { }
316
317       _It
318       operator()(_It __x, _It __y)
319       {
320         if (__comp(*__x, *__y))
321           return __x;
322         else
323           return __y;
324       }
325     };
326
327   /** @brief Reduction for finding the maximum element, using a comparator. */
328   template<typename _Compare, typename _It>
329     struct __max_element_reduct
330     {
331       _Compare& __comp;
332
333       explicit
334       __max_element_reduct(_Compare& __c) : __comp(__c) { }
335
336       _It
337       operator()(_It __x, _It __y)
338       {
339         if (__comp(*__x, *__y))
340           return __y;
341         else
342           return __x;
343       }
344     };
345
346   /** @brief General reduction, using a binary operator. */
347   template<typename _BinOp>
348     struct __accumulate_binop_reduct
349     {
350       _BinOp& __binop;
351
352       explicit
353       __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { }
354
355       template<typename _Result, typename _Addend>
356         _Result
357         operator()(const _Result& __x, const _Addend& __y)
358         { return __binop(__x, __y); }
359     };
360 }
361
362 #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */