xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/parallel/for_each_selectors.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the terms
7*38fd1498Szrj // of the GNU General Public License as published by the Free Software
8*38fd1498Szrj // Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj // version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful, but
12*38fd1498Szrj // WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*38fd1498Szrj // General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /** @file parallel/for_each_selectors.h
26*38fd1498Szrj  *  @brief Functors representing different tasks to be plugged into the
27*38fd1498Szrj  *  generic parallelization methods for embarrassingly parallel functions.
28*38fd1498Szrj  *  This file is a GNU parallel extension to the Standard C++ Library.
29*38fd1498Szrj  */
30*38fd1498Szrj 
31*38fd1498Szrj // Written by Felix Putze.
32*38fd1498Szrj 
33*38fd1498Szrj #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H
34*38fd1498Szrj #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1
35*38fd1498Szrj 
36*38fd1498Szrj #include <parallel/basic_iterator.h>
37*38fd1498Szrj 
38*38fd1498Szrj namespace __gnu_parallel
39*38fd1498Szrj {
40*38fd1498Szrj   /** @brief Generic __selector for embarrassingly parallel functions. */
41*38fd1498Szrj   template<typename _It>
42*38fd1498Szrj     struct __generic_for_each_selector
43*38fd1498Szrj     {
44*38fd1498Szrj       /** @brief _Iterator on last element processed; needed for some
45*38fd1498Szrj        *  algorithms (e. g. std::transform()).
46*38fd1498Szrj        */
47*38fd1498Szrj       _It _M_finish_iterator;
48*38fd1498Szrj     };
49*38fd1498Szrj 
50*38fd1498Szrj   /** @brief std::for_each() selector. */
51*38fd1498Szrj   template<typename _It>
52*38fd1498Szrj     struct __for_each_selector : public __generic_for_each_selector<_It>
53*38fd1498Szrj     {
54*38fd1498Szrj       /** @brief Functor execution.
55*38fd1498Szrj        *  @param __o Operator.
56*38fd1498Szrj        *  @param __i iterator referencing object. */
57*38fd1498Szrj       template<typename _Op>
58*38fd1498Szrj         bool
operator__for_each_selector59*38fd1498Szrj         operator()(_Op& __o, _It __i)
60*38fd1498Szrj         {
61*38fd1498Szrj           __o(*__i);
62*38fd1498Szrj           return true;
63*38fd1498Szrj         }
64*38fd1498Szrj     };
65*38fd1498Szrj 
66*38fd1498Szrj   /** @brief std::generate() selector. */
67*38fd1498Szrj   template<typename _It>
68*38fd1498Szrj     struct __generate_selector : public __generic_for_each_selector<_It>
69*38fd1498Szrj     {
70*38fd1498Szrj       /** @brief Functor execution.
71*38fd1498Szrj        *  @param __o Operator.
72*38fd1498Szrj        *  @param __i iterator referencing object. */
73*38fd1498Szrj       template<typename _Op>
74*38fd1498Szrj         bool
operator__generate_selector75*38fd1498Szrj         operator()(_Op& __o, _It __i)
76*38fd1498Szrj         {
77*38fd1498Szrj           *__i = __o();
78*38fd1498Szrj           return true;
79*38fd1498Szrj         }
80*38fd1498Szrj     };
81*38fd1498Szrj 
82*38fd1498Szrj   /** @brief std::fill() selector. */
83*38fd1498Szrj   template<typename _It>
84*38fd1498Szrj     struct __fill_selector : public __generic_for_each_selector<_It>
85*38fd1498Szrj     {
86*38fd1498Szrj       /** @brief Functor execution.
87*38fd1498Szrj        *  @param __v Current value.
88*38fd1498Szrj        *  @param __i iterator referencing object. */
89*38fd1498Szrj       template<typename _ValueType>
90*38fd1498Szrj         bool
operator__fill_selector91*38fd1498Szrj         operator()(_ValueType& __v, _It __i)
92*38fd1498Szrj         {
93*38fd1498Szrj           *__i = __v;
94*38fd1498Szrj           return true;
95*38fd1498Szrj         }
96*38fd1498Szrj     };
97*38fd1498Szrj 
98*38fd1498Szrj   /** @brief std::transform() __selector, one input sequence variant. */
99*38fd1498Szrj   template<typename _It>
100*38fd1498Szrj     struct __transform1_selector : public __generic_for_each_selector<_It>
101*38fd1498Szrj     {
102*38fd1498Szrj       /** @brief Functor execution.
103*38fd1498Szrj        *  @param __o Operator.
104*38fd1498Szrj        *  @param __i iterator referencing object. */
105*38fd1498Szrj       template<typename _Op>
106*38fd1498Szrj         bool
operator__transform1_selector107*38fd1498Szrj         operator()(_Op& __o, _It __i)
108*38fd1498Szrj         {
109*38fd1498Szrj           *__i.second = __o(*__i.first);
110*38fd1498Szrj           return true;
111*38fd1498Szrj         }
112*38fd1498Szrj     };
113*38fd1498Szrj 
114*38fd1498Szrj   /** @brief std::transform() __selector, two input sequences variant. */
115*38fd1498Szrj   template<typename _It>
116*38fd1498Szrj     struct __transform2_selector : public __generic_for_each_selector<_It>
117*38fd1498Szrj     {
118*38fd1498Szrj       /** @brief Functor execution.
119*38fd1498Szrj        *  @param __o Operator.
120*38fd1498Szrj        *  @param __i iterator referencing object. */
121*38fd1498Szrj       template<typename _Op>
122*38fd1498Szrj         bool
operator__transform2_selector123*38fd1498Szrj         operator()(_Op& __o, _It __i)
124*38fd1498Szrj         {
125*38fd1498Szrj           *__i._M_third = __o(*__i._M_first, *__i._M_second);
126*38fd1498Szrj           return true;
127*38fd1498Szrj         }
128*38fd1498Szrj     };
129*38fd1498Szrj 
130*38fd1498Szrj   /** @brief std::replace() selector. */
131*38fd1498Szrj   template<typename _It, typename _Tp>
132*38fd1498Szrj     struct __replace_selector : public __generic_for_each_selector<_It>
133*38fd1498Szrj     {
134*38fd1498Szrj       /** @brief Value to replace with. */
135*38fd1498Szrj       const _Tp& __new_val;
136*38fd1498Szrj 
137*38fd1498Szrj       /** @brief Constructor
138*38fd1498Szrj        *  @param __new_val Value to replace with. */
139*38fd1498Szrj       explicit
__replace_selector__replace_selector140*38fd1498Szrj       __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {}
141*38fd1498Szrj 
142*38fd1498Szrj       /** @brief Functor execution.
143*38fd1498Szrj        *  @param __v Current value.
144*38fd1498Szrj        *  @param __i iterator referencing object. */
145*38fd1498Szrj       bool
operator__replace_selector146*38fd1498Szrj       operator()(_Tp& __v, _It __i)
147*38fd1498Szrj       {
148*38fd1498Szrj         if (*__i == __v)
149*38fd1498Szrj           *__i = __new_val;
150*38fd1498Szrj         return true;
151*38fd1498Szrj       }
152*38fd1498Szrj     };
153*38fd1498Szrj 
154*38fd1498Szrj   /** @brief std::replace() selector. */
155*38fd1498Szrj   template<typename _It, typename _Op, typename _Tp>
156*38fd1498Szrj     struct __replace_if_selector : public __generic_for_each_selector<_It>
157*38fd1498Szrj     {
158*38fd1498Szrj       /** @brief Value to replace with. */
159*38fd1498Szrj       const _Tp& __new_val;
160*38fd1498Szrj 
161*38fd1498Szrj       /** @brief Constructor.
162*38fd1498Szrj        *  @param __new_val Value to replace with. */
163*38fd1498Szrj       explicit
__replace_if_selector__replace_if_selector164*38fd1498Szrj       __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { }
165*38fd1498Szrj 
166*38fd1498Szrj       /** @brief Functor execution.
167*38fd1498Szrj        *  @param __o Operator.
168*38fd1498Szrj        *  @param __i iterator referencing object. */
169*38fd1498Szrj       bool
operator__replace_if_selector170*38fd1498Szrj       operator()(_Op& __o, _It __i)
171*38fd1498Szrj       {
172*38fd1498Szrj         if (__o(*__i))
173*38fd1498Szrj           *__i = __new_val;
174*38fd1498Szrj         return true;
175*38fd1498Szrj       }
176*38fd1498Szrj     };
177*38fd1498Szrj 
178*38fd1498Szrj   /** @brief std::count() selector. */
179*38fd1498Szrj   template<typename _It, typename _Diff>
180*38fd1498Szrj     struct __count_selector : public __generic_for_each_selector<_It>
181*38fd1498Szrj     {
182*38fd1498Szrj       /** @brief Functor execution.
183*38fd1498Szrj        *  @param __v Current value.
184*38fd1498Szrj        *  @param __i iterator referencing object.
185*38fd1498Szrj        *  @return 1 if count, 0 if does not count. */
186*38fd1498Szrj       template<typename _ValueType>
187*38fd1498Szrj         _Diff
operator__count_selector188*38fd1498Szrj         operator()(_ValueType& __v, _It __i)
189*38fd1498Szrj         { return (__v == *__i) ? 1 : 0; }
190*38fd1498Szrj     };
191*38fd1498Szrj 
192*38fd1498Szrj   /** @brief std::count_if () selector. */
193*38fd1498Szrj   template<typename _It, typename _Diff>
194*38fd1498Szrj     struct __count_if_selector : public __generic_for_each_selector<_It>
195*38fd1498Szrj     {
196*38fd1498Szrj       /** @brief Functor execution.
197*38fd1498Szrj        *  @param __o Operator.
198*38fd1498Szrj        *  @param __i iterator referencing object.
199*38fd1498Szrj        *  @return 1 if count, 0 if does not count. */
200*38fd1498Szrj       template<typename _Op>
201*38fd1498Szrj         _Diff
operator__count_if_selector202*38fd1498Szrj         operator()(_Op& __o, _It __i)
203*38fd1498Szrj         { return (__o(*__i)) ? 1 : 0; }
204*38fd1498Szrj     };
205*38fd1498Szrj 
206*38fd1498Szrj   /** @brief std::accumulate() selector. */
207*38fd1498Szrj   template<typename _It>
208*38fd1498Szrj     struct __accumulate_selector : public __generic_for_each_selector<_It>
209*38fd1498Szrj     {
210*38fd1498Szrj       /** @brief Functor execution.
211*38fd1498Szrj        *  @param __o Operator (unused).
212*38fd1498Szrj        *  @param __i iterator referencing object.
213*38fd1498Szrj        *  @return The current value. */
214*38fd1498Szrj       template<typename _Op>
215*38fd1498Szrj         typename std::iterator_traits<_It>::value_type
operator__accumulate_selector216*38fd1498Szrj         operator()(_Op __o, _It __i)
217*38fd1498Szrj         { return *__i; }
218*38fd1498Szrj     };
219*38fd1498Szrj 
220*38fd1498Szrj   /** @brief std::inner_product() selector. */
221*38fd1498Szrj   template<typename _It, typename _It2, typename _Tp>
222*38fd1498Szrj     struct __inner_product_selector : public __generic_for_each_selector<_It>
223*38fd1498Szrj     {
224*38fd1498Szrj       /** @brief Begin iterator of first sequence. */
225*38fd1498Szrj       _It  __begin1_iterator;
226*38fd1498Szrj 
227*38fd1498Szrj       /** @brief Begin iterator of second sequence. */
228*38fd1498Szrj       _It2 __begin2_iterator;
229*38fd1498Szrj 
230*38fd1498Szrj       /** @brief Constructor.
231*38fd1498Szrj        *  @param __b1 Begin iterator of first sequence.
232*38fd1498Szrj        *  @param __b2 Begin iterator of second sequence. */
233*38fd1498Szrj       explicit
__inner_product_selector__inner_product_selector234*38fd1498Szrj       __inner_product_selector(_It __b1, _It2 __b2)
235*38fd1498Szrj       : __begin1_iterator(__b1), __begin2_iterator(__b2) { }
236*38fd1498Szrj 
237*38fd1498Szrj       /** @brief Functor execution.
238*38fd1498Szrj        *  @param __mult Multiplication functor.
239*38fd1498Szrj        *  @param __current iterator referencing object.
240*38fd1498Szrj        *  @return Inner product elemental __result. */
241*38fd1498Szrj       template<typename _Op>
242*38fd1498Szrj         _Tp
operator__inner_product_selector243*38fd1498Szrj         operator()(_Op __mult, _It __current)
244*38fd1498Szrj         {
245*38fd1498Szrj           typename std::iterator_traits<_It>::difference_type __position
246*38fd1498Szrj             = __current - __begin1_iterator;
247*38fd1498Szrj           return __mult(*__current, *(__begin2_iterator + __position));
248*38fd1498Szrj         }
249*38fd1498Szrj     };
250*38fd1498Szrj 
251*38fd1498Szrj   /** @brief Selector that just returns the passed iterator. */
252*38fd1498Szrj   template<typename _It>
253*38fd1498Szrj     struct __identity_selector : public __generic_for_each_selector<_It>
254*38fd1498Szrj     {
255*38fd1498Szrj       /** @brief Functor execution.
256*38fd1498Szrj        *  @param __o Operator (unused).
257*38fd1498Szrj        *  @param __i iterator referencing object.
258*38fd1498Szrj        *  @return Passed iterator. */
259*38fd1498Szrj       template<typename _Op>
260*38fd1498Szrj         _It
operator__identity_selector261*38fd1498Szrj         operator()(_Op __o, _It __i)
262*38fd1498Szrj         { return __i; }
263*38fd1498Szrj     };
264*38fd1498Szrj 
265*38fd1498Szrj   /** @brief Selector that returns the difference between two adjacent
266*38fd1498Szrj    *  __elements.
267*38fd1498Szrj    */
268*38fd1498Szrj   template<typename _It>
269*38fd1498Szrj     struct __adjacent_difference_selector
270*38fd1498Szrj     : public __generic_for_each_selector<_It>
271*38fd1498Szrj     {
272*38fd1498Szrj       template<typename _Op>
273*38fd1498Szrj         bool
operator__adjacent_difference_selector274*38fd1498Szrj         operator()(_Op& __o, _It __i)
275*38fd1498Szrj         {
276*38fd1498Szrj           typename _It::first_type __go_back_one = __i.first;
277*38fd1498Szrj           --__go_back_one;
278*38fd1498Szrj           *__i.second = __o(*__i.first, *__go_back_one);
279*38fd1498Szrj           return true;
280*38fd1498Szrj         }
281*38fd1498Szrj     };
282*38fd1498Szrj 
283*38fd1498Szrj   /** @brief Functor doing nothing
284*38fd1498Szrj    *
285*38fd1498Szrj    *  For some __reduction tasks (this is not a function object, but is
286*38fd1498Szrj    *  passed as __selector __dummy parameter.
287*38fd1498Szrj    */
288*38fd1498Szrj   struct _Nothing
289*38fd1498Szrj   {
290*38fd1498Szrj     /** @brief Functor execution.
291*38fd1498Szrj      *  @param __i iterator referencing object. */
292*38fd1498Szrj     template<typename _It>
293*38fd1498Szrj       void
operator_Nothing294*38fd1498Szrj       operator()(_It __i) { }
295*38fd1498Szrj   };
296*38fd1498Szrj 
297*38fd1498Szrj   /** @brief Reduction function doing nothing. */
298*38fd1498Szrj   struct _DummyReduct
299*38fd1498Szrj   {
300*38fd1498Szrj     bool
operator_DummyReduct301*38fd1498Szrj     operator()(bool, bool) const
302*38fd1498Szrj     { return true; }
303*38fd1498Szrj   };
304*38fd1498Szrj 
305*38fd1498Szrj   /** @brief Reduction for finding the maximum element, using a comparator. */
306*38fd1498Szrj   template<typename _Compare, typename _It>
307*38fd1498Szrj     struct __min_element_reduct
308*38fd1498Szrj     {
309*38fd1498Szrj       _Compare& __comp;
310*38fd1498Szrj 
311*38fd1498Szrj       explicit
__min_element_reduct__min_element_reduct312*38fd1498Szrj       __min_element_reduct(_Compare &__c) : __comp(__c) { }
313*38fd1498Szrj 
314*38fd1498Szrj       _It
operator__min_element_reduct315*38fd1498Szrj       operator()(_It __x, _It __y)
316*38fd1498Szrj       { return (__comp(*__x, *__y)) ? __x : __y; }
317*38fd1498Szrj     };
318*38fd1498Szrj 
319*38fd1498Szrj   /** @brief Reduction for finding the maximum element, using a comparator. */
320*38fd1498Szrj   template<typename _Compare, typename _It>
321*38fd1498Szrj     struct __max_element_reduct
322*38fd1498Szrj     {
323*38fd1498Szrj       _Compare& __comp;
324*38fd1498Szrj 
325*38fd1498Szrj       explicit
__max_element_reduct__max_element_reduct326*38fd1498Szrj       __max_element_reduct(_Compare& __c) : __comp(__c) { }
327*38fd1498Szrj 
328*38fd1498Szrj       _It
operator__max_element_reduct329*38fd1498Szrj       operator()(_It __x, _It __y)
330*38fd1498Szrj       { return (__comp(*__x, *__y)) ? __y : __x; }
331*38fd1498Szrj     };
332*38fd1498Szrj 
333*38fd1498Szrj   /** @brief General reduction, using a binary operator. */
334*38fd1498Szrj   template<typename _BinOp>
335*38fd1498Szrj     struct __accumulate_binop_reduct
336*38fd1498Szrj     {
337*38fd1498Szrj       _BinOp& __binop;
338*38fd1498Szrj 
339*38fd1498Szrj       explicit
__accumulate_binop_reduct__accumulate_binop_reduct340*38fd1498Szrj       __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { }
341*38fd1498Szrj 
342*38fd1498Szrj       template<typename _Result, typename _Addend>
343*38fd1498Szrj         _Result
operator__accumulate_binop_reduct344*38fd1498Szrj         operator()(const _Result& __x, const _Addend& __y)
345*38fd1498Szrj         { return __binop(__x, __y); }
346*38fd1498Szrj     };
347*38fd1498Szrj }
348*38fd1498Szrj 
349*38fd1498Szrj #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */
350