39 #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H 40 #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H 49 #if _GLIBCXX_PARALLEL_ASSERTIONS 54 #define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first) 58 template<
typename _RAIter1,
typename _RAIter2,
typename _OutputIterator,
59 typename _DifferenceTp,
typename _Compare>
62 _OutputIterator, _DifferenceTp, _Compare);
72 template<
typename _RAIter,
typename _Compare>
92 : _M_current(__begin), _M_end(__end), __comp(__comp)
108 {
return *_M_current; }
113 {
return _M_current; }
120 operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
123 if (__bi1._M_current == __bi1._M_end)
124 return __bi2._M_current == __bi2._M_end;
125 if (__bi2._M_current == __bi2._M_end)
127 return (__bi1.__comp)(*__bi1, *__bi2);
135 operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
138 if (__bi2._M_current == __bi2._M_end)
139 return __bi1._M_current != __bi1._M_end;
140 if (__bi1._M_current == __bi1._M_end)
142 return !(__bi1.__comp)(*__bi2, *__bi1);
146 template<
typename _RAIter,
typename _Compare>
147 class _UnguardedIterator
160 _UnguardedIterator(_RAIter __begin,
161 _RAIter , _Compare& __comp)
162 : _M_current(__begin), __comp(__comp)
167 _UnguardedIterator<_RAIter, _Compare>&
178 {
return *_M_current; }
183 {
return _M_current; }
190 operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1,
191 _UnguardedIterator<_RAIter, _Compare>& __bi2)
194 return (__bi1.__comp)(*__bi1, *__bi2);
202 operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1,
203 _UnguardedIterator<_RAIter, _Compare>& __bi2)
206 return !(__bi1.__comp)(*__bi2, *__bi1);
235 template<
template<
typename _RAI,
typename _Cp>
class iterator,
236 typename _RAIterIterator,
238 typename _DifferenceTp,
242 _RAIterIterator __seqs_end,
244 _DifferenceTp __length, _Compare __comp)
248 typedef _DifferenceTp _DifferenceType;
251 ::value_type::first_type
259 #if _GLIBCXX_PARALLEL_ASSERTIONS 260 _DifferenceTp __orig_length = __length;
263 iterator<_RAIter1, _Compare>
264 __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
265 __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
266 __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp);
268 if (__seq0 <= __seq1)
270 if (__seq1 <= __seq2)
280 if (__seq1 <= __seq2)
282 if (__seq0 <= __seq2)
290 #define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \ 291 __s ## __a ## __b ## __c : \ 292 *__target = *__seq ## __a; \ 296 if (__length == 0) goto __finish; \ 297 if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \ 298 if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \ 299 goto __s ## __b ## __c ## __a; 301 _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
302 _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
303 _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < );
304 _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=);
305 _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=);
306 _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < );
308 #undef _GLIBCXX_PARALLEL_MERGE_3_CASE 313 #if _GLIBCXX_PARALLEL_ASSERTIONS 314 _GLIBCXX_PARALLEL_ASSERT(
315 ((_RAIter1)__seq0 - __seqs_begin[0].first) +
316 ((_RAIter1)__seq1 - __seqs_begin[1].first) +
317 ((_RAIter1)__seq2 - __seqs_begin[2].first)
321 __seqs_begin[0].first = __seq0;
322 __seqs_begin[1].first = __seq1;
323 __seqs_begin[2].first = __seq2;
354 template<
template<
typename _RAI,
typename _Cp>
class iterator,
355 typename _RAIterIterator,
357 typename _DifferenceTp,
361 _RAIterIterator __seqs_end,
363 _DifferenceTp __length, _Compare __comp)
366 typedef _DifferenceTp _DifferenceType;
369 ::value_type::first_type
374 iterator<_RAIter1, _Compare>
375 __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
376 __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
377 __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp),
378 __seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp);
380 #define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) { \ 381 if (__seq ## __d < __seq ## __a) \ 382 goto __s ## __d ## __a ## __b ## __c; \ 383 if (__seq ## __d < __seq ## __b) \ 384 goto __s ## __a ## __d ## __b ## __c; \ 385 if (__seq ## __d < __seq ## __c) \ 386 goto __s ## __a ## __b ## __d ## __c; \ 387 goto __s ## __a ## __b ## __c ## __d; } 389 if (__seq0 <= __seq1)
391 if (__seq1 <= __seq2)
392 _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
395 _GLIBCXX_PARALLEL_DECISION(2,0,1,3)
397 _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
401 if (__seq1 <= __seq2)
403 if (__seq0 <= __seq2)
404 _GLIBCXX_PARALLEL_DECISION(1,0,2,3)
406 _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
409 _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
412 #define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d, \ 414 __s ## __a ## __b ## __c ## __d: \ 415 if (__length == 0) goto __finish; \ 416 *__target = *__seq ## __a; \ 420 if (__seq ## __a __c0 __seq ## __b) \ 421 goto __s ## __a ## __b ## __c ## __d; \ 422 if (__seq ## __a __c1 __seq ## __c) \ 423 goto __s ## __b ## __a ## __c ## __d; \ 424 if (__seq ## __a __c2 __seq ## __d) \ 425 goto __s ## __b ## __c ## __a ## __d; \ 426 goto __s ## __b ## __c ## __d ## __a; 428 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
429 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
430 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=);
431 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=);
432 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=);
433 _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=);
434 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=);
435 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=);
436 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=);
437 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < );
438 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=);
439 _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < );
440 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=);
441 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < );
442 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=);
443 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < );
444 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < );
445 _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < );
446 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < );
447 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < );
448 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < );
449 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < );
450 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < );
451 _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < );
453 #undef _GLIBCXX_PARALLEL_MERGE_4_CASE 454 #undef _GLIBCXX_PARALLEL_DECISION 459 __seqs_begin[0].first = __seq0;
460 __seqs_begin[1].first = __seq1;
461 __seqs_begin[2].first = __seq2;
462 __seqs_begin[3].first = __seq3;
485 template<
typename _LT,
486 typename _RAIterIterator,
488 typename _DifferenceTp,
492 _RAIterIterator __seqs_end,
494 _DifferenceTp __length, _Compare __comp)
498 typedef _DifferenceTp _DifferenceType;
500 ::difference_type _SeqNumber;
502 ::value_type::first_type
507 _SeqNumber __k =
static_cast<_SeqNumber
>(__seqs_end - __seqs_begin);
509 _LT __lt(__k, __comp);
512 _ValueType* __arbitrary_element = 0;
514 for (_SeqNumber __t = 0; __t < __k; ++__t)
516 if(!__arbitrary_element
518 __arbitrary_element = &(*__seqs_begin[__t].first);
521 for (_SeqNumber __t = 0; __t < __k; ++__t)
523 if (__seqs_begin[__t].first == __seqs_begin[__t].second)
524 __lt.__insert_start(*__arbitrary_element, __t,
true);
526 __lt.__insert_start(*__seqs_begin[__t].first, __t,
false);
533 for (_DifferenceType __i = 0; __i < __length; ++__i)
536 __source = __lt.__get_min_source();
538 *(__target++) = *(__seqs_begin[__source].first++);
541 if (__seqs_begin[__source].first == __seqs_begin[__source].second)
542 __lt.__delete_min_insert(*__arbitrary_element,
true);
545 __lt.__delete_min_insert(*__seqs_begin[__source].first,
false);
569 template<
typename _LT,
570 typename _RAIterIterator,
572 typename _DifferenceTp,
typename _Compare>
575 _RAIterIterator __seqs_end,
578 _RAIterIterator>::value_type::first_type>::value_type&
580 _DifferenceTp __length,
584 typedef _DifferenceTp _DifferenceType;
587 ::difference_type _SeqNumber;
589 ::value_type::first_type
594 _SeqNumber __k = __seqs_end - __seqs_begin;
596 _LT __lt(__k, __sentinel, __comp);
598 for (_SeqNumber __t = 0; __t < __k; ++__t)
600 #if _GLIBCXX_PARALLEL_ASSERTIONS 601 _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
602 != __seqs_begin[__t].second);
604 __lt.__insert_start(*__seqs_begin[__t].first, __t,
false);
611 #if _GLIBCXX_PARALLEL_ASSERTIONS 612 _DifferenceType __i = 0;
615 _RAIter3 __target_end = __target + __length;
616 while (__target < __target_end)
619 __source = __lt.__get_min_source();
621 #if _GLIBCXX_PARALLEL_ASSERTIONS 622 _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k);
623 _GLIBCXX_PARALLEL_ASSERT(__i == 0
624 || !__comp(*(__seqs_begin[__source].first), *(__target - 1)));
628 *(__target++) = *(__seqs_begin[__source].first++);
630 #if _GLIBCXX_PARALLEL_ASSERTIONS 634 __lt.__delete_min_insert(*__seqs_begin[__source].first,
false);