18 #ifndef TLX_ALGORITHM_MULTIWAY_MERGE_HEADER 19 #define TLX_ALGORITHM_MULTIWAY_MERGE_HEADER 37 namespace multiway_merge_detail {
40 template <
typename RandomAccessIteratorPair>
41 typename std::iterator_traits<
42 typename RandomAccessIteratorPair::first_type
45 return p.second - p.first;
53 template <
typename RandomAccessIterator,
typename Comparator>
62 typename std::iterator_traits<RandomAccessIterator>::value_type;
82 : current(begin), end_(end), comp_(comp)
121 return bi1.
comp_(*bi1, *bi2);
135 return !bi1.
comp_(*bi2, *bi1);
139 template <
typename RandomAccessIterator,
typename Comparator>
148 typename std::iterator_traits<RandomAccessIterator>::value_type;
164 RandomAccessIterator ,
166 : current(begin), comp_(comp)
201 return bi1.
comp_(*bi1, *bi2);
211 return !bi1.
comp_(*bi2, *bi1);
227 typename RandomAccessIteratorIterator,
229 typename std::iterator_traits<
230 typename std::iterator_traits<
231 RandomAccessIteratorIterator>::value_type::first_type>::difference_type
233 RandomAccessIteratorIterator seqs_begin,
234 RandomAccessIteratorIterator seqs_end,
237 using RandomAccessIterator =
238 typename std::iterator_traits<RandomAccessIteratorIterator>
239 ::value_type::first_type;
240 using value_type =
typename std::iterator_traits<RandomAccessIterator>
242 using diff_type =
typename std::iterator_traits<RandomAccessIterator>
245 if ((*seqs_begin).first == (*seqs_begin).second)
255 for (RandomAccessIteratorIterator s = seqs_begin + 1; s != seqs_end; ++s)
257 if ((*s).first == (*s).second)
260 min_sequence =
static_cast<int>(s - seqs_begin);
268 min_sequence =
static_cast<int>(s - seqs_begin);
272 diff_type overhang_size = 0;
275 for (s = 0; s <= min_sequence; ++s)
277 RandomAccessIterator
split;
279 split = std::upper_bound(seqs_begin[s].first, seqs_begin[s].second,
282 split = std::lower_bound(seqs_begin[s].first, seqs_begin[s].second,
285 overhang_size += seqs_begin[s].second -
split;
288 for ( ; s < (seqs_end - seqs_begin); ++s)
290 RandomAccessIterator
split =
291 std::lower_bound(seqs_begin[s].first, seqs_begin[s].second,
293 overhang_size += seqs_begin[s].second -
split;
297 return overhang_size;
306 template <
typename RandomAccessIteratorIterator,
typename Comparator>
307 typename std::iterator_traits<
308 typename std::iterator_traits<
309 RandomAccessIteratorIterator>::value_type::first_type>::difference_type
311 RandomAccessIteratorIterator seqs_begin,
312 RandomAccessIteratorIterator seqs_end,
314 using RandomAccessIterator =
315 typename std::iterator_traits<RandomAccessIteratorIterator>
316 ::value_type::first_type;
317 using value_type =
typename std::iterator_traits<RandomAccessIterator>
319 using diff_type =
typename std::iterator_traits<RandomAccessIterator>
323 for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
325 if ((*s).first == (*s).second)
328 if (!max_value || comp(*max_value, v))
332 diff_type overhang_size = 0;
334 for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
336 RandomAccessIterator
split = std::lower_bound(
337 (*s).first, (*s).second, *max_value, comp);
338 overhang_size += (*s).second -
split;
339 *((*s).second) = *max_value;
343 return overhang_size;
370 template <
typename RAI,
typename C>
class Iterator,
371 typename RandomAccessIteratorIterator,
372 typename RandomAccessIterator3,
375 RandomAccessIteratorIterator seqs_begin,
376 RandomAccessIteratorIterator seqs_end,
377 RandomAccessIterator3 target,
378 typename std::iterator_traits<
379 typename std::iterator_traits<
380 RandomAccessIteratorIterator>::value_type::first_type>::
381 difference_type size,
384 assert(seqs_end - seqs_begin == 3);
387 using RandomAccessIterator =
388 typename std::iterator_traits<RandomAccessIteratorIterator>
389 ::value_type::first_type;
394 Iterator<RandomAccessIterator, Comparator>
395 seq0(seqs_begin[0].first, seqs_begin[0].second, comp),
396 seq1(seqs_begin[1].first, seqs_begin[1].second, comp),
397 seq2(seqs_begin[2].first, seqs_begin[2].second, comp);
403 else if (seq2 < seq0)
421 #define TLX_MERGE3CASE(a, b, c, c0, c1) \ 423 *target = *seq ## a; \ 427 if (size == 0) goto finish; \ 428 if (seq ## a c0 seq ## b) goto s ## a ## b ## c; \ 429 if (seq ## a c1 seq ## c) goto s ## b ## a ## c; \ 430 goto s ## b ## c ## a; 439 #undef TLX_MERGE3CASE 442 seqs_begin[0].first = seq0.iterator();
443 seqs_begin[1].first = seq1.iterator();
444 seqs_begin[2].first = seq2.iterator();
450 typename RandomAccessIteratorIterator,
451 typename RandomAccessIterator3,
454 RandomAccessIteratorIterator seqs_begin,
455 RandomAccessIteratorIterator seqs_end,
456 RandomAccessIterator3 target,
457 typename std::iterator_traits<
458 typename std::iterator_traits<
459 RandomAccessIteratorIterator>::value_type::first_type>::
460 difference_type size,
462 using RandomAccessIterator =
463 typename std::iterator_traits<RandomAccessIteratorIterator>
464 ::value_type::first_type;
465 using DiffType =
typename std::iterator_traits<RandomAccessIterator>
468 assert(seqs_end - seqs_begin == 3);
471 RandomAccessIterator3 target_end;
472 DiffType overhang = prepare_unguarded<true>(seqs_begin, seqs_end, comp, min_seq);
474 DiffType total_size = 0;
475 for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
478 if (overhang != static_cast<DiffType>(-1))
480 DiffType unguarded_size =
std::min(size, total_size - overhang);
481 target_end = multiway_merge_3_variant<unguarded_iterator>
482 (seqs_begin, seqs_end, target, unguarded_size, comp);
483 overhang = size - unguarded_size;
497 seqs_begin[1].first, seqs_begin[1].second,
498 seqs_begin[2].first, seqs_begin[2].second,
499 target_end, overhang, comp);
503 seqs_begin[0].first, seqs_begin[0].second,
504 seqs_begin[2].first, seqs_begin[2].second,
505 target_end, overhang, comp);
509 seqs_begin[0].first, seqs_begin[0].second,
510 seqs_begin[1].first, seqs_begin[1].second,
511 target_end, overhang, comp);
544 template <
typename RAI,
typename C>
class iterator,
545 typename RandomAccessIteratorIterator,
546 typename RandomAccessIterator3,
549 RandomAccessIteratorIterator seqs_begin,
550 RandomAccessIteratorIterator seqs_end,
551 RandomAccessIterator3 target,
552 typename std::iterator_traits<
553 typename std::iterator_traits<
554 RandomAccessIteratorIterator>::value_type::first_type>::
555 difference_type size,
557 assert(seqs_end - seqs_begin == 4);
559 using RandomAccessIterator =
560 typename std::iterator_traits<RandomAccessIteratorIterator>
561 ::value_type::first_type;
566 iterator<RandomAccessIterator, Comparator>
567 seq0(seqs_begin[0].first, seqs_begin[0].second, comp),
568 seq1(seqs_begin[1].first, seqs_begin[1].second, comp),
569 seq2(seqs_begin[2].first, seqs_begin[2].second, comp),
570 seq3(seqs_begin[3].first, seqs_begin[3].second, comp);
572 #define TLX_DECISION(a, b, c, d) do { \ 573 if (seq ## d < seq ## a) goto s ## d ## a ## b ## c; \ 574 if (seq ## d < seq ## b) goto s ## a ## d ## b ## c; \ 575 if (seq ## d < seq ## c) goto s ## a ## b ## d ## c; \ 576 goto s ## a ## b ## c ## d; \ 584 else if (seq2 < seq0)
602 #define TLX_MERGE4CASE(a, b, c, d, c0, c1, c2) \ 603 s ## a ## b ## c ## d: \ 604 *target = *seq ## a; \ 608 if (size == 0) goto finish; \ 609 if (seq ## a c0 seq ## b) goto s ## a ## b ## c ## d; \ 610 if (seq ## a c1 seq ## c) goto s ## b ## a ## c ## d; \ 611 if (seq ## a c2 seq ## d) goto s ## b ## c ## a ## d; \ 612 goto s ## b ## c ## d ## a; 639 #undef TLX_MERGE4CASE 643 seqs_begin[0].first = seq0.iterator();
644 seqs_begin[1].first = seq1.iterator();
645 seqs_begin[2].first = seq2.iterator();
646 seqs_begin[3].first = seq3.iterator();
652 typename RandomAccessIteratorIterator,
653 typename RandomAccessIterator3,
656 RandomAccessIteratorIterator seqs_begin,
657 RandomAccessIteratorIterator seqs_end,
658 RandomAccessIterator3 target,
659 typename std::iterator_traits<
660 typename std::iterator_traits<
661 RandomAccessIteratorIterator>::value_type::first_type>::
662 difference_type size,
665 assert(seqs_end - seqs_begin == 4);
666 using RandomAccessIteratorPair =
667 typename std::iterator_traits<RandomAccessIteratorIterator>
669 using DiffType =
typename std::iterator_traits<RandomAccessIteratorIterator>
673 RandomAccessIterator3 target_end;
674 DiffType overhang = prepare_unguarded<true>(seqs_begin, seqs_end, comp, min_seq);
676 DiffType total_size = 0;
677 for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
680 if (overhang != static_cast<DiffType>(-1))
682 DiffType unguarded_size =
std::min(size, total_size - overhang);
683 target_end = multiway_merge_4_variant<unguarded_iterator>(
684 seqs_begin, seqs_end, target, unguarded_size, comp);
685 overhang = size - unguarded_size;
694 std::vector<RandomAccessIteratorPair> one_missing(seqs_begin, seqs_end);
696 one_missing.erase(one_missing.begin() + min_seq);
698 target_end = multiway_merge_3_variant<guarded_iterator>(
699 one_missing.begin(), one_missing.end(), target_end, overhang, comp);
702 one_missing.insert(one_missing.begin() + min_seq, seqs_begin[min_seq]);
704 std::copy(one_missing.begin(), one_missing.end(), seqs_begin);
725 typename RandomAccessIteratorIterator,
726 typename RandomAccessIterator3,
729 RandomAccessIteratorIterator seqs_begin,
730 RandomAccessIteratorIterator seqs_end,
731 RandomAccessIterator3 target,
732 typename std::iterator_traits<
733 typename std::iterator_traits<
734 RandomAccessIteratorIterator>::value_type::first_type>::
735 difference_type size,
737 using RandomAccessIterator =
738 typename std::iterator_traits<RandomAccessIteratorIterator>
739 ::value_type::first_type;
740 using value_type =
typename std::iterator_traits<RandomAccessIterator>
742 using DiffType =
typename std::iterator_traits<RandomAccessIterator>
746 int num_seqs =
static_cast<int>(seqs_end - seqs_begin), nrp;
750 DiffType total_size = 0;
752 #define TLX_POS(i) seqs_begin[(i)].first 753 #define TLX_STOPS(i) seqs_begin[(i)].second 757 for (
int pi = 0; pi < num_seqs; ++pi)
770 for (
int k = 0; k < nrp - 1; ++k)
771 for (
int pi = nrp - 1; pi > k; --pi)
772 if (comp(pl[pi], pl[pi - 1]) ||
773 (!comp(pl[pi - 1], pl[pi]) && source[pi] < source[pi - 1]))
781 for (
int k = 0; k < nrp - 1; ++k)
782 for (
int pi = nrp - 1; pi > k; --pi)
783 if (comp(pl[pi], pl[pi - 1]))
794 while (nrp > 0 && size > 0)
796 if (source[0] < source[1])
799 while ((nrp == 1 || !(comp(pl[1], pl[0]))) && size > 0)
808 for (
int s = 0; s < nrp - 1; ++s)
811 source[s] = source[s + 1];
823 while ((nrp == 1 || comp(pl[0], pl[1])) && size > 0)
831 for (
int s = 0; s < nrp - 1; ++s)
834 source[s] = source[s + 1];
846 while ((j < nrp) && (comp(pl[j], pl[j - 1]) ||
847 (!comp(pl[j - 1], pl[j]) && (source[j] < source[j - 1]))))
858 while (nrp > 0 && size > 0)
861 while ((nrp == 1 || !comp(pl[1], pl[0])) && size > 0)
869 for (
int s = 0; s < (nrp - 1); ++s)
872 source[s] = source[s + 1];
883 while ((j < nrp) && comp(pl[j], pl[j - 1]))
911 typename LoserTreeType,
912 typename RandomAccessIteratorIterator,
913 typename RandomAccessIterator3,
916 RandomAccessIteratorIterator seqs_begin,
917 RandomAccessIteratorIterator seqs_end,
918 RandomAccessIterator3 target,
919 typename std::iterator_traits<
920 typename std::iterator_traits<
921 RandomAccessIteratorIterator>::value_type::first_type>::
922 difference_type size,
924 using Source =
typename LoserTreeType::Source;
925 using size_type =
typename LoserTreeType::Source;
926 using RandomAccessIteratorPair =
927 typename std::iterator_traits<RandomAccessIteratorIterator>::value_type;
928 using RandomAccessIterator =
typename RandomAccessIteratorPair::first_type;
929 using DiffType =
typename std::iterator_traits<RandomAccessIterator>
932 const Source k =
static_cast<Source
>(seqs_end - seqs_begin);
934 LoserTreeType lt(static_cast<size_type>(k), comp);
936 const DiffType total_size = std::min<DiffType>(
938 std::accumulate(seqs_begin, seqs_end, DiffType(0),
939 [](DiffType sum,
const RandomAccessIteratorPair&
x) {
943 for (Source t = 0; t < k; ++t)
945 if (
TLX_UNLIKELY(seqs_begin[t].first == seqs_begin[t].second))
946 lt.insert_start(
nullptr, t,
true);
948 lt.insert_start(&*seqs_begin[t].first, t,
false);
957 Source source = lt.min_source();
959 *target = *seqs_begin[source].first;
961 ++seqs_begin[source].first;
963 for (DiffType i = 1; i < total_size; ++i)
966 if (seqs_begin[source].first == seqs_begin[source].second)
967 lt.delete_min_insert(
nullptr,
true);
970 lt.delete_min_insert(&*seqs_begin[source].first,
false);
973 source = lt.min_source();
975 *target = *seqs_begin[source].first;
977 ++seqs_begin[source].first;
997 typename LoserTreeType,
998 typename RandomAccessIteratorIterator,
999 typename RandomAccessIterator3,
1000 typename Comparator>
1002 RandomAccessIteratorIterator seqs_begin,
1003 RandomAccessIteratorIterator seqs_end,
1004 RandomAccessIterator3 target,
1005 typename std::iterator_traits<
1006 typename std::iterator_traits<
1007 RandomAccessIteratorIterator>::value_type::first_type>::
1008 difference_type size,
1010 using Source =
typename LoserTreeType::Source;
1011 using size_type =
typename LoserTreeType::Source;
1012 using RandomAccessIteratorPair =
1013 typename std::iterator_traits<RandomAccessIteratorIterator>
1015 using RandomAccessIterator =
typename RandomAccessIteratorPair
1017 using DiffType =
typename std::iterator_traits<RandomAccessIterator>
1020 Source k =
static_cast<Source
>(seqs_end - seqs_begin);
1023 LoserTreeType lt(static_cast<size_type>(k), *(seqs_begin->second - 1), comp);
1025 DiffType total_size = 0;
1027 for (Source t = 0; t < k; ++t)
1029 assert(seqs_begin[t].first != seqs_begin[t].second);
1031 lt.insert_start(&*seqs_begin[t].first, t,
false);
1041 RandomAccessIterator3 target_end = target + size;
1042 if (target == target_end)
1046 int source = lt.min_source();
1048 *target = *seqs_begin[source].first;
1049 ++seqs_begin[source].first;
1052 while (target < target_end)
1055 lt.delete_min_insert(&*seqs_begin[source].first,
false);
1058 source = lt.min_source();
1060 *target = *seqs_begin[source].first;
1061 ++seqs_begin[source].first;
1070 typename RandomAccessIteratorIterator,
1071 typename RandomAccessIterator3,
1072 typename Comparator>
1074 RandomAccessIteratorIterator seqs_begin,
1075 RandomAccessIteratorIterator seqs_end,
1076 RandomAccessIterator3 target,
1077 typename std::iterator_traits<
1078 typename std::iterator_traits<
1079 RandomAccessIteratorIterator>::value_type::first_type>::
1080 difference_type size,
1082 using RandomAccessIterator =
1083 typename std::iterator_traits<RandomAccessIteratorIterator>
1084 ::value_type::first_type;
1085 using value_type =
typename std::iterator_traits<RandomAccessIterator>
1087 using DiffType =
typename std::iterator_traits<RandomAccessIterator>
1091 RandomAccessIterator3 target_end;
1092 DiffType overhang = prepare_unguarded<Stable>(seqs_begin, seqs_end, comp, min_seq);
1094 DiffType total_size = 0;
1095 for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
1098 if (overhang != static_cast<DiffType>(-1))
1100 DiffType unguarded_size =
std::min(size, total_size - overhang);
1102 LoserTreeUnguarded<Stable, value_type, Comparator> >(
1103 seqs_begin, seqs_end, target, unguarded_size, comp);
1104 overhang = size - unguarded_size;
1110 target_end = target;
1114 LoserTree<Stable, value_type, Comparator> >(
1115 seqs_begin, seqs_end, target_end, overhang, comp);
1122 typename RandomAccessIteratorIterator,
1123 typename RandomAccessIterator3,
1124 typename Comparator>
1126 RandomAccessIteratorIterator seqs_begin,
1127 RandomAccessIteratorIterator seqs_end,
1128 RandomAccessIterator3 target,
1129 typename std::iterator_traits<
1130 typename std::iterator_traits<
1131 RandomAccessIteratorIterator>::value_type::first_type>::
1132 difference_type size,
1134 using RandomAccessIterator =
1135 typename std::iterator_traits<RandomAccessIteratorIterator>
1136 ::value_type::first_type;
1137 using value_type =
typename std::iterator_traits<RandomAccessIterator>
1141 for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
1144 RandomAccessIterator3 target_end
1146 LoserTreeUnguarded<Stable, value_type, Comparator> >(
1147 seqs_begin, seqs_end, target, size, comp);
1150 for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
1192 typename RandomAccessIteratorIterator,
1193 typename RandomAccessIterator3,
1194 typename Comparator = std::less<
1195 typename std::iterator_traits<
1196 typename std::iterator_traits<RandomAccessIteratorIterator>
1199 RandomAccessIteratorIterator seqs_begin,
1200 RandomAccessIteratorIterator seqs_end,
1201 RandomAccessIterator3 target,
1202 typename std::iterator_traits<
1203 typename std::iterator_traits<
1204 RandomAccessIteratorIterator>::value_type::first_type>::
1205 difference_type size,
1206 Comparator comp = Comparator(),
1209 using RandomAccessIterator =
1210 typename std::iterator_traits<RandomAccessIteratorIterator>
1211 ::value_type::first_type;
1212 using value_type =
typename std::iterator_traits<RandomAccessIterator>
1215 RandomAccessIterator3 return_target = target;
1216 int k =
static_cast<int>(seqs_end - seqs_begin);
1221 using namespace multiway_merge_detail;
1228 return_target = std::copy(
1229 seqs_begin[0].first, seqs_begin[0].first + size, target);
1230 seqs_begin[0].first += size;
1234 seqs_begin[0].first, seqs_begin[0].second,
1235 seqs_begin[1].first, seqs_begin[1].second,
1236 target, size, comp);
1243 seqs_begin, seqs_end, target, size, comp);
1246 return_target = multiway_merge_3_variant<unguarded_iterator>(
1247 seqs_begin, seqs_end, target, size, comp);
1250 return_target = multiway_merge_3_variant<guarded_iterator>(
1251 seqs_begin, seqs_end, target, size, comp);
1260 seqs_begin, seqs_end, target, size, comp);
1263 return_target = multiway_merge_4_variant<unguarded_iterator>(
1264 seqs_begin, seqs_end, target, size, comp);
1267 return_target = multiway_merge_4_variant<guarded_iterator>(
1268 seqs_begin, seqs_end, target, size, comp);
1277 return_target = multiway_merge_bubble<Stable>(
1278 seqs_begin, seqs_end, target, size, comp);
1282 LoserTree<Stable, value_type, Comparator> >(
1283 seqs_begin, seqs_end, target, size, comp);
1286 return_target = multiway_merge_loser_tree_combined<Stable>(
1287 seqs_begin, seqs_end, target, size, comp);
1290 return_target = multiway_merge_loser_tree_sentinel<Stable>(
1291 seqs_begin, seqs_end, target, size, comp);
1294 assert(0 &&
"multiway_merge algorithm not implemented");
1300 return return_target;
1318 typename RandomAccessIteratorIterator,
1319 typename RandomAccessIterator3,
1320 typename Comparator = std::less<
1321 typename std::iterator_traits<
1322 typename std::iterator_traits<RandomAccessIteratorIterator>
1325 RandomAccessIteratorIterator seqs_begin,
1326 RandomAccessIteratorIterator seqs_end,
1327 RandomAccessIterator3 target,
1328 typename std::iterator_traits<
1329 typename std::iterator_traits<
1330 RandomAccessIteratorIterator>::value_type::first_type>::
1331 difference_type size,
1332 Comparator comp = Comparator(),
1336 seqs_begin, seqs_end, target, size, comp, mwma);
1351 typename RandomAccessIteratorIterator,
1352 typename RandomAccessIterator3,
1353 typename Comparator = std::less<
1354 typename std::iterator_traits<
1355 typename std::iterator_traits<RandomAccessIteratorIterator>
1358 RandomAccessIteratorIterator seqs_begin,
1359 RandomAccessIteratorIterator seqs_end,
1360 RandomAccessIterator3 target,
1361 typename std::iterator_traits<
1362 typename std::iterator_traits<
1363 RandomAccessIteratorIterator>::value_type::first_type>::
1364 difference_type size,
1365 Comparator comp = Comparator(),
1369 seqs_begin, seqs_end, target, size, comp, mwma);
1384 typename RandomAccessIteratorIterator,
1385 typename RandomAccessIterator3,
1386 typename Comparator = std::less<
1387 typename std::iterator_traits<
1388 typename std::iterator_traits<RandomAccessIteratorIterator>
1391 RandomAccessIteratorIterator seqs_begin,
1392 RandomAccessIteratorIterator seqs_end,
1393 RandomAccessIterator3 target,
1394 typename std::iterator_traits<
1395 typename std::iterator_traits<
1396 RandomAccessIteratorIterator>::value_type::first_type>::
1397 difference_type size,
1398 Comparator comp = Comparator(),
1402 seqs_begin, seqs_end, target, size, comp, mwma);
1417 typename RandomAccessIteratorIterator,
1418 typename RandomAccessIterator3,
1419 typename Comparator = std::less<
1420 typename std::iterator_traits<
1421 typename std::iterator_traits<RandomAccessIteratorIterator>
1424 RandomAccessIteratorIterator seqs_begin,
1425 RandomAccessIteratorIterator seqs_end,
1426 RandomAccessIterator3 target,
1427 typename std::iterator_traits<
1428 typename std::iterator_traits<
1429 RandomAccessIteratorIterator>::value_type::first_type>::
1430 difference_type size,
1431 Comparator comp = Comparator(),
1435 seqs_begin, seqs_end, target, size, comp, mwma);
1442 #endif // !TLX_ALGORITHM_MULTIWAY_MERGE_HEADER
Comparator & comp_
Comparator.
std::iterator_traits< typename RandomAccessIteratorPair::first_type >::difference_type iterpair_size(const RandomAccessIteratorPair &p)
Size of a sequence described by a pair of iterators.
RandomAccessIterator3 multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
Multi-way merging procedure for a high branching factor, guarded case.
RandomAccessIterator end_
End iterator of the sequence.
RandomAccessIterator & iterator()
Convert to wrapped iterator.
RandomAccessIterator3 multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
Highly efficient 4-way merging procedure.
#define TLX_DECISION(a, b, c, d)
RandomAccessIterator3 multiway_merge_4_combined(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
Iterator wrapper supporting an implicit supremum at the end of the sequence, dominating all compariso...
RandomAccessIterator3 multiway_merge_bubble(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
Basic multi-way merging procedure.
RandomAccessIterator3 multiway_merge(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp=Comparator(), MultiwayMergeAlgorithm mwma=MWMA_ALGORITHM_DEFAULT)
Sequential multi-way merge.
Simpler non-growing vector without initialization.
MultiwayMergeAlgorithm
Different merging algorithms: bubblesort-alike, loser-tree variants, enum sentinel.
RandomAccessIterator current
Current iterator position.
RandomAccessIterator3 stable_multiway_merge(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp=Comparator(), MultiwayMergeAlgorithm mwma=MWMA_ALGORITHM_DEFAULT)
Stable sequential multi-way merge.
OutputIterator merge_advance(RandomAccessIterator1 &begin1, RandomAccessIterator1 end1, RandomAccessIterator2 &begin2, RandomAccessIterator2 end2, OutputIterator target, DiffType max_size, Comparator comp)
Merge routine being able to merge only the max_size smallest elements.
unguarded_iterator(RandomAccessIterator begin, RandomAccessIterator, Comparator &comp)
Constructor.
value_type & operator*()
Dereference operator.
friend bool operator<(self_type &bi1, self_type &bi2)
Compare two elements referenced by guarded iterators.
guarded_iterator(RandomAccessIterator begin, RandomAccessIterator end, Comparator &comp)
Constructor.
#define TLX_MERGE4CASE(a, b, c, d, c0, c1, c2)
std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type prepare_unguarded_sentinel(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, Comparator comp)
Prepare a set of sequences to be merged with a (end) guard (sentinel)
std::vector< std::string > split(char sep, const std::string &str, std::string::size_type limit)
Split the given string at each separator character into distinct substrings.
RandomAccessIterator3 multiway_merge_loser_tree_combined(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
#define TLX_MERGE3CASE(a, b, c, c0, c1)
typename std::iterator_traits< RandomAccessIterator >::value_type value_type
Value type of the iterator.
RandomAccessIterator3 multiway_merge_3_variant(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
Highly efficient 3-way merging procedure.
RandomAccessIterator current
Current iterator position.
std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type prepare_unguarded(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, Comparator comp, int &min_sequence)
Prepare a set of sequences to be merged without a (end) guard.
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
RandomAccessIterator3 stable_multiway_merge_sentinels(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp=Comparator(), MultiwayMergeAlgorithm mwma=MWMA_ALGORITHM_DEFAULT)
Stable sequential multi-way merge with sentinels in sequences.
RandomAccessIterator3 multiway_merge_loser_tree_unguarded(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
Multi-way merging procedure for a high branching factor, unguarded case.
RandomAccessIterator3 multiway_merge_loser_tree_sentinel(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
Comparator & comp_
Comparator.
RandomAccessIterator3 multiway_merge_base(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp=Comparator(), MultiwayMergeAlgorithm mwma=MWMA_ALGORITHM_DEFAULT)
Sequential multi-way merging switch.
friend bool operator<=(self_type &bi1, self_type &bi2)
Compare two elements referenced by guarded iterators.
self_type & operator++()
Pre-increment operator.
static uint_pair min()
return an uint_pair instance containing the smallest value possible
RandomAccessIterator3 multiway_merge_3_combined(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp)
typename std::iterator_traits< RandomAccessIterator >::value_type value_type
Value type of the iterator.
RandomAccessIterator3 multiway_merge_sentinels(RandomAccessIteratorIterator seqs_begin, RandomAccessIteratorIterator seqs_end, RandomAccessIterator3 target, typename std::iterator_traits< typename std::iterator_traits< RandomAccessIteratorIterator >::value_type::first_type >::difference_type size, Comparator comp=Comparator(), MultiwayMergeAlgorithm mwma=MWMA_ALGORITHM_DEFAULT)
Sequential multi-way merge with sentinels in sequences.
RandomAccessIterator & iterator()
Convert to wrapped iterator.