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