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

Generated on Sat Oct 25 05:09:01 2008 for libstdc++ by  doxygen 1.5.6