1*e4b17023SJohn Marino // -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 /** @file parallel/algobase.h 26*e4b17023SJohn Marino * @brief Parallel STL function calls corresponding to the 27*e4b17023SJohn Marino * stl_algobase.h header. The functions defined here mainly do case 28*e4b17023SJohn Marino * switches and call the actual parallelized versions in other files. 29*e4b17023SJohn Marino * Inlining policy: Functions that basically only contain one 30*e4b17023SJohn Marino * function call, are declared inline. 31*e4b17023SJohn Marino * This file is a GNU parallel extension to the Standard C++ Library. 32*e4b17023SJohn Marino */ 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino // Written by Johannes Singler and Felix Putze. 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H 37*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_ALGOBASE_H 1 38*e4b17023SJohn Marino 39*e4b17023SJohn Marino #include <bits/stl_algobase.h> 40*e4b17023SJohn Marino #include <parallel/base.h> 41*e4b17023SJohn Marino #include <parallel/algorithmfwd.h> 42*e4b17023SJohn Marino #include <parallel/find.h> 43*e4b17023SJohn Marino #include <parallel/find_selectors.h> 44*e4b17023SJohn Marino 45*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 46*e4b17023SJohn Marino { 47*e4b17023SJohn Marino namespace __parallel 48*e4b17023SJohn Marino { 49*e4b17023SJohn Marino // NB: equal and lexicographical_compare require mismatch. 50*e4b17023SJohn Marino 51*e4b17023SJohn Marino // Sequential fallback 52*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2> 53*e4b17023SJohn Marino inline pair<_IIter1, _IIter2> 54*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 55*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 56*e4b17023SJohn Marino { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); } 57*e4b17023SJohn Marino 58*e4b17023SJohn Marino // Sequential fallback 59*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate> 60*e4b17023SJohn Marino inline pair<_IIter1, _IIter2> 61*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 62*e4b17023SJohn Marino _Predicate __pred, __gnu_parallel::sequential_tag) 63*e4b17023SJohn Marino { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } 64*e4b17023SJohn Marino 65*e4b17023SJohn Marino // Sequential fallback for input iterator case 66*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, 67*e4b17023SJohn Marino typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> 68*e4b17023SJohn Marino inline pair<_IIter1, _IIter2> 69*e4b17023SJohn Marino __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 70*e4b17023SJohn Marino _Predicate __pred, _IteratorTag1, _IteratorTag2) 71*e4b17023SJohn Marino { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } 72*e4b17023SJohn Marino 73*e4b17023SJohn Marino // Parallel mismatch for random access iterators 74*e4b17023SJohn Marino template<typename _RAIter1, typename _RAIter2, typename _Predicate> 75*e4b17023SJohn Marino pair<_RAIter1, _RAIter2> 76*e4b17023SJohn Marino __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, 77*e4b17023SJohn Marino _RAIter2 __begin2, _Predicate __pred, 78*e4b17023SJohn Marino random_access_iterator_tag, random_access_iterator_tag) 79*e4b17023SJohn Marino { 80*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION(true)) 81*e4b17023SJohn Marino { 82*e4b17023SJohn Marino _RAIter1 __res = 83*e4b17023SJohn Marino __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, 84*e4b17023SJohn Marino __gnu_parallel:: 85*e4b17023SJohn Marino __mismatch_selector()).first; 86*e4b17023SJohn Marino return make_pair(__res , __begin2 + (__res - __begin1)); 87*e4b17023SJohn Marino } 88*e4b17023SJohn Marino else 89*e4b17023SJohn Marino return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); 90*e4b17023SJohn Marino } 91*e4b17023SJohn Marino 92*e4b17023SJohn Marino // Public interface 93*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2> 94*e4b17023SJohn Marino inline pair<_IIter1, _IIter2> 95*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) 96*e4b17023SJohn Marino { 97*e4b17023SJohn Marino typedef std::iterator_traits<_IIter1> _Iterator1Traits; 98*e4b17023SJohn Marino typedef std::iterator_traits<_IIter2> _Iterator2Traits; 99*e4b17023SJohn Marino typedef typename _Iterator1Traits::value_type _ValueType1; 100*e4b17023SJohn Marino typedef typename _Iterator2Traits::value_type _ValueType2; 101*e4b17023SJohn Marino typedef typename _Iterator1Traits::iterator_category _IteratorCategory1; 102*e4b17023SJohn Marino typedef typename _Iterator2Traits::iterator_category _IteratorCategory2; 103*e4b17023SJohn Marino 104*e4b17023SJohn Marino typedef __gnu_parallel::_EqualTo<_ValueType1, _ValueType2> _EqualTo; 105*e4b17023SJohn Marino 106*e4b17023SJohn Marino return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(), 107*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2()); 108*e4b17023SJohn Marino } 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino // Public interface 111*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate> 112*e4b17023SJohn Marino inline pair<_IIter1, _IIter2> 113*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 114*e4b17023SJohn Marino _Predicate __pred) 115*e4b17023SJohn Marino { 116*e4b17023SJohn Marino typedef std::iterator_traits<_IIter1> _Iterator1Traits; 117*e4b17023SJohn Marino typedef std::iterator_traits<_IIter2> _Iterator2Traits; 118*e4b17023SJohn Marino typedef typename _Iterator1Traits::iterator_category _IteratorCategory1; 119*e4b17023SJohn Marino typedef typename _Iterator2Traits::iterator_category _IteratorCategory2; 120*e4b17023SJohn Marino 121*e4b17023SJohn Marino return __mismatch_switch(__begin1, __end1, __begin2, __pred, 122*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2()); 123*e4b17023SJohn Marino } 124*e4b17023SJohn Marino 125*e4b17023SJohn Marino // Sequential fallback 126*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2> 127*e4b17023SJohn Marino inline bool 128*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 129*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 130*e4b17023SJohn Marino { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); } 131*e4b17023SJohn Marino 132*e4b17023SJohn Marino // Sequential fallback 133*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate> 134*e4b17023SJohn Marino inline bool 135*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 136*e4b17023SJohn Marino _Predicate __pred, __gnu_parallel::sequential_tag) 137*e4b17023SJohn Marino { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); } 138*e4b17023SJohn Marino 139*e4b17023SJohn Marino // Public interface 140*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2> 141*e4b17023SJohn Marino inline bool 142*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) 143*e4b17023SJohn Marino { 144*e4b17023SJohn Marino return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first 145*e4b17023SJohn Marino == __end1; 146*e4b17023SJohn Marino } 147*e4b17023SJohn Marino 148*e4b17023SJohn Marino // Public interface 149*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate> 150*e4b17023SJohn Marino inline bool 151*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 152*e4b17023SJohn Marino _Predicate __pred) 153*e4b17023SJohn Marino { 154*e4b17023SJohn Marino return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first 155*e4b17023SJohn Marino == __end1; 156*e4b17023SJohn Marino } 157*e4b17023SJohn Marino 158*e4b17023SJohn Marino // Sequential fallback 159*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2> 160*e4b17023SJohn Marino inline bool 161*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 162*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2, 163*e4b17023SJohn Marino __gnu_parallel::sequential_tag) 164*e4b17023SJohn Marino { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1, 165*e4b17023SJohn Marino __begin2, __end2); } 166*e4b17023SJohn Marino 167*e4b17023SJohn Marino // Sequential fallback 168*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate> 169*e4b17023SJohn Marino inline bool 170*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 171*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2, 172*e4b17023SJohn Marino _Predicate __pred, __gnu_parallel::sequential_tag) 173*e4b17023SJohn Marino { return _GLIBCXX_STD_A::lexicographical_compare( 174*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred); } 175*e4b17023SJohn Marino 176*e4b17023SJohn Marino // Sequential fallback for input iterator case 177*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, 178*e4b17023SJohn Marino typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> 179*e4b17023SJohn Marino inline bool 180*e4b17023SJohn Marino __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1, 181*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2, 182*e4b17023SJohn Marino _Predicate __pred, 183*e4b17023SJohn Marino _IteratorTag1, _IteratorTag2) 184*e4b17023SJohn Marino { return _GLIBCXX_STD_A::lexicographical_compare( 185*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred); } 186*e4b17023SJohn Marino 187*e4b17023SJohn Marino // Parallel lexicographical_compare for random access iterators 188*e4b17023SJohn Marino // Limitation: Both valuetypes must be the same 189*e4b17023SJohn Marino template<typename _RAIter1, typename _RAIter2, typename _Predicate> 190*e4b17023SJohn Marino bool 191*e4b17023SJohn Marino __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1, 192*e4b17023SJohn Marino _RAIter2 __begin2, _RAIter2 __end2, 193*e4b17023SJohn Marino _Predicate __pred, 194*e4b17023SJohn Marino random_access_iterator_tag, 195*e4b17023SJohn Marino random_access_iterator_tag) 196*e4b17023SJohn Marino { 197*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION(true)) 198*e4b17023SJohn Marino { 199*e4b17023SJohn Marino typedef iterator_traits<_RAIter1> _TraitsType1; 200*e4b17023SJohn Marino typedef typename _TraitsType1::value_type _ValueType1; 201*e4b17023SJohn Marino 202*e4b17023SJohn Marino typedef iterator_traits<_RAIter2> _TraitsType2; 203*e4b17023SJohn Marino typedef typename _TraitsType2::value_type _ValueType2; 204*e4b17023SJohn Marino 205*e4b17023SJohn Marino typedef __gnu_parallel:: 206*e4b17023SJohn Marino _EqualFromLess<_ValueType1, _ValueType2, _Predicate> 207*e4b17023SJohn Marino _EqualFromLessCompare; 208*e4b17023SJohn Marino 209*e4b17023SJohn Marino // Longer sequence in first place. 210*e4b17023SJohn Marino if ((__end1 - __begin1) < (__end2 - __begin2)) 211*e4b17023SJohn Marino { 212*e4b17023SJohn Marino typedef pair<_RAIter1, _RAIter2> _SpotType; 213*e4b17023SJohn Marino _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2, 214*e4b17023SJohn Marino _EqualFromLessCompare(__pred), 215*e4b17023SJohn Marino random_access_iterator_tag(), 216*e4b17023SJohn Marino random_access_iterator_tag()); 217*e4b17023SJohn Marino 218*e4b17023SJohn Marino return (__mm.first == __end1) 219*e4b17023SJohn Marino || bool(__pred(*__mm.first, *__mm.second)); 220*e4b17023SJohn Marino } 221*e4b17023SJohn Marino else 222*e4b17023SJohn Marino { 223*e4b17023SJohn Marino typedef pair<_RAIter2, _RAIter1> _SpotType; 224*e4b17023SJohn Marino _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1, 225*e4b17023SJohn Marino _EqualFromLessCompare(__pred), 226*e4b17023SJohn Marino random_access_iterator_tag(), 227*e4b17023SJohn Marino random_access_iterator_tag()); 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino return (__mm.first != __end2) 230*e4b17023SJohn Marino && bool(__pred(*__mm.second, *__mm.first)); 231*e4b17023SJohn Marino } 232*e4b17023SJohn Marino } 233*e4b17023SJohn Marino else 234*e4b17023SJohn Marino return _GLIBCXX_STD_A::lexicographical_compare( 235*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred); 236*e4b17023SJohn Marino } 237*e4b17023SJohn Marino 238*e4b17023SJohn Marino // Public interface 239*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2> 240*e4b17023SJohn Marino inline bool 241*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 242*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2) 243*e4b17023SJohn Marino { 244*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1; 245*e4b17023SJohn Marino typedef typename _TraitsType1::value_type _ValueType1; 246*e4b17023SJohn Marino typedef typename _TraitsType1::iterator_category _IteratorCategory1; 247*e4b17023SJohn Marino 248*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2; 249*e4b17023SJohn Marino typedef typename _TraitsType2::value_type _ValueType2; 250*e4b17023SJohn Marino typedef typename _TraitsType2::iterator_category _IteratorCategory2; 251*e4b17023SJohn Marino typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType; 252*e4b17023SJohn Marino 253*e4b17023SJohn Marino return __lexicographical_compare_switch( 254*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, _LessType(), 255*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2()); 256*e4b17023SJohn Marino } 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino // Public interface 259*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate> 260*e4b17023SJohn Marino inline bool 261*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 262*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2, 263*e4b17023SJohn Marino _Predicate __pred) 264*e4b17023SJohn Marino { 265*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1; 266*e4b17023SJohn Marino typedef typename _TraitsType1::iterator_category _IteratorCategory1; 267*e4b17023SJohn Marino 268*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2; 269*e4b17023SJohn Marino typedef typename _TraitsType2::iterator_category _IteratorCategory2; 270*e4b17023SJohn Marino 271*e4b17023SJohn Marino return __lexicographical_compare_switch( 272*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred, 273*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2()); 274*e4b17023SJohn Marino } 275*e4b17023SJohn Marino } // end namespace 276*e4b17023SJohn Marino } // end namespace 277*e4b17023SJohn Marino 278*e4b17023SJohn Marino #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */ 279