# for_each_selectors.h

Go to the documentation of this file.

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