for_each_selectors.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file parallel/for_each_selectors.h
00026  *  @brief Functors representing different tasks to be plugged into the
00027  *  generic parallelization methods for embarrassingly parallel functions.
00028  *  This file is a GNU parallel extension to the Standard C++ Library.
00029  */
00030 
00031 // Written by Felix Putze.
00032 
00033 #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H
00034 #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1
00035 
00036 #include <parallel/basic_iterator.h>
00037 
00038 namespace __gnu_parallel
00039 {
00040 
00041   /** @brief Generic selector for embarrassingly parallel functions. */
00042   template<typename It>
00043   struct generic_for_each_selector
00044   {
00045     /** @brief Iterator on last element processed; needed for some
00046      *  algorithms (e. g. std::transform()).
00047      */
00048     It finish_iterator;
00049   };
00050 
00051 
00052   /** @brief std::for_each() selector. */
00053   template<typename It>
00054     struct for_each_selector : public generic_for_each_selector<It>
00055     {
00056       /** @brief Functor execution.
00057        *  @param o Operator.
00058        *  @param i Iterator referencing object. */
00059       template<typename Op>
00060         bool
00061         operator()(Op& o, It i)
00062     {
00063       o(*i);
00064       return true;
00065     }
00066     };
00067 
00068   /** @brief std::generate() selector. */
00069   template<typename It>
00070     struct generate_selector : public generic_for_each_selector<It>
00071     {
00072       /** @brief Functor execution.
00073        *  @param o Operator.
00074        *  @param i Iterator referencing object. */
00075       template<typename Op>
00076         bool
00077         operator()(Op& o, It i)
00078         {
00079       *i = o();
00080       return true;
00081     }
00082     };
00083 
00084   /** @brief std::fill() selector. */
00085   template<typename It>
00086     struct fill_selector : public generic_for_each_selector<It>
00087     {
00088       /** @brief Functor execution.
00089        *  @param v Current value.
00090        *  @param i Iterator referencing object. */
00091       template<typename Val>
00092         bool
00093         operator()(Val& v, It i)
00094     {
00095       *i = v;
00096       return true;
00097     }
00098     };
00099 
00100   /** @brief std::transform() selector, one input sequence variant. */
00101   template<typename It>
00102     struct transform1_selector : public generic_for_each_selector<It>
00103     {
00104       /** @brief Functor execution.
00105        *  @param o Operator.
00106        *  @param i Iterator referencing object. */
00107       template<typename Op>
00108         bool
00109         operator()(Op& o, It i)
00110     {
00111       *i.second = o(*i.first);
00112       return true;
00113     }
00114     };
00115 
00116   /** @brief std::transform() selector, two input sequences variant. */
00117   template<typename It>
00118     struct transform2_selector : public generic_for_each_selector<It>
00119     {
00120       /** @brief Functor execution.
00121        *  @param o Operator.
00122        *  @param i Iterator referencing object. */
00123       template<typename Op>
00124         bool
00125         operator()(Op& o, It i)
00126     {
00127       *i.third = o(*i.first, *i.second);
00128       return true;
00129     }
00130     };
00131 
00132   /** @brief std::replace() selector. */
00133   template<typename It, typename T>
00134     struct replace_selector : public generic_for_each_selector<It>
00135     {
00136       /** @brief Value to replace with. */
00137       const T& new_val;
00138 
00139       /** @brief Constructor
00140        *  @param new_val Value to replace with. */
00141       explicit
00142       replace_selector(const T &new_val) : new_val(new_val) {}
00143 
00144       /** @brief Functor execution.
00145        *  @param v Current value.
00146        *  @param i Iterator referencing object. */
00147       bool
00148       operator()(T& v, It i)
00149       {
00150     if (*i == v)
00151       *i = new_val;
00152     return true;
00153       }
00154     };
00155 
00156   /** @brief std::replace() selector. */
00157   template<typename It, typename Op, typename T>
00158     struct replace_if_selector : public generic_for_each_selector<It>
00159     {
00160       /** @brief Value to replace with. */
00161       const T& new_val;
00162 
00163       /** @brief Constructor.
00164        *  @param new_val Value to replace with. */
00165       explicit
00166       replace_if_selector(const T &new_val) : new_val(new_val) { }
00167 
00168       /** @brief Functor execution.
00169        *  @param o Operator.
00170        *  @param i Iterator referencing object. */
00171       bool
00172       operator()(Op& o, It i)
00173       {
00174     if (o(*i))
00175       *i = new_val;
00176     return true;
00177       }
00178     };
00179 
00180   /** @brief std::count() selector. */
00181   template<typename It, typename Diff>
00182     struct count_selector : public generic_for_each_selector<It>
00183     {
00184       /** @brief Functor execution.
00185        *  @param v Current value.
00186        *  @param i Iterator referencing object.
00187        *  @return 1 if count, 0 if does not count. */
00188       template<typename Val>
00189         Diff
00190         operator()(Val& v, It i)
00191     { return (v == *i) ? 1 : 0; }
00192     };
00193 
00194   /** @brief std::count_if () selector. */
00195   template<typename It, typename Diff>
00196     struct count_if_selector : public generic_for_each_selector<It>
00197     {
00198       /** @brief Functor execution.
00199        *  @param o Operator.
00200        *  @param i Iterator referencing object.
00201        *  @return 1 if count, 0 if does not count. */
00202       template<typename Op>
00203         Diff
00204         operator()(Op& o, It i)
00205     { return (o(*i)) ? 1 : 0; }
00206     };
00207 
00208   /** @brief std::accumulate() selector. */
00209   template<typename It>
00210     struct accumulate_selector : public generic_for_each_selector<It>
00211     {
00212       /** @brief Functor execution.
00213        *  @param o Operator (unused).
00214        *  @param i Iterator referencing object.
00215        *  @return The current value. */
00216       template<typename Op>
00217         typename std::iterator_traits<It>::value_type operator()(Op o, It i)
00218     { return *i; }
00219     };
00220 
00221   /** @brief std::inner_product() selector. */
00222   template<typename It, typename It2, typename T>
00223     struct inner_product_selector : public generic_for_each_selector<It>
00224     {
00225       /** @brief Begin iterator of first sequence. */
00226       It begin1_iterator;
00227 
00228       /** @brief Begin iterator of second sequence. */
00229       It2 begin2_iterator;
00230 
00231       /** @brief Constructor.
00232        *  @param b1 Begin iterator of first sequence.
00233        *  @param b2 Begin iterator of second sequence. */
00234       explicit
00235       inner_product_selector(It b1, It2 b2)
00236       : begin1_iterator(b1), begin2_iterator(b2) { }
00237 
00238       /** @brief Functor execution.
00239        *  @param mult Multiplication functor.
00240        *  @param current Iterator referencing object.
00241        *  @return Inner product elemental result. */
00242       template<typename Op>
00243         T
00244         operator()(Op mult, It current)
00245     {
00246       typename std::iterator_traits<It>::difference_type position
00247         = current - begin1_iterator;
00248       return mult(*current, *(begin2_iterator + position));
00249     }
00250     };
00251 
00252   /** @brief Selector that just returns the passed iterator. */
00253   template<typename It>
00254     struct identity_selector : public generic_for_each_selector<It>
00255     {
00256       /** @brief Functor execution.
00257        *  @param o Operator (unused).
00258        *  @param i Iterator referencing object.
00259        *  @return Passed iterator. */
00260       template<typename Op>
00261         It
00262         operator()(Op o, It i)
00263     { return i; }
00264     };
00265 
00266   /** @brief Selector that returns the difference between two adjacent
00267    *  elements.
00268    */
00269   template<typename It>
00270     struct adjacent_difference_selector : public generic_for_each_selector<It>
00271     {
00272       template<typename Op>
00273         bool
00274         operator()(Op& o, It i)
00275     {
00276       typename It::first_type go_back_one = i.first;
00277       --go_back_one;
00278       *i.second = o(*i.first, *go_back_one);
00279       return true;
00280     }
00281     };
00282 
00283   // XXX move into type_traits?
00284   /** @brief Functor doing nothing
00285    *
00286    *  For some reduction tasks (this is not a function object, but is
00287    *  passed as selector dummy parameter.
00288    */
00289   struct nothing
00290   {
00291     /** @brief Functor execution.
00292      *  @param i Iterator referencing object. */
00293     template<typename It>
00294       void
00295       operator()(It i) { }
00296   };
00297 
00298   /** @brief Reduction function doing nothing. */
00299   struct dummy_reduct
00300   {
00301     bool
00302     operator()(bool /*x*/, bool /*y*/) const
00303     { return true; }
00304   };
00305 
00306   /** @brief Reduction for finding the maximum element, using a comparator. */
00307   template<typename Comp, typename It>
00308     struct min_element_reduct
00309     {
00310       Comp& comp;
00311 
00312       explicit
00313       min_element_reduct(Comp &c) : comp(c) { }
00314 
00315       It
00316       operator()(It x, It y)
00317       {
00318     if (comp(*x, *y))
00319       return x;
00320     else
00321       return y;
00322       }
00323     };
00324 
00325   /** @brief Reduction for finding the maximum element, using a comparator. */
00326   template<typename Comp, typename It>
00327     struct max_element_reduct
00328     {
00329       Comp& comp;
00330 
00331       explicit
00332       max_element_reduct(Comp& c) : comp(c) { }
00333 
00334       It
00335       operator()(It x, It y)
00336       {
00337     if (comp(*x, *y))
00338       return y;
00339     else
00340       return x;
00341       }
00342     };
00343 
00344   /** @brief General reduction, using a binary operator. */
00345   template<typename BinOp>
00346     struct accumulate_binop_reduct
00347     {
00348       BinOp& binop;
00349 
00350       explicit
00351       accumulate_binop_reduct(BinOp& b) : binop(b) { }
00352 
00353       template<typename Result, typename Addend>
00354         Result
00355         operator()(const Result& x, const Addend& y)
00356     { return binop(x, y); }
00357     };
00358 }
00359 
00360 #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */

Generated on 19 Jun 2018 for libstdc++ by  doxygen 1.6.1