xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/parallel/multiway_merge.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 /** @file parallel/multiway_merge.h
26*e4b17023SJohn Marino *  @brief Implementation of sequential and parallel multiway merge.
27*e4b17023SJohn Marino *
28*e4b17023SJohn Marino *  Explanations on the high-speed merging routines in the appendix of
29*e4b17023SJohn Marino *
30*e4b17023SJohn Marino *  P. Sanders.
31*e4b17023SJohn Marino *  Fast priority queues for cached memory.
32*e4b17023SJohn Marino *  ACM Journal of Experimental Algorithmics, 5, 2000.
33*e4b17023SJohn Marino *
34*e4b17023SJohn Marino *  This file is a GNU parallel extension to the Standard C++ Library.
35*e4b17023SJohn Marino */
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino // Written by Johannes Singler and Manuel Holtgrewe.
38*e4b17023SJohn Marino 
39*e4b17023SJohn Marino #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
40*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
41*e4b17023SJohn Marino 
42*e4b17023SJohn Marino #include <vector>
43*e4b17023SJohn Marino 
44*e4b17023SJohn Marino #include <bits/stl_algo.h>
45*e4b17023SJohn Marino #include <parallel/features.h>
46*e4b17023SJohn Marino #include <parallel/parallel.h>
47*e4b17023SJohn Marino #include <parallel/losertree.h>
48*e4b17023SJohn Marino #include <parallel/multiseq_selection.h>
49*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
50*e4b17023SJohn Marino #include <parallel/checkers.h>
51*e4b17023SJohn Marino #endif
52*e4b17023SJohn Marino 
53*e4b17023SJohn Marino /** @brief Length of a sequence described by a pair of iterators. */
54*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first)
55*e4b17023SJohn Marino 
56*e4b17023SJohn Marino namespace __gnu_parallel
57*e4b17023SJohn Marino {
58*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2, typename _OutputIterator,
59*e4b17023SJohn Marino 	   typename _DifferenceTp, typename _Compare>
60*e4b17023SJohn Marino     _OutputIterator
61*e4b17023SJohn Marino     __merge_advance(_RAIter1&, _RAIter1, _RAIter2&, _RAIter2,
62*e4b17023SJohn Marino 		    _OutputIterator, _DifferenceTp, _Compare);
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino   /** @brief _Iterator wrapper supporting an implicit supremum at the end
65*e4b17023SJohn Marino    *         of the sequence, dominating all comparisons.
66*e4b17023SJohn Marino    *
67*e4b17023SJohn Marino    * The implicit supremum comes with a performance cost.
68*e4b17023SJohn Marino    *
69*e4b17023SJohn Marino    * Deriving from _RAIter is not possible since
70*e4b17023SJohn Marino    * _RAIter need not be a class.
71*e4b17023SJohn Marino    */
72*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
73*e4b17023SJohn Marino     class _GuardedIterator
74*e4b17023SJohn Marino     {
75*e4b17023SJohn Marino     private:
76*e4b17023SJohn Marino       /** @brief Current iterator __position. */
77*e4b17023SJohn Marino       _RAIter _M_current;
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino       /** @brief End iterator of the sequence. */
80*e4b17023SJohn Marino       _RAIter _M_end;
81*e4b17023SJohn Marino 
82*e4b17023SJohn Marino       /** @brief _Compare. */
83*e4b17023SJohn Marino       _Compare& __comp;
84*e4b17023SJohn Marino 
85*e4b17023SJohn Marino     public:
86*e4b17023SJohn Marino       /** @brief Constructor. Sets iterator to beginning of sequence.
87*e4b17023SJohn Marino       *  @param __begin Begin iterator of sequence.
88*e4b17023SJohn Marino       *  @param __end End iterator of sequence.
89*e4b17023SJohn Marino       *  @param __comp Comparator provided for associated overloaded
90*e4b17023SJohn Marino       *  compare operators. */
_GuardedIterator(_RAIter __begin,_RAIter __end,_Compare & __comp)91*e4b17023SJohn Marino       _GuardedIterator(_RAIter __begin, _RAIter __end, _Compare& __comp)
92*e4b17023SJohn Marino       : _M_current(__begin), _M_end(__end), __comp(__comp)
93*e4b17023SJohn Marino       { }
94*e4b17023SJohn Marino 
95*e4b17023SJohn Marino       /** @brief Pre-increment operator.
96*e4b17023SJohn Marino       *  @return This. */
97*e4b17023SJohn Marino       _GuardedIterator<_RAIter, _Compare>&
98*e4b17023SJohn Marino       operator++()
99*e4b17023SJohn Marino       {
100*e4b17023SJohn Marino 	++_M_current;
101*e4b17023SJohn Marino 	return *this;
102*e4b17023SJohn Marino       }
103*e4b17023SJohn Marino 
104*e4b17023SJohn Marino       /** @brief Dereference operator.
105*e4b17023SJohn Marino       *  @return Referenced element. */
106*e4b17023SJohn Marino       typename std::iterator_traits<_RAIter>::value_type&
107*e4b17023SJohn Marino       operator*()
108*e4b17023SJohn Marino       { return *_M_current; }
109*e4b17023SJohn Marino 
110*e4b17023SJohn Marino       /** @brief Convert to wrapped iterator.
111*e4b17023SJohn Marino       *  @return Wrapped iterator. */
_RAIter()112*e4b17023SJohn Marino       operator _RAIter()
113*e4b17023SJohn Marino       { return _M_current; }
114*e4b17023SJohn Marino 
115*e4b17023SJohn Marino       /** @brief Compare two elements referenced by guarded iterators.
116*e4b17023SJohn Marino        *  @param __bi1 First iterator.
117*e4b17023SJohn Marino        *  @param __bi2 Second iterator.
118*e4b17023SJohn Marino        *  @return @c true if less. */
119*e4b17023SJohn Marino       friend bool
120*e4b17023SJohn Marino       operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
121*e4b17023SJohn Marino 		_GuardedIterator<_RAIter, _Compare>& __bi2)
122*e4b17023SJohn Marino       {
123*e4b17023SJohn Marino 	if (__bi1._M_current == __bi1._M_end)       // __bi1 is sup
124*e4b17023SJohn Marino 	  return __bi2._M_current == __bi2._M_end;  // __bi2 is not sup
125*e4b17023SJohn Marino 	if (__bi2._M_current == __bi2._M_end)       // __bi2 is sup
126*e4b17023SJohn Marino 	  return true;
127*e4b17023SJohn Marino 	return (__bi1.__comp)(*__bi1, *__bi2);      // normal compare
128*e4b17023SJohn Marino       }
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino       /** @brief Compare two elements referenced by guarded iterators.
131*e4b17023SJohn Marino        *  @param __bi1 First iterator.
132*e4b17023SJohn Marino        *  @param __bi2 Second iterator.
133*e4b17023SJohn Marino        *  @return @c True if less equal. */
134*e4b17023SJohn Marino       friend bool
135*e4b17023SJohn Marino       operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
136*e4b17023SJohn Marino 		 _GuardedIterator<_RAIter, _Compare>& __bi2)
137*e4b17023SJohn Marino       {
138*e4b17023SJohn Marino 	if (__bi2._M_current == __bi2._M_end)       // __bi1 is sup
139*e4b17023SJohn Marino 	  return __bi1._M_current != __bi1._M_end;  // __bi2 is not sup
140*e4b17023SJohn Marino 	if (__bi1._M_current == __bi1._M_end)       // __bi2 is sup
141*e4b17023SJohn Marino 	  return false;
142*e4b17023SJohn Marino 	return !(__bi1.__comp)(*__bi2, *__bi1);     // normal compare
143*e4b17023SJohn Marino       }
144*e4b17023SJohn Marino     };
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
147*e4b17023SJohn Marino     class _UnguardedIterator
148*e4b17023SJohn Marino     {
149*e4b17023SJohn Marino     private:
150*e4b17023SJohn Marino       /** @brief Current iterator __position. */
151*e4b17023SJohn Marino       _RAIter _M_current;
152*e4b17023SJohn Marino       /** @brief _Compare. */
153*e4b17023SJohn Marino       _Compare& __comp;
154*e4b17023SJohn Marino 
155*e4b17023SJohn Marino     public:
156*e4b17023SJohn Marino       /** @brief Constructor. Sets iterator to beginning of sequence.
157*e4b17023SJohn Marino       *  @param __begin Begin iterator of sequence.
158*e4b17023SJohn Marino       *  @param __end Unused, only for compatibility.
159*e4b17023SJohn Marino       *  @param __comp Unused, only for compatibility. */
_UnguardedIterator(_RAIter __begin,_RAIter,_Compare & __comp)160*e4b17023SJohn Marino       _UnguardedIterator(_RAIter __begin,
161*e4b17023SJohn Marino                 	 _RAIter /* __end */, _Compare& __comp)
162*e4b17023SJohn Marino       : _M_current(__begin), __comp(__comp)
163*e4b17023SJohn Marino       { }
164*e4b17023SJohn Marino 
165*e4b17023SJohn Marino       /** @brief Pre-increment operator.
166*e4b17023SJohn Marino       *  @return This. */
167*e4b17023SJohn Marino       _UnguardedIterator<_RAIter, _Compare>&
168*e4b17023SJohn Marino       operator++()
169*e4b17023SJohn Marino       {
170*e4b17023SJohn Marino 	++_M_current;
171*e4b17023SJohn Marino 	return *this;
172*e4b17023SJohn Marino       }
173*e4b17023SJohn Marino 
174*e4b17023SJohn Marino       /** @brief Dereference operator.
175*e4b17023SJohn Marino       *  @return Referenced element. */
176*e4b17023SJohn Marino       typename std::iterator_traits<_RAIter>::value_type&
177*e4b17023SJohn Marino       operator*()
178*e4b17023SJohn Marino       { return *_M_current; }
179*e4b17023SJohn Marino 
180*e4b17023SJohn Marino       /** @brief Convert to wrapped iterator.
181*e4b17023SJohn Marino       *  @return Wrapped iterator. */
_RAIter()182*e4b17023SJohn Marino       operator _RAIter()
183*e4b17023SJohn Marino       { return _M_current; }
184*e4b17023SJohn Marino 
185*e4b17023SJohn Marino       /** @brief Compare two elements referenced by unguarded iterators.
186*e4b17023SJohn Marino        *  @param __bi1 First iterator.
187*e4b17023SJohn Marino        *  @param __bi2 Second iterator.
188*e4b17023SJohn Marino        *  @return @c true if less. */
189*e4b17023SJohn Marino       friend bool
190*e4b17023SJohn Marino       operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1,
191*e4b17023SJohn Marino 		_UnguardedIterator<_RAIter, _Compare>& __bi2)
192*e4b17023SJohn Marino       {
193*e4b17023SJohn Marino 	// Normal compare.
194*e4b17023SJohn Marino 	return (__bi1.__comp)(*__bi1, *__bi2);
195*e4b17023SJohn Marino       }
196*e4b17023SJohn Marino 
197*e4b17023SJohn Marino       /** @brief Compare two elements referenced by unguarded iterators.
198*e4b17023SJohn Marino        *  @param __bi1 First iterator.
199*e4b17023SJohn Marino        *  @param __bi2 Second iterator.
200*e4b17023SJohn Marino        *  @return @c True if less equal. */
201*e4b17023SJohn Marino       friend bool
202*e4b17023SJohn Marino       operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1,
203*e4b17023SJohn Marino 		 _UnguardedIterator<_RAIter, _Compare>& __bi2)
204*e4b17023SJohn Marino       {
205*e4b17023SJohn Marino 	// Normal compare.
206*e4b17023SJohn Marino 	return !(__bi1.__comp)(*__bi2, *__bi1);
207*e4b17023SJohn Marino       }
208*e4b17023SJohn Marino     };
209*e4b17023SJohn Marino 
210*e4b17023SJohn Marino   /** @brief Highly efficient 3-way merging procedure.
211*e4b17023SJohn Marino    *
212*e4b17023SJohn Marino    * Merging is done with the algorithm implementation described by Peter
213*e4b17023SJohn Marino    * Sanders.  Basically, the idea is to minimize the number of necessary
214*e4b17023SJohn Marino    * comparison after merging an element.  The implementation trick
215*e4b17023SJohn Marino    * that makes this fast is that the order of the sequences is stored
216*e4b17023SJohn Marino    * in the instruction pointer (translated into labels in C++).
217*e4b17023SJohn Marino    *
218*e4b17023SJohn Marino    * This works well for merging up to 4 sequences.
219*e4b17023SJohn Marino    *
220*e4b17023SJohn Marino    * Note that making the merging stable does @a not come at a
221*e4b17023SJohn Marino    * performance hit.
222*e4b17023SJohn Marino    *
223*e4b17023SJohn Marino    * Whether the merging is done guarded or unguarded is selected by the
224*e4b17023SJohn Marino    * used iterator class.
225*e4b17023SJohn Marino    *
226*e4b17023SJohn Marino    * @param __seqs_begin Begin iterator of iterator pair input sequence.
227*e4b17023SJohn Marino    * @param __seqs_end End iterator of iterator pair input sequence.
228*e4b17023SJohn Marino    * @param __target Begin iterator of output sequence.
229*e4b17023SJohn Marino    * @param __comp Comparator.
230*e4b17023SJohn Marino    * @param __length Maximum length to merge, less equal than the
231*e4b17023SJohn Marino    * total number of elements available.
232*e4b17023SJohn Marino    *
233*e4b17023SJohn Marino    * @return End iterator of output sequence.
234*e4b17023SJohn Marino    */
235*e4b17023SJohn Marino   template<template<typename RAI, typename C> class iterator,
236*e4b17023SJohn Marino            typename _RAIterIterator,
237*e4b17023SJohn Marino            typename _RAIter3,
238*e4b17023SJohn Marino            typename _DifferenceTp,
239*e4b17023SJohn Marino            typename _Compare>
240*e4b17023SJohn Marino     _RAIter3
multiway_merge_3_variant(_RAIterIterator __seqs_begin,_RAIterIterator __seqs_end,_RAIter3 __target,_DifferenceTp __length,_Compare __comp)241*e4b17023SJohn Marino     multiway_merge_3_variant(_RAIterIterator __seqs_begin,
242*e4b17023SJohn Marino 			     _RAIterIterator __seqs_end,
243*e4b17023SJohn Marino 			     _RAIter3 __target,
244*e4b17023SJohn Marino 			     _DifferenceTp __length, _Compare __comp)
245*e4b17023SJohn Marino     {
246*e4b17023SJohn Marino       _GLIBCXX_CALL(__length);
247*e4b17023SJohn Marino 
248*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
249*e4b17023SJohn Marino 
250*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
251*e4b17023SJohn Marino 	::value_type::first_type
252*e4b17023SJohn Marino 	_RAIter1;
253*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIter1>::value_type
254*e4b17023SJohn Marino 	_ValueType;
255*e4b17023SJohn Marino 
256*e4b17023SJohn Marino       if (__length == 0)
257*e4b17023SJohn Marino 	return __target;
258*e4b17023SJohn Marino 
259*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
260*e4b17023SJohn Marino       _DifferenceTp __orig_length = __length;
261*e4b17023SJohn Marino #endif
262*e4b17023SJohn Marino 
263*e4b17023SJohn Marino       iterator<_RAIter1, _Compare>
264*e4b17023SJohn Marino 	__seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
265*e4b17023SJohn Marino 	__seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
266*e4b17023SJohn Marino 	__seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp);
267*e4b17023SJohn Marino 
268*e4b17023SJohn Marino       if (__seq0 <= __seq1)
269*e4b17023SJohn Marino 	{
270*e4b17023SJohn Marino           if (__seq1 <= __seq2)
271*e4b17023SJohn Marino             goto __s012;
272*e4b17023SJohn Marino           else
273*e4b17023SJohn Marino             if (__seq2 <  __seq0)
274*e4b17023SJohn Marino               goto __s201;
275*e4b17023SJohn Marino             else
276*e4b17023SJohn Marino               goto __s021;
277*e4b17023SJohn Marino 	}
278*e4b17023SJohn Marino       else
279*e4b17023SJohn Marino 	{
280*e4b17023SJohn Marino           if (__seq1 <= __seq2)
281*e4b17023SJohn Marino             {
282*e4b17023SJohn Marino               if (__seq0 <= __seq2)
283*e4b17023SJohn Marino         	goto __s102;
284*e4b17023SJohn Marino               else
285*e4b17023SJohn Marino         	goto __s120;
286*e4b17023SJohn Marino             }
287*e4b17023SJohn Marino           else
288*e4b17023SJohn Marino             goto __s210;
289*e4b17023SJohn Marino 	}
290*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \
291*e4b17023SJohn Marino       __s ## __a ## __b ## __c :                            \
292*e4b17023SJohn Marino 	*__target = *__seq ## __a;                          \
293*e4b17023SJohn Marino 	++__target;                                         \
294*e4b17023SJohn Marino 	--__length;                                         \
295*e4b17023SJohn Marino 	++__seq ## __a;                                     \
296*e4b17023SJohn Marino 	if (__length == 0) goto __finish;                   \
297*e4b17023SJohn Marino 	if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \
298*e4b17023SJohn Marino 	if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \
299*e4b17023SJohn Marino 	goto __s ## __b ## __c ## __a;
300*e4b17023SJohn Marino 
301*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
302*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
303*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < );
304*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=);
305*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=);
306*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < );
307*e4b17023SJohn Marino 
308*e4b17023SJohn Marino #undef _GLIBCXX_PARALLEL_MERGE_3_CASE
309*e4b17023SJohn Marino 
310*e4b17023SJohn Marino     __finish:
311*e4b17023SJohn Marino       ;
312*e4b17023SJohn Marino 
313*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
314*e4b17023SJohn Marino     _GLIBCXX_PARALLEL_ASSERT(
315*e4b17023SJohn Marino 	((_RAIter1)__seq0 - __seqs_begin[0].first) +
316*e4b17023SJohn Marino 	((_RAIter1)__seq1 - __seqs_begin[1].first) +
317*e4b17023SJohn Marino 	((_RAIter1)__seq2 - __seqs_begin[2].first)
318*e4b17023SJohn Marino 	== __orig_length);
319*e4b17023SJohn Marino #endif
320*e4b17023SJohn Marino 
321*e4b17023SJohn Marino       __seqs_begin[0].first = __seq0;
322*e4b17023SJohn Marino       __seqs_begin[1].first = __seq1;
323*e4b17023SJohn Marino       __seqs_begin[2].first = __seq2;
324*e4b17023SJohn Marino 
325*e4b17023SJohn Marino       return __target;
326*e4b17023SJohn Marino     }
327*e4b17023SJohn Marino 
328*e4b17023SJohn Marino   /**
329*e4b17023SJohn Marino    * @brief Highly efficient 4-way merging procedure.
330*e4b17023SJohn Marino    *
331*e4b17023SJohn Marino    * Merging is done with the algorithm implementation described by Peter
332*e4b17023SJohn Marino    * Sanders. Basically, the idea is to minimize the number of necessary
333*e4b17023SJohn Marino    * comparison after merging an element.  The implementation trick
334*e4b17023SJohn Marino    * that makes this fast is that the order of the sequences is stored
335*e4b17023SJohn Marino    * in the instruction pointer (translated into goto labels in C++).
336*e4b17023SJohn Marino    *
337*e4b17023SJohn Marino    * This works well for merging up to 4 sequences.
338*e4b17023SJohn Marino    *
339*e4b17023SJohn Marino    * Note that making the merging stable does @a not come at a
340*e4b17023SJohn Marino    * performance hit.
341*e4b17023SJohn Marino    *
342*e4b17023SJohn Marino    * Whether the merging is done guarded or unguarded is selected by the
343*e4b17023SJohn Marino    * used iterator class.
344*e4b17023SJohn Marino    *
345*e4b17023SJohn Marino    * @param __seqs_begin Begin iterator of iterator pair input sequence.
346*e4b17023SJohn Marino    * @param __seqs_end End iterator of iterator pair input sequence.
347*e4b17023SJohn Marino    * @param __target Begin iterator of output sequence.
348*e4b17023SJohn Marino    * @param __comp Comparator.
349*e4b17023SJohn Marino    * @param __length Maximum length to merge, less equal than the
350*e4b17023SJohn Marino    * total number of elements available.
351*e4b17023SJohn Marino    *
352*e4b17023SJohn Marino    * @return End iterator of output sequence.
353*e4b17023SJohn Marino    */
354*e4b17023SJohn Marino   template<template<typename RAI, typename C> class iterator,
355*e4b17023SJohn Marino            typename _RAIterIterator,
356*e4b17023SJohn Marino            typename _RAIter3,
357*e4b17023SJohn Marino            typename _DifferenceTp,
358*e4b17023SJohn Marino            typename _Compare>
359*e4b17023SJohn Marino     _RAIter3
multiway_merge_4_variant(_RAIterIterator __seqs_begin,_RAIterIterator __seqs_end,_RAIter3 __target,_DifferenceTp __length,_Compare __comp)360*e4b17023SJohn Marino     multiway_merge_4_variant(_RAIterIterator __seqs_begin,
361*e4b17023SJohn Marino                              _RAIterIterator __seqs_end,
362*e4b17023SJohn Marino                              _RAIter3 __target,
363*e4b17023SJohn Marino                              _DifferenceTp __length, _Compare __comp)
364*e4b17023SJohn Marino     {
365*e4b17023SJohn Marino       _GLIBCXX_CALL(__length);
366*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
367*e4b17023SJohn Marino 
368*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
369*e4b17023SJohn Marino 	::value_type::first_type
370*e4b17023SJohn Marino 	_RAIter1;
371*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIter1>::value_type
372*e4b17023SJohn Marino 	_ValueType;
373*e4b17023SJohn Marino 
374*e4b17023SJohn Marino       iterator<_RAIter1, _Compare>
375*e4b17023SJohn Marino 	__seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
376*e4b17023SJohn Marino 	__seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
377*e4b17023SJohn Marino 	__seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp),
378*e4b17023SJohn Marino 	__seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp);
379*e4b17023SJohn Marino 
380*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) {  \
381*e4b17023SJohn Marino 	if (__seq ## __d < __seq ## __a)		  \
382*e4b17023SJohn Marino 	  goto __s ## __d ## __a ## __b ## __c;		  \
383*e4b17023SJohn Marino 	if (__seq ## __d < __seq ## __b)		  \
384*e4b17023SJohn Marino 	  goto __s ## __a ## __d ## __b ## __c;		  \
385*e4b17023SJohn Marino 	if (__seq ## __d < __seq ## __c)		  \
386*e4b17023SJohn Marino 	  goto __s ## __a ## __b ## __d ## __c;		  \
387*e4b17023SJohn Marino 	goto __s ## __a ## __b ## __c ## __d;  }
388*e4b17023SJohn Marino 
389*e4b17023SJohn Marino       if (__seq0 <= __seq1)
390*e4b17023SJohn Marino 	{
391*e4b17023SJohn Marino           if (__seq1 <= __seq2)
392*e4b17023SJohn Marino             _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
393*e4b17023SJohn Marino             else
394*e4b17023SJohn Marino               if (__seq2 < __seq0)
395*e4b17023SJohn Marino         	_GLIBCXX_PARALLEL_DECISION(2,0,1,3)
396*e4b17023SJohn Marino         	else
397*e4b17023SJohn Marino                   _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
398*e4b17023SJohn Marino                     }
399*e4b17023SJohn Marino       else
400*e4b17023SJohn Marino 	{
401*e4b17023SJohn Marino           if (__seq1 <= __seq2)
402*e4b17023SJohn Marino             {
403*e4b17023SJohn Marino               if (__seq0 <= __seq2)
404*e4b17023SJohn Marino         	_GLIBCXX_PARALLEL_DECISION(1,0,2,3)
405*e4b17023SJohn Marino         	else
406*e4b17023SJohn Marino                   _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
407*e4b17023SJohn Marino                     }
408*e4b17023SJohn Marino           else
409*e4b17023SJohn Marino             _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
410*e4b17023SJohn Marino               }
411*e4b17023SJohn Marino 
412*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d,  \
413*e4b17023SJohn Marino 				       __c0, __c1, __c2)    \
414*e4b17023SJohn Marino       __s ## __a ## __b ## __c ## __d:                      \
415*e4b17023SJohn Marino       if (__length == 0) goto __finish;                     \
416*e4b17023SJohn Marino       *__target = *__seq ## __a;                            \
417*e4b17023SJohn Marino       ++__target;                                           \
418*e4b17023SJohn Marino       --__length;                                           \
419*e4b17023SJohn Marino       ++__seq ## __a;                                       \
420*e4b17023SJohn Marino       if (__seq ## __a __c0 __seq ## __b)      \
421*e4b17023SJohn Marino 	goto __s ## __a ## __b ## __c ## __d;  \
422*e4b17023SJohn Marino       if (__seq ## __a __c1 __seq ## __c)      \
423*e4b17023SJohn Marino 	goto __s ## __b ## __a ## __c ## __d;  \
424*e4b17023SJohn Marino       if (__seq ## __a __c2 __seq ## __d)      \
425*e4b17023SJohn Marino 	goto __s ## __b ## __c ## __a ## __d;  \
426*e4b17023SJohn Marino       goto __s ## __b ## __c ## __d ## __a;
427*e4b17023SJohn Marino 
428*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
429*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
430*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=);
431*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=);
432*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=);
433*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=);
434*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=);
435*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=);
436*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=);
437*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < );
438*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=);
439*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < );
440*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=);
441*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < );
442*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=);
443*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < );
444*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < );
445*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < );
446*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < );
447*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < );
448*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < );
449*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < );
450*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < );
451*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < );
452*e4b17023SJohn Marino 
453*e4b17023SJohn Marino #undef _GLIBCXX_PARALLEL_MERGE_4_CASE
454*e4b17023SJohn Marino #undef _GLIBCXX_PARALLEL_DECISION
455*e4b17023SJohn Marino 
456*e4b17023SJohn Marino     __finish:
457*e4b17023SJohn Marino       ;
458*e4b17023SJohn Marino 
459*e4b17023SJohn Marino       __seqs_begin[0].first = __seq0;
460*e4b17023SJohn Marino       __seqs_begin[1].first = __seq1;
461*e4b17023SJohn Marino       __seqs_begin[2].first = __seq2;
462*e4b17023SJohn Marino       __seqs_begin[3].first = __seq3;
463*e4b17023SJohn Marino 
464*e4b17023SJohn Marino       return __target;
465*e4b17023SJohn Marino     }
466*e4b17023SJohn Marino 
467*e4b17023SJohn Marino   /** @brief Multi-way merging procedure for a high branching factor,
468*e4b17023SJohn Marino    *         guarded case.
469*e4b17023SJohn Marino    *
470*e4b17023SJohn Marino    * This merging variant uses a LoserTree class as selected by <tt>_LT</tt>.
471*e4b17023SJohn Marino    *
472*e4b17023SJohn Marino    * Stability is selected through the used LoserTree class <tt>_LT</tt>.
473*e4b17023SJohn Marino    *
474*e4b17023SJohn Marino    * At least one non-empty sequence is required.
475*e4b17023SJohn Marino    *
476*e4b17023SJohn Marino    * @param __seqs_begin Begin iterator of iterator pair input sequence.
477*e4b17023SJohn Marino    * @param __seqs_end End iterator of iterator pair input sequence.
478*e4b17023SJohn Marino    * @param __target Begin iterator of output sequence.
479*e4b17023SJohn Marino    * @param __comp Comparator.
480*e4b17023SJohn Marino    * @param __length Maximum length to merge, less equal than the
481*e4b17023SJohn Marino    * total number of elements available.
482*e4b17023SJohn Marino    *
483*e4b17023SJohn Marino    * @return End iterator of output sequence.
484*e4b17023SJohn Marino    */
485*e4b17023SJohn Marino   template<typename _LT,
486*e4b17023SJohn Marino            typename _RAIterIterator,
487*e4b17023SJohn Marino            typename _RAIter3,
488*e4b17023SJohn Marino            typename _DifferenceTp,
489*e4b17023SJohn Marino            typename _Compare>
490*e4b17023SJohn Marino     _RAIter3
multiway_merge_loser_tree(_RAIterIterator __seqs_begin,_RAIterIterator __seqs_end,_RAIter3 __target,_DifferenceTp __length,_Compare __comp)491*e4b17023SJohn Marino     multiway_merge_loser_tree(_RAIterIterator __seqs_begin,
492*e4b17023SJohn Marino                               _RAIterIterator __seqs_end,
493*e4b17023SJohn Marino                               _RAIter3 __target,
494*e4b17023SJohn Marino                               _DifferenceTp __length, _Compare __comp)
495*e4b17023SJohn Marino     {
496*e4b17023SJohn Marino       _GLIBCXX_CALL(__length)
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
499*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
500*e4b17023SJohn Marino 	::difference_type _SeqNumber;
501*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
502*e4b17023SJohn Marino 	::value_type::first_type
503*e4b17023SJohn Marino 	_RAIter1;
504*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIter1>::value_type
505*e4b17023SJohn Marino 	_ValueType;
506*e4b17023SJohn Marino 
507*e4b17023SJohn Marino       _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
508*e4b17023SJohn Marino 
509*e4b17023SJohn Marino       _LT __lt(__k, __comp);
510*e4b17023SJohn Marino 
511*e4b17023SJohn Marino       // Default value for potentially non-default-constructible types.
512*e4b17023SJohn Marino       _ValueType* __arbitrary_element = 0;
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino       for (_SeqNumber __t = 0; __t < __k; ++__t)
515*e4b17023SJohn Marino 	{
516*e4b17023SJohn Marino           if(!__arbitrary_element
517*e4b17023SJohn Marino 	     && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0)
518*e4b17023SJohn Marino             __arbitrary_element = &(*__seqs_begin[__t].first);
519*e4b17023SJohn Marino 	}
520*e4b17023SJohn Marino 
521*e4b17023SJohn Marino       for (_SeqNumber __t = 0; __t < __k; ++__t)
522*e4b17023SJohn Marino 	{
523*e4b17023SJohn Marino           if (__seqs_begin[__t].first == __seqs_begin[__t].second)
524*e4b17023SJohn Marino             __lt.__insert_start(*__arbitrary_element, __t, true);
525*e4b17023SJohn Marino           else
526*e4b17023SJohn Marino             __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
527*e4b17023SJohn Marino 	}
528*e4b17023SJohn Marino 
529*e4b17023SJohn Marino       __lt.__init();
530*e4b17023SJohn Marino 
531*e4b17023SJohn Marino       _SeqNumber __source;
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino       for (_DifferenceType __i = 0; __i < __length; ++__i)
534*e4b17023SJohn Marino 	{
535*e4b17023SJohn Marino           //take out
536*e4b17023SJohn Marino           __source = __lt.__get_min_source();
537*e4b17023SJohn Marino 
538*e4b17023SJohn Marino           *(__target++) = *(__seqs_begin[__source].first++);
539*e4b17023SJohn Marino 
540*e4b17023SJohn Marino           // Feed.
541*e4b17023SJohn Marino           if (__seqs_begin[__source].first == __seqs_begin[__source].second)
542*e4b17023SJohn Marino             __lt.__delete_min_insert(*__arbitrary_element, true);
543*e4b17023SJohn Marino           else
544*e4b17023SJohn Marino             // Replace from same __source.
545*e4b17023SJohn Marino             __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
546*e4b17023SJohn Marino 	}
547*e4b17023SJohn Marino 
548*e4b17023SJohn Marino       return __target;
549*e4b17023SJohn Marino     }
550*e4b17023SJohn Marino 
551*e4b17023SJohn Marino   /** @brief Multi-way merging procedure for a high branching factor,
552*e4b17023SJohn Marino    *         unguarded case.
553*e4b17023SJohn Marino    *
554*e4b17023SJohn Marino    * Merging is done using the LoserTree class <tt>_LT</tt>.
555*e4b17023SJohn Marino    *
556*e4b17023SJohn Marino    * Stability is selected by the used LoserTrees.
557*e4b17023SJohn Marino    *
558*e4b17023SJohn Marino    * @pre No input will run out of elements during the merge.
559*e4b17023SJohn Marino    *
560*e4b17023SJohn Marino    * @param __seqs_begin Begin iterator of iterator pair input sequence.
561*e4b17023SJohn Marino    * @param __seqs_end End iterator of iterator pair input sequence.
562*e4b17023SJohn Marino    * @param __target Begin iterator of output sequence.
563*e4b17023SJohn Marino    * @param __comp Comparator.
564*e4b17023SJohn Marino    * @param __length Maximum length to merge, less equal than the
565*e4b17023SJohn Marino    * total number of elements available.
566*e4b17023SJohn Marino    *
567*e4b17023SJohn Marino    * @return End iterator of output sequence.
568*e4b17023SJohn Marino    */
569*e4b17023SJohn Marino   template<typename _LT,
570*e4b17023SJohn Marino 	   typename _RAIterIterator,
571*e4b17023SJohn Marino 	   typename _RAIter3,
572*e4b17023SJohn Marino 	   typename _DifferenceTp, typename _Compare>
573*e4b17023SJohn Marino     _RAIter3
multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin,_RAIterIterator __seqs_end,_RAIter3 __target,const typename std::iterator_traits<typename std::iterator_traits<_RAIterIterator>::value_type::first_type>::value_type & __sentinel,_DifferenceTp __length,_Compare __comp)574*e4b17023SJohn Marino     multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin,
575*e4b17023SJohn Marino 					_RAIterIterator __seqs_end,
576*e4b17023SJohn Marino 					_RAIter3 __target,
577*e4b17023SJohn Marino        const typename std::iterator_traits<typename std::iterator_traits<
578*e4b17023SJohn Marino 	  _RAIterIterator>::value_type::first_type>::value_type&
579*e4b17023SJohn Marino 					__sentinel,
580*e4b17023SJohn Marino 					_DifferenceTp __length,
581*e4b17023SJohn Marino 					_Compare __comp)
582*e4b17023SJohn Marino     {
583*e4b17023SJohn Marino       _GLIBCXX_CALL(__length)
584*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
585*e4b17023SJohn Marino 
586*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
587*e4b17023SJohn Marino 	::difference_type _SeqNumber;
588*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
589*e4b17023SJohn Marino 	::value_type::first_type
590*e4b17023SJohn Marino 	_RAIter1;
591*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIter1>::value_type
592*e4b17023SJohn Marino 	_ValueType;
593*e4b17023SJohn Marino 
594*e4b17023SJohn Marino       _SeqNumber __k = __seqs_end - __seqs_begin;
595*e4b17023SJohn Marino 
596*e4b17023SJohn Marino       _LT __lt(__k, __sentinel, __comp);
597*e4b17023SJohn Marino 
598*e4b17023SJohn Marino       for (_SeqNumber __t = 0; __t < __k; ++__t)
599*e4b17023SJohn Marino 	{
600*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
601*e4b17023SJohn Marino           _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
602*e4b17023SJohn Marino                                    != __seqs_begin[__t].second);
603*e4b17023SJohn Marino #endif
604*e4b17023SJohn Marino           __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
605*e4b17023SJohn Marino 	}
606*e4b17023SJohn Marino 
607*e4b17023SJohn Marino       __lt.__init();
608*e4b17023SJohn Marino 
609*e4b17023SJohn Marino       _SeqNumber __source;
610*e4b17023SJohn Marino 
611*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
612*e4b17023SJohn Marino       _DifferenceType __i = 0;
613*e4b17023SJohn Marino #endif
614*e4b17023SJohn Marino 
615*e4b17023SJohn Marino       _RAIter3 __target_end = __target + __length;
616*e4b17023SJohn Marino       while (__target < __target_end)
617*e4b17023SJohn Marino 	{
618*e4b17023SJohn Marino           // Take out.
619*e4b17023SJohn Marino           __source = __lt.__get_min_source();
620*e4b17023SJohn Marino 
621*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
622*e4b17023SJohn Marino           _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k);
623*e4b17023SJohn Marino           _GLIBCXX_PARALLEL_ASSERT(__i == 0
624*e4b17023SJohn Marino               || !__comp(*(__seqs_begin[__source].first), *(__target - 1)));
625*e4b17023SJohn Marino #endif
626*e4b17023SJohn Marino 
627*e4b17023SJohn Marino           // Feed.
628*e4b17023SJohn Marino           *(__target++) = *(__seqs_begin[__source].first++);
629*e4b17023SJohn Marino 
630*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
631*e4b17023SJohn Marino           ++__i;
632*e4b17023SJohn Marino #endif
633*e4b17023SJohn Marino           // Replace from same __source.
634*e4b17023SJohn Marino           __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
635*e4b17023SJohn Marino 	}
636*e4b17023SJohn Marino 
637*e4b17023SJohn Marino       return __target;
638*e4b17023SJohn Marino     }
639*e4b17023SJohn Marino 
640*e4b17023SJohn Marino 
641*e4b17023SJohn Marino   /** @brief Multi-way merging procedure for a high branching factor,
642*e4b17023SJohn Marino    *         requiring sentinels to exist.
643*e4b17023SJohn Marino    *
644*e4b17023SJohn Marino    * @tparam UnguardedLoserTree _Loser Tree variant to use for the unguarded
645*e4b17023SJohn Marino    *   merging.
646*e4b17023SJohn Marino    *
647*e4b17023SJohn Marino    * @param __seqs_begin Begin iterator of iterator pair input sequence.
648*e4b17023SJohn Marino    * @param __seqs_end End iterator of iterator pair input sequence.
649*e4b17023SJohn Marino    * @param __target Begin iterator of output sequence.
650*e4b17023SJohn Marino    * @param __comp Comparator.
651*e4b17023SJohn Marino    * @param __length Maximum length to merge, less equal than the
652*e4b17023SJohn Marino    * total number of elements available.
653*e4b17023SJohn Marino    *
654*e4b17023SJohn Marino    * @return End iterator of output sequence.
655*e4b17023SJohn Marino    */
656*e4b17023SJohn Marino   template<typename UnguardedLoserTree,
657*e4b17023SJohn Marino 	   typename _RAIterIterator,
658*e4b17023SJohn Marino 	   typename _RAIter3,
659*e4b17023SJohn Marino 	   typename _DifferenceTp,
660*e4b17023SJohn Marino 	   typename _Compare>
661*e4b17023SJohn Marino     _RAIter3
multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin,_RAIterIterator __seqs_end,_RAIter3 __target,const typename std::iterator_traits<typename std::iterator_traits<_RAIterIterator>::value_type::first_type>::value_type & __sentinel,_DifferenceTp __length,_Compare __comp)662*e4b17023SJohn Marino     multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin,
663*e4b17023SJohn Marino 				       _RAIterIterator __seqs_end,
664*e4b17023SJohn Marino 				       _RAIter3 __target,
665*e4b17023SJohn Marino       const typename std::iterator_traits<typename std::iterator_traits<
666*e4b17023SJohn Marino 	_RAIterIterator>::value_type::first_type>::value_type&
667*e4b17023SJohn Marino 				       __sentinel,
668*e4b17023SJohn Marino 				       _DifferenceTp __length,
669*e4b17023SJohn Marino 				       _Compare __comp)
670*e4b17023SJohn Marino     {
671*e4b17023SJohn Marino       _GLIBCXX_CALL(__length)
672*e4b17023SJohn Marino 
673*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
674*e4b17023SJohn Marino       typedef std::iterator_traits<_RAIterIterator> _TraitsType;
675*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
676*e4b17023SJohn Marino 	::value_type::first_type
677*e4b17023SJohn Marino 	_RAIter1;
678*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIter1>::value_type
679*e4b17023SJohn Marino 	_ValueType;
680*e4b17023SJohn Marino 
681*e4b17023SJohn Marino       _RAIter3 __target_end;
682*e4b17023SJohn Marino 
683*e4b17023SJohn Marino       for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
684*e4b17023SJohn Marino 	// Move the sequence ends to the sentinel.  This has the
685*e4b17023SJohn Marino 	// effect that the sentinel appears to be within the sequence. Then,
686*e4b17023SJohn Marino 	// we can use the unguarded variant if we merge out as many
687*e4b17023SJohn Marino 	// non-sentinel elements as we have.
688*e4b17023SJohn Marino 	++((*__s).second);
689*e4b17023SJohn Marino 
690*e4b17023SJohn Marino       __target_end = multiway_merge_loser_tree_unguarded<UnguardedLoserTree>
691*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
692*e4b17023SJohn Marino 
693*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
694*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length);
695*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp));
696*e4b17023SJohn Marino #endif
697*e4b17023SJohn Marino 
698*e4b17023SJohn Marino       // Restore the sequence ends so the sentinels are not contained in the
699*e4b17023SJohn Marino       // sequence any more (see comment in loop above).
700*e4b17023SJohn Marino       for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
701*e4b17023SJohn Marino 	--((*__s).second);
702*e4b17023SJohn Marino 
703*e4b17023SJohn Marino       return __target_end;
704*e4b17023SJohn Marino     }
705*e4b17023SJohn Marino 
706*e4b17023SJohn Marino   /**
707*e4b17023SJohn Marino    * @brief Traits for determining whether the loser tree should
708*e4b17023SJohn Marino    *   use pointers or copies.
709*e4b17023SJohn Marino    *
710*e4b17023SJohn Marino    * The field "_M_use_pointer" is used to determine whether to use pointers
711*e4b17023SJohn Marino    * in he loser trees or whether to copy the values into the loser tree.
712*e4b17023SJohn Marino    *
713*e4b17023SJohn Marino    * The default behavior is to use pointers if the data type is 4 times as
714*e4b17023SJohn Marino    * big as the pointer to it.
715*e4b17023SJohn Marino    *
716*e4b17023SJohn Marino    * Specialize for your data type to customize the behavior.
717*e4b17023SJohn Marino    *
718*e4b17023SJohn Marino    * Example:
719*e4b17023SJohn Marino    *
720*e4b17023SJohn Marino    *   template<>
721*e4b17023SJohn Marino    *   struct _LoserTreeTraits<int>
722*e4b17023SJohn Marino    *   { static const bool _M_use_pointer = false; };
723*e4b17023SJohn Marino    *
724*e4b17023SJohn Marino    *   template<>
725*e4b17023SJohn Marino    *   struct _LoserTreeTraits<heavyweight_type>
726*e4b17023SJohn Marino    *   { static const bool _M_use_pointer = true; };
727*e4b17023SJohn Marino    *
728*e4b17023SJohn Marino    * @param _Tp type to give the loser tree traits for.
729*e4b17023SJohn Marino    */
730*e4b17023SJohn Marino   template <typename _Tp>
731*e4b17023SJohn Marino     struct _LoserTreeTraits
732*e4b17023SJohn Marino     {
733*e4b17023SJohn Marino       /**
734*e4b17023SJohn Marino        * @brief True iff to use pointers instead of values in loser trees.
735*e4b17023SJohn Marino        *
736*e4b17023SJohn Marino        * The default behavior is to use pointers if the data type is four
737*e4b17023SJohn Marino        * times as big as the pointer to it.
738*e4b17023SJohn Marino        */
739*e4b17023SJohn Marino       static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*));
740*e4b17023SJohn Marino     };
741*e4b17023SJohn Marino 
742*e4b17023SJohn Marino   /**
743*e4b17023SJohn Marino    * @brief Switch for 3-way merging with __sentinels turned off.
744*e4b17023SJohn Marino    *
745*e4b17023SJohn Marino    * Note that 3-way merging is always stable!
746*e4b17023SJohn Marino    */
747*e4b17023SJohn Marino   template<bool __sentinels /*default == false*/,
748*e4b17023SJohn Marino 	   typename _RAIterIterator,
749*e4b17023SJohn Marino 	   typename _RAIter3,
750*e4b17023SJohn Marino 	   typename _DifferenceTp,
751*e4b17023SJohn Marino 	   typename _Compare>
752*e4b17023SJohn Marino     struct __multiway_merge_3_variant_sentinel_switch
753*e4b17023SJohn Marino     {
754*e4b17023SJohn Marino       _RAIter3
operator__multiway_merge_3_variant_sentinel_switch755*e4b17023SJohn Marino       operator()(_RAIterIterator __seqs_begin,
756*e4b17023SJohn Marino 		 _RAIterIterator __seqs_end,
757*e4b17023SJohn Marino 		 _RAIter3 __target,
758*e4b17023SJohn Marino 		 _DifferenceTp __length, _Compare __comp)
759*e4b17023SJohn Marino       { return multiway_merge_3_variant<_GuardedIterator>
760*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
761*e4b17023SJohn Marino     };
762*e4b17023SJohn Marino 
763*e4b17023SJohn Marino   /**
764*e4b17023SJohn Marino    * @brief Switch for 3-way merging with __sentinels turned on.
765*e4b17023SJohn Marino    *
766*e4b17023SJohn Marino    * Note that 3-way merging is always stable!
767*e4b17023SJohn Marino    */
768*e4b17023SJohn Marino   template<typename _RAIterIterator,
769*e4b17023SJohn Marino 	   typename _RAIter3,
770*e4b17023SJohn Marino 	   typename _DifferenceTp,
771*e4b17023SJohn Marino 	   typename _Compare>
772*e4b17023SJohn Marino     struct __multiway_merge_3_variant_sentinel_switch<true, _RAIterIterator,
773*e4b17023SJohn Marino 						      _RAIter3, _DifferenceTp,
774*e4b17023SJohn Marino 						      _Compare>
775*e4b17023SJohn Marino     {
776*e4b17023SJohn Marino       _RAIter3
777*e4b17023SJohn Marino       operator()(_RAIterIterator __seqs_begin,
778*e4b17023SJohn Marino 		 _RAIterIterator __seqs_end,
779*e4b17023SJohn Marino 		 _RAIter3 __target,
780*e4b17023SJohn Marino 		 _DifferenceTp __length, _Compare __comp)
781*e4b17023SJohn Marino       { return multiway_merge_3_variant<_UnguardedIterator>
782*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
783*e4b17023SJohn Marino     };
784*e4b17023SJohn Marino 
785*e4b17023SJohn Marino   /**
786*e4b17023SJohn Marino    * @brief Switch for 4-way merging with __sentinels turned off.
787*e4b17023SJohn Marino    *
788*e4b17023SJohn Marino    * Note that 4-way merging is always stable!
789*e4b17023SJohn Marino    */
790*e4b17023SJohn Marino   template<bool __sentinels /*default == false*/,
791*e4b17023SJohn Marino 	   typename _RAIterIterator,
792*e4b17023SJohn Marino 	   typename _RAIter3,
793*e4b17023SJohn Marino 	   typename _DifferenceTp,
794*e4b17023SJohn Marino 	   typename _Compare>
795*e4b17023SJohn Marino     struct __multiway_merge_4_variant_sentinel_switch
796*e4b17023SJohn Marino     {
797*e4b17023SJohn Marino       _RAIter3
798*e4b17023SJohn Marino       operator()(_RAIterIterator __seqs_begin,
799*e4b17023SJohn Marino 		 _RAIterIterator __seqs_end,
800*e4b17023SJohn Marino 		 _RAIter3 __target,
801*e4b17023SJohn Marino 		 _DifferenceTp __length, _Compare __comp)
802*e4b17023SJohn Marino       { return multiway_merge_4_variant<_GuardedIterator>
803*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
804*e4b17023SJohn Marino     };
805*e4b17023SJohn Marino 
806*e4b17023SJohn Marino   /**
807*e4b17023SJohn Marino    * @brief Switch for 4-way merging with __sentinels turned on.
808*e4b17023SJohn Marino    *
809*e4b17023SJohn Marino    * Note that 4-way merging is always stable!
810*e4b17023SJohn Marino    */
811*e4b17023SJohn Marino   template<typename _RAIterIterator,
812*e4b17023SJohn Marino 	   typename _RAIter3,
813*e4b17023SJohn Marino 	   typename _DifferenceTp,
814*e4b17023SJohn Marino 	   typename _Compare>
815*e4b17023SJohn Marino     struct __multiway_merge_4_variant_sentinel_switch<true, _RAIterIterator,
816*e4b17023SJohn Marino 						      _RAIter3, _DifferenceTp,
817*e4b17023SJohn Marino 						      _Compare>
818*e4b17023SJohn Marino     {
819*e4b17023SJohn Marino       _RAIter3
820*e4b17023SJohn Marino       operator()(_RAIterIterator __seqs_begin,
821*e4b17023SJohn Marino 		 _RAIterIterator __seqs_end,
822*e4b17023SJohn Marino 		 _RAIter3 __target,
823*e4b17023SJohn Marino 		 _DifferenceTp __length, _Compare __comp)
824*e4b17023SJohn Marino       { return multiway_merge_4_variant<_UnguardedIterator>
825*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
826*e4b17023SJohn Marino     };
827*e4b17023SJohn Marino 
828*e4b17023SJohn Marino   /**
829*e4b17023SJohn Marino    * @brief Switch for k-way merging with __sentinels turned on.
830*e4b17023SJohn Marino    */
831*e4b17023SJohn Marino   template<bool __sentinels,
832*e4b17023SJohn Marino 	   bool __stable,
833*e4b17023SJohn Marino 	   typename _RAIterIterator,
834*e4b17023SJohn Marino 	   typename _RAIter3,
835*e4b17023SJohn Marino 	   typename _DifferenceTp,
836*e4b17023SJohn Marino 	   typename _Compare>
837*e4b17023SJohn Marino     struct __multiway_merge_k_variant_sentinel_switch
838*e4b17023SJohn Marino     {
839*e4b17023SJohn Marino       _RAIter3
840*e4b17023SJohn Marino       operator()(_RAIterIterator __seqs_begin,
841*e4b17023SJohn Marino 		 _RAIterIterator __seqs_end,
842*e4b17023SJohn Marino 		 _RAIter3 __target,
843*e4b17023SJohn Marino       const typename std::iterator_traits<typename std::iterator_traits<
844*e4b17023SJohn Marino       _RAIterIterator>::value_type::first_type>::value_type&
845*e4b17023SJohn Marino 		 __sentinel,
846*e4b17023SJohn Marino 		 _DifferenceTp __length, _Compare __comp)
847*e4b17023SJohn Marino       {
848*e4b17023SJohn Marino 	typedef typename std::iterator_traits<_RAIterIterator>
849*e4b17023SJohn Marino 	  ::value_type::first_type
850*e4b17023SJohn Marino 	  _RAIter1;
851*e4b17023SJohn Marino 	typedef typename std::iterator_traits<_RAIter1>::value_type
852*e4b17023SJohn Marino 	  _ValueType;
853*e4b17023SJohn Marino 
854*e4b17023SJohn Marino 	return multiway_merge_loser_tree_sentinel<
855*e4b17023SJohn Marino 	typename __gnu_cxx::__conditional_type<
856*e4b17023SJohn Marino 	_LoserTreeTraits<_ValueType>::_M_use_pointer,
857*e4b17023SJohn Marino 	  _LoserTreePointerUnguarded<__stable, _ValueType, _Compare>,
858*e4b17023SJohn Marino 	  _LoserTreeUnguarded<__stable, _ValueType, _Compare>
859*e4b17023SJohn Marino           >::__type>
860*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
861*e4b17023SJohn Marino       }
862*e4b17023SJohn Marino     };
863*e4b17023SJohn Marino 
864*e4b17023SJohn Marino   /**
865*e4b17023SJohn Marino    * @brief Switch for k-way merging with __sentinels turned off.
866*e4b17023SJohn Marino    */
867*e4b17023SJohn Marino   template<bool __stable,
868*e4b17023SJohn Marino 	   typename _RAIterIterator,
869*e4b17023SJohn Marino 	   typename _RAIter3,
870*e4b17023SJohn Marino 	   typename _DifferenceTp,
871*e4b17023SJohn Marino 	   typename _Compare>
872*e4b17023SJohn Marino     struct __multiway_merge_k_variant_sentinel_switch<false, __stable,
873*e4b17023SJohn Marino 						      _RAIterIterator,
874*e4b17023SJohn Marino 						      _RAIter3, _DifferenceTp,
875*e4b17023SJohn Marino 						      _Compare>
876*e4b17023SJohn Marino     {
877*e4b17023SJohn Marino       _RAIter3
878*e4b17023SJohn Marino       operator()(_RAIterIterator __seqs_begin,
879*e4b17023SJohn Marino 		 _RAIterIterator __seqs_end,
880*e4b17023SJohn Marino 		 _RAIter3 __target,
881*e4b17023SJohn Marino        const typename std::iterator_traits<typename std::iterator_traits<
882*e4b17023SJohn Marino        _RAIterIterator>::value_type::first_type>::value_type&
883*e4b17023SJohn Marino 		 __sentinel,
884*e4b17023SJohn Marino 		 _DifferenceTp __length, _Compare __comp)
885*e4b17023SJohn Marino       {
886*e4b17023SJohn Marino 	typedef typename std::iterator_traits<_RAIterIterator>
887*e4b17023SJohn Marino 	  ::value_type::first_type
888*e4b17023SJohn Marino 	  _RAIter1;
889*e4b17023SJohn Marino 	typedef typename std::iterator_traits<_RAIter1>::value_type
890*e4b17023SJohn Marino 	  _ValueType;
891*e4b17023SJohn Marino 
892*e4b17023SJohn Marino 	return multiway_merge_loser_tree<
893*e4b17023SJohn Marino 	typename __gnu_cxx::__conditional_type<
894*e4b17023SJohn Marino 	_LoserTreeTraits<_ValueType>::_M_use_pointer,
895*e4b17023SJohn Marino 	  _LoserTreePointer<__stable, _ValueType, _Compare>,
896*e4b17023SJohn Marino 	  _LoserTree<__stable, _ValueType, _Compare>
897*e4b17023SJohn Marino           >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp);
898*e4b17023SJohn Marino       }
899*e4b17023SJohn Marino     };
900*e4b17023SJohn Marino 
901*e4b17023SJohn Marino   /** @brief Sequential multi-way merging switch.
902*e4b17023SJohn Marino    *
903*e4b17023SJohn Marino    *  The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and
904*e4b17023SJohn Marino    *  runtime settings.
905*e4b17023SJohn Marino    *  @param __seqs_begin Begin iterator of iterator pair input sequence.
906*e4b17023SJohn Marino    *  @param __seqs_end End iterator of iterator pair input sequence.
907*e4b17023SJohn Marino    *  @param __target Begin iterator of output sequence.
908*e4b17023SJohn Marino    *  @param __comp Comparator.
909*e4b17023SJohn Marino    *  @param __length Maximum length to merge, possibly larger than the
910*e4b17023SJohn Marino    *  number of elements available.
911*e4b17023SJohn Marino    *  @param __sentinel The sequences have __a __sentinel element.
912*e4b17023SJohn Marino    *  @return End iterator of output sequence. */
913*e4b17023SJohn Marino   template<bool __stable,
914*e4b17023SJohn Marino 	   bool __sentinels,
915*e4b17023SJohn Marino 	   typename _RAIterIterator,
916*e4b17023SJohn Marino 	   typename _RAIter3,
917*e4b17023SJohn Marino 	   typename _DifferenceTp,
918*e4b17023SJohn Marino 	   typename _Compare>
919*e4b17023SJohn Marino     _RAIter3
920*e4b17023SJohn Marino     __sequential_multiway_merge(_RAIterIterator __seqs_begin,
921*e4b17023SJohn Marino 				_RAIterIterator __seqs_end,
922*e4b17023SJohn Marino 				_RAIter3 __target,
923*e4b17023SJohn Marino       const typename std::iterator_traits<typename std::iterator_traits<
924*e4b17023SJohn Marino 	_RAIterIterator>::value_type::first_type>::value_type&
925*e4b17023SJohn Marino 				__sentinel,
926*e4b17023SJohn Marino 				_DifferenceTp __length, _Compare __comp)
927*e4b17023SJohn Marino     {
928*e4b17023SJohn Marino       _GLIBCXX_CALL(__length)
929*e4b17023SJohn Marino 
930*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
931*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
932*e4b17023SJohn Marino 	::difference_type _SeqNumber;
933*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
934*e4b17023SJohn Marino 	::value_type::first_type
935*e4b17023SJohn Marino 	_RAIter1;
936*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIter1>::value_type
937*e4b17023SJohn Marino 	_ValueType;
938*e4b17023SJohn Marino 
939*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
940*e4b17023SJohn Marino       for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
941*e4b17023SJohn Marino 	{
942*e4b17023SJohn Marino           _GLIBCXX_PARALLEL_ASSERT(__is_sorted((*__s).first,
943*e4b17023SJohn Marino 					       (*__s).second, __comp));
944*e4b17023SJohn Marino 	}
945*e4b17023SJohn Marino #endif
946*e4b17023SJohn Marino 
947*e4b17023SJohn Marino       _DifferenceTp __total_length = 0;
948*e4b17023SJohn Marino       for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
949*e4b17023SJohn Marino 	__total_length += _GLIBCXX_PARALLEL_LENGTH(*__s);
950*e4b17023SJohn Marino 
951*e4b17023SJohn Marino       __length = std::min<_DifferenceTp>(__length, __total_length);
952*e4b17023SJohn Marino 
953*e4b17023SJohn Marino       if(__length == 0)
954*e4b17023SJohn Marino 	return __target;
955*e4b17023SJohn Marino 
956*e4b17023SJohn Marino       _RAIter3 __return_target = __target;
957*e4b17023SJohn Marino       _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
958*e4b17023SJohn Marino 
959*e4b17023SJohn Marino       switch (__k)
960*e4b17023SJohn Marino 	{
961*e4b17023SJohn Marino 	case 0:
962*e4b17023SJohn Marino           break;
963*e4b17023SJohn Marino 	case 1:
964*e4b17023SJohn Marino           __return_target = std::copy(__seqs_begin[0].first,
965*e4b17023SJohn Marino 				      __seqs_begin[0].first + __length,
966*e4b17023SJohn Marino 				      __target);
967*e4b17023SJohn Marino           __seqs_begin[0].first += __length;
968*e4b17023SJohn Marino           break;
969*e4b17023SJohn Marino 	case 2:
970*e4b17023SJohn Marino           __return_target = __merge_advance(__seqs_begin[0].first,
971*e4b17023SJohn Marino 					    __seqs_begin[0].second,
972*e4b17023SJohn Marino 					    __seqs_begin[1].first,
973*e4b17023SJohn Marino 					    __seqs_begin[1].second,
974*e4b17023SJohn Marino 					    __target, __length, __comp);
975*e4b17023SJohn Marino           break;
976*e4b17023SJohn Marino 	case 3:
977*e4b17023SJohn Marino           __return_target = __multiway_merge_3_variant_sentinel_switch
978*e4b17023SJohn Marino 	    <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
979*e4b17023SJohn Marino 	    (__seqs_begin, __seqs_end, __target, __length, __comp);
980*e4b17023SJohn Marino           break;
981*e4b17023SJohn Marino 	case 4:
982*e4b17023SJohn Marino           __return_target = __multiway_merge_4_variant_sentinel_switch
983*e4b17023SJohn Marino 	    <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
984*e4b17023SJohn Marino 	    (__seqs_begin, __seqs_end, __target, __length, __comp);
985*e4b17023SJohn Marino           break;
986*e4b17023SJohn Marino 	default:
987*e4b17023SJohn Marino 	  __return_target = __multiway_merge_k_variant_sentinel_switch
988*e4b17023SJohn Marino 	    <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp,
989*e4b17023SJohn Marino 	     _Compare>()
990*e4b17023SJohn Marino 	    (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
991*e4b17023SJohn Marino 	  break;
992*e4b17023SJohn Marino 	}
993*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
994*e4b17023SJohn Marino       _GLIBCXX_PARALLEL_ASSERT(
995*e4b17023SJohn Marino 	__is_sorted(__target, __target + __length, __comp));
996*e4b17023SJohn Marino #endif
997*e4b17023SJohn Marino 
998*e4b17023SJohn Marino       return __return_target;
999*e4b17023SJohn Marino     }
1000*e4b17023SJohn Marino 
1001*e4b17023SJohn Marino   /**
1002*e4b17023SJohn Marino    * @brief Stable sorting functor.
1003*e4b17023SJohn Marino    *
1004*e4b17023SJohn Marino    * Used to reduce code instanciation in multiway_merge_sampling_splitting.
1005*e4b17023SJohn Marino    */
1006*e4b17023SJohn Marino   template<bool __stable, class _RAIter, class _StrictWeakOrdering>
1007*e4b17023SJohn Marino     struct _SamplingSorter
1008*e4b17023SJohn Marino     {
1009*e4b17023SJohn Marino       void
1010*e4b17023SJohn Marino       operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1011*e4b17023SJohn Marino       { __gnu_sequential::stable_sort(__first, __last, __comp); }
1012*e4b17023SJohn Marino     };
1013*e4b17023SJohn Marino 
1014*e4b17023SJohn Marino   /**
1015*e4b17023SJohn Marino    * @brief Non-__stable sorting functor.
1016*e4b17023SJohn Marino    *
1017*e4b17023SJohn Marino    * Used to reduce code instantiation in multiway_merge_sampling_splitting.
1018*e4b17023SJohn Marino    */
1019*e4b17023SJohn Marino   template<class _RAIter, class _StrictWeakOrdering>
1020*e4b17023SJohn Marino     struct _SamplingSorter<false, _RAIter, _StrictWeakOrdering>
1021*e4b17023SJohn Marino     {
1022*e4b17023SJohn Marino       void
1023*e4b17023SJohn Marino       operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
1024*e4b17023SJohn Marino       { __gnu_sequential::sort(__first, __last, __comp); }
1025*e4b17023SJohn Marino     };
1026*e4b17023SJohn Marino 
1027*e4b17023SJohn Marino   /**
1028*e4b17023SJohn Marino    * @brief Sampling based splitting for parallel multiway-merge routine.
1029*e4b17023SJohn Marino    */
1030*e4b17023SJohn Marino   template<bool __stable,
1031*e4b17023SJohn Marino 	   typename _RAIterIterator,
1032*e4b17023SJohn Marino 	   typename _Compare,
1033*e4b17023SJohn Marino 	   typename _DifferenceType>
1034*e4b17023SJohn Marino     void
1035*e4b17023SJohn Marino     multiway_merge_sampling_splitting(_RAIterIterator __seqs_begin,
1036*e4b17023SJohn Marino 				      _RAIterIterator __seqs_end,
1037*e4b17023SJohn Marino 				      _DifferenceType __length,
1038*e4b17023SJohn Marino 				      _DifferenceType __total_length,
1039*e4b17023SJohn Marino 				      _Compare __comp,
1040*e4b17023SJohn Marino      std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
1041*e4b17023SJohn Marino     {
1042*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
1043*e4b17023SJohn Marino 	::difference_type _SeqNumber;
1044*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
1045*e4b17023SJohn Marino 	::value_type::first_type
1046*e4b17023SJohn Marino 	_RAIter1;
1047*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIter1>::value_type
1048*e4b17023SJohn Marino 	_ValueType;
1049*e4b17023SJohn Marino 
1050*e4b17023SJohn Marino       // __k sequences.
1051*e4b17023SJohn Marino       const _SeqNumber __k
1052*e4b17023SJohn Marino 	= static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
1053*e4b17023SJohn Marino 
1054*e4b17023SJohn Marino       const _ThreadIndex __num_threads = omp_get_num_threads();
1055*e4b17023SJohn Marino 
1056*e4b17023SJohn Marino       const _DifferenceType __num_samples =
1057*e4b17023SJohn Marino 	__gnu_parallel::_Settings::get().merge_oversampling * __num_threads;
1058*e4b17023SJohn Marino 
1059*e4b17023SJohn Marino       _ValueType* __samples = static_cast<_ValueType*>
1060*e4b17023SJohn Marino 	(::operator new(sizeof(_ValueType) * __k * __num_samples));
1061*e4b17023SJohn Marino       // Sample.
1062*e4b17023SJohn Marino       for (_SeqNumber __s = 0; __s < __k; ++__s)
1063*e4b17023SJohn Marino 	for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
1064*e4b17023SJohn Marino 	  {
1065*e4b17023SJohn Marino 	    _DifferenceType sample_index = static_cast<_DifferenceType>
1066*e4b17023SJohn Marino 	      (_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s])
1067*e4b17023SJohn Marino 	       * (double(__i + 1) / (__num_samples + 1))
1068*e4b17023SJohn Marino 	       * (double(__length) / __total_length));
1069*e4b17023SJohn Marino 	    new(&(__samples[__s * __num_samples + __i]))
1070*e4b17023SJohn Marino               _ValueType(__seqs_begin[__s].first[sample_index]);
1071*e4b17023SJohn Marino 	  }
1072*e4b17023SJohn Marino 
1073*e4b17023SJohn Marino       // Sort stable or non-stable, depending on value of template parameter
1074*e4b17023SJohn Marino       // "__stable".
1075*e4b17023SJohn Marino       _SamplingSorter<__stable, _ValueType*, _Compare>()
1076*e4b17023SJohn Marino 	(__samples, __samples + (__num_samples * __k), __comp);
1077*e4b17023SJohn Marino 
1078*e4b17023SJohn Marino       for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1079*e4b17023SJohn Marino 	// For each slab / processor.
1080*e4b17023SJohn Marino 	for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1081*e4b17023SJohn Marino 	  {
1082*e4b17023SJohn Marino 	    // For each sequence.
1083*e4b17023SJohn Marino 	    if (__slab > 0)
1084*e4b17023SJohn Marino 	      __pieces[__slab][__seq].first = std::upper_bound
1085*e4b17023SJohn Marino 		(__seqs_begin[__seq].first, __seqs_begin[__seq].second,
1086*e4b17023SJohn Marino 		 __samples[__num_samples * __k * __slab / __num_threads],
1087*e4b17023SJohn Marino 		 __comp)
1088*e4b17023SJohn Marino 		- __seqs_begin[__seq].first;
1089*e4b17023SJohn Marino 	    else
1090*e4b17023SJohn Marino 	      // Absolute beginning.
1091*e4b17023SJohn Marino 	      __pieces[__slab][__seq].first = 0;
1092*e4b17023SJohn Marino 	    if ((__slab + 1) < __num_threads)
1093*e4b17023SJohn Marino 	      __pieces[__slab][__seq].second = std::upper_bound
1094*e4b17023SJohn Marino 		(__seqs_begin[__seq].first, __seqs_begin[__seq].second,
1095*e4b17023SJohn Marino 		 __samples[__num_samples * __k * (__slab + 1) / __num_threads],
1096*e4b17023SJohn Marino 		 __comp)
1097*e4b17023SJohn Marino 		- __seqs_begin[__seq].first;
1098*e4b17023SJohn Marino 	    else
1099*e4b17023SJohn Marino               // Absolute end.
1100*e4b17023SJohn Marino 	      __pieces[__slab][__seq].second =
1101*e4b17023SJohn Marino 		_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
1102*e4b17023SJohn Marino 	  }
1103*e4b17023SJohn Marino 
1104*e4b17023SJohn Marino       for (_SeqNumber __s = 0; __s < __k; ++__s)
1105*e4b17023SJohn Marino 	for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
1106*e4b17023SJohn Marino 	  __samples[__s * __num_samples + __i].~_ValueType();
1107*e4b17023SJohn Marino       ::operator delete(__samples);
1108*e4b17023SJohn Marino     }
1109*e4b17023SJohn Marino 
1110*e4b17023SJohn Marino   /**
1111*e4b17023SJohn Marino    * @brief Exact splitting for parallel multiway-merge routine.
1112*e4b17023SJohn Marino    *
1113*e4b17023SJohn Marino    * None of the passed sequences may be empty.
1114*e4b17023SJohn Marino    */
1115*e4b17023SJohn Marino   template<bool __stable,
1116*e4b17023SJohn Marino 	   typename _RAIterIterator,
1117*e4b17023SJohn Marino 	   typename _Compare,
1118*e4b17023SJohn Marino 	   typename _DifferenceType>
1119*e4b17023SJohn Marino     void
1120*e4b17023SJohn Marino     multiway_merge_exact_splitting(_RAIterIterator __seqs_begin,
1121*e4b17023SJohn Marino 				   _RAIterIterator __seqs_end,
1122*e4b17023SJohn Marino 				   _DifferenceType __length,
1123*e4b17023SJohn Marino 				   _DifferenceType __total_length,
1124*e4b17023SJohn Marino 				   _Compare __comp,
1125*e4b17023SJohn Marino        std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
1126*e4b17023SJohn Marino     {
1127*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
1128*e4b17023SJohn Marino 	::difference_type _SeqNumber;
1129*e4b17023SJohn Marino       typedef typename std::iterator_traits<_RAIterIterator>
1130*e4b17023SJohn Marino 	::value_type::first_type
1131*e4b17023SJohn Marino 	_RAIter1;
1132*e4b17023SJohn Marino 
1133*e4b17023SJohn Marino       const bool __tight = (__total_length == __length);
1134*e4b17023SJohn Marino 
1135*e4b17023SJohn Marino       // __k sequences.
1136*e4b17023SJohn Marino       const _SeqNumber __k = __seqs_end - __seqs_begin;
1137*e4b17023SJohn Marino 
1138*e4b17023SJohn Marino       const _ThreadIndex __num_threads = omp_get_num_threads();
1139*e4b17023SJohn Marino 
1140*e4b17023SJohn Marino       // (Settings::multiway_merge_splitting
1141*e4b17023SJohn Marino       //  == __gnu_parallel::_Settings::EXACT).
1142*e4b17023SJohn Marino       std::vector<_RAIter1>* __offsets =
1143*e4b17023SJohn Marino 	new std::vector<_RAIter1>[__num_threads];
1144*e4b17023SJohn Marino       std::vector<std::pair<_RAIter1, _RAIter1> > __se(__k);
1145*e4b17023SJohn Marino 
1146*e4b17023SJohn Marino       copy(__seqs_begin, __seqs_end, __se.begin());
1147*e4b17023SJohn Marino 
1148*e4b17023SJohn Marino       _DifferenceType* __borders =
1149*e4b17023SJohn Marino 	new _DifferenceType[__num_threads + 1];
1150*e4b17023SJohn Marino       __equally_split(__length, __num_threads, __borders);
1151*e4b17023SJohn Marino 
1152*e4b17023SJohn Marino       for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s)
1153*e4b17023SJohn Marino 	{
1154*e4b17023SJohn Marino 	  __offsets[__s].resize(__k);
1155*e4b17023SJohn Marino 	  multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1],
1156*e4b17023SJohn Marino 			     __offsets[__s].begin(), __comp);
1157*e4b17023SJohn Marino 
1158*e4b17023SJohn Marino 	  // Last one also needed and available.
1159*e4b17023SJohn Marino 	  if (!__tight)
1160*e4b17023SJohn Marino 	    {
1161*e4b17023SJohn Marino 	      __offsets[__num_threads - 1].resize(__k);
1162*e4b17023SJohn Marino 	      multiseq_partition(__se.begin(), __se.end(),
1163*e4b17023SJohn Marino 				 _DifferenceType(__length),
1164*e4b17023SJohn Marino 				 __offsets[__num_threads - 1].begin(),
1165*e4b17023SJohn Marino 				 __comp);
1166*e4b17023SJohn Marino 	    }
1167*e4b17023SJohn Marino 	}
1168*e4b17023SJohn Marino       delete[] __borders;
1169*e4b17023SJohn Marino 
1170*e4b17023SJohn Marino       for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
1171*e4b17023SJohn Marino 	{
1172*e4b17023SJohn Marino 	  // For each slab / processor.
1173*e4b17023SJohn Marino 	  for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
1174*e4b17023SJohn Marino 	    {
1175*e4b17023SJohn Marino 	      // For each sequence.
1176*e4b17023SJohn Marino 	      if (__slab == 0)
1177*e4b17023SJohn Marino 		{
1178*e4b17023SJohn Marino 		  // Absolute beginning.
1179*e4b17023SJohn Marino 		  __pieces[__slab][__seq].first = 0;
1180*e4b17023SJohn Marino 		}
1181*e4b17023SJohn Marino 	      else
1182*e4b17023SJohn Marino 		__pieces[__slab][__seq].first =
1183*e4b17023SJohn Marino 		  __pieces[__slab - 1][__seq].second;
1184*e4b17023SJohn Marino 	      if (!__tight || __slab < (__num_threads - 1))
1185*e4b17023SJohn Marino 		__pieces[__slab][__seq].second =
1186*e4b17023SJohn Marino 		  __offsets[__slab][__seq] - __seqs_begin[__seq].first;
1187*e4b17023SJohn Marino 	      else
1188*e4b17023SJohn Marino 		{
1189*e4b17023SJohn Marino 		  // __slab == __num_threads - 1
1190*e4b17023SJohn Marino 		  __pieces[__slab][__seq].second =
1191*e4b17023SJohn Marino                     _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
1192*e4b17023SJohn Marino 		}
1193*e4b17023SJohn Marino 	    }
1194*e4b17023SJohn Marino 	}
1195*e4b17023SJohn Marino       delete[] __offsets;
1196*e4b17023SJohn Marino     }
1197*e4b17023SJohn Marino 
1198*e4b17023SJohn Marino   /** @brief Parallel multi-way merge routine.
1199*e4b17023SJohn Marino    *
1200*e4b17023SJohn Marino    * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor
1201*e4b17023SJohn Marino    * and runtime settings.
1202*e4b17023SJohn Marino    *
1203*e4b17023SJohn Marino    * Must not be called if the number of sequences is 1.
1204*e4b17023SJohn Marino    *
1205*e4b17023SJohn Marino    * @tparam _Splitter functor to split input (either __exact or sampling based)
1206*e4b17023SJohn Marino    * @tparam __stable Stable merging incurs a performance penalty.
1207*e4b17023SJohn Marino    * @tparam __sentinel Ignored.
1208*e4b17023SJohn Marino    *
1209*e4b17023SJohn Marino    * @param __seqs_begin Begin iterator of iterator pair input sequence.
1210*e4b17023SJohn Marino    * @param __seqs_end End iterator of iterator pair input sequence.
1211*e4b17023SJohn Marino    * @param __target Begin iterator of output sequence.
1212*e4b17023SJohn Marino    * @param __comp Comparator.
1213*e4b17023SJohn Marino    * @param __length Maximum length to merge, possibly larger than the
1214*e4b17023SJohn Marino    * number of elements available.
1215*e4b17023SJohn Marino    * @return End iterator of output sequence.
1216*e4b17023SJohn Marino    */
1217*e4b17023SJohn Marino   template<bool __stable,
1218*e4b17023SJohn Marino 	   bool __sentinels,
1219*e4b17023SJohn Marino 	   typename _RAIterIterator,
1220*e4b17023SJohn Marino 	   typename _RAIter3,
1221*e4b17023SJohn Marino 	   typename _DifferenceTp,
1222*e4b17023SJohn Marino 	   typename _Splitter,
1223*e4b17023SJohn Marino 	   typename _Compare>
1224*e4b17023SJohn Marino     _RAIter3
1225*e4b17023SJohn Marino     parallel_multiway_merge(_RAIterIterator __seqs_begin,
1226*e4b17023SJohn Marino                             _RAIterIterator __seqs_end,
1227*e4b17023SJohn Marino                             _RAIter3 __target,
1228*e4b17023SJohn Marino                             _Splitter __splitter,
1229*e4b17023SJohn Marino                             _DifferenceTp __length,
1230*e4b17023SJohn Marino                             _Compare __comp,
1231*e4b17023SJohn Marino                             _ThreadIndex __num_threads)
1232*e4b17023SJohn Marino       {
1233*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
1234*e4b17023SJohn Marino 	_GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1);
1235*e4b17023SJohn Marino #endif
1236*e4b17023SJohn Marino 
1237*e4b17023SJohn Marino 	_GLIBCXX_CALL(__length)
1238*e4b17023SJohn Marino 
1239*e4b17023SJohn Marino 	typedef _DifferenceTp _DifferenceType;
1240*e4b17023SJohn Marino         typedef typename std::iterator_traits<_RAIterIterator>
1241*e4b17023SJohn Marino 	  ::difference_type _SeqNumber;
1242*e4b17023SJohn Marino 	typedef typename std::iterator_traits<_RAIterIterator>
1243*e4b17023SJohn Marino           ::value_type::first_type
1244*e4b17023SJohn Marino           _RAIter1;
1245*e4b17023SJohn Marino 	typedef typename
1246*e4b17023SJohn Marino           std::iterator_traits<_RAIter1>::value_type _ValueType;
1247*e4b17023SJohn Marino 
1248*e4b17023SJohn Marino 	// Leave only non-empty sequences.
1249*e4b17023SJohn Marino 	typedef std::pair<_RAIter1, _RAIter1> seq_type;
1250*e4b17023SJohn Marino 	seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin];
1251*e4b17023SJohn Marino 	_SeqNumber __k = 0;
1252*e4b17023SJohn Marino 	_DifferenceType __total_length = 0;
1253*e4b17023SJohn Marino 	for (_RAIterIterator __raii = __seqs_begin;
1254*e4b17023SJohn Marino              __raii != __seqs_end; ++__raii)
1255*e4b17023SJohn Marino           {
1256*e4b17023SJohn Marino             _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
1257*e4b17023SJohn Marino             if(__seq_length > 0)
1258*e4b17023SJohn Marino               {
1259*e4b17023SJohn Marino         	__total_length += __seq_length;
1260*e4b17023SJohn Marino         	__ne_seqs[__k++] = *__raii;
1261*e4b17023SJohn Marino               }
1262*e4b17023SJohn Marino           }
1263*e4b17023SJohn Marino 
1264*e4b17023SJohn Marino 	_GLIBCXX_CALL(__total_length)
1265*e4b17023SJohn Marino 
1266*e4b17023SJohn Marino 	__length = std::min<_DifferenceTp>(__length, __total_length);
1267*e4b17023SJohn Marino 
1268*e4b17023SJohn Marino 	if (__total_length == 0 || __k == 0)
1269*e4b17023SJohn Marino 	  {
1270*e4b17023SJohn Marino 	    delete[] __ne_seqs;
1271*e4b17023SJohn Marino 	    return __target;
1272*e4b17023SJohn Marino 	  }
1273*e4b17023SJohn Marino 
1274*e4b17023SJohn Marino 	std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;
1275*e4b17023SJohn Marino 
1276*e4b17023SJohn Marino 	__num_threads = static_cast<_ThreadIndex>
1277*e4b17023SJohn Marino           (std::min<_DifferenceType>(__num_threads, __total_length));
1278*e4b17023SJohn Marino 
1279*e4b17023SJohn Marino #       pragma omp parallel num_threads (__num_threads)
1280*e4b17023SJohn Marino 	{
1281*e4b17023SJohn Marino #         pragma omp single
1282*e4b17023SJohn Marino 	  {
1283*e4b17023SJohn Marino 	    __num_threads = omp_get_num_threads();
1284*e4b17023SJohn Marino 	    // Thread __t will have to merge pieces[__iam][0..__k - 1]
1285*e4b17023SJohn Marino 	    __pieces = new std::vector<
1286*e4b17023SJohn Marino 	    std::pair<_DifferenceType, _DifferenceType> >[__num_threads];
1287*e4b17023SJohn Marino 	    for (_ThreadIndex __s = 0; __s < __num_threads; ++__s)
1288*e4b17023SJohn Marino 	      __pieces[__s].resize(__k);
1289*e4b17023SJohn Marino 
1290*e4b17023SJohn Marino 	    _DifferenceType __num_samples =
1291*e4b17023SJohn Marino 	      __gnu_parallel::_Settings::get().merge_oversampling
1292*e4b17023SJohn Marino 	      * __num_threads;
1293*e4b17023SJohn Marino 
1294*e4b17023SJohn Marino 	    __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length,
1295*e4b17023SJohn Marino 		       __comp, __pieces);
1296*e4b17023SJohn Marino 	  } //single
1297*e4b17023SJohn Marino 
1298*e4b17023SJohn Marino 	  _ThreadIndex __iam = omp_get_thread_num();
1299*e4b17023SJohn Marino 
1300*e4b17023SJohn Marino 	  _DifferenceType __target_position = 0;
1301*e4b17023SJohn Marino 
1302*e4b17023SJohn Marino 	  for (_SeqNumber __c = 0; __c < __k; ++__c)
1303*e4b17023SJohn Marino 	    __target_position += __pieces[__iam][__c].first;
1304*e4b17023SJohn Marino 
1305*e4b17023SJohn Marino 	  seq_type* __chunks = new seq_type[__k];
1306*e4b17023SJohn Marino 
1307*e4b17023SJohn Marino 	  for (_SeqNumber __s = 0; __s < __k; ++__s)
1308*e4b17023SJohn Marino 	    __chunks[__s] = std::make_pair(__ne_seqs[__s].first
1309*e4b17023SJohn Marino 					   + __pieces[__iam][__s].first,
1310*e4b17023SJohn Marino 					   __ne_seqs[__s].first
1311*e4b17023SJohn Marino 					   + __pieces[__iam][__s].second);
1312*e4b17023SJohn Marino 
1313*e4b17023SJohn Marino 	  if(__length > __target_position)
1314*e4b17023SJohn Marino 	    __sequential_multiway_merge<__stable, __sentinels>
1315*e4b17023SJohn Marino 	      (__chunks, __chunks + __k, __target + __target_position,
1316*e4b17023SJohn Marino 	       *(__seqs_begin->second), __length - __target_position, __comp);
1317*e4b17023SJohn Marino 
1318*e4b17023SJohn Marino 	  delete[] __chunks;
1319*e4b17023SJohn Marino 	} // parallel
1320*e4b17023SJohn Marino 
1321*e4b17023SJohn Marino #if _GLIBCXX_ASSERTIONS
1322*e4b17023SJohn Marino 	_GLIBCXX_PARALLEL_ASSERT(
1323*e4b17023SJohn Marino           __is_sorted(__target, __target + __length, __comp));
1324*e4b17023SJohn Marino #endif
1325*e4b17023SJohn Marino 
1326*e4b17023SJohn Marino 	__k = 0;
1327*e4b17023SJohn Marino 	// Update ends of sequences.
1328*e4b17023SJohn Marino 	for (_RAIterIterator __raii = __seqs_begin;
1329*e4b17023SJohn Marino              __raii != __seqs_end; ++__raii)
1330*e4b17023SJohn Marino           {
1331*e4b17023SJohn Marino             _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
1332*e4b17023SJohn Marino             if(__length > 0)
1333*e4b17023SJohn Marino               (*__raii).first += __pieces[__num_threads - 1][__k++].second;
1334*e4b17023SJohn Marino           }
1335*e4b17023SJohn Marino 
1336*e4b17023SJohn Marino 	delete[] __pieces;
1337*e4b17023SJohn Marino 	delete[] __ne_seqs;
1338*e4b17023SJohn Marino 
1339*e4b17023SJohn Marino 	return __target + __length;
1340*e4b17023SJohn Marino       }
1341*e4b17023SJohn Marino 
1342*e4b17023SJohn Marino   /**
1343*e4b17023SJohn Marino    * @brief Multiway Merge Frontend.
1344*e4b17023SJohn Marino    *
1345*e4b17023SJohn Marino    * Merge the sequences specified by seqs_begin and __seqs_end into
1346*e4b17023SJohn Marino    * __target.  __seqs_begin and __seqs_end must point to a sequence of
1347*e4b17023SJohn Marino    * pairs.  These pairs must contain an iterator to the beginning
1348*e4b17023SJohn Marino    * of a sequence in their first entry and an iterator the _M_end of
1349*e4b17023SJohn Marino    * the same sequence in their second entry.
1350*e4b17023SJohn Marino    *
1351*e4b17023SJohn Marino    * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
1352*e4b17023SJohn Marino    * that breaks ties by sequence number but is slower.
1353*e4b17023SJohn Marino    *
1354*e4b17023SJohn Marino    * The first entries of the pairs (i.e. the begin iterators) will be moved
1355*e4b17023SJohn Marino    * forward.
1356*e4b17023SJohn Marino    *
1357*e4b17023SJohn Marino    * The output sequence has to provide enough space for all elements
1358*e4b17023SJohn Marino    * that are written to it.
1359*e4b17023SJohn Marino    *
1360*e4b17023SJohn Marino    * This function will merge the input sequences:
1361*e4b17023SJohn Marino    *
1362*e4b17023SJohn Marino    * - not stable
1363*e4b17023SJohn Marino    * - parallel, depending on the input size and Settings
1364*e4b17023SJohn Marino    * - using sampling for splitting
1365*e4b17023SJohn Marino    * - not using sentinels
1366*e4b17023SJohn Marino    *
1367*e4b17023SJohn Marino    * Example:
1368*e4b17023SJohn Marino    *
1369*e4b17023SJohn Marino    * <pre>
1370*e4b17023SJohn Marino    *   int sequences[10][10];
1371*e4b17023SJohn Marino    *   for (int __i = 0; __i < 10; ++__i)
1372*e4b17023SJohn Marino    *     for (int __j = 0; __i < 10; ++__j)
1373*e4b17023SJohn Marino    *       sequences[__i][__j] = __j;
1374*e4b17023SJohn Marino    *
1375*e4b17023SJohn Marino    *   int __out[33];
1376*e4b17023SJohn Marino    *   std::vector<std::pair<int*> > seqs;
1377*e4b17023SJohn Marino    *   for (int __i = 0; __i < 10; ++__i)
1378*e4b17023SJohn Marino    *     { seqs.push(std::make_pair<int*>(sequences[__i],
1379*e4b17023SJohn Marino    *                                      sequences[__i] + 10)) }
1380*e4b17023SJohn Marino    *
1381*e4b17023SJohn Marino    *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
1382*e4b17023SJohn Marino    * </pre>
1383*e4b17023SJohn Marino    *
1384*e4b17023SJohn Marino    * @see stable_multiway_merge
1385*e4b17023SJohn Marino    *
1386*e4b17023SJohn Marino    * @pre All input sequences must be sorted.
1387*e4b17023SJohn Marino    * @pre Target must provide enough space to merge out length elements or
1388*e4b17023SJohn Marino    *    the number of elements in all sequences, whichever is smaller.
1389*e4b17023SJohn Marino    *
1390*e4b17023SJohn Marino    * @post [__target, return __value) contains merged __elements from the
1391*e4b17023SJohn Marino    *    input sequences.
1392*e4b17023SJohn Marino    * @post return __value - __target = min(__length, number of elements in all
1393*e4b17023SJohn Marino    *    sequences).
1394*e4b17023SJohn Marino    *
1395*e4b17023SJohn Marino    * @tparam _RAIterPairIterator iterator over sequence
1396*e4b17023SJohn Marino    *    of pairs of iterators
1397*e4b17023SJohn Marino    * @tparam _RAIterOut iterator over target sequence
1398*e4b17023SJohn Marino    * @tparam _DifferenceTp difference type for the sequence
1399*e4b17023SJohn Marino    * @tparam _Compare strict weak ordering type to compare elements
1400*e4b17023SJohn Marino    *    in sequences
1401*e4b17023SJohn Marino    *
1402*e4b17023SJohn Marino    * @param __seqs_begin  __begin of sequence __sequence
1403*e4b17023SJohn Marino    * @param __seqs_end    _M_end of sequence __sequence
1404*e4b17023SJohn Marino    * @param __target      target sequence to merge to.
1405*e4b17023SJohn Marino    * @param __comp        strict weak ordering to use for element comparison.
1406*e4b17023SJohn Marino    * @param __length Maximum length to merge, possibly larger than the
1407*e4b17023SJohn Marino    * number of elements available.
1408*e4b17023SJohn Marino    *
1409*e4b17023SJohn Marino    * @return _M_end iterator of output sequence
1410*e4b17023SJohn Marino    */
1411*e4b17023SJohn Marino   // multiway_merge
1412*e4b17023SJohn Marino   // public interface
1413*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1414*e4b17023SJohn Marino 	   typename _RAIterOut,
1415*e4b17023SJohn Marino 	   typename _DifferenceTp,
1416*e4b17023SJohn Marino 	   typename _Compare>
1417*e4b17023SJohn Marino     _RAIterOut
1418*e4b17023SJohn Marino     multiway_merge(_RAIterPairIterator __seqs_begin,
1419*e4b17023SJohn Marino 		   _RAIterPairIterator __seqs_end,
1420*e4b17023SJohn Marino 		   _RAIterOut __target,
1421*e4b17023SJohn Marino 		   _DifferenceTp __length, _Compare __comp,
1422*e4b17023SJohn Marino 		   __gnu_parallel::sequential_tag)
1423*e4b17023SJohn Marino     {
1424*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1425*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1426*e4b17023SJohn Marino 
1427*e4b17023SJohn Marino       // catch special case: no sequences
1428*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1429*e4b17023SJohn Marino 	return __target;
1430*e4b17023SJohn Marino 
1431*e4b17023SJohn Marino       // Execute multiway merge *sequentially*.
1432*e4b17023SJohn Marino       return __sequential_multiway_merge
1433*e4b17023SJohn Marino 	</* __stable = */ false, /* __sentinels = */ false>
1434*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target,
1435*e4b17023SJohn Marino 	 *(__seqs_begin->second), __length, __comp);
1436*e4b17023SJohn Marino     }
1437*e4b17023SJohn Marino 
1438*e4b17023SJohn Marino   // public interface
1439*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1440*e4b17023SJohn Marino 	   typename _RAIterOut,
1441*e4b17023SJohn Marino 	   typename _DifferenceTp,
1442*e4b17023SJohn Marino 	   typename _Compare>
1443*e4b17023SJohn Marino     _RAIterOut
1444*e4b17023SJohn Marino     multiway_merge(_RAIterPairIterator __seqs_begin,
1445*e4b17023SJohn Marino 		   _RAIterPairIterator __seqs_end,
1446*e4b17023SJohn Marino 		   _RAIterOut __target,
1447*e4b17023SJohn Marino 		   _DifferenceTp __length, _Compare __comp,
1448*e4b17023SJohn Marino 		   __gnu_parallel::exact_tag __tag)
1449*e4b17023SJohn Marino     {
1450*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1451*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1452*e4b17023SJohn Marino 
1453*e4b17023SJohn Marino       // catch special case: no sequences
1454*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1455*e4b17023SJohn Marino 	return __target;
1456*e4b17023SJohn Marino 
1457*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
1458*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
1459*e4b17023SJohn Marino       // Settings.
1460*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
1461*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
1462*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
1463*e4b17023SJohn Marino                __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1464*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
1465*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1466*e4b17023SJohn Marino 	return parallel_multiway_merge
1467*e4b17023SJohn Marino 	  </* __stable = */ false, /* __sentinels = */ false>
1468*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1469*e4b17023SJohn Marino 	   multiway_merge_exact_splitting</* __stable = */ false,
1470*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
1471*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
1472*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
1473*e4b17023SJohn Marino 	   __tag.__get_num_threads());
1474*e4b17023SJohn Marino       else
1475*e4b17023SJohn Marino 	return __sequential_multiway_merge
1476*e4b17023SJohn Marino 	  </* __stable = */ false, /* __sentinels = */ false>
1477*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1478*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
1479*e4b17023SJohn Marino     }
1480*e4b17023SJohn Marino 
1481*e4b17023SJohn Marino   // public interface
1482*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1483*e4b17023SJohn Marino 	   typename _RAIterOut,
1484*e4b17023SJohn Marino 	   typename _DifferenceTp,
1485*e4b17023SJohn Marino 	   typename _Compare>
1486*e4b17023SJohn Marino     _RAIterOut
1487*e4b17023SJohn Marino     multiway_merge(_RAIterPairIterator __seqs_begin,
1488*e4b17023SJohn Marino 		   _RAIterPairIterator __seqs_end,
1489*e4b17023SJohn Marino 		   _RAIterOut __target,
1490*e4b17023SJohn Marino 		   _DifferenceTp __length, _Compare __comp,
1491*e4b17023SJohn Marino 		   __gnu_parallel::sampling_tag __tag)
1492*e4b17023SJohn Marino     {
1493*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1494*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1495*e4b17023SJohn Marino 
1496*e4b17023SJohn Marino       // catch special case: no sequences
1497*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1498*e4b17023SJohn Marino 	return __target;
1499*e4b17023SJohn Marino 
1500*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
1501*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
1502*e4b17023SJohn Marino       // Settings.
1503*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
1504*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
1505*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
1506*e4b17023SJohn Marino                __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1507*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
1508*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1509*e4b17023SJohn Marino 	return parallel_multiway_merge
1510*e4b17023SJohn Marino 	  </* __stable = */ false, /* __sentinels = */ false>
1511*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1512*e4b17023SJohn Marino 	   multiway_merge_exact_splitting</* __stable = */ false,
1513*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
1514*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
1515*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
1516*e4b17023SJohn Marino 	   __tag.__get_num_threads());
1517*e4b17023SJohn Marino       else
1518*e4b17023SJohn Marino 	return __sequential_multiway_merge
1519*e4b17023SJohn Marino 	  </* __stable = */ false, /* __sentinels = */ false>
1520*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1521*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
1522*e4b17023SJohn Marino     }
1523*e4b17023SJohn Marino 
1524*e4b17023SJohn Marino   // public interface
1525*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1526*e4b17023SJohn Marino 	   typename _RAIterOut,
1527*e4b17023SJohn Marino 	   typename _DifferenceTp,
1528*e4b17023SJohn Marino 	   typename _Compare>
1529*e4b17023SJohn Marino     _RAIterOut
1530*e4b17023SJohn Marino     multiway_merge(_RAIterPairIterator __seqs_begin,
1531*e4b17023SJohn Marino 		   _RAIterPairIterator __seqs_end,
1532*e4b17023SJohn Marino 		   _RAIterOut __target,
1533*e4b17023SJohn Marino 		   _DifferenceTp __length, _Compare __comp,
1534*e4b17023SJohn Marino 		   parallel_tag __tag = parallel_tag(0))
1535*e4b17023SJohn Marino     { return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
1536*e4b17023SJohn Marino 			    __comp, exact_tag(__tag.__get_num_threads())); }
1537*e4b17023SJohn Marino 
1538*e4b17023SJohn Marino   // public interface
1539*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1540*e4b17023SJohn Marino 	   typename _RAIterOut,
1541*e4b17023SJohn Marino 	   typename _DifferenceTp,
1542*e4b17023SJohn Marino 	   typename _Compare>
1543*e4b17023SJohn Marino     _RAIterOut
1544*e4b17023SJohn Marino     multiway_merge(_RAIterPairIterator __seqs_begin,
1545*e4b17023SJohn Marino 		   _RAIterPairIterator __seqs_end,
1546*e4b17023SJohn Marino 		   _RAIterOut __target,
1547*e4b17023SJohn Marino 		   _DifferenceTp __length, _Compare __comp,
1548*e4b17023SJohn Marino 		   default_parallel_tag __tag)
1549*e4b17023SJohn Marino     { return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
1550*e4b17023SJohn Marino 			    __comp, exact_tag(__tag.__get_num_threads())); }
1551*e4b17023SJohn Marino 
1552*e4b17023SJohn Marino   // stable_multiway_merge
1553*e4b17023SJohn Marino   // public interface
1554*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1555*e4b17023SJohn Marino 	   typename _RAIterOut,
1556*e4b17023SJohn Marino 	   typename _DifferenceTp,
1557*e4b17023SJohn Marino 	   typename _Compare>
1558*e4b17023SJohn Marino     _RAIterOut
1559*e4b17023SJohn Marino     stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1560*e4b17023SJohn Marino 			  _RAIterPairIterator __seqs_end,
1561*e4b17023SJohn Marino 			  _RAIterOut __target,
1562*e4b17023SJohn Marino 			  _DifferenceTp __length, _Compare __comp,
1563*e4b17023SJohn Marino 			  __gnu_parallel::sequential_tag)
1564*e4b17023SJohn Marino     {
1565*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1566*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1567*e4b17023SJohn Marino 
1568*e4b17023SJohn Marino       // catch special case: no sequences
1569*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1570*e4b17023SJohn Marino 	return __target;
1571*e4b17023SJohn Marino 
1572*e4b17023SJohn Marino       // Execute multiway merge *sequentially*.
1573*e4b17023SJohn Marino       return __sequential_multiway_merge
1574*e4b17023SJohn Marino 	</* __stable = */ true, /* __sentinels = */ false>
1575*e4b17023SJohn Marino           (__seqs_begin, __seqs_end, __target,
1576*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
1577*e4b17023SJohn Marino     }
1578*e4b17023SJohn Marino 
1579*e4b17023SJohn Marino   // public interface
1580*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1581*e4b17023SJohn Marino 	   typename _RAIterOut,
1582*e4b17023SJohn Marino 	   typename _DifferenceTp,
1583*e4b17023SJohn Marino 	   typename _Compare>
1584*e4b17023SJohn Marino     _RAIterOut
1585*e4b17023SJohn Marino     stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1586*e4b17023SJohn Marino 			  _RAIterPairIterator __seqs_end,
1587*e4b17023SJohn Marino 			  _RAIterOut __target,
1588*e4b17023SJohn Marino 			  _DifferenceTp __length, _Compare __comp,
1589*e4b17023SJohn Marino 			  __gnu_parallel::exact_tag __tag)
1590*e4b17023SJohn Marino     {
1591*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1592*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1593*e4b17023SJohn Marino 
1594*e4b17023SJohn Marino       // catch special case: no sequences
1595*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1596*e4b17023SJohn Marino 	return __target;
1597*e4b17023SJohn Marino 
1598*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
1599*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
1600*e4b17023SJohn Marino       // Settings.
1601*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
1602*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
1603*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
1604*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1605*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
1606*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1607*e4b17023SJohn Marino 	return parallel_multiway_merge
1608*e4b17023SJohn Marino           </* __stable = */ true, /* __sentinels = */ false>
1609*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1610*e4b17023SJohn Marino 	   multiway_merge_exact_splitting</* __stable = */ true,
1611*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
1612*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
1613*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
1614*e4b17023SJohn Marino 	   __tag.__get_num_threads());
1615*e4b17023SJohn Marino       else
1616*e4b17023SJohn Marino 	return __sequential_multiway_merge
1617*e4b17023SJohn Marino 	  </* __stable = */ true, /* __sentinels = */ false>
1618*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1619*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
1620*e4b17023SJohn Marino     }
1621*e4b17023SJohn Marino 
1622*e4b17023SJohn Marino   // public interface
1623*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1624*e4b17023SJohn Marino 	   typename _RAIterOut,
1625*e4b17023SJohn Marino 	   typename _DifferenceTp,
1626*e4b17023SJohn Marino 	   typename _Compare>
1627*e4b17023SJohn Marino     _RAIterOut
1628*e4b17023SJohn Marino     stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1629*e4b17023SJohn Marino 			  _RAIterPairIterator __seqs_end,
1630*e4b17023SJohn Marino 			  _RAIterOut __target,
1631*e4b17023SJohn Marino 			  _DifferenceTp __length, _Compare __comp,
1632*e4b17023SJohn Marino 			  sampling_tag __tag)
1633*e4b17023SJohn Marino     {
1634*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1635*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1636*e4b17023SJohn Marino 
1637*e4b17023SJohn Marino       // catch special case: no sequences
1638*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1639*e4b17023SJohn Marino 	return __target;
1640*e4b17023SJohn Marino 
1641*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
1642*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
1643*e4b17023SJohn Marino       // Settings.
1644*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
1645*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
1646*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
1647*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1648*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
1649*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1650*e4b17023SJohn Marino 	return parallel_multiway_merge
1651*e4b17023SJohn Marino           </* __stable = */ true, /* __sentinels = */ false>
1652*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1653*e4b17023SJohn Marino 	   multiway_merge_sampling_splitting</* __stable = */ true,
1654*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
1655*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
1656*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
1657*e4b17023SJohn Marino 	   __tag.__get_num_threads());
1658*e4b17023SJohn Marino       else
1659*e4b17023SJohn Marino 	return __sequential_multiway_merge
1660*e4b17023SJohn Marino           </* __stable = */ true, /* __sentinels = */ false>
1661*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1662*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
1663*e4b17023SJohn Marino     }
1664*e4b17023SJohn Marino 
1665*e4b17023SJohn Marino   // public interface
1666*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1667*e4b17023SJohn Marino 	   typename _RAIterOut,
1668*e4b17023SJohn Marino 	   typename _DifferenceTp,
1669*e4b17023SJohn Marino 	   typename _Compare>
1670*e4b17023SJohn Marino     _RAIterOut
1671*e4b17023SJohn Marino     stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1672*e4b17023SJohn Marino 			  _RAIterPairIterator __seqs_end,
1673*e4b17023SJohn Marino 			  _RAIterOut __target,
1674*e4b17023SJohn Marino 			  _DifferenceTp __length, _Compare __comp,
1675*e4b17023SJohn Marino 			  parallel_tag __tag = parallel_tag(0))
1676*e4b17023SJohn Marino     {
1677*e4b17023SJohn Marino       return stable_multiway_merge
1678*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target, __length, __comp,
1679*e4b17023SJohn Marino 	 exact_tag(__tag.__get_num_threads()));
1680*e4b17023SJohn Marino     }
1681*e4b17023SJohn Marino 
1682*e4b17023SJohn Marino   // public interface
1683*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1684*e4b17023SJohn Marino 	   typename _RAIterOut,
1685*e4b17023SJohn Marino 	   typename _DifferenceTp,
1686*e4b17023SJohn Marino 	   typename _Compare>
1687*e4b17023SJohn Marino     _RAIterOut
1688*e4b17023SJohn Marino     stable_multiway_merge(_RAIterPairIterator __seqs_begin,
1689*e4b17023SJohn Marino 			  _RAIterPairIterator __seqs_end,
1690*e4b17023SJohn Marino 			  _RAIterOut __target,
1691*e4b17023SJohn Marino 			  _DifferenceTp __length, _Compare __comp,
1692*e4b17023SJohn Marino 			  default_parallel_tag __tag)
1693*e4b17023SJohn Marino     {
1694*e4b17023SJohn Marino       return stable_multiway_merge
1695*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target, __length, __comp,
1696*e4b17023SJohn Marino 	 exact_tag(__tag.__get_num_threads()));
1697*e4b17023SJohn Marino     }
1698*e4b17023SJohn Marino 
1699*e4b17023SJohn Marino   /**
1700*e4b17023SJohn Marino    * @brief Multiway Merge Frontend.
1701*e4b17023SJohn Marino    *
1702*e4b17023SJohn Marino    * Merge the sequences specified by seqs_begin and __seqs_end into
1703*e4b17023SJohn Marino    * __target.  __seqs_begin and __seqs_end must point to a sequence of
1704*e4b17023SJohn Marino    * pairs.  These pairs must contain an iterator to the beginning
1705*e4b17023SJohn Marino    * of a sequence in their first entry and an iterator the _M_end of
1706*e4b17023SJohn Marino    * the same sequence in their second entry.
1707*e4b17023SJohn Marino    *
1708*e4b17023SJohn Marino    * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
1709*e4b17023SJohn Marino    * that breaks ties by sequence number but is slower.
1710*e4b17023SJohn Marino    *
1711*e4b17023SJohn Marino    * The first entries of the pairs (i.e. the begin iterators) will be moved
1712*e4b17023SJohn Marino    * forward accordingly.
1713*e4b17023SJohn Marino    *
1714*e4b17023SJohn Marino    * The output sequence has to provide enough space for all elements
1715*e4b17023SJohn Marino    * that are written to it.
1716*e4b17023SJohn Marino    *
1717*e4b17023SJohn Marino    * This function will merge the input sequences:
1718*e4b17023SJohn Marino    *
1719*e4b17023SJohn Marino    * - not stable
1720*e4b17023SJohn Marino    * - parallel, depending on the input size and Settings
1721*e4b17023SJohn Marino    * - using sampling for splitting
1722*e4b17023SJohn Marino    * - using sentinels
1723*e4b17023SJohn Marino    *
1724*e4b17023SJohn Marino    * You have to take care that the element the _M_end iterator points to is
1725*e4b17023SJohn Marino    * readable and contains a value that is greater than any other non-sentinel
1726*e4b17023SJohn Marino    * value in all sequences.
1727*e4b17023SJohn Marino    *
1728*e4b17023SJohn Marino    * Example:
1729*e4b17023SJohn Marino    *
1730*e4b17023SJohn Marino    * <pre>
1731*e4b17023SJohn Marino    *   int sequences[10][11];
1732*e4b17023SJohn Marino    *   for (int __i = 0; __i < 10; ++__i)
1733*e4b17023SJohn Marino    *     for (int __j = 0; __i < 11; ++__j)
1734*e4b17023SJohn Marino    *       sequences[__i][__j] = __j; // __last one is sentinel!
1735*e4b17023SJohn Marino    *
1736*e4b17023SJohn Marino    *   int __out[33];
1737*e4b17023SJohn Marino    *   std::vector<std::pair<int*> > seqs;
1738*e4b17023SJohn Marino    *   for (int __i = 0; __i < 10; ++__i)
1739*e4b17023SJohn Marino    *     { seqs.push(std::make_pair<int*>(sequences[__i],
1740*e4b17023SJohn Marino    *                                      sequences[__i] + 10)) }
1741*e4b17023SJohn Marino    *
1742*e4b17023SJohn Marino    *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
1743*e4b17023SJohn Marino    * </pre>
1744*e4b17023SJohn Marino    *
1745*e4b17023SJohn Marino    * @pre All input sequences must be sorted.
1746*e4b17023SJohn Marino    * @pre Target must provide enough space to merge out length elements or
1747*e4b17023SJohn Marino    *    the number of elements in all sequences, whichever is smaller.
1748*e4b17023SJohn Marino    * @pre For each @c __i, @c __seqs_begin[__i].second must be the end
1749*e4b17023SJohn Marino    *    marker of the sequence, but also reference the one more __sentinel
1750*e4b17023SJohn Marino    *    element.
1751*e4b17023SJohn Marino    *
1752*e4b17023SJohn Marino    * @post [__target, return __value) contains merged __elements from the
1753*e4b17023SJohn Marino    *    input sequences.
1754*e4b17023SJohn Marino    * @post return __value - __target = min(__length, number of elements in all
1755*e4b17023SJohn Marino    *    sequences).
1756*e4b17023SJohn Marino    *
1757*e4b17023SJohn Marino    * @see stable_multiway_merge_sentinels
1758*e4b17023SJohn Marino    *
1759*e4b17023SJohn Marino    * @tparam _RAIterPairIterator iterator over sequence
1760*e4b17023SJohn Marino    *    of pairs of iterators
1761*e4b17023SJohn Marino    * @tparam _RAIterOut iterator over target sequence
1762*e4b17023SJohn Marino    * @tparam _DifferenceTp difference type for the sequence
1763*e4b17023SJohn Marino    * @tparam _Compare strict weak ordering type to compare elements
1764*e4b17023SJohn Marino    *    in sequences
1765*e4b17023SJohn Marino    *
1766*e4b17023SJohn Marino    * @param __seqs_begin  __begin of sequence __sequence
1767*e4b17023SJohn Marino    * @param __seqs_end    _M_end of sequence __sequence
1768*e4b17023SJohn Marino    * @param __target      target sequence to merge to.
1769*e4b17023SJohn Marino    * @param __comp        strict weak ordering to use for element comparison.
1770*e4b17023SJohn Marino    * @param __length Maximum length to merge, possibly larger than the
1771*e4b17023SJohn Marino    * number of elements available.
1772*e4b17023SJohn Marino    *
1773*e4b17023SJohn Marino    * @return _M_end iterator of output sequence
1774*e4b17023SJohn Marino    */
1775*e4b17023SJohn Marino   // multiway_merge_sentinels
1776*e4b17023SJohn Marino   // public interface
1777*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1778*e4b17023SJohn Marino 	   typename _RAIterOut,
1779*e4b17023SJohn Marino 	   typename _DifferenceTp,
1780*e4b17023SJohn Marino 	   typename _Compare>
1781*e4b17023SJohn Marino     _RAIterOut
1782*e4b17023SJohn Marino     multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1783*e4b17023SJohn Marino 			     _RAIterPairIterator __seqs_end,
1784*e4b17023SJohn Marino 			     _RAIterOut __target,
1785*e4b17023SJohn Marino 			     _DifferenceTp __length, _Compare __comp,
1786*e4b17023SJohn Marino 			     __gnu_parallel::sequential_tag)
1787*e4b17023SJohn Marino     {
1788*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1789*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1790*e4b17023SJohn Marino 
1791*e4b17023SJohn Marino       // catch special case: no sequences
1792*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1793*e4b17023SJohn Marino 	return __target;
1794*e4b17023SJohn Marino 
1795*e4b17023SJohn Marino       // Execute multiway merge *sequentially*.
1796*e4b17023SJohn Marino       return __sequential_multiway_merge
1797*e4b17023SJohn Marino 	</* __stable = */ false, /* __sentinels = */ true>
1798*e4b17023SJohn Marino           (__seqs_begin, __seqs_end,
1799*e4b17023SJohn Marino            __target, *(__seqs_begin->second), __length, __comp);
1800*e4b17023SJohn Marino     }
1801*e4b17023SJohn Marino 
1802*e4b17023SJohn Marino   // public interface
1803*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1804*e4b17023SJohn Marino 	   typename _RAIterOut,
1805*e4b17023SJohn Marino 	   typename _DifferenceTp,
1806*e4b17023SJohn Marino 	   typename _Compare>
1807*e4b17023SJohn Marino     _RAIterOut
1808*e4b17023SJohn Marino     multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1809*e4b17023SJohn Marino 			     _RAIterPairIterator __seqs_end,
1810*e4b17023SJohn Marino 			     _RAIterOut __target,
1811*e4b17023SJohn Marino 			     _DifferenceTp __length, _Compare __comp,
1812*e4b17023SJohn Marino 			     __gnu_parallel::exact_tag __tag)
1813*e4b17023SJohn Marino     {
1814*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1815*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1816*e4b17023SJohn Marino 
1817*e4b17023SJohn Marino       // catch special case: no sequences
1818*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1819*e4b17023SJohn Marino 	return __target;
1820*e4b17023SJohn Marino 
1821*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
1822*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
1823*e4b17023SJohn Marino       // Settings.
1824*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
1825*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
1826*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
1827*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1828*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
1829*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1830*e4b17023SJohn Marino 	return parallel_multiway_merge
1831*e4b17023SJohn Marino           </* __stable = */ false, /* __sentinels = */ true>
1832*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1833*e4b17023SJohn Marino 	   multiway_merge_exact_splitting</* __stable = */ false,
1834*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
1835*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
1836*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
1837*e4b17023SJohn Marino 	   __tag.__get_num_threads());
1838*e4b17023SJohn Marino       else
1839*e4b17023SJohn Marino 	return __sequential_multiway_merge
1840*e4b17023SJohn Marino           </* __stable = */ false, /* __sentinels = */ true>
1841*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1842*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
1843*e4b17023SJohn Marino     }
1844*e4b17023SJohn Marino 
1845*e4b17023SJohn Marino   // public interface
1846*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1847*e4b17023SJohn Marino 	   typename _RAIterOut,
1848*e4b17023SJohn Marino 	   typename _DifferenceTp,
1849*e4b17023SJohn Marino 	   typename _Compare>
1850*e4b17023SJohn Marino     _RAIterOut
1851*e4b17023SJohn Marino     multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1852*e4b17023SJohn Marino 			     _RAIterPairIterator __seqs_end,
1853*e4b17023SJohn Marino 			     _RAIterOut __target,
1854*e4b17023SJohn Marino 			     _DifferenceTp __length, _Compare __comp,
1855*e4b17023SJohn Marino 			     sampling_tag __tag)
1856*e4b17023SJohn Marino     {
1857*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1858*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1859*e4b17023SJohn Marino 
1860*e4b17023SJohn Marino       // catch special case: no sequences
1861*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1862*e4b17023SJohn Marino 	return __target;
1863*e4b17023SJohn Marino 
1864*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
1865*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
1866*e4b17023SJohn Marino       // Settings.
1867*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
1868*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
1869*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
1870*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1871*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
1872*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1873*e4b17023SJohn Marino 	return parallel_multiway_merge
1874*e4b17023SJohn Marino           </* __stable = */ false, /* __sentinels = */ true>
1875*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1876*e4b17023SJohn Marino 	   multiway_merge_sampling_splitting</* __stable = */ false,
1877*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
1878*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
1879*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
1880*e4b17023SJohn Marino 	   __tag.__get_num_threads());
1881*e4b17023SJohn Marino       else
1882*e4b17023SJohn Marino 	return __sequential_multiway_merge
1883*e4b17023SJohn Marino           </* __stable = */false, /* __sentinels = */ true>(
1884*e4b17023SJohn Marino             __seqs_begin, __seqs_end, __target,
1885*e4b17023SJohn Marino 	    *(__seqs_begin->second), __length, __comp);
1886*e4b17023SJohn Marino     }
1887*e4b17023SJohn Marino 
1888*e4b17023SJohn Marino   // public interface
1889*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1890*e4b17023SJohn Marino 	   typename _RAIterOut,
1891*e4b17023SJohn Marino 	   typename _DifferenceTp,
1892*e4b17023SJohn Marino 	   typename _Compare>
1893*e4b17023SJohn Marino     _RAIterOut
1894*e4b17023SJohn Marino     multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1895*e4b17023SJohn Marino 			     _RAIterPairIterator __seqs_end,
1896*e4b17023SJohn Marino 			     _RAIterOut __target,
1897*e4b17023SJohn Marino 			     _DifferenceTp __length, _Compare __comp,
1898*e4b17023SJohn Marino 			     parallel_tag __tag = parallel_tag(0))
1899*e4b17023SJohn Marino     {
1900*e4b17023SJohn Marino       return multiway_merge_sentinels
1901*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target, __length, __comp,
1902*e4b17023SJohn Marino 	 exact_tag(__tag.__get_num_threads()));
1903*e4b17023SJohn Marino     }
1904*e4b17023SJohn Marino 
1905*e4b17023SJohn Marino   // public interface
1906*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1907*e4b17023SJohn Marino 	   typename _RAIterOut,
1908*e4b17023SJohn Marino 	   typename _DifferenceTp,
1909*e4b17023SJohn Marino 	   typename _Compare>
1910*e4b17023SJohn Marino     _RAIterOut
1911*e4b17023SJohn Marino     multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1912*e4b17023SJohn Marino 			     _RAIterPairIterator __seqs_end,
1913*e4b17023SJohn Marino 			     _RAIterOut __target,
1914*e4b17023SJohn Marino 			     _DifferenceTp __length, _Compare __comp,
1915*e4b17023SJohn Marino 			     default_parallel_tag __tag)
1916*e4b17023SJohn Marino     {
1917*e4b17023SJohn Marino       return multiway_merge_sentinels
1918*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target, __length, __comp,
1919*e4b17023SJohn Marino 	 exact_tag(__tag.__get_num_threads()));
1920*e4b17023SJohn Marino     }
1921*e4b17023SJohn Marino 
1922*e4b17023SJohn Marino   // stable_multiway_merge_sentinels
1923*e4b17023SJohn Marino   // public interface
1924*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1925*e4b17023SJohn Marino 	   typename _RAIterOut,
1926*e4b17023SJohn Marino 	   typename _DifferenceTp,
1927*e4b17023SJohn Marino 	   typename _Compare>
1928*e4b17023SJohn Marino     _RAIterOut
1929*e4b17023SJohn Marino     stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1930*e4b17023SJohn Marino 				    _RAIterPairIterator __seqs_end,
1931*e4b17023SJohn Marino 				    _RAIterOut __target,
1932*e4b17023SJohn Marino 				    _DifferenceTp __length, _Compare __comp,
1933*e4b17023SJohn Marino 				    __gnu_parallel::sequential_tag)
1934*e4b17023SJohn Marino     {
1935*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1936*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1937*e4b17023SJohn Marino 
1938*e4b17023SJohn Marino       // catch special case: no sequences
1939*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1940*e4b17023SJohn Marino 	return __target;
1941*e4b17023SJohn Marino 
1942*e4b17023SJohn Marino       // Execute multiway merge *sequentially*.
1943*e4b17023SJohn Marino       return __sequential_multiway_merge
1944*e4b17023SJohn Marino 	</* __stable = */ true, /* __sentinels = */ true>
1945*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target,
1946*e4b17023SJohn Marino 	 *(__seqs_begin->second), __length, __comp);
1947*e4b17023SJohn Marino     }
1948*e4b17023SJohn Marino 
1949*e4b17023SJohn Marino   // public interface
1950*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1951*e4b17023SJohn Marino 	   typename _RAIterOut,
1952*e4b17023SJohn Marino 	   typename _DifferenceTp,
1953*e4b17023SJohn Marino 	   typename _Compare>
1954*e4b17023SJohn Marino     _RAIterOut
1955*e4b17023SJohn Marino     stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1956*e4b17023SJohn Marino 				    _RAIterPairIterator __seqs_end,
1957*e4b17023SJohn Marino 				    _RAIterOut __target,
1958*e4b17023SJohn Marino 				    _DifferenceTp __length, _Compare __comp,
1959*e4b17023SJohn Marino 				    __gnu_parallel::exact_tag __tag)
1960*e4b17023SJohn Marino     {
1961*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
1962*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
1963*e4b17023SJohn Marino 
1964*e4b17023SJohn Marino       // catch special case: no sequences
1965*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
1966*e4b17023SJohn Marino 	return __target;
1967*e4b17023SJohn Marino 
1968*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
1969*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
1970*e4b17023SJohn Marino       // Settings.
1971*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
1972*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
1973*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
1974*e4b17023SJohn Marino             __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
1975*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
1976*e4b17023SJohn Marino             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
1977*e4b17023SJohn Marino 	return parallel_multiway_merge
1978*e4b17023SJohn Marino           </* __stable = */ true, /* __sentinels = */ true>
1979*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1980*e4b17023SJohn Marino 	   multiway_merge_exact_splitting</* __stable = */ true,
1981*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
1982*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
1983*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
1984*e4b17023SJohn Marino 	   __tag.__get_num_threads());
1985*e4b17023SJohn Marino       else
1986*e4b17023SJohn Marino 	return __sequential_multiway_merge
1987*e4b17023SJohn Marino           </* __stable = */ true, /* __sentinels = */ true>
1988*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
1989*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
1990*e4b17023SJohn Marino     }
1991*e4b17023SJohn Marino 
1992*e4b17023SJohn Marino   // public interface
1993*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
1994*e4b17023SJohn Marino 	   typename _RAIterOut,
1995*e4b17023SJohn Marino 	   typename _DifferenceTp,
1996*e4b17023SJohn Marino 	   typename _Compare>
1997*e4b17023SJohn Marino     _RAIterOut
1998*e4b17023SJohn Marino     stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
1999*e4b17023SJohn Marino 				    _RAIterPairIterator __seqs_end,
2000*e4b17023SJohn Marino 				    _RAIterOut __target,
2001*e4b17023SJohn Marino 				    _DifferenceTp __length,
2002*e4b17023SJohn Marino 				    _Compare __comp,
2003*e4b17023SJohn Marino 				    sampling_tag __tag)
2004*e4b17023SJohn Marino     {
2005*e4b17023SJohn Marino       typedef _DifferenceTp _DifferenceType;
2006*e4b17023SJohn Marino       _GLIBCXX_CALL(__seqs_end - __seqs_begin)
2007*e4b17023SJohn Marino 
2008*e4b17023SJohn Marino       // catch special case: no sequences
2009*e4b17023SJohn Marino       if (__seqs_begin == __seqs_end)
2010*e4b17023SJohn Marino 	return __target;
2011*e4b17023SJohn Marino 
2012*e4b17023SJohn Marino       // Execute merge; maybe parallel, depending on the number of merged
2013*e4b17023SJohn Marino       // elements and the number of sequences and global thresholds in
2014*e4b17023SJohn Marino       // Settings.
2015*e4b17023SJohn Marino       if ((__seqs_end - __seqs_begin > 1)
2016*e4b17023SJohn Marino 	  && _GLIBCXX_PARALLEL_CONDITION(
2017*e4b17023SJohn Marino             ((__seqs_end - __seqs_begin) >=
2018*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
2019*e4b17023SJohn Marino             && ((_SequenceIndex)__length >=
2020*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
2021*e4b17023SJohn Marino 	return parallel_multiway_merge
2022*e4b17023SJohn Marino           </* __stable = */ true, /* __sentinels = */ true>
2023*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
2024*e4b17023SJohn Marino 	   multiway_merge_sampling_splitting</* __stable = */ true,
2025*e4b17023SJohn Marino 	   typename std::iterator_traits<_RAIterPairIterator>
2026*e4b17023SJohn Marino 	   ::value_type*, _Compare, _DifferenceTp>,
2027*e4b17023SJohn Marino 	   static_cast<_DifferenceType>(__length), __comp,
2028*e4b17023SJohn Marino 	   __tag.__get_num_threads());
2029*e4b17023SJohn Marino       else
2030*e4b17023SJohn Marino 	return __sequential_multiway_merge
2031*e4b17023SJohn Marino           </* __stable = */ true, /* __sentinels = */ true>
2032*e4b17023SJohn Marino 	  (__seqs_begin, __seqs_end, __target,
2033*e4b17023SJohn Marino 	   *(__seqs_begin->second), __length, __comp);
2034*e4b17023SJohn Marino     }
2035*e4b17023SJohn Marino 
2036*e4b17023SJohn Marino   // public interface
2037*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
2038*e4b17023SJohn Marino 	   typename _RAIterOut,
2039*e4b17023SJohn Marino 	   typename _DifferenceTp,
2040*e4b17023SJohn Marino 	   typename _Compare>
2041*e4b17023SJohn Marino     _RAIterOut
2042*e4b17023SJohn Marino     stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
2043*e4b17023SJohn Marino 				    _RAIterPairIterator __seqs_end,
2044*e4b17023SJohn Marino 				    _RAIterOut __target,
2045*e4b17023SJohn Marino 				    _DifferenceTp __length,
2046*e4b17023SJohn Marino 				    _Compare __comp,
2047*e4b17023SJohn Marino 				    parallel_tag __tag = parallel_tag(0))
2048*e4b17023SJohn Marino     {
2049*e4b17023SJohn Marino       return stable_multiway_merge_sentinels
2050*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target, __length, __comp,
2051*e4b17023SJohn Marino 	 exact_tag(__tag.__get_num_threads()));
2052*e4b17023SJohn Marino     }
2053*e4b17023SJohn Marino 
2054*e4b17023SJohn Marino   // public interface
2055*e4b17023SJohn Marino   template<typename _RAIterPairIterator,
2056*e4b17023SJohn Marino 	   typename _RAIterOut,
2057*e4b17023SJohn Marino 	   typename _DifferenceTp,
2058*e4b17023SJohn Marino 	   typename _Compare>
2059*e4b17023SJohn Marino     _RAIterOut
2060*e4b17023SJohn Marino     stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
2061*e4b17023SJohn Marino 				    _RAIterPairIterator __seqs_end,
2062*e4b17023SJohn Marino 				    _RAIterOut __target,
2063*e4b17023SJohn Marino 				    _DifferenceTp __length, _Compare __comp,
2064*e4b17023SJohn Marino 				    default_parallel_tag __tag)
2065*e4b17023SJohn Marino     {
2066*e4b17023SJohn Marino       return stable_multiway_merge_sentinels
2067*e4b17023SJohn Marino 	(__seqs_begin, __seqs_end, __target, __length, __comp,
2068*e4b17023SJohn Marino 	 exact_tag(__tag.__get_num_threads()));
2069*e4b17023SJohn Marino     }
2070*e4b17023SJohn Marino }; // namespace __gnu_parallel
2071*e4b17023SJohn Marino 
2072*e4b17023SJohn Marino #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */
2073