Commit 214ece29 by Johannes Singler Committed by Johannes Singler

2008-04-23 Johannes Singler <singler@ira.uka.de>

        * include/parallel/multiway_merge.h
        (multiway_merge_loser_tree):
        Leave checks to callers, add precondition instead.
        (multiway_merge_loser_tree_unguarded): Likewise.
        (multiway_merge_loser_tree_sentinel): Likewise.
        (sequential_multiway_merge): Added checks for total length 0.
        (parallel_multiway_merge): Skip empty sequences.
        (multiway_merge, all variants):
        Remove temporary variable, return directly.
        (stable_multiway_merge, all variants): Likewise.
        (multiway_merge_sentinels, all variants):  Likewise.
        (stable_multiway_merge_sentinels, all variants): Likewise.
        * include/parallel/multiseq_selection.h
        (multiseq_partition): More detailed assertions.

From-SVN: r134580
parent 7edc89d4
2008-04-23 Johannes Singler <singler@ira.uka.de>
* include/parallel/multiway_merge.h
(multiway_merge_loser_tree):
Leave checks to callers, add precondition instead.
(multiway_merge_loser_tree_unguarded): Likewise.
(multiway_merge_loser_tree_sentinel): Likewise.
(sequential_multiway_merge): Added checks for total length 0.
(parallel_multiway_merge): Skip empty sequences.
(multiway_merge, all variants):
Remove temporary variable, return directly.
(stable_multiway_merge, all variants): Likewise.
(multiway_merge_sentinels, all variants): Likewise.
(stable_multiway_merge_sentinels, all variants): Likewise.
* include/parallel/multiseq_selection.h
(multiseq_partition): More detailed assertions.
2008-04-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> 2008-04-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* acinclude.m4 (GLIBCXX_CHECK_SETRLIMIT, GLIBCXX_ENABLE_C99) * acinclude.m4 (GLIBCXX_CHECK_SETRLIMIT, GLIBCXX_ENABLE_C99)
......
...@@ -124,22 +124,22 @@ namespace __gnu_parallel ...@@ -124,22 +124,22 @@ namespace __gnu_parallel
* @param comp The ordering functor, defaults to std::less<T>. * @param comp The ordering functor, defaults to std::less<T>.
*/ */
template<typename RanSeqs, typename RankType, typename RankIterator, template<typename RanSeqs, typename RankType, typename RankIterator,
typename Comparator> typename Comparator>
void void
multiseq_partition(RanSeqs begin_seqs, RanSeqs end_seqs, multiseq_partition(RanSeqs begin_seqs, RanSeqs end_seqs,
RankType rank, RankType rank,
RankIterator begin_offsets, RankIterator begin_offsets,
Comparator comp = std::less< Comparator comp = std::less<
typename std::iterator_traits<typename typename std::iterator_traits<typename
std::iterator_traits<RanSeqs>::value_type:: std::iterator_traits<RanSeqs>::value_type::
first_type>::value_type>()) // std::less<T> first_type>::value_type>()) // std::less<T>
{ {
_GLIBCXX_CALL(end_seqs - begin_seqs) _GLIBCXX_CALL(end_seqs - begin_seqs)
typedef typename std::iterator_traits<RanSeqs>::value_type::first_type typedef typename std::iterator_traits<RanSeqs>::value_type::first_type
It; It;
typedef typename std::iterator_traits<It>::difference_type typedef typename std::iterator_traits<It>::difference_type
difference_type; difference_type;
typedef typename std::iterator_traits<It>::value_type value_type; typedef typename std::iterator_traits<It>::value_type value_type;
lexicographic<value_type, int, Comparator> lcomp(comp); lexicographic<value_type, int, Comparator> lcomp(comp);
...@@ -148,19 +148,27 @@ namespace __gnu_parallel ...@@ -148,19 +148,27 @@ namespace __gnu_parallel
// Number of sequences, number of elements in total (possibly // Number of sequences, number of elements in total (possibly
// including padding). // including padding).
difference_type m = std::distance(begin_seqs, end_seqs), N = 0, difference_type m = std::distance(begin_seqs, end_seqs), N = 0,
nmax, n, r; nmax, n, r;
for (int i = 0; i < m; i++) for (int i = 0; i < m; i++)
N += std::distance(begin_seqs[i].first, begin_seqs[i].second); {
N += std::distance(begin_seqs[i].first, begin_seqs[i].second);
_GLIBCXX_PARALLEL_ASSERT(
std::distance(begin_seqs[i].first, begin_seqs[i].second) > 0);
}
if (rank == N) if (rank == N)
{ {
for (int i = 0; i < m; i++) for (int i = 0; i < m; i++)
begin_offsets[i] = begin_seqs[i].second; // Very end. begin_offsets[i] = begin_seqs[i].second; // Very end.
// Return m - 1; // Return m - 1;
} return;
}
_GLIBCXX_PARALLEL_ASSERT(m != 0 && N != 0 && rank >= 0 && rank < N);
_GLIBCXX_PARALLEL_ASSERT(m != 0);
_GLIBCXX_PARALLEL_ASSERT(N != 0);
_GLIBCXX_PARALLEL_ASSERT(rank >= 0);
_GLIBCXX_PARALLEL_ASSERT(rank < N);
difference_type* ns = new difference_type[m]; difference_type* ns = new difference_type[m];
difference_type* a = new difference_type[m]; difference_type* a = new difference_type[m];
......
...@@ -282,7 +282,8 @@ template<typename RandomAccessIterator, typename Comparator> ...@@ -282,7 +282,8 @@ template<typename RandomAccessIterator, typename Comparator>
* @param seqs_end End iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence. * @param target Begin iterator out output sequence.
* @param comp Comparator. * @param comp Comparator.
* @param length Maximum length to merge. * @param length Maximum length to merge, less equal than the
* total number of elements available.
* *
* @return End iterator of output sequence. * @return End iterator of output sequence.
*/ */
...@@ -401,7 +402,8 @@ template<template<typename RAI, typename C> class iterator, ...@@ -401,7 +402,8 @@ template<template<typename RAI, typename C> class iterator,
* @param seqs_end End iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence. * @param target Begin iterator out output sequence.
* @param comp Comparator. * @param comp Comparator.
* @param length Maximum length to merge. * @param length Maximum length to merge, less equal than the
* total number of elements available.
* *
* @return End iterator of output sequence. * @return End iterator of output sequence.
*/ */
...@@ -518,11 +520,14 @@ template<template<typename RAI, typename C> class iterator, ...@@ -518,11 +520,14 @@ template<template<typename RAI, typename C> class iterator,
* *
* Stability is selected through the used LoserTree class <tt>LT</tt>. * Stability is selected through the used LoserTree class <tt>LT</tt>.
* *
* At least one non-empty sequence is required.
*
* @param seqs_begin Begin iterator of iterator pair input sequence. * @param seqs_begin Begin iterator of iterator pair input sequence.
* @param seqs_end End iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence. * @param target Begin iterator out output sequence.
* @param comp Comparator. * @param comp Comparator.
* @param length Maximum length to merge. * @param length Maximum length to merge, less equal than the
* total number of elements available.
* *
* @return End iterator of output sequence. * @return End iterator of output sequence.
*/ */
...@@ -551,22 +556,16 @@ template<typename LT, ...@@ -551,22 +556,16 @@ template<typename LT,
LT lt(k, comp); LT lt(k, comp);
difference_type total_length = 0;
// Default value for potentially non-default-constructible types. // Default value for potentially non-default-constructible types.
value_type* arbitrary_element = NULL; value_type* arbitrary_element = NULL;
for (int t = 0; t < k; ++t) for (int t = 0; t < k; ++t)
{ {
if(arbitrary_element == NULL if(arbitrary_element == NULL
&& _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0) && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
arbitrary_element = &(*seqs_begin[t].first); arbitrary_element = &(*seqs_begin[t].first);
total_length += _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]);
} }
if(total_length == 0)
return target;
for (int t = 0; t < k; ++t) for (int t = 0; t < k; ++t)
{ {
if (seqs_begin[t].first == seqs_begin[t].second) if (seqs_begin[t].first == seqs_begin[t].second)
...@@ -577,11 +576,9 @@ template<typename LT, ...@@ -577,11 +576,9 @@ template<typename LT,
lt.init(); lt.init();
const difference_type const_total_length(std::min(total_length, length));
int source; int source;
for (difference_type i = 0; i < const_total_length; ++i) for (difference_type i = 0; i < length; ++i)
{ {
//take out //take out
source = lt.get_min_source(); source = lt.get_min_source();
...@@ -612,7 +609,8 @@ template<typename LT, ...@@ -612,7 +609,8 @@ template<typename LT,
* @param seqs_end End iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence. * @param target Begin iterator out output sequence.
* @param comp Comparator. * @param comp Comparator.
* @param length Maximum length to merge. * @param length Maximum length to merge, less equal than the
* total number of elements available.
* *
* @return End iterator of output sequence. * @return End iterator of output sequence.
*/ */
...@@ -644,23 +642,16 @@ template<typename LT, ...@@ -644,23 +642,16 @@ template<typename LT,
LT lt(k, sentinel, comp); LT lt(k, sentinel, comp);
difference_type total_length = 0;
for (int t = 0; t < k; ++t) for (int t = 0; t < k; ++t)
{ {
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(seqs_begin[t].first != seqs_begin[t].second); _GLIBCXX_PARALLEL_ASSERT(seqs_begin[t].first != seqs_begin[t].second);
#endif #endif
lt.insert_start(*seqs_begin[t].first, t, false); lt.insert_start(*seqs_begin[t].first, t, false);
total_length += _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]);
} }
lt.init(); lt.init();
// Do not go past end.
length = std::min(total_length, length);
int source; int source;
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
...@@ -698,6 +689,7 @@ template<typename LT, ...@@ -698,6 +689,7 @@ template<typename LT,
/** @brief Multi-way merging procedure for a high branching factor, /** @brief Multi-way merging procedure for a high branching factor,
* requiring sentinels to exist. * requiring sentinels to exist.
*
* @param stable The value must the same as for the used LoserTrees. * @param stable The value must the same as for the used LoserTrees.
* @param UnguardedLoserTree Loser Tree variant to use for the unguarded * @param UnguardedLoserTree Loser Tree variant to use for the unguarded
* merging. * merging.
...@@ -708,7 +700,8 @@ template<typename LT, ...@@ -708,7 +700,8 @@ template<typename LT,
* @param seqs_end End iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence. * @param target Begin iterator out output sequence.
* @param comp Comparator. * @param comp Comparator.
* @param length Maximum length to merge. * @param length Maximum length to merge, less equal than the
* total number of elements available.
* *
* @return End iterator of output sequence. * @return End iterator of output sequence.
*/ */
...@@ -737,23 +730,16 @@ template< ...@@ -737,23 +730,16 @@ template<
RandomAccessIterator3 target_end; RandomAccessIterator3 target_end;
difference_type total_length = 0;
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s) for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
{ // Move the sequends end behind the sentinel spots. This has the
total_length += _GLIBCXX_PARALLEL_LENGTH(*s); // effect that the sentinel appears to be within the sequence. Then,
// we can use the unguarded variant if we merge out as many
// Move the sequends end behind the sentinel spots. This has the // non-sentinel elements as we have.
// effect that the sentinel appears to be within the sequence. Then, ++((*s).second);
// we can use the unguarded variant if we merge out as many
// non-sentinel elements as we have.
++((*s).second);
}
difference_type unguarded_length =
std::min(length, total_length);
target_end = multiway_merge_loser_tree_unguarded target_end = multiway_merge_loser_tree_unguarded
<UnguardedLoserTree> <UnguardedLoserTree>
(seqs_begin, seqs_end, target, 0, comp, unguarded_length); (seqs_begin, seqs_end, target, 0, comp, length);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(target_end == target + length); _GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
...@@ -763,7 +749,7 @@ template< ...@@ -763,7 +749,7 @@ template<
// Restore the sequence ends so the sentinels are not contained in the // Restore the sequence ends so the sentinels are not contained in the
// sequence any more (see comment in loop above). // sequence any more (see comment in loop above).
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s) for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
{ --((*s).second); } --((*s).second);
return target_end; return target_end;
} }
...@@ -977,7 +963,8 @@ struct multiway_merge_k_variant_sentinel_switch ...@@ -977,7 +963,8 @@ struct multiway_merge_k_variant_sentinel_switch
* @param seqs_end End iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence. * @param target Begin iterator out output sequence.
* @param comp Comparator. * @param comp Comparator.
* @param length Maximum length to merge. * @param length Maximum length to merge, possibly larger than the
* number of elements available.
* @param stable Stable merging incurs a performance penalty. * @param stable Stable merging incurs a performance penalty.
* @param sentinel The sequences have a sentinel element. * @param sentinel The sequences have a sentinel element.
* @return End iterator of output sequence. */ * @return End iterator of output sequence. */
...@@ -1010,7 +997,16 @@ template< ...@@ -1010,7 +997,16 @@ template<
} }
#endif #endif
RandomAccessIterator3 return_target = target; _DifferenceTp total_length = 0;
for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
total_length += _GLIBCXX_PARALLEL_LENGTH(*s);
length = std::min<_DifferenceTp>(length, total_length);
if(length == 0)
return target;
RandomAccessIterator3 return_target = target;
int k = static_cast<int>(seqs_end - seqs_begin); int k = static_cast<int>(seqs_end - seqs_begin);
switch (k) switch (k)
...@@ -1079,7 +1075,7 @@ struct sampling_sorter ...@@ -1079,7 +1075,7 @@ struct sampling_sorter
/** /**
* @brief Non-stable sorting functor. * @brief Non-stable sorting functor.
* *
* Used to reduce code instanciation in multiway_merge_sampling_splitting. * Used to reduce code instantiation in multiway_merge_sampling_splitting.
*/ */
template<class RandomAccessIterator, class StrictWeakOrdering> template<class RandomAccessIterator, class StrictWeakOrdering>
struct sampling_sorter<false, RandomAccessIterator, StrictWeakOrdering> struct sampling_sorter<false, RandomAccessIterator, StrictWeakOrdering>
...@@ -1126,11 +1122,11 @@ void multiway_merge_sampling_splitting( ...@@ -1126,11 +1122,11 @@ void multiway_merge_sampling_splitting(
{ {
difference_type sample_index = difference_type sample_index =
static_cast<difference_type>( static_cast<difference_type>(
_GLIBCXX_PARALLEL_LENGTH(seqs_begin[s]) * (double(i + 1) / _GLIBCXX_PARALLEL_LENGTH(seqs_begin[s])
(num_samples + 1)) * (double(length) * (double(i + 1) / (num_samples + 1))
/ total_length)); * (double(length) / total_length));
new(&(samples[s * num_samples + i])) value_type( new(&(samples[s * num_samples + i]))
seqs_begin[s].first[sample_index]); value_type(seqs_begin[s].first[sample_index]);
} }
// Sort stable or non-stable, depending on value of template parameter // Sort stable or non-stable, depending on value of template parameter
...@@ -1152,10 +1148,8 @@ void multiway_merge_sampling_splitting( ...@@ -1152,10 +1148,8 @@ void multiway_merge_sampling_splitting(
comp) comp)
- seqs_begin[seq].first; - seqs_begin[seq].first;
else else
{ // Absolute beginning.
// Absolute beginning. pieces[slab][seq].first = 0;
pieces[slab][seq].first = 0;
}
if ((slab + 1) < num_threads) if ((slab + 1) < num_threads)
pieces[slab][seq].second = pieces[slab][seq].second =
std::upper_bound( std::upper_bound(
...@@ -1165,13 +1159,16 @@ void multiway_merge_sampling_splitting( ...@@ -1165,13 +1159,16 @@ void multiway_merge_sampling_splitting(
num_threads], comp) num_threads], comp)
- seqs_begin[seq].first; - seqs_begin[seq].first;
else else
pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]); // Absolute end.
pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
} }
::operator delete(samples); ::operator delete(samples);
} }
/** /**
* @brief Exact splitting for parallel multiway-merge routine. * @brief Exact splitting for parallel multiway-merge routine.
*
* None of the passed sequences may be empty.
*/ */
template< template<
bool stable bool stable
...@@ -1269,7 +1266,8 @@ void multiway_merge_exact_splitting( ...@@ -1269,7 +1266,8 @@ void multiway_merge_exact_splitting(
* @param seqs_end End iterator of iterator pair input sequence. * @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence. * @param target Begin iterator out output sequence.
* @param comp Comparator. * @param comp Comparator.
* @param length Maximum length to merge. * @param length Maximum length to merge, possibly larger than the
* number of elements available.
* @param stable Stable merging incurs a performance penalty. * @param stable Stable merging incurs a performance penalty.
* @param sentinel Ignored. * @param sentinel Ignored.
* @return End iterator of output sequence. * @return End iterator of output sequence.
...@@ -1304,23 +1302,41 @@ template< ...@@ -1304,23 +1302,41 @@ template<
typedef typename typedef typename
std::iterator_traits<RandomAccessIterator1>::value_type value_type; std::iterator_traits<RandomAccessIterator1>::value_type value_type;
// k sequences. // Leave only non-empty sequences.
int k = static_cast<int>(seqs_end - seqs_begin); std::pair<RandomAccessIterator1, RandomAccessIterator1>* ne_seqs =
static_cast<std::pair<RandomAccessIterator1, RandomAccessIterator1>*>(
::operator new(
sizeof(std::pair<RandomAccessIterator1, RandomAccessIterator1>)
* (seqs_end - seqs_begin)));
int k = 0;
difference_type total_length = 0; difference_type total_length = 0;
for (RandomAccessIteratorIterator raii = seqs_begin; for (RandomAccessIteratorIterator raii = seqs_begin;
raii != seqs_end; ++raii) raii != seqs_end; ++raii)
total_length += _GLIBCXX_PARALLEL_LENGTH(*raii); {
_DifferenceTp seq_length = _GLIBCXX_PARALLEL_LENGTH(*raii);
if(seq_length > 0)
{
total_length += seq_length;
//ne_seqs[k] = *raii;
new(&(ne_seqs[k++]))
std::pair<RandomAccessIterator1, RandomAccessIterator1>(*raii);
}
}
_GLIBCXX_CALL(total_length) _GLIBCXX_CALL(total_length)
length = std::min<_DifferenceTp>(length, total_length);
if (total_length == 0 || k == 0) if (total_length == 0 || k == 0)
{
::operator delete(ne_seqs);
return target; return target;
}
std::vector<std::pair<difference_type, difference_type> >* pieces; std::vector<std::pair<difference_type, difference_type> >* pieces;
thread_index_t num_threads = static_cast<thread_index_t>( thread_index_t num_threads = static_cast<thread_index_t>
std::min<difference_type>(get_max_threads(), total_length)); (std::min<difference_type>(get_max_threads(), total_length));
# pragma omp parallel num_threads (num_threads) # pragma omp parallel num_threads (num_threads)
{ {
...@@ -1337,7 +1353,7 @@ template< ...@@ -1337,7 +1353,7 @@ template<
__gnu_parallel::_Settings::get().merge_oversampling * __gnu_parallel::_Settings::get().merge_oversampling *
num_threads; num_threads;
splitter(seqs_begin, seqs_end, comp, length, total_length, splitter(ne_seqs, ne_seqs + k, comp, length, total_length,
pieces); pieces);
} //single } //single
...@@ -1348,50 +1364,37 @@ template< ...@@ -1348,50 +1364,37 @@ template<
for (int c = 0; c < k; ++c) for (int c = 0; c < k; ++c)
target_position += pieces[iam][c].first; target_position += pieces[iam][c].first;
if (k > 2) std::pair<RandomAccessIterator1, RandomAccessIterator1>* chunks
{ = new std::pair<RandomAccessIterator1, RandomAccessIterator1>[k];
std::pair<RandomAccessIterator1, RandomAccessIterator1>* chunks
= new for (int s = 0; s < k; ++s)
std::pair<RandomAccessIterator1, RandomAccessIterator1>[k];
difference_type local_length = 0;
for (int s = 0; s < k; ++s)
{
chunks[s] = std::make_pair(
seqs_begin[s].first + pieces[iam][s].first,
seqs_begin[s].first + pieces[iam][s].second);
local_length += _GLIBCXX_PARALLEL_LENGTH(chunks[s]);
}
sequential_multiway_merge<stable, sentinels>(
chunks, chunks + k, target + target_position, comp,
std::min(local_length, length - target_position));
delete[] chunks;
}
else if (k == 2)
{ {
RandomAccessIterator1 chunks[s] = std::make_pair(
begin0 = seqs_begin[0].first + pieces[iam][0].first, ne_seqs[s].first + pieces[iam][s].first,
begin1 = seqs_begin[1].first + pieces[iam][1].first; ne_seqs[s].first + pieces[iam][s].second);
merge_advance(begin0,
seqs_begin[0].first + pieces[iam][0].second,
begin1,
seqs_begin[1].first + pieces[iam][1].second,
target + target_position,
(pieces[iam][0].second - pieces[iam][0].first) +
(pieces[iam][1].second - pieces[iam][1].first),
comp);
} }
if(length > target_position)
sequential_multiway_merge<stable, sentinels>(
chunks, chunks + k, target + target_position, comp,
length - target_position);
delete[] chunks;
} // parallel } // parallel
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target + length, comp)); _GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target + length, comp));
#endif #endif
k = 0;
// Update ends of sequences. // Update ends of sequences.
for (int s = 0; s < k; ++s) for (RandomAccessIteratorIterator raii = seqs_begin;
seqs_begin[s].first += pieces[num_threads - 1][s].second; raii != seqs_end; ++raii)
{
_DifferenceTp length = _GLIBCXX_PARALLEL_LENGTH(*raii);
if(length > 0)
(*raii).first += pieces[num_threads - 1][k++].second;
}
delete[] pieces; delete[] pieces;
...@@ -1430,12 +1433,12 @@ template< ...@@ -1430,12 +1433,12 @@ template<
* for (int i = 0; i < 10; ++i) * for (int i = 0; i < 10; ++i)
* for (int j = 0; i < 10; ++j) * for (int j = 0; i < 10; ++j)
* sequences[i][j] = j; * sequences[i][j] = j;
* *
* int out[33]; * int out[33];
* std::vector<std::pair<int*> > seqs; * std::vector<std::pair<int*> > seqs;
* for (int i = 0; i < 10; ++i) * for (int i = 0; i < 10; ++i)
* { seqs.push(std::make_pair<int*>(sequences[i], sequences[i] + 10)) } * { seqs.push(std::make_pair<int*>(sequences[i], sequences[i] + 10)) }
* *
* multiway_merge(seqs.begin(), seqs.end(), target, std::less<int>(), 33); * multiway_merge(seqs.begin(), seqs.end(), target, std::less<int>(), 33);
* </pre> * </pre>
* *
...@@ -1461,10 +1464,12 @@ template< ...@@ -1461,10 +1464,12 @@ template<
* @param seqs_end end of sequence sequence * @param seqs_end end of sequence sequence
* @param target target sequence to merge to. * @param target target sequence to merge to.
* @param comp strict weak ordering to use for element comparison. * @param comp strict weak ordering to use for element comparison.
* @param length the number of elements to merge into target. * @param length Maximum length to merge, possibly larger than the
* number of elements available.
* *
* @return end iterator of output sequence * @return end iterator of output sequence
*/ */
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1486,28 +1491,26 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1486,28 +1491,26 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ false> </* stable = */ false, /* sentinels = */ false>
(seqs_begin, seqs_end, target, comp, (seqs_begin, seqs_end, target, comp,
multiway_merge_sampling_splitting</* stable = */ false, multiway_merge_sampling_splitting</* stable = */ false,
RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>, RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge return sequential_multiway_merge
</* stable = */false, /* sentinels = */ false>( </* stable = */false, /* sentinels = */ false>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1533,6 +1536,7 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1533,6 +1536,7 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length); (seqs_begin, seqs_end, target, comp, length);
} }
//public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1555,14 +1559,13 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1555,14 +1559,13 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ false>( </* stable = */ false, /* sentinels = */ false>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, target, comp,
...@@ -1570,14 +1573,13 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1570,14 +1573,13 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>, RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ false>( </* stable = */ false, /* sentinels = */ false>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1599,14 +1601,13 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1599,14 +1601,13 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ false>( </* stable = */ true, /* sentinels = */ false>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, target, comp,
...@@ -1614,14 +1615,13 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1614,14 +1615,13 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>, RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ false>( </* stable = */ true, /* sentinels = */ false>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1639,7 +1639,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1639,7 +1639,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute multiway merge *sequentially*. // Execute multiway merge *sequentially*.
return sequential_multiway_merge return sequential_multiway_merge
...@@ -1647,6 +1647,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1647,6 +1647,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length); (seqs_begin, seqs_end, target, comp, length);
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1664,19 +1665,18 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1664,19 +1665,18 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ false>( </* stable = */ true, /* sentinels = */ false>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, target, comp,
...@@ -1685,12 +1685,10 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1685,12 +1685,10 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge</* stable = */ true, return sequential_multiway_merge</* stable = */ true,
/* sentinels = */ false>( /* sentinels = */ false>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
/** /**
...@@ -1706,7 +1704,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1706,7 +1704,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
* that breaks ties by sequence number but is slower. * that breaks ties by sequence number but is slower.
* *
* The first entries of the pairs (i.e. the begin iterators) will be moved * The first entries of the pairs (i.e. the begin iterators) will be moved
* forward. * forward accordingly.
* *
* The output sequence has to provide enough space for all elements * The output sequence has to provide enough space for all elements
* that are written to it. * that are written to it.
...@@ -1763,10 +1761,12 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin ...@@ -1763,10 +1761,12 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
* @param seqs_end end of sequence sequence * @param seqs_end end of sequence sequence
* @param target target sequence to merge to. * @param target target sequence to merge to.
* @param comp strict weak ordering to use for element comparison. * @param comp strict weak ordering to use for element comparison.
* @param length the number of elements to merge into target. * @param length Maximum length to merge, possibly larger than the
* number of elements available.
* *
* @return end iterator of output sequence * @return end iterator of output sequence
*/ */
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1783,19 +1783,18 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1783,19 +1783,18 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ true> </* stable = */ false, /* sentinels = */ true>
(seqs_begin, seqs_end, target, comp, (seqs_begin, seqs_end, target, comp,
multiway_merge_sampling_splitting multiway_merge_sampling_splitting
...@@ -1803,14 +1802,13 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1803,14 +1802,13 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge return sequential_multiway_merge
</* stable = */false, /* sentinels = */ true>( </* stable = */false, /* sentinels = */ true>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
//public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1828,7 +1826,7 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1828,7 +1826,7 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute multiway merge *sequentially*. // Execute multiway merge *sequentially*.
return sequential_multiway_merge return sequential_multiway_merge
...@@ -1836,6 +1834,7 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1836,6 +1834,7 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length); (seqs_begin, seqs_end, target, comp, length);
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1853,19 +1852,18 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1853,19 +1852,18 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ false, /* sentinels = */ true>( </* stable = */ false, /* sentinels = */ true>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, target, comp,
...@@ -1874,14 +1872,13 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1874,14 +1872,13 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ true>( </* stable = */ false, /* sentinels = */ true>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1898,19 +1895,18 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1898,19 +1895,18 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ true>( </* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, target, comp,
...@@ -1919,14 +1915,13 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1919,14 +1915,13 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ true>( </* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1944,7 +1939,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1944,7 +1939,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute multiway merge *sequentially*. // Execute multiway merge *sequentially*.
return sequential_multiway_merge return sequential_multiway_merge
...@@ -1952,6 +1947,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1952,6 +1947,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
(seqs_begin, seqs_end, target, comp, length); (seqs_begin, seqs_end, target, comp, length);
} }
// public interface
template< template<
typename RandomAccessIteratorPairIterator typename RandomAccessIteratorPairIterator
, typename RandomAccessIteratorOut , typename RandomAccessIteratorOut
...@@ -1969,19 +1965,18 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1969,19 +1965,18 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
// catch special case: no sequences // catch special case: no sequences
if (seqs_begin == seqs_end) if (seqs_begin == seqs_end)
{ return target; } return target;
// Execute merge; maybe parallel, depending on the number of merged // Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in // elements and the number of sequences and global thresholds in
// Settings. // Settings.
RandomAccessIteratorOut target_end;
if ((seqs_end - seqs_begin > 1) && if ((seqs_end - seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION( _GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= ((seqs_end - seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k) __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
&& ((sequence_index_t)length >= && ((sequence_index_t)length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n))) __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
target_end = parallel_multiway_merge return parallel_multiway_merge
</* stable = */ true, /* sentinels = */ true>( </* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, target, comp,
...@@ -1990,12 +1985,10 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin ...@@ -1990,12 +1985,10 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
Comparator, _DifferenceTp>, Comparator, _DifferenceTp>,
static_cast<difference_type>(length)); static_cast<difference_type>(length));
else else
target_end = sequential_multiway_merge return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ true>( </* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end, seqs_begin, seqs_end,
target, comp, length); target, comp, length);
return target_end;
} }
}; // namespace __gnu_parallel }; // namespace __gnu_parallel
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment