// Do not pass a const reference since key will be used as local variable.
void delete_min_insert(T key, bool sup)
{
+#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
+ _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+#endif
+
int source = losers[0].source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
{
delete_min_insert(T key, bool sup)
{
#if _GLIBCXX_ASSERTIONS
- // loser trees are only used for at least 2 sequences
- _GLIBCXX_PARALLEL_ASSERT(_M_log_k > 1);
+ // no dummy sequence can ever be at the top!
+ _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
int source = losers[0].source;
void delete_min_insert(const T& key, bool sup)
{
+#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
+ _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+#endif
+
const T* keyp = &key;
int source = losers[0].source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
void delete_min_insert(const T& key, bool sup)
{
+#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
+ _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+#endif
+
const T* keyp = &key;
int source = losers[0].source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
// Avoid default-constructing losers[].key
losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser)));
- for (unsigned int i = /*k + ik - 1*/0; i < (2 * k); ++i)
+ for (unsigned int i = k + ik - 1; i < (2 * k); ++i)
{
losers[i].key = _sentinel;
losers[i].source = -1;
inline int
get_min_source()
{
- // no dummy sequence can ever be at the top!
#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
return losers[0].source;
{
losers[0] = losers[init_winner(1)];
- // no dummy sequence can ever be at the top at the beginning (0 sequences!)
#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
}
inline void
delete_min_insert(T key, bool)
{
- // No dummy sequence can ever be at the top and be retrieved!
#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
int source = losers[0].source;
- printf("%d\n", source);
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
{
// The smaller one gets promoted, ties are broken by source.
{
losers[0] = losers[init_winner(1)];
- // no dummy sequence can ever be at the top at the beginning (0 sequences!)
#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
}
inline void
delete_min_insert(T key, bool)
{
- printf("wrong\n");
+#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
+ _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+#endif
+
int source = losers[0].source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
{
unsigned int ik, k, offset;
Loser* losers;
- const T sentinel;
Comparator comp;
public:
inline
- LoserTreePointerUnguardedBase(unsigned int _k, const T _sentinel,
+ LoserTreePointerUnguardedBase(unsigned int _k, const T& _sentinel,
Comparator _comp = std::less<T>())
- : sentinel(_sentinel), comp(_comp)
+ : comp(_comp)
{
ik = _k;
// Avoid default-constructing losers[].key
losers = new Loser[2 * k];
- for (unsigned int i = /*k + ik - 1*/0; i < (2 * k); ++i)
+ for (unsigned int i = k + ik - 1; i < (2 * k); ++i)
{
- losers[i].keyp = &sentinel;
+ losers[i].keyp = &_sentinel;
losers[i].source = -1;
}
}
inline int
get_min_source()
{
- // no dummy sequence can ever be at the top!
#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
return losers[0].source;
using Base::losers;
public:
- LoserTreePointerUnguarded(unsigned int _k, const T _sentinel,
+ LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel,
Comparator _comp = std::less<T>())
: Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
{}
{
losers[0] = losers[init_winner(1)];
- // no dummy sequence can ever be at the top at the beginning (0 sequences!)
#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
}
inline void
delete_min_insert(const T& key, bool sup)
{
+#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
+ _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+#endif
+
const T* keyp = &key;
int source = losers[0].source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
losers[0].source = source;
losers[0].keyp = keyp;
-
- // no dummy sequence can ever be at the top!
-#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
-#endif
}
};
using Base::losers;
public:
- LoserTreePointerUnguarded(unsigned int _k, const T _sentinel,
+ LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel,
Comparator _comp = std::less<T>())
: Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
{}
{
losers[0] = losers[init_winner(1)];
- // no dummy sequence can ever be at the top at the beginning (0 sequences!)
#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top at the beginning (0 sequences!)
_GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
#endif
}
inline void
delete_min_insert(const T& key, bool sup)
{
+#if _GLIBCXX_ASSERTIONS
+ // no dummy sequence can ever be at the top!
+ _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+#endif
+
const T* keyp = &key;
int source = losers[0].source;
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
* @return End iterator of output sequence.
*/
template<typename LT,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp, typename Comparator>
+ typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp, typename Comparator>
RandomAccessIterator3
- multiway_merge_loser_tree_unguarded(RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- int min_seq, Comparator comp,
- _DifferenceTp length)
+ multiway_merge_loser_tree_unguarded(
+ RandomAccessIteratorIterator seqs_begin,
+ RandomAccessIteratorIterator seqs_end,
+ RandomAccessIterator3 target,
+ const typename std::iterator_traits<typename std::iterator_traits<
+ RandomAccessIteratorIterator>::value_type::first_type>::value_type&
+ sentinel,
+ Comparator comp,
+ _DifferenceTp length)
{
_GLIBCXX_CALL(length)
typedef _DifferenceTp difference_type;
int k = seqs_end - seqs_begin;
- // Determine the sentinel. The sentinel is largest/last element of the
- // sequences with the smallest largest/last element.
- value_type sentinel = *(seqs_begin[min_seq].second - 1);
-
LT lt(k, sentinel, comp);
for (int t = 0; t < k; ++t)
*(target++) = *(seqs_begin[source].first++);
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(
- (seqs_begin[source].first != seqs_begin[source].second)
- || (i >= length - 1));
++i;
#endif
// Replace from same source.
typename _DifferenceTp,
typename Comparator>
RandomAccessIterator3
- multiway_merge_loser_tree_sentinel(RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- Comparator comp,
- _DifferenceTp length)
+ multiway_merge_loser_tree_sentinel(
+ RandomAccessIteratorIterator seqs_begin,
+ RandomAccessIteratorIterator seqs_end,
+ RandomAccessIterator3 target,
+ const typename std::iterator_traits<typename std::iterator_traits<
+ RandomAccessIteratorIterator>::value_type::first_type>::value_type&
+ sentinel,
+ Comparator comp,
+ _DifferenceTp length)
{
_GLIBCXX_CALL(length)
target_end = multiway_merge_loser_tree_unguarded
<UnguardedLoserTree>
- (seqs_begin, seqs_end, target, 0, comp, length);
+ (seqs_begin, seqs_end, target, sentinel, comp, length);
#if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
RandomAccessIterator3 target,
+ const typename std::iterator_traits<typename std::iterator_traits<
+ RandomAccessIteratorIterator>::value_type::first_type>::value_type&
+ sentinel,
Comparator comp, _DifferenceTp length)
{
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
loser_tree_traits<value_type>::use_pointer
, LoserTreePointerUnguarded<stable, value_type, Comparator>
, LoserTreeUnguarded<stable, value_type, Comparator>
- >::__type>(seqs_begin, seqs_end, target, comp, length);
+ >::__type>(seqs_begin, seqs_end, target, sentinel, comp, length);
}
};
RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
RandomAccessIterator3 target,
+ const typename std::iterator_traits<typename std::iterator_traits<
+ RandomAccessIteratorIterator>::value_type::first_type>::value_type&
+ sentinel,
Comparator comp, _DifferenceTp length)
{
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
typename _DifferenceTp,
typename Comparator>
RandomAccessIterator3
- sequential_multiway_merge(RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- Comparator comp, _DifferenceTp length)
+ sequential_multiway_merge(
+ RandomAccessIteratorIterator seqs_begin,
+ RandomAccessIteratorIterator seqs_end,
+ RandomAccessIterator3 target,
+ const typename std::iterator_traits<typename std::iterator_traits<
+ RandomAccessIteratorIterator>::value_type::first_type>::value_type&
+ sentinel,
+ Comparator comp, _DifferenceTp length)
{
_GLIBCXX_CALL(length)
, RandomAccessIteratorIterator
, RandomAccessIterator3
, _DifferenceTp
- , Comparator>()(seqs_begin, seqs_end, target, comp, length);
+ , Comparator>()
+ (seqs_begin, seqs_end, target, sentinel, comp, length);
break;
}
#if _GLIBCXX_ASSERTIONS
if(length > target_position)
sequential_multiway_merge<stable, sentinels>(
- chunks, chunks + k, target + target_position, comp,
- length - target_position);
+ chunks, chunks + k, target + target_position,
+ *(seqs_begin->second), comp, length - target_position);
delete[] chunks;
} // parallel
</* stable = */ false, /* sentinels = */ false>
(seqs_begin, seqs_end, target, comp,
multiway_merge_sampling_splitting</* stable = */ false,
- RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge
</* stable = */false, /* sentinels = */ false>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
// public interface
// Execute multiway merge *sequentially*.
return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ false>
- (seqs_begin, seqs_end, target, comp, length);
+ (seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
}
//public interface
seqs_begin, seqs_end,
target, comp,
multiway_merge_exact_splitting</* stable = */ false,
- RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ false>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
// public interface
seqs_begin, seqs_end,
target, comp,
multiway_merge_sampling_splitting</* stable = */ true,
- RandomAccessIteratorPairIterator, Comparator, _DifferenceTp>,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ false>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
// public interface
// Execute multiway merge *sequentially*.
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ false>
- (seqs_begin, seqs_end, target, comp, length);
+ (seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
}
// public interface
seqs_begin, seqs_end,
target, comp,
multiway_merge_exact_splitting
- </* stable = */ true, RandomAccessIteratorPairIterator,
- Comparator, _DifferenceTp>,
+ </* stable = */ true,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge</* stable = */ true,
/* sentinels = */ false>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
/**
</* stable = */ false, /* sentinels = */ true>
(seqs_begin, seqs_end, target, comp,
multiway_merge_sampling_splitting
- </* stable = */ false, RandomAccessIteratorPairIterator,
- Comparator, _DifferenceTp>,
+ </* stable = */ false,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge
</* stable = */false, /* sentinels = */ true>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
//public interface
// Execute multiway merge *sequentially*.
return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ true>
- (seqs_begin, seqs_end, target, comp, length);
+ (seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
}
// public interface
seqs_begin, seqs_end,
target, comp,
multiway_merge_exact_splitting
- </* stable = */ false, RandomAccessIteratorPairIterator,
- Comparator, _DifferenceTp>,
+ </* stable = */ false,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge
</* stable = */ false, /* sentinels = */ true>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
// public interface
seqs_begin, seqs_end,
target, comp,
multiway_merge_sampling_splitting
- </* stable = */ true, RandomAccessIteratorPairIterator,
- Comparator, _DifferenceTp>,
+ </* stable = */ true,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
// public interface
// Execute multiway merge *sequentially*.
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ true>
- (seqs_begin, seqs_end, target, comp, length);
+ (seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
}
// public interface
seqs_begin, seqs_end,
target, comp,
multiway_merge_exact_splitting
- </* stable = */ true, RandomAccessIteratorPairIterator,
- Comparator, _DifferenceTp>,
+ </* stable = */ true,
+ typename std::iterator_traits<RandomAccessIteratorPairIterator>
+ ::value_type*, Comparator, _DifferenceTp>,
static_cast<difference_type>(length));
else
return sequential_multiway_merge
</* stable = */ true, /* sentinels = */ true>(
seqs_begin, seqs_end,
- target, comp, length);
+ target, *(seqs_begin->second), comp, length);
}
}; // namespace __gnu_parallel