19 #ifndef TLX_CONTAINER_LOSER_TREE_HEADER 20 #define TLX_CONTAINER_LOSER_TREE_HEADER 54 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
89 const Comparator& cmp = Comparator())
91 losers_(2 * k_), cmp_(cmp), first_insert_(true) {
93 for (
Source i = ik_ - 1; i <
k_; ++i) {
94 losers_[i +
k_].sup =
true;
113 assert(pos < losers_.
size());
114 assert(sup == (keyp ==
nullptr));
116 losers_[pos].sup =
sup;
117 losers_[pos].source =
source;
121 for (
Source i = 0; i < 2 *
k_; ++i) {
123 losers_[i].key = *keyp;
125 losers_[i].key = ValueType();
127 first_insert_ =
false;
130 losers_[pos].key = keyp ? *keyp : ValueType();
146 if (losers_[right].
sup ||
147 (!losers_[left].
sup &&
148 !
cmp_(losers_[right].
key, losers_[left].key))) {
150 losers_[root] = losers_[right];
155 losers_[root] = losers_[left];
180 template <
bool Stable ,
typename ValueType,
181 typename Comparator = std::less<ValueType> >
190 using Super::losers_;
195 const Comparator& cmp = Comparator())
201 assert(sup == (keyp ==
nullptr));
204 ValueType
key = keyp ? *keyp : ValueType();
210 swap(losers_[pos].sup, sup);
211 swap(losers_[pos].source, source);
212 swap(losers_[pos].key, key);
217 else if (
cmp_(losers_[pos].key, key)) {
219 swap(losers_[pos].source, source);
220 swap(losers_[pos].key, key);
228 losers_[0].sup =
sup;
229 losers_[0].source =
source;
230 losers_[0].key =
key;
247 template <
typename ValueType,
typename Comparator>
257 using Super::losers_;
262 const Comparator& cmp = Comparator())
268 assert(sup == (keyp ==
nullptr));
271 ValueType
key = keyp ? *keyp : ValueType();
277 losers_[pos].source < source)) ||
279 ((
cmp_(losers_[pos].key, key)) ||
280 (!
cmp_(key, losers_[pos].key) &&
281 losers_[pos].source <
source)))) {
283 swap(losers_[pos].sup, sup);
284 swap(losers_[pos].source, source);
285 swap(losers_[pos].key, key);
290 losers_[0].sup =
sup;
291 losers_[0].source =
source;
292 losers_[0].key =
key;
306 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
336 Source k,
const Comparator& cmp = Comparator())
339 for (
Source i = ik_ - 1; i <
k_; i++) {
340 losers_[i +
k_].keyp =
nullptr;
352 return losers_[0].keyp ? losers_[0].source :
invalid_;
366 assert(pos < losers_.
size());
367 assert(sup == (keyp ==
nullptr));
370 losers_[pos].source =
source;
371 losers_[pos].keyp = keyp;
386 if (!losers_[right].keyp ||
387 (losers_[left].keyp &&
388 !
cmp_(*losers_[right].keyp, *losers_[left].keyp))) {
390 losers_[root] = losers_[right];
395 losers_[root] = losers_[left];
417 template <
bool Stable ,
typename ValueType,
418 typename Comparator = std::less<ValueType> >
427 using Super::losers_;
436 assert(sup == (keyp ==
nullptr));
445 swap(losers_[pos].source, source);
446 swap(losers_[pos].keyp, keyp);
451 else if (
cmp_(*losers_[pos].keyp, *keyp)) {
453 swap(losers_[pos].source, source);
454 swap(losers_[pos].keyp, keyp);
462 losers_[0].source =
source;
463 losers_[0].keyp = keyp;
477 template <
typename ValueType,
typename Comparator>
487 using Super::losers_;
496 assert(sup == (keyp ==
nullptr));
500 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
503 (losers_[pos].keyp || losers_[pos].source < source)) ||
504 (keyp && losers_[pos].keyp &&
505 ((
cmp_(*losers_[pos].keyp, *keyp)) ||
506 (!
cmp_(*keyp, *losers_[pos].keyp) &&
507 losers_[pos].source < source)))) {
509 swap(losers_[pos].source, source);
510 swap(losers_[pos].keyp, keyp);
514 losers_[0].source =
source;
515 losers_[0].keyp = keyp;
528 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
558 const Comparator& cmp = Comparator())
561 for (
Source i = 0; i < 2 *
k_; i++) {
563 losers_[i].key = sentinel;
569 assert(losers_[0].
source != invalid_ &&
570 "Data underrun in unguarded merging.");
571 return losers_[0].source;
577 assert(pos < losers_.
size());
578 assert(sup == (keyp ==
nullptr));
581 losers_[pos].source =
source;
582 losers_[pos].key = *keyp;
591 if (!
cmp_(losers_[right].
key, losers_[left].key)) {
593 losers_[root] = losers_[right];
598 losers_[root] = losers_[left];
610 template <
bool Stable ,
typename ValueType,
611 typename Comparator = std::less<ValueType> >
621 using Super::losers_;
626 const Comparator& cmp = Comparator())
627 :
Super(k, sentinel, cmp) { }
632 assert(sup == (keyp ==
nullptr));
636 ValueType
key = keyp ? *keyp : ValueType();
638 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
640 if (
cmp_(losers_[pos].key, key)) {
642 swap(losers_[pos].source, source);
643 swap(losers_[pos].key, key);
647 losers_[0].source =
source;
648 losers_[0].key =
key;
652 template <
typename ValueType,
typename Comparator>
662 using Super::losers_;
667 const Comparator& comp = Comparator())
668 :
Super(k, sentinel, comp) { }
673 assert(sup == (keyp ==
nullptr));
677 ValueType
key = keyp ? *keyp : ValueType();
679 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
680 if (
cmp_(losers_[pos].key, key) ||
681 (!
cmp_(key, losers_[pos].key) &&
682 losers_[pos].source < source)) {
684 swap(losers_[pos].source, source);
685 swap(losers_[pos].key, key);
689 losers_[0].source =
source;
690 losers_[0].key =
key;
704 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
734 const Comparator& cmp = Comparator())
736 losers_(k_ * 2), cmp_(cmp) {
737 for (
Source i = ik_ - 1; i <
k_; i++) {
739 losers_[i +
k_].keyp = &sentinel;
755 assert(pos < losers_.
size());
756 assert(sup == (keyp ==
nullptr));
759 losers_[pos].source =
source;
760 losers_[pos].keyp = keyp;
769 if (!
cmp_(*losers_[right].keyp, *losers_[left].keyp)) {
771 losers_[root] = losers_[right];
776 losers_[root] = losers_[left];
788 template <
bool Stable ,
typename ValueType,
789 typename Comparator = std::less<ValueType> >
799 using Super::losers_;
804 const Comparator& cmp = Comparator())
805 :
Super(k, sentinel, cmp) { }
809 assert(sup == (keyp ==
nullptr));
813 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
815 if (
cmp_(*losers_[pos].keyp, *keyp)) {
817 swap(losers_[pos].source, source);
818 swap(losers_[pos].keyp, keyp);
822 losers_[0].source =
source;
823 losers_[0].keyp = keyp;
827 template <
typename ValueType,
typename Comparator>
837 using Super::losers_;
842 const Comparator& cmp = Comparator())
843 :
Super(k, sentinel, cmp) { }
847 assert(sup == (keyp ==
nullptr));
851 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
853 if (
cmp_(*losers_[pos].keyp, *keyp) ||
854 (!
cmp_(*keyp, *losers_[pos].keyp) &&
855 losers_[pos].source < source)) {
857 swap(losers_[pos].source, source);
858 swap(losers_[pos].keyp, keyp);
862 losers_[0].source =
source;
863 losers_[0].keyp = keyp;
870 template <
bool Stable,
typename ValueType,
typename Comparator,
871 typename Enable =
void>
878 template <
bool Stable,
typename ValueType,
typename Comparator>
880 Stable, ValueType, Comparator,
881 typename
std::
enable_if<sizeof(ValueType) <= 2 * sizeof(size_t)>::type>
887 template <
bool Stable,
typename ValueType,
typename Comparator>
892 template <
bool Stable,
typename ValueType,
typename Comparator,
893 typename Enable =
void>
894 class LoserTreeUnguardedSwitch
900 template <
bool Stable,
typename ValueType,
typename Comparator>
901 class LoserTreeUnguardedSwitch<
902 Stable, ValueType, Comparator,
903 typename std::
enable_if<sizeof(ValueType) <= 2 * sizeof(size_t)>::type>
909 template <
bool Stable,
typename ValueType,
typename Comparator>
910 using LoserTreeUnguarded =
911 typename LoserTreeUnguardedSwitch<Stable, ValueType, Comparator>::Type;
918 #endif // !TLX_CONTAINER_LOSER_TREE_HEADER static constexpr Source invalid_
sentinel for invalid or finished Sources
const ValueType * keyp
pointer to key value of the element in this node
Source source
index of source
const Source ik_
number of nodes
LoserTreeCopyUnguarded(Source k, const ValueType &sentinel, const Comparator &comp=Comparator())
SimpleVector< Loser > losers_
array containing loser tree nodes – avoid default-constructing losers[].key
Simpler non-growing vector without initialization.
void insert_start(const ValueType *keyp, const Source &source, bool sup)
Initializes the player source with the element key.
typename Super::Source Source
Guarded loser tree, using pointers to the elements instead of copying them into the tree nodes...
const Source k_
log_2(ik) next greater power of 2
Source k_
log_2(ik) next greater power of 2
Source min_source()
return the index of the player with the smallest element.
ValueType key
copy of key value of the element in this node
Source init_winner(const Source &root)
Computes the winner of the competition at player root.
bool first_insert_
still have to construct keys
Source ik_
number of nodes
bool sup
flag, true iff is a virtual maximum sentinel
Internal representation of a loser tree player/node.
LoserTreePointerUnguarded(const Source &k, const ValueType &sentinel, const Comparator &cmp=Comparator())
LoserTreeCopyUnguarded(Source k, const ValueType &sentinel, const Comparator &cmp=Comparator())
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
swap enclosed object with another counting pointer (no reference counts need change) ...
LoserTreePointerUnguardedBase(const Source &k, const ValueType &sentinel, const Comparator &cmp=Comparator())
Comparator cmp_
the comparator object
size_type size() const noexcept
return number of items in vector
SFINAE enable_if – copy of std::enable_if<> with less extra cruft.
LoserTreeCopyBase(const Source &k, const Comparator &cmp=Comparator())
void delete_min_insert(const ValueType *keyp, bool sup)
Internal representation of a loser tree player/node.
LoserTreePointerBase(Source k, const Comparator &cmp=Comparator())
Guarded loser tree, using pointers to the elements instead of copying them into the tree nodes...
Guarded loser tree/tournament tree, either copying the whole element into the tree structure...
Internal representation of a loser tree player/node.
LoserTreeCopy(const Source &k, const Comparator &cmp=Comparator())
static int round_up_to_power_of_two(int i)
does what it says: round up to next power of two
Guarded loser tree/tournament tree, either copying the whole element into the tree structure...
Internal representation of a loser tree player/node.
LoserTreePointer(Source k, const Comparator &cmp=Comparator())
uint32_t Source
size of counters and array indexes
Unguarded loser tree, keeping only pointers to the elements in the tree structure.
LoserTreeCopyUnguardedBase(Source k, const ValueType &sentinel, const Comparator &cmp=Comparator())
Unguarded loser tree, copying the whole element into the tree structure.