69 typedef std::pair<Stat_, Index_> Element;
70 std::vector<Element> my_queue, my_ties;
73 bool operator()(
const Element& left,
const Element& right)
const {
74 if (left.first == right.first) {
75 return left.second < right.second;
77 return left.first > right.first;
83 bool operator()(
const Element& left,
const Element& right)
const {
84 if (left.first == right.first) {
85 return left.second < right.second;
87 return left.first < right.first;
93 bool operator()(
const Element& left,
const Element& right)
const {
94 return left.second < right.second;
100 std::optional<Stat_> my_bound;
106 template<
class Compare_,
class Skip_>
107 void push_internal(std::pair<Stat_, Index_> gene,
const Compare_ cmp,
const Skip_ skip) {
108 if (my_bound.has_value()) {
109 if (skip(*my_bound, gene.first)) {
111 }
else if (my_open_bound && *my_bound == gene.first) {
116 if constexpr(std::numeric_limits<Stat_>::has_quiet_NaN) {
117 if (my_check_nan && std::isnan(gene.first)) {
122 if (sanisizer::is_less_than(my_queue.size(), my_top)) {
123 my_queue.push_back(std::move(gene));
124 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
131 const auto&
top = my_queue.front();
132 if (skip(
top.first, gene.first)) {
137 if (
top.first != gene.first || gene.second <
top.second) {
138 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
139 my_queue.back() = std::move(gene);
140 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
145 if (
top.first == gene.first) {
147 if (gene.second >=
top.second) {
148 my_ties.push_back(std::move(gene));
149 std::push_heap(my_ties.begin(), my_ties.end(), SortTies());
152 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
153 my_queue.back() = std::move(gene);
154 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
155 my_ties.push_back(std::move(retop));
156 std::push_heap(my_ties.begin(), my_ties.end(), SortTies());
162 my_queue.front() = std::move(gene);
169 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
170 if (retop.first == my_queue.front().first) {
171 my_ties.push_back(std::move(retop));
172 std::push_heap(my_ties.begin(), my_ties.end(), SortTies());
176 my_queue.back() = std::move(gene);
177 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
180 template<
class Compare_>
181 void pop_internal(Compare_ cmp) {
182 if (my_ties.size()) {
183 std::pop_heap(my_ties.begin(), my_ties.end(), SortTies());
186 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
201 my_bound(options.bound),
202 my_open_bound(options.open_bound),
203 my_keep_ties(options.keep_ties),
204 my_check_nan(options.check_nan)
211 void push(std::pair<Stat_, Index_> gene) {
216 [](
const Stat_ existing,
const Stat_ latest) ->
bool {
return existing > latest; }
222 [](
const Stat_ existing,
const Stat_ latest) ->
bool {
return existing < latest; }
234 push({ statistic, index });
242 return my_queue.size() + my_ties.size();
258 const std::pair<Stat_, Index_>&
top()
const {
259 if (my_ties.size()) {
260 return my_ties.front();
262 return my_queue.front();
272 pop_internal(SortGreater());
274 pop_internal(SortLess());