// -*- C++ -*- // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, or (at your option) any later // version. // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/for_each_selectors.h * @brief Functors representing different tasks to be plugged into the * generic parallelization methods for embarrassingly parallel functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1 #include namespace __gnu_parallel { /** @brief Generic selector for embarrassingly parallel functions. */ template struct generic_for_each_selector { /** @brief Iterator on last element processed; needed for some * algorithms (e. g. std::transform()). */ It finish_iterator; }; /** @brief std::for_each() selector. */ template struct for_each_selector : public generic_for_each_selector { /** @brief Functor execution. * @param o Operator. * @param i Iterator referencing object. */ template bool operator()(Op& o, It i) { o(*i); return true; } }; /** @brief std::generate() selector. */ template struct generate_selector : public generic_for_each_selector { /** @brief Functor execution. * @param o Operator. * @param i Iterator referencing object. */ template bool operator()(Op& o, It i) { *i = o(); return true; } }; /** @brief std::fill() selector. */ template struct fill_selector : public generic_for_each_selector { /** @brief Functor execution. * @param v Current value. * @param i Iterator referencing object. */ template bool operator()(Val& v, It i) { *i = v; return true; } }; /** @brief std::transform() selector, one input sequence variant. */ template struct transform1_selector : public generic_for_each_selector { /** @brief Functor execution. * @param o Operator. * @param i Iterator referencing object. */ template bool operator()(Op& o, It i) { *i.second = o(*i.first); return true; } }; /** @brief std::transform() selector, two input sequences variant. */ template struct transform2_selector : public generic_for_each_selector { /** @brief Functor execution. * @param o Operator. * @param i Iterator referencing object. */ template bool operator()(Op& o, It i) { *i.third = o(*i.first, *i.second); return true; } }; /** @brief std::replace() selector. */ template struct replace_selector : public generic_for_each_selector { /** @brief Value to replace with. */ const T& new_val; /** @brief Constructor * @param new_val Value to replace with. */ explicit replace_selector(const T &new_val) : new_val(new_val) {} /** @brief Functor execution. * @param v Current value. * @param i Iterator referencing object. */ bool operator()(T& v, It i) { if (*i == v) *i = new_val; return true; } }; /** @brief std::replace() selector. */ template struct replace_if_selector : public generic_for_each_selector { /** @brief Value to replace with. */ const T& new_val; /** @brief Constructor. * @param new_val Value to replace with. */ explicit replace_if_selector(const T &new_val) : new_val(new_val) { } /** @brief Functor execution. * @param o Operator. * @param i Iterator referencing object. */ bool operator()(Op& o, It i) { if (o(*i)) *i = new_val; return true; } }; /** @brief std::count() selector. */ template struct count_selector : public generic_for_each_selector { /** @brief Functor execution. * @param v Current value. * @param i Iterator referencing object. * @return 1 if count, 0 if does not count. */ template Diff operator()(Val& v, It i) { return (v == *i) ? 1 : 0; } }; /** @brief std::count_if () selector. */ template struct count_if_selector : public generic_for_each_selector { /** @brief Functor execution. * @param o Operator. * @param i Iterator referencing object. * @return 1 if count, 0 if does not count. */ template Diff operator()(Op& o, It i) { return (o(*i)) ? 1 : 0; } }; /** @brief std::accumulate() selector. */ template struct accumulate_selector : public generic_for_each_selector { /** @brief Functor execution. * @param o Operator (unused). * @param i Iterator referencing object. * @return The current value. */ template typename std::iterator_traits::value_type operator()(Op o, It i) { return *i; } }; /** @brief std::inner_product() selector. */ template struct inner_product_selector : public generic_for_each_selector { /** @brief Begin iterator of first sequence. */ It begin1_iterator; /** @brief Begin iterator of second sequence. */ It2 begin2_iterator; /** @brief Constructor. * @param b1 Begin iterator of first sequence. * @param b2 Begin iterator of second sequence. */ explicit inner_product_selector(It b1, It2 b2) : begin1_iterator(b1), begin2_iterator(b2) { } /** @brief Functor execution. * @param mult Multiplication functor. * @param current Iterator referencing object. * @return Inner product elemental result. */ template T operator()(Op mult, It current) { typename std::iterator_traits::difference_type position = current - begin1_iterator; return mult(*current, *(begin2_iterator + position)); } }; /** @brief Selector that just returns the passed iterator. */ template struct identity_selector : public generic_for_each_selector { /** @brief Functor execution. * @param o Operator (unused). * @param i Iterator referencing object. * @return Passed iterator. */ template It operator()(Op o, It i) { return i; } }; /** @brief Selector that returns the difference between two adjacent * elements. */ template struct adjacent_difference_selector : public generic_for_each_selector { template bool operator()(Op& o, It i) { typename It::first_type go_back_one = i.first; --go_back_one; *i.second = o(*i.first, *go_back_one); return true; } }; // XXX move into type_traits? /** @brief Functor doing nothing * * For some reduction tasks (this is not a function object, but is * passed as selector dummy parameter. */ struct nothing { /** @brief Functor execution. * @param i Iterator referencing object. */ template void operator()(It i) { } }; /** @brief Reduction function doing nothing. */ struct dummy_reduct { bool operator()(bool /*x*/, bool /*y*/) const { return true; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template struct min_element_reduct { Comp& comp; explicit min_element_reduct(Comp &c) : comp(c) { } It operator()(It x, It y) { if (comp(*x, *y)) return x; else return y; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template struct max_element_reduct { Comp& comp; explicit max_element_reduct(Comp& c) : comp(c) { } It operator()(It x, It y) { if (comp(*x, *y)) return y; else return x; } }; /** @brief General reduction, using a binary operator. */ template struct accumulate_binop_reduct { BinOp& binop; explicit accumulate_binop_reduct(BinOp& b) : binop(b) { } template Result operator()(const Result& x, const Addend& y) { return binop(x, y); } }; } #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */