19 #ifndef TLX_CONTAINER_LOSER_TREE_HEADER 20 #define TLX_CONTAINER_LOSER_TREE_HEADER 53 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
88 const Comparator& cmp = Comparator())
90 losers_(2 * k_), cmp_(cmp), first_insert_(true) {
92 for (
Source i = ik_ - 1; i <
k_; ++i) {
93 losers_[i +
k_].sup =
true;
112 assert(pos < losers_.
size());
113 assert(sup == (keyp ==
nullptr));
115 losers_[pos].sup =
sup;
116 losers_[pos].source =
source;
120 for (
Source i = 0; i < 2 *
k_; ++i) {
122 losers_[i].key = *keyp;
124 losers_[i].key = ValueType();
126 first_insert_ =
false;
129 losers_[pos].key = keyp ? *keyp : ValueType();
145 if (losers_[right].
sup ||
146 (!losers_[left].
sup &&
147 !
cmp_(losers_[right].
key, losers_[left].key))) {
149 losers_[root] = losers_[right];
154 losers_[root] = losers_[left];
179 template <
bool Stable ,
typename ValueType,
180 typename Comparator = std::less<ValueType> >
189 using Super::losers_;
194 const Comparator& cmp = Comparator())
200 assert(sup == (keyp ==
nullptr));
203 ValueType
key = keyp ? *keyp : ValueType();
209 swap(losers_[pos].sup, sup);
210 swap(losers_[pos].source, source);
211 swap(losers_[pos].key, key);
216 else if (
cmp_(losers_[pos].key, key)) {
218 swap(losers_[pos].source, source);
219 swap(losers_[pos].key, key);
227 losers_[0].sup =
sup;
228 losers_[0].source =
source;
229 losers_[0].key =
key;
246 template <
typename ValueType,
typename Comparator>
256 using Super::losers_;
261 const Comparator& cmp = Comparator())
267 assert(sup == (keyp ==
nullptr));
270 ValueType
key = keyp ? *keyp : ValueType();
276 losers_[pos].source < source)) ||
278 ((
cmp_(losers_[pos].key, key)) ||
279 (!
cmp_(key, losers_[pos].key) &&
280 losers_[pos].source <
source)))) {
282 swap(losers_[pos].sup, sup);
283 swap(losers_[pos].source, source);
284 swap(losers_[pos].key, key);
289 losers_[0].sup =
sup;
290 losers_[0].source =
source;
291 losers_[0].key =
key;
305 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
335 Source k,
const Comparator& cmp = Comparator())
338 for (
Source i = ik_ - 1; i <
k_; i++) {
339 losers_[i +
k_].keyp =
nullptr;
351 return losers_[0].keyp ? losers_[0].source :
invalid_;
365 assert(pos < losers_.
size());
366 assert(sup == (keyp ==
nullptr));
369 losers_[pos].source =
source;
370 losers_[pos].keyp = keyp;
385 if (!losers_[right].keyp ||
386 (losers_[left].keyp &&
387 !
cmp_(*losers_[right].keyp, *losers_[left].keyp))) {
389 losers_[root] = losers_[right];
394 losers_[root] = losers_[left];
416 template <
bool Stable ,
typename ValueType,
417 typename Comparator = std::less<ValueType> >
426 using Super::losers_;
435 assert(sup == (keyp ==
nullptr));
444 swap(losers_[pos].source, source);
445 swap(losers_[pos].keyp, keyp);
450 else if (
cmp_(*losers_[pos].keyp, *keyp)) {
452 swap(losers_[pos].source, source);
453 swap(losers_[pos].keyp, keyp);
461 losers_[0].source =
source;
462 losers_[0].keyp = keyp;
476 template <
typename ValueType,
typename Comparator>
486 using Super::losers_;
495 assert(sup == (keyp ==
nullptr));
499 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
502 (losers_[pos].keyp || losers_[pos].source < source)) ||
503 (keyp && losers_[pos].keyp &&
504 ((
cmp_(*losers_[pos].keyp, *keyp)) ||
505 (!
cmp_(*keyp, *losers_[pos].keyp) &&
506 losers_[pos].source < source)))) {
508 swap(losers_[pos].source, source);
509 swap(losers_[pos].keyp, keyp);
513 losers_[0].source =
source;
514 losers_[0].keyp = keyp;
527 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
557 const Comparator& cmp = Comparator())
560 for (
Source i = 0; i < 2 *
k_; i++) {
568 assert(losers_[0].
source != invalid_ &&
569 "Data underrun in unguarded merging.");
570 return losers_[0].source;
576 assert(pos < losers_.
size());
577 assert(sup == (keyp ==
nullptr));
580 losers_[pos].source =
source;
581 losers_[pos].key = *keyp;
590 if (!
cmp_(losers_[right].
key, losers_[left].key)) {
592 losers_[root] = losers_[right];
597 losers_[root] = losers_[left];
609 template <
bool Stable ,
typename ValueType,
610 typename Comparator = std::less<ValueType> >
620 using Super::losers_;
625 const Comparator& cmp = Comparator())
626 :
Super(k, sentinel, cmp) { }
631 assert(sup == (keyp ==
nullptr));
635 ValueType
key = keyp ? *keyp : ValueType();
637 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
639 if (
cmp_(losers_[pos].key, key)) {
641 swap(losers_[pos].source, source);
642 swap(losers_[pos].key, key);
646 losers_[0].source =
source;
647 losers_[0].key =
key;
651 template <
typename ValueType,
typename Comparator>
661 using Super::losers_;
666 const Comparator& comp = Comparator())
667 :
Super(k, sentinel, comp) { }
672 assert(sup == (keyp ==
nullptr));
676 ValueType
key = keyp ? *keyp : ValueType();
678 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
679 if (
cmp_(losers_[pos].key, key) ||
680 (!
cmp_(key, losers_[pos].key) &&
681 losers_[pos].source < source)) {
683 swap(losers_[pos].source, source);
684 swap(losers_[pos].key, key);
688 losers_[0].source =
source;
689 losers_[0].key =
key;
703 template <
typename ValueType,
typename Comparator = std::less<ValueType> >
733 const Comparator& cmp = Comparator())
735 losers_(k_ * 2), cmp_(cmp) {
736 for (
Source i = ik_ - 1; i <
k_; i++) {
754 assert(pos < losers_.
size());
755 assert(sup == (keyp ==
nullptr));
758 losers_[pos].source =
source;
759 losers_[pos].keyp = keyp;
768 if (!
cmp_(*losers_[right].keyp, *losers_[left].keyp)) {
770 losers_[root] = losers_[right];
775 losers_[root] = losers_[left];
787 template <
bool Stable ,
typename ValueType,
788 typename Comparator = std::less<ValueType> >
798 using Super::losers_;
803 const Comparator& cmp = Comparator())
804 :
Super(k, sentinel, cmp) { }
808 assert(sup == (keyp ==
nullptr));
812 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
814 if (
cmp_(*losers_[pos].keyp, *keyp)) {
816 swap(losers_[pos].source, source);
817 swap(losers_[pos].keyp, keyp);
821 losers_[0].source =
source;
822 losers_[0].keyp = keyp;
826 template <
typename ValueType,
typename Comparator>
836 using Super::losers_;
841 const Comparator& cmp = Comparator())
842 :
Super(k, sentinel, cmp) { }
846 assert(sup == (keyp ==
nullptr));
850 for (
Source pos = (k_ + source) / 2; pos > 0; pos /= 2) {
852 if (
cmp_(*losers_[pos].keyp, *keyp) ||
853 (!
cmp_(*keyp, *losers_[pos].keyp) &&
854 losers_[pos].source < source)) {
856 swap(losers_[pos].source, source);
857 swap(losers_[pos].keyp, keyp);
861 losers_[0].source =
source;
862 losers_[0].keyp = keyp;
869 template <
bool Stable,
typename ValueType,
typename Comparator,
870 typename Enable =
void>
877 template <
bool Stable,
typename ValueType,
typename Comparator>
879 Stable, ValueType, Comparator,
880 typename
std::
enable_if<sizeof(ValueType) <= 2 * sizeof(size_t)>::type>
886 template <
bool Stable,
typename ValueType,
typename Comparator>
891 template <
bool Stable,
typename ValueType,
typename Comparator,
892 typename Enable =
void>
893 class LoserTreeUnguardedSwitch
899 template <
bool Stable,
typename ValueType,
typename Comparator>
900 class LoserTreeUnguardedSwitch<
901 Stable, ValueType, Comparator,
902 typename std::
enable_if<sizeof(ValueType) <= 2 * sizeof(size_t)>::type>
908 template <
bool Stable,
typename ValueType,
typename Comparator>
909 using LoserTreeUnguarded =
917 #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_
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.
static constexpr size_t sentinel
a sentinel value prefixed to each allocation
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
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.