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