77 typedef std::pair<Stat_, Index_> Element;
78 std::vector<Element> my_queue, my_ties;
81 bool operator()(
const Element& left,
const Element& right)
const {
82 if (left.first == right.first) {
83 return left.second < right.second;
85 return left.first > right.first;
91 bool operator()(
const Element& left,
const Element& right)
const {
92 if (left.first == right.first) {
93 return left.second < right.second;
95 return left.first < right.first;
101 bool operator()(
const Element& left,
const Element& right)
const {
102 return left.second < right.second;
108 std::optional<Stat_> my_bound;
114 template<
class Compare_,
class Skip_>
115 void push_internal(std::pair<Stat_, Index_> gene,
const Compare_ cmp,
const Skip_ skip) {
116 if (my_bound.has_value()) {
117 if (skip(*my_bound, gene.first)) {
119 }
else if (my_open_bound && *my_bound == gene.first) {
124 if constexpr(std::numeric_limits<Stat_>::has_quiet_NaN) {
125 if (my_check_nan && std::isnan(gene.first)) {
130 if (sanisizer::is_less_than(my_queue.size(), my_top)) {
131 my_queue.push_back(std::move(gene));
132 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
139 const auto&
top = my_queue.front();
140 if (skip(
top.first, gene.first)) {
145 if (
top.first != gene.first || gene.second <
top.second) {
146 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
147 my_queue.back() = std::move(gene);
148 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
153 if (
top.first == gene.first) {
155 if (gene.second >=
top.second) {
156 my_ties.push_back(std::move(gene));
157 std::push_heap(my_ties.begin(), my_ties.end(), SortTies());
160 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
161 my_queue.back() = std::move(gene);
162 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
163 my_ties.push_back(std::move(retop));
164 std::push_heap(my_ties.begin(), my_ties.end(), SortTies());
170 my_queue.front() = std::move(gene);
177 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
178 if (retop.first == my_queue.front().first) {
179 my_ties.push_back(std::move(retop));
180 std::push_heap(my_ties.begin(), my_ties.end(), SortTies());
184 my_queue.back() = std::move(gene);
185 std::push_heap(my_queue.begin(), my_queue.end(), cmp);
188 template<
class Compare_>
189 void pop_internal(Compare_ cmp) {
190 if (my_ties.size()) {
191 std::pop_heap(my_ties.begin(), my_ties.end(), SortTies());
194 std::pop_heap(my_queue.begin(), my_queue.end(), cmp);
209 my_bound(options.bound),
210 my_open_bound(options.open_bound),
211 my_keep_ties(options.keep_ties),
212 my_check_nan(options.check_nan)
214 if (options.
reserve.has_value()) {
215 my_queue.reserve(*(options.reserve));
217 my_queue.reserve(my_top);
225 void push(std::pair<Stat_, Index_> gene) {
230 [](
const Stat_ existing,
const Stat_ latest) ->
bool {
return existing > latest; }
236 [](
const Stat_ existing,
const Stat_ latest) ->
bool {
return existing < latest; }
248 push({ statistic, index });
256 return my_queue.size() + my_ties.size();
272 const std::pair<Stat_, Index_>&
top()
const {
273 if (my_ties.size()) {
274 return my_ties.front();
276 return my_queue.front();
286 pop_internal(SortGreater());
288 pop_internal(SortLess());