1*38fd1498Szrj // -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the terms 7*38fd1498Szrj // of the GNU General Public License as published by the Free Software 8*38fd1498Szrj // Foundation; either version 3, or (at your option) any later 9*38fd1498Szrj // version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, but 12*38fd1498Szrj // WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*38fd1498Szrj // General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file parallel/for_each_selectors.h 26*38fd1498Szrj * @brief Functors representing different tasks to be plugged into the 27*38fd1498Szrj * generic parallelization methods for embarrassingly parallel functions. 28*38fd1498Szrj * This file is a GNU parallel extension to the Standard C++ Library. 29*38fd1498Szrj */ 30*38fd1498Szrj 31*38fd1498Szrj // Written by Felix Putze. 32*38fd1498Szrj 33*38fd1498Szrj #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 34*38fd1498Szrj #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1 35*38fd1498Szrj 36*38fd1498Szrj #include <parallel/basic_iterator.h> 37*38fd1498Szrj 38*38fd1498Szrj namespace __gnu_parallel 39*38fd1498Szrj { 40*38fd1498Szrj /** @brief Generic __selector for embarrassingly parallel functions. */ 41*38fd1498Szrj template<typename _It> 42*38fd1498Szrj struct __generic_for_each_selector 43*38fd1498Szrj { 44*38fd1498Szrj /** @brief _Iterator on last element processed; needed for some 45*38fd1498Szrj * algorithms (e. g. std::transform()). 46*38fd1498Szrj */ 47*38fd1498Szrj _It _M_finish_iterator; 48*38fd1498Szrj }; 49*38fd1498Szrj 50*38fd1498Szrj /** @brief std::for_each() selector. */ 51*38fd1498Szrj template<typename _It> 52*38fd1498Szrj struct __for_each_selector : public __generic_for_each_selector<_It> 53*38fd1498Szrj { 54*38fd1498Szrj /** @brief Functor execution. 55*38fd1498Szrj * @param __o Operator. 56*38fd1498Szrj * @param __i iterator referencing object. */ 57*38fd1498Szrj template<typename _Op> 58*38fd1498Szrj bool operator__for_each_selector59*38fd1498Szrj operator()(_Op& __o, _It __i) 60*38fd1498Szrj { 61*38fd1498Szrj __o(*__i); 62*38fd1498Szrj return true; 63*38fd1498Szrj } 64*38fd1498Szrj }; 65*38fd1498Szrj 66*38fd1498Szrj /** @brief std::generate() selector. */ 67*38fd1498Szrj template<typename _It> 68*38fd1498Szrj struct __generate_selector : public __generic_for_each_selector<_It> 69*38fd1498Szrj { 70*38fd1498Szrj /** @brief Functor execution. 71*38fd1498Szrj * @param __o Operator. 72*38fd1498Szrj * @param __i iterator referencing object. */ 73*38fd1498Szrj template<typename _Op> 74*38fd1498Szrj bool operator__generate_selector75*38fd1498Szrj operator()(_Op& __o, _It __i) 76*38fd1498Szrj { 77*38fd1498Szrj *__i = __o(); 78*38fd1498Szrj return true; 79*38fd1498Szrj } 80*38fd1498Szrj }; 81*38fd1498Szrj 82*38fd1498Szrj /** @brief std::fill() selector. */ 83*38fd1498Szrj template<typename _It> 84*38fd1498Szrj struct __fill_selector : public __generic_for_each_selector<_It> 85*38fd1498Szrj { 86*38fd1498Szrj /** @brief Functor execution. 87*38fd1498Szrj * @param __v Current value. 88*38fd1498Szrj * @param __i iterator referencing object. */ 89*38fd1498Szrj template<typename _ValueType> 90*38fd1498Szrj bool operator__fill_selector91*38fd1498Szrj operator()(_ValueType& __v, _It __i) 92*38fd1498Szrj { 93*38fd1498Szrj *__i = __v; 94*38fd1498Szrj return true; 95*38fd1498Szrj } 96*38fd1498Szrj }; 97*38fd1498Szrj 98*38fd1498Szrj /** @brief std::transform() __selector, one input sequence variant. */ 99*38fd1498Szrj template<typename _It> 100*38fd1498Szrj struct __transform1_selector : public __generic_for_each_selector<_It> 101*38fd1498Szrj { 102*38fd1498Szrj /** @brief Functor execution. 103*38fd1498Szrj * @param __o Operator. 104*38fd1498Szrj * @param __i iterator referencing object. */ 105*38fd1498Szrj template<typename _Op> 106*38fd1498Szrj bool operator__transform1_selector107*38fd1498Szrj operator()(_Op& __o, _It __i) 108*38fd1498Szrj { 109*38fd1498Szrj *__i.second = __o(*__i.first); 110*38fd1498Szrj return true; 111*38fd1498Szrj } 112*38fd1498Szrj }; 113*38fd1498Szrj 114*38fd1498Szrj /** @brief std::transform() __selector, two input sequences variant. */ 115*38fd1498Szrj template<typename _It> 116*38fd1498Szrj struct __transform2_selector : public __generic_for_each_selector<_It> 117*38fd1498Szrj { 118*38fd1498Szrj /** @brief Functor execution. 119*38fd1498Szrj * @param __o Operator. 120*38fd1498Szrj * @param __i iterator referencing object. */ 121*38fd1498Szrj template<typename _Op> 122*38fd1498Szrj bool operator__transform2_selector123*38fd1498Szrj operator()(_Op& __o, _It __i) 124*38fd1498Szrj { 125*38fd1498Szrj *__i._M_third = __o(*__i._M_first, *__i._M_second); 126*38fd1498Szrj return true; 127*38fd1498Szrj } 128*38fd1498Szrj }; 129*38fd1498Szrj 130*38fd1498Szrj /** @brief std::replace() selector. */ 131*38fd1498Szrj template<typename _It, typename _Tp> 132*38fd1498Szrj struct __replace_selector : public __generic_for_each_selector<_It> 133*38fd1498Szrj { 134*38fd1498Szrj /** @brief Value to replace with. */ 135*38fd1498Szrj const _Tp& __new_val; 136*38fd1498Szrj 137*38fd1498Szrj /** @brief Constructor 138*38fd1498Szrj * @param __new_val Value to replace with. */ 139*38fd1498Szrj explicit __replace_selector__replace_selector140*38fd1498Szrj __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {} 141*38fd1498Szrj 142*38fd1498Szrj /** @brief Functor execution. 143*38fd1498Szrj * @param __v Current value. 144*38fd1498Szrj * @param __i iterator referencing object. */ 145*38fd1498Szrj bool operator__replace_selector146*38fd1498Szrj operator()(_Tp& __v, _It __i) 147*38fd1498Szrj { 148*38fd1498Szrj if (*__i == __v) 149*38fd1498Szrj *__i = __new_val; 150*38fd1498Szrj return true; 151*38fd1498Szrj } 152*38fd1498Szrj }; 153*38fd1498Szrj 154*38fd1498Szrj /** @brief std::replace() selector. */ 155*38fd1498Szrj template<typename _It, typename _Op, typename _Tp> 156*38fd1498Szrj struct __replace_if_selector : public __generic_for_each_selector<_It> 157*38fd1498Szrj { 158*38fd1498Szrj /** @brief Value to replace with. */ 159*38fd1498Szrj const _Tp& __new_val; 160*38fd1498Szrj 161*38fd1498Szrj /** @brief Constructor. 162*38fd1498Szrj * @param __new_val Value to replace with. */ 163*38fd1498Szrj explicit __replace_if_selector__replace_if_selector164*38fd1498Szrj __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { } 165*38fd1498Szrj 166*38fd1498Szrj /** @brief Functor execution. 167*38fd1498Szrj * @param __o Operator. 168*38fd1498Szrj * @param __i iterator referencing object. */ 169*38fd1498Szrj bool operator__replace_if_selector170*38fd1498Szrj operator()(_Op& __o, _It __i) 171*38fd1498Szrj { 172*38fd1498Szrj if (__o(*__i)) 173*38fd1498Szrj *__i = __new_val; 174*38fd1498Szrj return true; 175*38fd1498Szrj } 176*38fd1498Szrj }; 177*38fd1498Szrj 178*38fd1498Szrj /** @brief std::count() selector. */ 179*38fd1498Szrj template<typename _It, typename _Diff> 180*38fd1498Szrj struct __count_selector : public __generic_for_each_selector<_It> 181*38fd1498Szrj { 182*38fd1498Szrj /** @brief Functor execution. 183*38fd1498Szrj * @param __v Current value. 184*38fd1498Szrj * @param __i iterator referencing object. 185*38fd1498Szrj * @return 1 if count, 0 if does not count. */ 186*38fd1498Szrj template<typename _ValueType> 187*38fd1498Szrj _Diff operator__count_selector188*38fd1498Szrj operator()(_ValueType& __v, _It __i) 189*38fd1498Szrj { return (__v == *__i) ? 1 : 0; } 190*38fd1498Szrj }; 191*38fd1498Szrj 192*38fd1498Szrj /** @brief std::count_if () selector. */ 193*38fd1498Szrj template<typename _It, typename _Diff> 194*38fd1498Szrj struct __count_if_selector : public __generic_for_each_selector<_It> 195*38fd1498Szrj { 196*38fd1498Szrj /** @brief Functor execution. 197*38fd1498Szrj * @param __o Operator. 198*38fd1498Szrj * @param __i iterator referencing object. 199*38fd1498Szrj * @return 1 if count, 0 if does not count. */ 200*38fd1498Szrj template<typename _Op> 201*38fd1498Szrj _Diff operator__count_if_selector202*38fd1498Szrj operator()(_Op& __o, _It __i) 203*38fd1498Szrj { return (__o(*__i)) ? 1 : 0; } 204*38fd1498Szrj }; 205*38fd1498Szrj 206*38fd1498Szrj /** @brief std::accumulate() selector. */ 207*38fd1498Szrj template<typename _It> 208*38fd1498Szrj struct __accumulate_selector : public __generic_for_each_selector<_It> 209*38fd1498Szrj { 210*38fd1498Szrj /** @brief Functor execution. 211*38fd1498Szrj * @param __o Operator (unused). 212*38fd1498Szrj * @param __i iterator referencing object. 213*38fd1498Szrj * @return The current value. */ 214*38fd1498Szrj template<typename _Op> 215*38fd1498Szrj typename std::iterator_traits<_It>::value_type operator__accumulate_selector216*38fd1498Szrj operator()(_Op __o, _It __i) 217*38fd1498Szrj { return *__i; } 218*38fd1498Szrj }; 219*38fd1498Szrj 220*38fd1498Szrj /** @brief std::inner_product() selector. */ 221*38fd1498Szrj template<typename _It, typename _It2, typename _Tp> 222*38fd1498Szrj struct __inner_product_selector : public __generic_for_each_selector<_It> 223*38fd1498Szrj { 224*38fd1498Szrj /** @brief Begin iterator of first sequence. */ 225*38fd1498Szrj _It __begin1_iterator; 226*38fd1498Szrj 227*38fd1498Szrj /** @brief Begin iterator of second sequence. */ 228*38fd1498Szrj _It2 __begin2_iterator; 229*38fd1498Szrj 230*38fd1498Szrj /** @brief Constructor. 231*38fd1498Szrj * @param __b1 Begin iterator of first sequence. 232*38fd1498Szrj * @param __b2 Begin iterator of second sequence. */ 233*38fd1498Szrj explicit __inner_product_selector__inner_product_selector234*38fd1498Szrj __inner_product_selector(_It __b1, _It2 __b2) 235*38fd1498Szrj : __begin1_iterator(__b1), __begin2_iterator(__b2) { } 236*38fd1498Szrj 237*38fd1498Szrj /** @brief Functor execution. 238*38fd1498Szrj * @param __mult Multiplication functor. 239*38fd1498Szrj * @param __current iterator referencing object. 240*38fd1498Szrj * @return Inner product elemental __result. */ 241*38fd1498Szrj template<typename _Op> 242*38fd1498Szrj _Tp operator__inner_product_selector243*38fd1498Szrj operator()(_Op __mult, _It __current) 244*38fd1498Szrj { 245*38fd1498Szrj typename std::iterator_traits<_It>::difference_type __position 246*38fd1498Szrj = __current - __begin1_iterator; 247*38fd1498Szrj return __mult(*__current, *(__begin2_iterator + __position)); 248*38fd1498Szrj } 249*38fd1498Szrj }; 250*38fd1498Szrj 251*38fd1498Szrj /** @brief Selector that just returns the passed iterator. */ 252*38fd1498Szrj template<typename _It> 253*38fd1498Szrj struct __identity_selector : public __generic_for_each_selector<_It> 254*38fd1498Szrj { 255*38fd1498Szrj /** @brief Functor execution. 256*38fd1498Szrj * @param __o Operator (unused). 257*38fd1498Szrj * @param __i iterator referencing object. 258*38fd1498Szrj * @return Passed iterator. */ 259*38fd1498Szrj template<typename _Op> 260*38fd1498Szrj _It operator__identity_selector261*38fd1498Szrj operator()(_Op __o, _It __i) 262*38fd1498Szrj { return __i; } 263*38fd1498Szrj }; 264*38fd1498Szrj 265*38fd1498Szrj /** @brief Selector that returns the difference between two adjacent 266*38fd1498Szrj * __elements. 267*38fd1498Szrj */ 268*38fd1498Szrj template<typename _It> 269*38fd1498Szrj struct __adjacent_difference_selector 270*38fd1498Szrj : public __generic_for_each_selector<_It> 271*38fd1498Szrj { 272*38fd1498Szrj template<typename _Op> 273*38fd1498Szrj bool operator__adjacent_difference_selector274*38fd1498Szrj operator()(_Op& __o, _It __i) 275*38fd1498Szrj { 276*38fd1498Szrj typename _It::first_type __go_back_one = __i.first; 277*38fd1498Szrj --__go_back_one; 278*38fd1498Szrj *__i.second = __o(*__i.first, *__go_back_one); 279*38fd1498Szrj return true; 280*38fd1498Szrj } 281*38fd1498Szrj }; 282*38fd1498Szrj 283*38fd1498Szrj /** @brief Functor doing nothing 284*38fd1498Szrj * 285*38fd1498Szrj * For some __reduction tasks (this is not a function object, but is 286*38fd1498Szrj * passed as __selector __dummy parameter. 287*38fd1498Szrj */ 288*38fd1498Szrj struct _Nothing 289*38fd1498Szrj { 290*38fd1498Szrj /** @brief Functor execution. 291*38fd1498Szrj * @param __i iterator referencing object. */ 292*38fd1498Szrj template<typename _It> 293*38fd1498Szrj void operator_Nothing294*38fd1498Szrj operator()(_It __i) { } 295*38fd1498Szrj }; 296*38fd1498Szrj 297*38fd1498Szrj /** @brief Reduction function doing nothing. */ 298*38fd1498Szrj struct _DummyReduct 299*38fd1498Szrj { 300*38fd1498Szrj bool operator_DummyReduct301*38fd1498Szrj operator()(bool, bool) const 302*38fd1498Szrj { return true; } 303*38fd1498Szrj }; 304*38fd1498Szrj 305*38fd1498Szrj /** @brief Reduction for finding the maximum element, using a comparator. */ 306*38fd1498Szrj template<typename _Compare, typename _It> 307*38fd1498Szrj struct __min_element_reduct 308*38fd1498Szrj { 309*38fd1498Szrj _Compare& __comp; 310*38fd1498Szrj 311*38fd1498Szrj explicit __min_element_reduct__min_element_reduct312*38fd1498Szrj __min_element_reduct(_Compare &__c) : __comp(__c) { } 313*38fd1498Szrj 314*38fd1498Szrj _It operator__min_element_reduct315*38fd1498Szrj operator()(_It __x, _It __y) 316*38fd1498Szrj { return (__comp(*__x, *__y)) ? __x : __y; } 317*38fd1498Szrj }; 318*38fd1498Szrj 319*38fd1498Szrj /** @brief Reduction for finding the maximum element, using a comparator. */ 320*38fd1498Szrj template<typename _Compare, typename _It> 321*38fd1498Szrj struct __max_element_reduct 322*38fd1498Szrj { 323*38fd1498Szrj _Compare& __comp; 324*38fd1498Szrj 325*38fd1498Szrj explicit __max_element_reduct__max_element_reduct326*38fd1498Szrj __max_element_reduct(_Compare& __c) : __comp(__c) { } 327*38fd1498Szrj 328*38fd1498Szrj _It operator__max_element_reduct329*38fd1498Szrj operator()(_It __x, _It __y) 330*38fd1498Szrj { return (__comp(*__x, *__y)) ? __y : __x; } 331*38fd1498Szrj }; 332*38fd1498Szrj 333*38fd1498Szrj /** @brief General reduction, using a binary operator. */ 334*38fd1498Szrj template<typename _BinOp> 335*38fd1498Szrj struct __accumulate_binop_reduct 336*38fd1498Szrj { 337*38fd1498Szrj _BinOp& __binop; 338*38fd1498Szrj 339*38fd1498Szrj explicit __accumulate_binop_reduct__accumulate_binop_reduct340*38fd1498Szrj __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { } 341*38fd1498Szrj 342*38fd1498Szrj template<typename _Result, typename _Addend> 343*38fd1498Szrj _Result operator__accumulate_binop_reduct344*38fd1498Szrj operator()(const _Result& __x, const _Addend& __y) 345*38fd1498Szrj { return __binop(__x, __y); } 346*38fd1498Szrj }; 347*38fd1498Szrj } 348*38fd1498Szrj 349*38fd1498Szrj #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */ 350