1*e4b17023SJohn Marino// -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 4*e4b17023SJohn Marino// 5*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the terms 7*e4b17023SJohn Marino// of the GNU General Public License as published by the Free Software 8*e4b17023SJohn Marino// Foundation; either version 3, or (at your option) any later 9*e4b17023SJohn Marino// version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful, but 12*e4b17023SJohn Marino// WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*e4b17023SJohn Marino// General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino/** 26*e4b17023SJohn Marino * @file parallel/numeric 27*e4b17023SJohn Marino* 28*e4b17023SJohn Marino * @brief Parallel STL function calls corresponding to stl_numeric.h. 29*e4b17023SJohn Marino * The functions defined here mainly do case switches and 30*e4b17023SJohn Marino * call the actual parallelized versions in other files. 31*e4b17023SJohn Marino * Inlining policy: Functions that basically only contain one function call, 32*e4b17023SJohn Marino * are declared inline. 33*e4b17023SJohn Marino * This file is a GNU parallel extension to the Standard C++ Library. 34*e4b17023SJohn Marino */ 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino// Written by Johannes Singler and Felix Putze. 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino#ifndef _GLIBCXX_PARALLEL_NUMERIC_H 39*e4b17023SJohn Marino#define _GLIBCXX_PARALLEL_NUMERIC_H 1 40*e4b17023SJohn Marino 41*e4b17023SJohn Marino#include <numeric> 42*e4b17023SJohn Marino#include <bits/stl_function.h> 43*e4b17023SJohn Marino#include <parallel/numericfwd.h> 44*e4b17023SJohn Marino#include <parallel/iterator.h> 45*e4b17023SJohn Marino#include <parallel/for_each.h> 46*e4b17023SJohn Marino#include <parallel/for_each_selectors.h> 47*e4b17023SJohn Marino#include <parallel/partial_sum.h> 48*e4b17023SJohn Marino 49*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 50*e4b17023SJohn Marino{ 51*e4b17023SJohn Marinonamespace __parallel 52*e4b17023SJohn Marino{ 53*e4b17023SJohn Marino // Sequential fallback. 54*e4b17023SJohn Marino template<typename _IIter, typename _Tp> 55*e4b17023SJohn Marino inline _Tp 56*e4b17023SJohn Marino accumulate(_IIter __begin, _IIter __end, _Tp __init, 57*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 58*e4b17023SJohn Marino { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init); } 59*e4b17023SJohn Marino 60*e4b17023SJohn Marino template<typename _IIter, typename _Tp, typename _BinaryOperation> 61*e4b17023SJohn Marino inline _Tp 62*e4b17023SJohn Marino accumulate(_IIter __begin, _IIter __end, _Tp __init, 63*e4b17023SJohn Marino _BinaryOperation __binary_op, __gnu_parallel::sequential_tag) 64*e4b17023SJohn Marino { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init, __binary_op); } 65*e4b17023SJohn Marino 66*e4b17023SJohn Marino // Sequential fallback for input iterator case. 67*e4b17023SJohn Marino template<typename _IIter, typename _Tp, typename _IteratorTag> 68*e4b17023SJohn Marino inline _Tp 69*e4b17023SJohn Marino __accumulate_switch(_IIter __begin, _IIter __end, 70*e4b17023SJohn Marino _Tp __init, _IteratorTag) 71*e4b17023SJohn Marino { return accumulate(__begin, __end, __init, 72*e4b17023SJohn Marino __gnu_parallel::sequential_tag()); } 73*e4b17023SJohn Marino 74*e4b17023SJohn Marino template<typename _IIter, typename _Tp, typename _BinaryOperation, 75*e4b17023SJohn Marino typename _IteratorTag> 76*e4b17023SJohn Marino inline _Tp 77*e4b17023SJohn Marino __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init, 78*e4b17023SJohn Marino _BinaryOperation __binary_op, _IteratorTag) 79*e4b17023SJohn Marino { return accumulate(__begin, __end, __init, __binary_op, 80*e4b17023SJohn Marino __gnu_parallel::sequential_tag()); } 81*e4b17023SJohn Marino 82*e4b17023SJohn Marino // Parallel algorithm for random access iterators. 83*e4b17023SJohn Marino template<typename __RAIter, typename _Tp, typename _BinaryOperation> 84*e4b17023SJohn Marino _Tp 85*e4b17023SJohn Marino __accumulate_switch(__RAIter __begin, __RAIter __end, 86*e4b17023SJohn Marino _Tp __init, _BinaryOperation __binary_op, 87*e4b17023SJohn Marino random_access_iterator_tag, 88*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag 89*e4b17023SJohn Marino = __gnu_parallel::parallel_unbalanced) 90*e4b17023SJohn Marino { 91*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION( 92*e4b17023SJohn Marino static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) 93*e4b17023SJohn Marino >= __gnu_parallel::_Settings::get().accumulate_minimal_n 94*e4b17023SJohn Marino && __gnu_parallel::__is_parallel(__parallelism_tag))) 95*e4b17023SJohn Marino { 96*e4b17023SJohn Marino _Tp __res = __init; 97*e4b17023SJohn Marino __gnu_parallel::__accumulate_selector<__RAIter> 98*e4b17023SJohn Marino __my_selector; 99*e4b17023SJohn Marino __gnu_parallel:: 100*e4b17023SJohn Marino __for_each_template_random_access_ed(__begin, __end, 101*e4b17023SJohn Marino __gnu_parallel::_Nothing(), 102*e4b17023SJohn Marino __my_selector, 103*e4b17023SJohn Marino __gnu_parallel:: 104*e4b17023SJohn Marino __accumulate_binop_reduct 105*e4b17023SJohn Marino <_BinaryOperation>(__binary_op), 106*e4b17023SJohn Marino __res, __res, -1); 107*e4b17023SJohn Marino return __res; 108*e4b17023SJohn Marino } 109*e4b17023SJohn Marino else 110*e4b17023SJohn Marino return accumulate(__begin, __end, __init, __binary_op, 111*e4b17023SJohn Marino __gnu_parallel::sequential_tag()); 112*e4b17023SJohn Marino } 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino // Public interface. 115*e4b17023SJohn Marino template<typename _IIter, typename _Tp> 116*e4b17023SJohn Marino inline _Tp 117*e4b17023SJohn Marino accumulate(_IIter __begin, _IIter __end, _Tp __init, 118*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag) 119*e4b17023SJohn Marino { 120*e4b17023SJohn Marino typedef std::iterator_traits<_IIter> _IteratorTraits; 121*e4b17023SJohn Marino typedef typename _IteratorTraits::value_type _ValueType; 122*e4b17023SJohn Marino typedef typename _IteratorTraits::iterator_category _IteratorCategory; 123*e4b17023SJohn Marino 124*e4b17023SJohn Marino return __accumulate_switch(__begin, __end, __init, 125*e4b17023SJohn Marino __gnu_parallel::_Plus<_Tp, _ValueType>(), 126*e4b17023SJohn Marino _IteratorCategory(), __parallelism_tag); 127*e4b17023SJohn Marino } 128*e4b17023SJohn Marino 129*e4b17023SJohn Marino template<typename _IIter, typename _Tp> 130*e4b17023SJohn Marino inline _Tp 131*e4b17023SJohn Marino accumulate(_IIter __begin, _IIter __end, _Tp __init) 132*e4b17023SJohn Marino { 133*e4b17023SJohn Marino typedef std::iterator_traits<_IIter> _IteratorTraits; 134*e4b17023SJohn Marino typedef typename _IteratorTraits::value_type _ValueType; 135*e4b17023SJohn Marino typedef typename _IteratorTraits::iterator_category _IteratorCategory; 136*e4b17023SJohn Marino 137*e4b17023SJohn Marino return __accumulate_switch(__begin, __end, __init, 138*e4b17023SJohn Marino __gnu_parallel::_Plus<_Tp, _ValueType>(), 139*e4b17023SJohn Marino _IteratorCategory()); 140*e4b17023SJohn Marino } 141*e4b17023SJohn Marino 142*e4b17023SJohn Marino template<typename _IIter, typename _Tp, typename _BinaryOperation> 143*e4b17023SJohn Marino inline _Tp 144*e4b17023SJohn Marino accumulate(_IIter __begin, _IIter __end, _Tp __init, 145*e4b17023SJohn Marino _BinaryOperation __binary_op, 146*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag) 147*e4b17023SJohn Marino { 148*e4b17023SJohn Marino typedef iterator_traits<_IIter> _IteratorTraits; 149*e4b17023SJohn Marino typedef typename _IteratorTraits::iterator_category _IteratorCategory; 150*e4b17023SJohn Marino return __accumulate_switch(__begin, __end, __init, __binary_op, 151*e4b17023SJohn Marino _IteratorCategory(), __parallelism_tag); 152*e4b17023SJohn Marino } 153*e4b17023SJohn Marino 154*e4b17023SJohn Marino template<typename _IIter, typename _Tp, typename _BinaryOperation> 155*e4b17023SJohn Marino inline _Tp 156*e4b17023SJohn Marino accumulate(_IIter __begin, _IIter __end, _Tp __init, 157*e4b17023SJohn Marino _BinaryOperation __binary_op) 158*e4b17023SJohn Marino { 159*e4b17023SJohn Marino typedef iterator_traits<_IIter> _IteratorTraits; 160*e4b17023SJohn Marino typedef typename _IteratorTraits::iterator_category _IteratorCategory; 161*e4b17023SJohn Marino return __accumulate_switch(__begin, __end, __init, __binary_op, 162*e4b17023SJohn Marino _IteratorCategory()); 163*e4b17023SJohn Marino } 164*e4b17023SJohn Marino 165*e4b17023SJohn Marino 166*e4b17023SJohn Marino // Sequential fallback. 167*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Tp> 168*e4b17023SJohn Marino inline _Tp 169*e4b17023SJohn Marino inner_product(_IIter1 __first1, _IIter1 __last1, 170*e4b17023SJohn Marino _IIter2 __first2, _Tp __init, 171*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 172*e4b17023SJohn Marino { return _GLIBCXX_STD_A::inner_product( 173*e4b17023SJohn Marino __first1, __last1, __first2, __init); } 174*e4b17023SJohn Marino 175*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Tp, 176*e4b17023SJohn Marino typename _BinaryFunction1, typename _BinaryFunction2> 177*e4b17023SJohn Marino inline _Tp 178*e4b17023SJohn Marino inner_product(_IIter1 __first1, _IIter1 __last1, 179*e4b17023SJohn Marino _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, 180*e4b17023SJohn Marino _BinaryFunction2 __binary_op2, 181*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 182*e4b17023SJohn Marino { return _GLIBCXX_STD_A::inner_product(__first1, __last1, __first2, __init, 183*e4b17023SJohn Marino __binary_op1, __binary_op2); } 184*e4b17023SJohn Marino 185*e4b17023SJohn Marino // Parallel algorithm for random access iterators. 186*e4b17023SJohn Marino template<typename _RAIter1, typename _RAIter2, 187*e4b17023SJohn Marino typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2> 188*e4b17023SJohn Marino _Tp 189*e4b17023SJohn Marino __inner_product_switch(_RAIter1 __first1, 190*e4b17023SJohn Marino _RAIter1 __last1, 191*e4b17023SJohn Marino _RAIter2 __first2, _Tp __init, 192*e4b17023SJohn Marino _BinaryFunction1 __binary_op1, 193*e4b17023SJohn Marino _BinaryFunction2 __binary_op2, 194*e4b17023SJohn Marino random_access_iterator_tag, 195*e4b17023SJohn Marino random_access_iterator_tag, 196*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag 197*e4b17023SJohn Marino = __gnu_parallel::parallel_unbalanced) 198*e4b17023SJohn Marino { 199*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION((__last1 - __first1) 200*e4b17023SJohn Marino >= __gnu_parallel::_Settings::get(). 201*e4b17023SJohn Marino accumulate_minimal_n 202*e4b17023SJohn Marino && __gnu_parallel:: 203*e4b17023SJohn Marino __is_parallel(__parallelism_tag))) 204*e4b17023SJohn Marino { 205*e4b17023SJohn Marino _Tp __res = __init; 206*e4b17023SJohn Marino __gnu_parallel:: 207*e4b17023SJohn Marino __inner_product_selector<_RAIter1, 208*e4b17023SJohn Marino _RAIter2, _Tp> __my_selector(__first1, __first2); 209*e4b17023SJohn Marino __gnu_parallel:: 210*e4b17023SJohn Marino __for_each_template_random_access_ed( 211*e4b17023SJohn Marino __first1, __last1, __binary_op2, __my_selector, __binary_op1, 212*e4b17023SJohn Marino __res, __res, -1); 213*e4b17023SJohn Marino return __res; 214*e4b17023SJohn Marino } 215*e4b17023SJohn Marino else 216*e4b17023SJohn Marino return inner_product(__first1, __last1, __first2, __init, 217*e4b17023SJohn Marino __gnu_parallel::sequential_tag()); 218*e4b17023SJohn Marino } 219*e4b17023SJohn Marino 220*e4b17023SJohn Marino // No parallelism for input iterators. 221*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Tp, 222*e4b17023SJohn Marino typename _BinaryFunction1, typename _BinaryFunction2, 223*e4b17023SJohn Marino typename _IteratorTag1, typename _IteratorTag2> 224*e4b17023SJohn Marino inline _Tp 225*e4b17023SJohn Marino __inner_product_switch(_IIter1 __first1, _IIter1 __last1, 226*e4b17023SJohn Marino _IIter2 __first2, _Tp __init, 227*e4b17023SJohn Marino _BinaryFunction1 __binary_op1, 228*e4b17023SJohn Marino _BinaryFunction2 __binary_op2, 229*e4b17023SJohn Marino _IteratorTag1, _IteratorTag2) 230*e4b17023SJohn Marino { return inner_product(__first1, __last1, __first2, __init, __binary_op1, 231*e4b17023SJohn Marino __binary_op2, __gnu_parallel::sequential_tag()); } 232*e4b17023SJohn Marino 233*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Tp, 234*e4b17023SJohn Marino typename _BinaryFunction1, typename _BinaryFunction2> 235*e4b17023SJohn Marino inline _Tp 236*e4b17023SJohn Marino inner_product(_IIter1 __first1, _IIter1 __last1, 237*e4b17023SJohn Marino _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, 238*e4b17023SJohn Marino _BinaryFunction2 __binary_op2, 239*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag) 240*e4b17023SJohn Marino { 241*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1; 242*e4b17023SJohn Marino typedef typename _TraitsType1::iterator_category _IteratorCategory1; 243*e4b17023SJohn Marino 244*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2; 245*e4b17023SJohn Marino typedef typename _TraitsType2::iterator_category _IteratorCategory2; 246*e4b17023SJohn Marino 247*e4b17023SJohn Marino return __inner_product_switch(__first1, __last1, __first2, __init, 248*e4b17023SJohn Marino __binary_op1, __binary_op2, 249*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2(), 250*e4b17023SJohn Marino __parallelism_tag); 251*e4b17023SJohn Marino } 252*e4b17023SJohn Marino 253*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Tp, 254*e4b17023SJohn Marino typename _BinaryFunction1, typename _BinaryFunction2> 255*e4b17023SJohn Marino inline _Tp 256*e4b17023SJohn Marino inner_product(_IIter1 __first1, _IIter1 __last1, 257*e4b17023SJohn Marino _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, 258*e4b17023SJohn Marino _BinaryFunction2 __binary_op2) 259*e4b17023SJohn Marino { 260*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1; 261*e4b17023SJohn Marino typedef typename _TraitsType1::iterator_category _IteratorCategory1; 262*e4b17023SJohn Marino 263*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2; 264*e4b17023SJohn Marino typedef typename _TraitsType2::iterator_category _IteratorCategory2; 265*e4b17023SJohn Marino 266*e4b17023SJohn Marino return __inner_product_switch(__first1, __last1, __first2, __init, 267*e4b17023SJohn Marino __binary_op1, __binary_op2, 268*e4b17023SJohn Marino _IteratorCategory1(), 269*e4b17023SJohn Marino _IteratorCategory2()); 270*e4b17023SJohn Marino } 271*e4b17023SJohn Marino 272*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Tp> 273*e4b17023SJohn Marino inline _Tp 274*e4b17023SJohn Marino inner_product(_IIter1 __first1, _IIter1 __last1, 275*e4b17023SJohn Marino _IIter2 __first2, _Tp __init, 276*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag) 277*e4b17023SJohn Marino { 278*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1; 279*e4b17023SJohn Marino typedef typename _TraitsType1::value_type _ValueType1; 280*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2; 281*e4b17023SJohn Marino typedef typename _TraitsType2::value_type _ValueType2; 282*e4b17023SJohn Marino 283*e4b17023SJohn Marino typedef typename 284*e4b17023SJohn Marino __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type 285*e4b17023SJohn Marino _MultipliesResultType; 286*e4b17023SJohn Marino return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, 287*e4b17023SJohn Marino __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), 288*e4b17023SJohn Marino __gnu_parallel:: 289*e4b17023SJohn Marino _Multiplies<_ValueType1, _ValueType2>(), 290*e4b17023SJohn Marino __parallelism_tag); 291*e4b17023SJohn Marino } 292*e4b17023SJohn Marino 293*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Tp> 294*e4b17023SJohn Marino inline _Tp 295*e4b17023SJohn Marino inner_product(_IIter1 __first1, _IIter1 __last1, 296*e4b17023SJohn Marino _IIter2 __first2, _Tp __init) 297*e4b17023SJohn Marino { 298*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1; 299*e4b17023SJohn Marino typedef typename _TraitsType1::value_type _ValueType1; 300*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2; 301*e4b17023SJohn Marino typedef typename _TraitsType2::value_type _ValueType2; 302*e4b17023SJohn Marino 303*e4b17023SJohn Marino typedef typename 304*e4b17023SJohn Marino __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type 305*e4b17023SJohn Marino _MultipliesResultType; 306*e4b17023SJohn Marino return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, 307*e4b17023SJohn Marino __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), 308*e4b17023SJohn Marino __gnu_parallel:: 309*e4b17023SJohn Marino _Multiplies<_ValueType1, _ValueType2>()); 310*e4b17023SJohn Marino } 311*e4b17023SJohn Marino 312*e4b17023SJohn Marino // Sequential fallback. 313*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator> 314*e4b17023SJohn Marino inline _OutputIterator 315*e4b17023SJohn Marino partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, 316*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 317*e4b17023SJohn Marino { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result); } 318*e4b17023SJohn Marino 319*e4b17023SJohn Marino // Sequential fallback. 320*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 321*e4b17023SJohn Marino typename _BinaryOperation> 322*e4b17023SJohn Marino inline _OutputIterator 323*e4b17023SJohn Marino partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, 324*e4b17023SJohn Marino _BinaryOperation __bin_op, __gnu_parallel::sequential_tag) 325*e4b17023SJohn Marino { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } 326*e4b17023SJohn Marino 327*e4b17023SJohn Marino // Sequential fallback for input iterator case. 328*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 329*e4b17023SJohn Marino typename _BinaryOperation, typename _IteratorTag1, 330*e4b17023SJohn Marino typename _IteratorTag2> 331*e4b17023SJohn Marino inline _OutputIterator 332*e4b17023SJohn Marino __partial_sum_switch(_IIter __begin, _IIter __end, 333*e4b17023SJohn Marino _OutputIterator __result, _BinaryOperation __bin_op, 334*e4b17023SJohn Marino _IteratorTag1, _IteratorTag2) 335*e4b17023SJohn Marino { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } 336*e4b17023SJohn Marino 337*e4b17023SJohn Marino // Parallel algorithm for random access iterators. 338*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 339*e4b17023SJohn Marino typename _BinaryOperation> 340*e4b17023SJohn Marino _OutputIterator 341*e4b17023SJohn Marino __partial_sum_switch(_IIter __begin, _IIter __end, 342*e4b17023SJohn Marino _OutputIterator __result, _BinaryOperation __bin_op, 343*e4b17023SJohn Marino random_access_iterator_tag, 344*e4b17023SJohn Marino random_access_iterator_tag) 345*e4b17023SJohn Marino { 346*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION( 347*e4b17023SJohn Marino static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) 348*e4b17023SJohn Marino >= __gnu_parallel::_Settings::get().partial_sum_minimal_n)) 349*e4b17023SJohn Marino return __gnu_parallel::__parallel_partial_sum(__begin, __end, 350*e4b17023SJohn Marino __result, __bin_op); 351*e4b17023SJohn Marino else 352*e4b17023SJohn Marino return partial_sum(__begin, __end, __result, __bin_op, 353*e4b17023SJohn Marino __gnu_parallel::sequential_tag()); 354*e4b17023SJohn Marino } 355*e4b17023SJohn Marino 356*e4b17023SJohn Marino // Public interface. 357*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator> 358*e4b17023SJohn Marino inline _OutputIterator 359*e4b17023SJohn Marino partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result) 360*e4b17023SJohn Marino { 361*e4b17023SJohn Marino typedef typename iterator_traits<_IIter>::value_type _ValueType; 362*e4b17023SJohn Marino return __gnu_parallel::partial_sum(__begin, __end, 363*e4b17023SJohn Marino __result, std::plus<_ValueType>()); 364*e4b17023SJohn Marino } 365*e4b17023SJohn Marino 366*e4b17023SJohn Marino // Public interface 367*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 368*e4b17023SJohn Marino typename _BinaryOperation> 369*e4b17023SJohn Marino inline _OutputIterator 370*e4b17023SJohn Marino partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, 371*e4b17023SJohn Marino _BinaryOperation __binary_op) 372*e4b17023SJohn Marino { 373*e4b17023SJohn Marino typedef iterator_traits<_IIter> _ITraitsType; 374*e4b17023SJohn Marino typedef typename _ITraitsType::iterator_category _IIteratorCategory; 375*e4b17023SJohn Marino 376*e4b17023SJohn Marino typedef iterator_traits<_OutputIterator> _OTraitsType; 377*e4b17023SJohn Marino typedef typename _OTraitsType::iterator_category _OIterCategory; 378*e4b17023SJohn Marino 379*e4b17023SJohn Marino return __partial_sum_switch(__begin, __end, __result, __binary_op, 380*e4b17023SJohn Marino _IIteratorCategory(), _OIterCategory()); 381*e4b17023SJohn Marino } 382*e4b17023SJohn Marino 383*e4b17023SJohn Marino // Sequential fallback. 384*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator> 385*e4b17023SJohn Marino inline _OutputIterator 386*e4b17023SJohn Marino adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, 387*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 388*e4b17023SJohn Marino { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, __result); } 389*e4b17023SJohn Marino 390*e4b17023SJohn Marino // Sequential fallback. 391*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 392*e4b17023SJohn Marino typename _BinaryOperation> 393*e4b17023SJohn Marino inline _OutputIterator 394*e4b17023SJohn Marino adjacent_difference(_IIter __begin, _IIter __end, 395*e4b17023SJohn Marino _OutputIterator __result, _BinaryOperation __bin_op, 396*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 397*e4b17023SJohn Marino { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, 398*e4b17023SJohn Marino __result, __bin_op); } 399*e4b17023SJohn Marino 400*e4b17023SJohn Marino // Sequential fallback for input iterator case. 401*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 402*e4b17023SJohn Marino typename _BinaryOperation, typename _IteratorTag1, 403*e4b17023SJohn Marino typename _IteratorTag2> 404*e4b17023SJohn Marino inline _OutputIterator 405*e4b17023SJohn Marino __adjacent_difference_switch(_IIter __begin, _IIter __end, 406*e4b17023SJohn Marino _OutputIterator __result, 407*e4b17023SJohn Marino _BinaryOperation __bin_op, _IteratorTag1, 408*e4b17023SJohn Marino _IteratorTag2) 409*e4b17023SJohn Marino { return adjacent_difference(__begin, __end, __result, __bin_op, 410*e4b17023SJohn Marino __gnu_parallel::sequential_tag()); } 411*e4b17023SJohn Marino 412*e4b17023SJohn Marino // Parallel algorithm for random access iterators. 413*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 414*e4b17023SJohn Marino typename _BinaryOperation> 415*e4b17023SJohn Marino _OutputIterator 416*e4b17023SJohn Marino __adjacent_difference_switch(_IIter __begin, _IIter __end, 417*e4b17023SJohn Marino _OutputIterator __result, 418*e4b17023SJohn Marino _BinaryOperation __bin_op, 419*e4b17023SJohn Marino random_access_iterator_tag, 420*e4b17023SJohn Marino random_access_iterator_tag, 421*e4b17023SJohn Marino __gnu_parallel::_Parallelism 422*e4b17023SJohn Marino __parallelism_tag 423*e4b17023SJohn Marino = __gnu_parallel::parallel_balanced) 424*e4b17023SJohn Marino { 425*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION( 426*e4b17023SJohn Marino static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) 427*e4b17023SJohn Marino >= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n 428*e4b17023SJohn Marino && __gnu_parallel::__is_parallel(__parallelism_tag))) 429*e4b17023SJohn Marino { 430*e4b17023SJohn Marino bool __dummy = true; 431*e4b17023SJohn Marino typedef __gnu_parallel::_IteratorPair<_IIter, _OutputIterator, 432*e4b17023SJohn Marino random_access_iterator_tag> _ItTrip; 433*e4b17023SJohn Marino *__result = *__begin; 434*e4b17023SJohn Marino _ItTrip __begin_pair(__begin + 1, __result + 1), 435*e4b17023SJohn Marino __end_pair(__end, __result + (__end - __begin)); 436*e4b17023SJohn Marino __gnu_parallel::__adjacent_difference_selector<_ItTrip> 437*e4b17023SJohn Marino __functionality; 438*e4b17023SJohn Marino __gnu_parallel:: 439*e4b17023SJohn Marino __for_each_template_random_access_ed( 440*e4b17023SJohn Marino __begin_pair, __end_pair, __bin_op, __functionality, 441*e4b17023SJohn Marino __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1); 442*e4b17023SJohn Marino return __functionality._M_finish_iterator; 443*e4b17023SJohn Marino } 444*e4b17023SJohn Marino else 445*e4b17023SJohn Marino return adjacent_difference(__begin, __end, __result, __bin_op, 446*e4b17023SJohn Marino __gnu_parallel::sequential_tag()); 447*e4b17023SJohn Marino } 448*e4b17023SJohn Marino 449*e4b17023SJohn Marino // Public interface. 450*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator> 451*e4b17023SJohn Marino inline _OutputIterator 452*e4b17023SJohn Marino adjacent_difference(_IIter __begin, _IIter __end, 453*e4b17023SJohn Marino _OutputIterator __result, 454*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag) 455*e4b17023SJohn Marino { 456*e4b17023SJohn Marino typedef iterator_traits<_IIter> _TraitsType; 457*e4b17023SJohn Marino typedef typename _TraitsType::value_type _ValueType; 458*e4b17023SJohn Marino return adjacent_difference(__begin, __end, __result, 459*e4b17023SJohn Marino std::minus<_ValueType>(), 460*e4b17023SJohn Marino __parallelism_tag); 461*e4b17023SJohn Marino } 462*e4b17023SJohn Marino 463*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator> 464*e4b17023SJohn Marino inline _OutputIterator 465*e4b17023SJohn Marino adjacent_difference(_IIter __begin, _IIter __end, 466*e4b17023SJohn Marino _OutputIterator __result) 467*e4b17023SJohn Marino { 468*e4b17023SJohn Marino typedef iterator_traits<_IIter> _TraitsType; 469*e4b17023SJohn Marino typedef typename _TraitsType::value_type _ValueType; 470*e4b17023SJohn Marino return adjacent_difference(__begin, __end, __result, 471*e4b17023SJohn Marino std::minus<_ValueType>()); 472*e4b17023SJohn Marino } 473*e4b17023SJohn Marino 474*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 475*e4b17023SJohn Marino typename _BinaryOperation> 476*e4b17023SJohn Marino inline _OutputIterator 477*e4b17023SJohn Marino adjacent_difference(_IIter __begin, _IIter __end, 478*e4b17023SJohn Marino _OutputIterator __result, _BinaryOperation __binary_op, 479*e4b17023SJohn Marino __gnu_parallel::_Parallelism __parallelism_tag) 480*e4b17023SJohn Marino { 481*e4b17023SJohn Marino typedef iterator_traits<_IIter> _ITraitsType; 482*e4b17023SJohn Marino typedef typename _ITraitsType::iterator_category _IIteratorCategory; 483*e4b17023SJohn Marino 484*e4b17023SJohn Marino typedef iterator_traits<_OutputIterator> _OTraitsType; 485*e4b17023SJohn Marino typedef typename _OTraitsType::iterator_category _OIterCategory; 486*e4b17023SJohn Marino 487*e4b17023SJohn Marino return __adjacent_difference_switch(__begin, __end, __result, 488*e4b17023SJohn Marino __binary_op, 489*e4b17023SJohn Marino _IIteratorCategory(), 490*e4b17023SJohn Marino _OIterCategory(), 491*e4b17023SJohn Marino __parallelism_tag); 492*e4b17023SJohn Marino } 493*e4b17023SJohn Marino 494*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator, 495*e4b17023SJohn Marino typename _BinaryOperation> 496*e4b17023SJohn Marino inline _OutputIterator 497*e4b17023SJohn Marino adjacent_difference(_IIter __begin, _IIter __end, 498*e4b17023SJohn Marino _OutputIterator __result, _BinaryOperation __binary_op) 499*e4b17023SJohn Marino { 500*e4b17023SJohn Marino typedef iterator_traits<_IIter> _ITraitsType; 501*e4b17023SJohn Marino typedef typename _ITraitsType::iterator_category _IIteratorCategory; 502*e4b17023SJohn Marino 503*e4b17023SJohn Marino typedef iterator_traits<_OutputIterator> _OTraitsType; 504*e4b17023SJohn Marino typedef typename _OTraitsType::iterator_category _OIterCategory; 505*e4b17023SJohn Marino 506*e4b17023SJohn Marino return __adjacent_difference_switch(__begin, __end, __result, 507*e4b17023SJohn Marino __binary_op, 508*e4b17023SJohn Marino _IIteratorCategory(), 509*e4b17023SJohn Marino _OIterCategory()); 510*e4b17023SJohn Marino } 511*e4b17023SJohn Marino} // end namespace 512*e4b17023SJohn Marino} // end namespace 513*e4b17023SJohn Marino 514*e4b17023SJohn Marino#endif /* _GLIBCXX_NUMERIC_H */ 515