xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/parallel/set_operations.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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