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