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 /** 26*e4b17023SJohn Marino * @file parallel/set_operations.h 27*e4b17023SJohn Marino * @brief Parallel implementations of set operations for random-access 28*e4b17023SJohn Marino * iterators. 29*e4b17023SJohn Marino * This file is a GNU parallel extension to the Standard C++ Library. 30*e4b17023SJohn Marino */ 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino // Written by Marius Elvert and Felix Bondarenko. 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino #ifndef _GLIBCXX_PARALLEL_SET_OPERATIONS_H 35*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_SET_OPERATIONS_H 1 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino #include <omp.h> 38*e4b17023SJohn Marino 39*e4b17023SJohn Marino #include <parallel/settings.h> 40*e4b17023SJohn Marino #include <parallel/multiseq_selection.h> 41*e4b17023SJohn Marino 42*e4b17023SJohn Marino namespace __gnu_parallel 43*e4b17023SJohn Marino { 44*e4b17023SJohn Marino template<typename _IIter, typename _OutputIterator> 45*e4b17023SJohn Marino _OutputIterator __copy_tail(std::pair<_IIter,_IIter> __b,std::pair<_IIter,_IIter> __e,_OutputIterator __r)46*e4b17023SJohn Marino __copy_tail(std::pair<_IIter, _IIter> __b, 47*e4b17023SJohn Marino std::pair<_IIter, _IIter> __e, _OutputIterator __r) 48*e4b17023SJohn Marino { 49*e4b17023SJohn Marino if (__b.first != __e.first) 50*e4b17023SJohn Marino { 51*e4b17023SJohn Marino do 52*e4b17023SJohn Marino { 53*e4b17023SJohn Marino *__r++ = *__b.first++; 54*e4b17023SJohn Marino } 55*e4b17023SJohn Marino while (__b.first != __e.first); 56*e4b17023SJohn Marino } 57*e4b17023SJohn Marino else 58*e4b17023SJohn Marino { 59*e4b17023SJohn Marino while (__b.second != __e.second) 60*e4b17023SJohn Marino *__r++ = *__b.second++; 61*e4b17023SJohn Marino } 62*e4b17023SJohn Marino return __r; 63*e4b17023SJohn Marino } 64*e4b17023SJohn Marino 65*e4b17023SJohn Marino template<typename _IIter, 66*e4b17023SJohn Marino typename _OutputIterator, 67*e4b17023SJohn Marino typename _Compare> 68*e4b17023SJohn Marino struct __symmetric_difference_func 69*e4b17023SJohn Marino { 70*e4b17023SJohn Marino typedef std::iterator_traits<_IIter> _TraitsType; 71*e4b17023SJohn Marino typedef typename _TraitsType::difference_type _DifferenceType; 72*e4b17023SJohn Marino typedef typename std::pair<_IIter, _IIter> _IteratorPair; 73*e4b17023SJohn Marino __symmetric_difference_func__symmetric_difference_func74*e4b17023SJohn Marino __symmetric_difference_func(_Compare __comp) : _M_comp(__comp) {} 75*e4b17023SJohn Marino 76*e4b17023SJohn Marino _Compare _M_comp; 77*e4b17023SJohn Marino 78*e4b17023SJohn Marino _OutputIterator _M_invoke__symmetric_difference_func79*e4b17023SJohn Marino _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, 80*e4b17023SJohn Marino _OutputIterator __r) const 81*e4b17023SJohn Marino { 82*e4b17023SJohn Marino while (__a != __b && __c != __d) 83*e4b17023SJohn Marino { 84*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 85*e4b17023SJohn Marino { 86*e4b17023SJohn Marino *__r = *__a; 87*e4b17023SJohn Marino ++__a; 88*e4b17023SJohn Marino ++__r; 89*e4b17023SJohn Marino } 90*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 91*e4b17023SJohn Marino { 92*e4b17023SJohn Marino *__r = *__c; 93*e4b17023SJohn Marino ++__c; 94*e4b17023SJohn Marino ++__r; 95*e4b17023SJohn Marino } 96*e4b17023SJohn Marino else 97*e4b17023SJohn Marino { 98*e4b17023SJohn Marino ++__a; 99*e4b17023SJohn Marino ++__c; 100*e4b17023SJohn Marino } 101*e4b17023SJohn Marino } 102*e4b17023SJohn Marino return std::copy(__c, __d, std::copy(__a, __b, __r)); 103*e4b17023SJohn Marino } 104*e4b17023SJohn Marino 105*e4b17023SJohn Marino _DifferenceType __count__symmetric_difference_func106*e4b17023SJohn Marino __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const 107*e4b17023SJohn Marino { 108*e4b17023SJohn Marino _DifferenceType __counter = 0; 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino while (__a != __b && __c != __d) 111*e4b17023SJohn Marino { 112*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 113*e4b17023SJohn Marino { 114*e4b17023SJohn Marino ++__a; 115*e4b17023SJohn Marino ++__counter; 116*e4b17023SJohn Marino } 117*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 118*e4b17023SJohn Marino { 119*e4b17023SJohn Marino ++__c; 120*e4b17023SJohn Marino ++__counter; 121*e4b17023SJohn Marino } 122*e4b17023SJohn Marino else 123*e4b17023SJohn Marino { 124*e4b17023SJohn Marino ++__a; 125*e4b17023SJohn Marino ++__c; 126*e4b17023SJohn Marino } 127*e4b17023SJohn Marino } 128*e4b17023SJohn Marino 129*e4b17023SJohn Marino return __counter + (__b - __a) + (__d - __c); 130*e4b17023SJohn Marino } 131*e4b17023SJohn Marino 132*e4b17023SJohn Marino _OutputIterator __first_empty__symmetric_difference_func133*e4b17023SJohn Marino __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const 134*e4b17023SJohn Marino { return std::copy(__c, __d, __out); } 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino _OutputIterator __second_empty__symmetric_difference_func137*e4b17023SJohn Marino __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const 138*e4b17023SJohn Marino { return std::copy(__a, __b, __out); } 139*e4b17023SJohn Marino }; 140*e4b17023SJohn Marino 141*e4b17023SJohn Marino 142*e4b17023SJohn Marino template<typename _IIter, 143*e4b17023SJohn Marino typename _OutputIterator, 144*e4b17023SJohn Marino typename _Compare> 145*e4b17023SJohn Marino struct __difference_func 146*e4b17023SJohn Marino { 147*e4b17023SJohn Marino typedef std::iterator_traits<_IIter> _TraitsType; 148*e4b17023SJohn Marino typedef typename _TraitsType::difference_type _DifferenceType; 149*e4b17023SJohn Marino typedef typename std::pair<_IIter, _IIter> _IteratorPair; 150*e4b17023SJohn Marino __difference_func__difference_func151*e4b17023SJohn Marino __difference_func(_Compare __comp) : _M_comp(__comp) {} 152*e4b17023SJohn Marino 153*e4b17023SJohn Marino _Compare _M_comp; 154*e4b17023SJohn Marino 155*e4b17023SJohn Marino _OutputIterator _M_invoke__difference_func156*e4b17023SJohn Marino _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, 157*e4b17023SJohn Marino _OutputIterator __r) const 158*e4b17023SJohn Marino { 159*e4b17023SJohn Marino while (__a != __b && __c != __d) 160*e4b17023SJohn Marino { 161*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 162*e4b17023SJohn Marino { 163*e4b17023SJohn Marino *__r = *__a; 164*e4b17023SJohn Marino ++__a; 165*e4b17023SJohn Marino ++__r; 166*e4b17023SJohn Marino } 167*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 168*e4b17023SJohn Marino { ++__c; } 169*e4b17023SJohn Marino else 170*e4b17023SJohn Marino { 171*e4b17023SJohn Marino ++__a; 172*e4b17023SJohn Marino ++__c; 173*e4b17023SJohn Marino } 174*e4b17023SJohn Marino } 175*e4b17023SJohn Marino return std::copy(__a, __b, __r); 176*e4b17023SJohn Marino } 177*e4b17023SJohn Marino 178*e4b17023SJohn Marino _DifferenceType __count__difference_func179*e4b17023SJohn Marino __count(_IIter __a, _IIter __b, 180*e4b17023SJohn Marino _IIter __c, _IIter __d) const 181*e4b17023SJohn Marino { 182*e4b17023SJohn Marino _DifferenceType __counter = 0; 183*e4b17023SJohn Marino 184*e4b17023SJohn Marino while (__a != __b && __c != __d) 185*e4b17023SJohn Marino { 186*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 187*e4b17023SJohn Marino { 188*e4b17023SJohn Marino ++__a; 189*e4b17023SJohn Marino ++__counter; 190*e4b17023SJohn Marino } 191*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 192*e4b17023SJohn Marino { ++__c; } 193*e4b17023SJohn Marino else 194*e4b17023SJohn Marino { ++__a; ++__c; } 195*e4b17023SJohn Marino } 196*e4b17023SJohn Marino 197*e4b17023SJohn Marino return __counter + (__b - __a); 198*e4b17023SJohn Marino } 199*e4b17023SJohn Marino 200*e4b17023SJohn Marino _OutputIterator __first_empty__difference_func201*e4b17023SJohn Marino __first_empty(_IIter, _IIter, _OutputIterator __out) const 202*e4b17023SJohn Marino { return __out; } 203*e4b17023SJohn Marino 204*e4b17023SJohn Marino _OutputIterator __second_empty__difference_func205*e4b17023SJohn Marino __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const 206*e4b17023SJohn Marino { return std::copy(__a, __b, __out); } 207*e4b17023SJohn Marino }; 208*e4b17023SJohn Marino 209*e4b17023SJohn Marino 210*e4b17023SJohn Marino template<typename _IIter, 211*e4b17023SJohn Marino typename _OutputIterator, 212*e4b17023SJohn Marino typename _Compare> 213*e4b17023SJohn Marino struct __intersection_func 214*e4b17023SJohn Marino { 215*e4b17023SJohn Marino typedef std::iterator_traits<_IIter> _TraitsType; 216*e4b17023SJohn Marino typedef typename _TraitsType::difference_type _DifferenceType; 217*e4b17023SJohn Marino typedef typename std::pair<_IIter, _IIter> _IteratorPair; 218*e4b17023SJohn Marino __intersection_func__intersection_func219*e4b17023SJohn Marino __intersection_func(_Compare __comp) : _M_comp(__comp) {} 220*e4b17023SJohn Marino 221*e4b17023SJohn Marino _Compare _M_comp; 222*e4b17023SJohn Marino 223*e4b17023SJohn Marino _OutputIterator _M_invoke__intersection_func224*e4b17023SJohn Marino _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, 225*e4b17023SJohn Marino _OutputIterator __r) const 226*e4b17023SJohn Marino { 227*e4b17023SJohn Marino while (__a != __b && __c != __d) 228*e4b17023SJohn Marino { 229*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 230*e4b17023SJohn Marino { ++__a; } 231*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 232*e4b17023SJohn Marino { ++__c; } 233*e4b17023SJohn Marino else 234*e4b17023SJohn Marino { 235*e4b17023SJohn Marino *__r = *__a; 236*e4b17023SJohn Marino ++__a; 237*e4b17023SJohn Marino ++__c; 238*e4b17023SJohn Marino ++__r; 239*e4b17023SJohn Marino } 240*e4b17023SJohn Marino } 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino return __r; 243*e4b17023SJohn Marino } 244*e4b17023SJohn Marino 245*e4b17023SJohn Marino _DifferenceType __count__intersection_func246*e4b17023SJohn Marino __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const 247*e4b17023SJohn Marino { 248*e4b17023SJohn Marino _DifferenceType __counter = 0; 249*e4b17023SJohn Marino 250*e4b17023SJohn Marino while (__a != __b && __c != __d) 251*e4b17023SJohn Marino { 252*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 253*e4b17023SJohn Marino { ++__a; } 254*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 255*e4b17023SJohn Marino { ++__c; } 256*e4b17023SJohn Marino else 257*e4b17023SJohn Marino { 258*e4b17023SJohn Marino ++__a; 259*e4b17023SJohn Marino ++__c; 260*e4b17023SJohn Marino ++__counter; 261*e4b17023SJohn Marino } 262*e4b17023SJohn Marino } 263*e4b17023SJohn Marino 264*e4b17023SJohn Marino return __counter; 265*e4b17023SJohn Marino } 266*e4b17023SJohn Marino 267*e4b17023SJohn Marino _OutputIterator __first_empty__intersection_func268*e4b17023SJohn Marino __first_empty(_IIter, _IIter, _OutputIterator __out) const 269*e4b17023SJohn Marino { return __out; } 270*e4b17023SJohn Marino 271*e4b17023SJohn Marino _OutputIterator __second_empty__intersection_func272*e4b17023SJohn Marino __second_empty(_IIter, _IIter, _OutputIterator __out) const 273*e4b17023SJohn Marino { return __out; } 274*e4b17023SJohn Marino }; 275*e4b17023SJohn Marino 276*e4b17023SJohn Marino template<class _IIter, class _OutputIterator, class _Compare> 277*e4b17023SJohn Marino struct __union_func 278*e4b17023SJohn Marino { 279*e4b17023SJohn Marino typedef typename std::iterator_traits<_IIter>::difference_type 280*e4b17023SJohn Marino _DifferenceType; 281*e4b17023SJohn Marino __union_func__union_func282*e4b17023SJohn Marino __union_func(_Compare __comp) : _M_comp(__comp) {} 283*e4b17023SJohn Marino 284*e4b17023SJohn Marino _Compare _M_comp; 285*e4b17023SJohn Marino 286*e4b17023SJohn Marino _OutputIterator _M_invoke__union_func287*e4b17023SJohn Marino _M_invoke(_IIter __a, const _IIter __b, _IIter __c, 288*e4b17023SJohn Marino const _IIter __d, _OutputIterator __r) const 289*e4b17023SJohn Marino { 290*e4b17023SJohn Marino while (__a != __b && __c != __d) 291*e4b17023SJohn Marino { 292*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 293*e4b17023SJohn Marino { 294*e4b17023SJohn Marino *__r = *__a; 295*e4b17023SJohn Marino ++__a; 296*e4b17023SJohn Marino } 297*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 298*e4b17023SJohn Marino { 299*e4b17023SJohn Marino *__r = *__c; 300*e4b17023SJohn Marino ++__c; 301*e4b17023SJohn Marino } 302*e4b17023SJohn Marino else 303*e4b17023SJohn Marino { 304*e4b17023SJohn Marino *__r = *__a; 305*e4b17023SJohn Marino ++__a; 306*e4b17023SJohn Marino ++__c; 307*e4b17023SJohn Marino } 308*e4b17023SJohn Marino ++__r; 309*e4b17023SJohn Marino } 310*e4b17023SJohn Marino return std::copy(__c, __d, std::copy(__a, __b, __r)); 311*e4b17023SJohn Marino } 312*e4b17023SJohn Marino 313*e4b17023SJohn Marino _DifferenceType __count__union_func314*e4b17023SJohn Marino __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const 315*e4b17023SJohn Marino { 316*e4b17023SJohn Marino _DifferenceType __counter = 0; 317*e4b17023SJohn Marino 318*e4b17023SJohn Marino while (__a != __b && __c != __d) 319*e4b17023SJohn Marino { 320*e4b17023SJohn Marino if (_M_comp(*__a, *__c)) 321*e4b17023SJohn Marino { ++__a; } 322*e4b17023SJohn Marino else if (_M_comp(*__c, *__a)) 323*e4b17023SJohn Marino { ++__c; } 324*e4b17023SJohn Marino else 325*e4b17023SJohn Marino { 326*e4b17023SJohn Marino ++__a; 327*e4b17023SJohn Marino ++__c; 328*e4b17023SJohn Marino } 329*e4b17023SJohn Marino ++__counter; 330*e4b17023SJohn Marino } 331*e4b17023SJohn Marino 332*e4b17023SJohn Marino __counter += (__b - __a); 333*e4b17023SJohn Marino __counter += (__d - __c); 334*e4b17023SJohn Marino return __counter; 335*e4b17023SJohn Marino } 336*e4b17023SJohn Marino 337*e4b17023SJohn Marino _OutputIterator __first_empty__union_func338*e4b17023SJohn Marino __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const 339*e4b17023SJohn Marino { return std::copy(__c, __d, __out); } 340*e4b17023SJohn Marino 341*e4b17023SJohn Marino _OutputIterator __second_empty__union_func342*e4b17023SJohn Marino __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const 343*e4b17023SJohn Marino { return std::copy(__a, __b, __out); } 344*e4b17023SJohn Marino }; 345*e4b17023SJohn Marino 346*e4b17023SJohn Marino template<typename _IIter, 347*e4b17023SJohn Marino typename _OutputIterator, 348*e4b17023SJohn Marino typename _Operation> 349*e4b17023SJohn Marino _OutputIterator __parallel_set_operation(_IIter __begin1,_IIter __end1,_IIter __begin2,_IIter __end2,_OutputIterator __result,_Operation __op)350*e4b17023SJohn Marino __parallel_set_operation(_IIter __begin1, _IIter __end1, 351*e4b17023SJohn Marino _IIter __begin2, _IIter __end2, 352*e4b17023SJohn Marino _OutputIterator __result, _Operation __op) 353*e4b17023SJohn Marino { 354*e4b17023SJohn Marino _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)) 355*e4b17023SJohn Marino 356*e4b17023SJohn Marino typedef std::iterator_traits<_IIter> _TraitsType; 357*e4b17023SJohn Marino typedef typename _TraitsType::difference_type _DifferenceType; 358*e4b17023SJohn Marino typedef typename std::pair<_IIter, _IIter> _IteratorPair; 359*e4b17023SJohn Marino 360*e4b17023SJohn Marino if (__begin1 == __end1) 361*e4b17023SJohn Marino return __op.__first_empty(__begin2, __end2, __result); 362*e4b17023SJohn Marino 363*e4b17023SJohn Marino if (__begin2 == __end2) 364*e4b17023SJohn Marino return __op.__second_empty(__begin1, __end1, __result); 365*e4b17023SJohn Marino 366*e4b17023SJohn Marino const _DifferenceType __size = (__end1 - __begin1) + (__end2 - __begin2); 367*e4b17023SJohn Marino 368*e4b17023SJohn Marino const _IteratorPair __sequence[2] = { std::make_pair(__begin1, __end1), 369*e4b17023SJohn Marino std::make_pair(__begin2, __end2) }; 370*e4b17023SJohn Marino _OutputIterator __return_value = __result; 371*e4b17023SJohn Marino _DifferenceType *__borders; 372*e4b17023SJohn Marino _IteratorPair *__block_begins; 373*e4b17023SJohn Marino _DifferenceType* __lengths; 374*e4b17023SJohn Marino 375*e4b17023SJohn Marino _ThreadIndex __num_threads = 376*e4b17023SJohn Marino std::min<_DifferenceType>(__get_max_threads(), 377*e4b17023SJohn Marino std::min(__end1 - __begin1, __end2 - __begin2)); 378*e4b17023SJohn Marino 379*e4b17023SJohn Marino # pragma omp parallel num_threads(__num_threads) 380*e4b17023SJohn Marino { 381*e4b17023SJohn Marino # pragma omp single 382*e4b17023SJohn Marino { 383*e4b17023SJohn Marino __num_threads = omp_get_num_threads(); 384*e4b17023SJohn Marino 385*e4b17023SJohn Marino __borders = new _DifferenceType[__num_threads + 2]; 386*e4b17023SJohn Marino __equally_split(__size, __num_threads + 1, __borders); 387*e4b17023SJohn Marino __block_begins = new _IteratorPair[__num_threads + 1]; 388*e4b17023SJohn Marino // Very __start. 389*e4b17023SJohn Marino __block_begins[0] = std::make_pair(__begin1, __begin2); 390*e4b17023SJohn Marino __lengths = new _DifferenceType[__num_threads]; 391*e4b17023SJohn Marino } //single 392*e4b17023SJohn Marino 393*e4b17023SJohn Marino _ThreadIndex __iam = omp_get_thread_num(); 394*e4b17023SJohn Marino 395*e4b17023SJohn Marino // _Result from multiseq_partition. 396*e4b17023SJohn Marino _IIter __offset[2]; 397*e4b17023SJohn Marino const _DifferenceType __rank = __borders[__iam + 1]; 398*e4b17023SJohn Marino 399*e4b17023SJohn Marino multiseq_partition(__sequence, __sequence + 2, 400*e4b17023SJohn Marino __rank, __offset, __op._M_comp); 401*e4b17023SJohn Marino 402*e4b17023SJohn Marino // allowed to read? 403*e4b17023SJohn Marino // together 404*e4b17023SJohn Marino // *(__offset[ 0 ] - 1) == *__offset[ 1 ] 405*e4b17023SJohn Marino if (__offset[ 0 ] != __begin1 && __offset[1] != __end2 406*e4b17023SJohn Marino && !__op._M_comp(*(__offset[0] - 1), *__offset[1]) 407*e4b17023SJohn Marino && !__op._M_comp(*__offset[1], *(__offset[0] - 1))) 408*e4b17023SJohn Marino { 409*e4b17023SJohn Marino // Avoid split between globally equal elements: move one to 410*e4b17023SJohn Marino // front in first sequence. 411*e4b17023SJohn Marino --__offset[0]; 412*e4b17023SJohn Marino } 413*e4b17023SJohn Marino 414*e4b17023SJohn Marino _IteratorPair __block_end = __block_begins[__iam + 1] = 415*e4b17023SJohn Marino _IteratorPair(__offset[0], __offset[1]); 416*e4b17023SJohn Marino 417*e4b17023SJohn Marino // Make sure all threads have their block_begin result written out. 418*e4b17023SJohn Marino # pragma omp barrier 419*e4b17023SJohn Marino 420*e4b17023SJohn Marino _IteratorPair __block_begin = __block_begins[__iam]; 421*e4b17023SJohn Marino 422*e4b17023SJohn Marino // Begin working for the first block, while the others except 423*e4b17023SJohn Marino // the last start to count. 424*e4b17023SJohn Marino if (__iam == 0) 425*e4b17023SJohn Marino { 426*e4b17023SJohn Marino // The first thread can copy already. 427*e4b17023SJohn Marino __lengths[ __iam ] = 428*e4b17023SJohn Marino __op._M_invoke(__block_begin.first, __block_end.first, 429*e4b17023SJohn Marino __block_begin.second, __block_end.second, 430*e4b17023SJohn Marino __result) - __result; 431*e4b17023SJohn Marino } 432*e4b17023SJohn Marino else 433*e4b17023SJohn Marino { 434*e4b17023SJohn Marino __lengths[ __iam ] = 435*e4b17023SJohn Marino __op.__count(__block_begin.first, __block_end.first, 436*e4b17023SJohn Marino __block_begin.second, __block_end.second); 437*e4b17023SJohn Marino } 438*e4b17023SJohn Marino 439*e4b17023SJohn Marino // Make sure everyone wrote their lengths. 440*e4b17023SJohn Marino # pragma omp barrier 441*e4b17023SJohn Marino 442*e4b17023SJohn Marino _OutputIterator __r = __result; 443*e4b17023SJohn Marino 444*e4b17023SJohn Marino if (__iam == 0) 445*e4b17023SJohn Marino { 446*e4b17023SJohn Marino // Do the last block. 447*e4b17023SJohn Marino for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) 448*e4b17023SJohn Marino __r += __lengths[__i]; 449*e4b17023SJohn Marino 450*e4b17023SJohn Marino __block_begin = __block_begins[__num_threads]; 451*e4b17023SJohn Marino 452*e4b17023SJohn Marino // Return the result iterator of the last block. 453*e4b17023SJohn Marino __return_value = 454*e4b17023SJohn Marino __op._M_invoke(__block_begin.first, __end1, 455*e4b17023SJohn Marino __block_begin.second, __end2, __r); 456*e4b17023SJohn Marino 457*e4b17023SJohn Marino } 458*e4b17023SJohn Marino else 459*e4b17023SJohn Marino { 460*e4b17023SJohn Marino for (_ThreadIndex __i = 0; __i < __iam; ++__i) 461*e4b17023SJohn Marino __r += __lengths[ __i ]; 462*e4b17023SJohn Marino 463*e4b17023SJohn Marino // Reset begins for copy pass. 464*e4b17023SJohn Marino __op._M_invoke(__block_begin.first, __block_end.first, 465*e4b17023SJohn Marino __block_begin.second, __block_end.second, __r); 466*e4b17023SJohn Marino } 467*e4b17023SJohn Marino } 468*e4b17023SJohn Marino return __return_value; 469*e4b17023SJohn Marino } 470*e4b17023SJohn Marino 471*e4b17023SJohn Marino template<typename _IIter, 472*e4b17023SJohn Marino typename _OutputIterator, 473*e4b17023SJohn Marino typename _Compare> 474*e4b17023SJohn Marino inline _OutputIterator __parallel_set_union(_IIter __begin1,_IIter __end1,_IIter __begin2,_IIter __end2,_OutputIterator __result,_Compare __comp)475*e4b17023SJohn Marino __parallel_set_union(_IIter __begin1, _IIter __end1, 476*e4b17023SJohn Marino _IIter __begin2, _IIter __end2, 477*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 478*e4b17023SJohn Marino { 479*e4b17023SJohn Marino return __parallel_set_operation(__begin1, __end1, __begin2, __end2, 480*e4b17023SJohn Marino __result, 481*e4b17023SJohn Marino __union_func< _IIter, _OutputIterator, 482*e4b17023SJohn Marino _Compare>(__comp)); 483*e4b17023SJohn Marino } 484*e4b17023SJohn Marino 485*e4b17023SJohn Marino template<typename _IIter, 486*e4b17023SJohn Marino typename _OutputIterator, 487*e4b17023SJohn Marino typename _Compare> 488*e4b17023SJohn Marino inline _OutputIterator __parallel_set_intersection(_IIter __begin1,_IIter __end1,_IIter __begin2,_IIter __end2,_OutputIterator __result,_Compare __comp)489*e4b17023SJohn Marino __parallel_set_intersection(_IIter __begin1, _IIter __end1, 490*e4b17023SJohn Marino _IIter __begin2, _IIter __end2, 491*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 492*e4b17023SJohn Marino { 493*e4b17023SJohn Marino return __parallel_set_operation(__begin1, __end1, __begin2, __end2, 494*e4b17023SJohn Marino __result, 495*e4b17023SJohn Marino __intersection_func<_IIter, 496*e4b17023SJohn Marino _OutputIterator, _Compare>(__comp)); 497*e4b17023SJohn Marino } 498*e4b17023SJohn Marino 499*e4b17023SJohn Marino template<typename _IIter, 500*e4b17023SJohn Marino typename _OutputIterator, 501*e4b17023SJohn Marino typename _Compare> 502*e4b17023SJohn Marino inline _OutputIterator __parallel_set_difference(_IIter __begin1,_IIter __end1,_IIter __begin2,_IIter __end2,_OutputIterator __result,_Compare __comp)503*e4b17023SJohn Marino __parallel_set_difference(_IIter __begin1, _IIter __end1, 504*e4b17023SJohn Marino _IIter __begin2, _IIter __end2, 505*e4b17023SJohn Marino _OutputIterator __result, _Compare __comp) 506*e4b17023SJohn Marino { 507*e4b17023SJohn Marino return __parallel_set_operation(__begin1, __end1, __begin2, __end2, 508*e4b17023SJohn Marino __result, 509*e4b17023SJohn Marino __difference_func<_IIter, 510*e4b17023SJohn Marino _OutputIterator, _Compare>(__comp)); 511*e4b17023SJohn Marino } 512*e4b17023SJohn Marino 513*e4b17023SJohn Marino template<typename _IIter, 514*e4b17023SJohn Marino typename _OutputIterator, 515*e4b17023SJohn Marino typename _Compare> 516*e4b17023SJohn Marino inline _OutputIterator __parallel_set_symmetric_difference(_IIter __begin1,_IIter __end1,_IIter __begin2,_IIter __end2,_OutputIterator __result,_Compare __comp)517*e4b17023SJohn Marino __parallel_set_symmetric_difference(_IIter __begin1, _IIter __end1, 518*e4b17023SJohn Marino _IIter __begin2, _IIter __end2, 519*e4b17023SJohn Marino _OutputIterator __result, 520*e4b17023SJohn Marino _Compare __comp) 521*e4b17023SJohn Marino { 522*e4b17023SJohn Marino return __parallel_set_operation(__begin1, __end1, __begin2, __end2, 523*e4b17023SJohn Marino __result, 524*e4b17023SJohn Marino __symmetric_difference_func<_IIter, 525*e4b17023SJohn Marino _OutputIterator, _Compare>(__comp)); 526*e4b17023SJohn Marino } 527*e4b17023SJohn Marino } 528*e4b17023SJohn Marino 529*e4b17023SJohn Marino #endif /* _GLIBCXX_PARALLEL_SET_OPERATIONS_H */ 530