From 907d20432605385cecc1a391da79f5081fcbdbc3 Mon Sep 17 00:00:00 2001
From: Jonathan Wakely
Date: Mon, 4 Nov 2024 17:33:11 +0000
Subject: [PATCH] Replace repeated sorts with one std::ranges::sort using a
projection
Instead of sorting several times in a row using different orderings, we
can define a single projection that defines the desired final order.
---
src/report_generator.cpp | 48 ++++++++++++++++++++++++++--------------
1 file changed, 31 insertions(+), 17 deletions(-)
diff --git a/src/report_generator.cpp b/src/report_generator.cpp
index 3cf74160f1..346f522bbc 100644
--- a/src/report_generator.cpp
+++ b/src/report_generator.cpp
@@ -63,6 +63,23 @@ struct order_by_major_section {
lwg::section_map& section_db;
};
+// Create a LessThanComparable object that defines an ordering based on date,
+// with newer dates first.
+auto ordered_date(lwg::issue const & issue) {
+ std::chrono::sys_days date(issue.mod_date);
+ return -date.time_since_epoch().count();
+}
+
+// Create a LessThanComparable object that defines an ordering that depends on
+// the section number (e.g. 23.5.1) first and then on the section stable tag.
+// Using both is not redundant, because we use section 99 for all sections of some TS's.
+// Including the tag in the order gives a total order for sections in those TS's,
+// e.g., {99,[arrays.ts::dynarray]} < {99,[arrays.ts::dynarraconstructible_from.cons]}.
+auto ordered_section(lwg::section_map & section_db, lwg::issue const & issue) {
+ assert(!issue.tags.empty());
+ return std::tie(section_db[issue.tags.front()], issue.tags.front());
+}
+
struct order_by_section {
explicit order_by_section(lwg::section_map §ions)
: section_db(sections)
@@ -70,12 +87,7 @@ struct order_by_section {
}
auto operator()(lwg::issue const & x, lwg::issue const & y) const -> bool {
- assert(!x.tags.empty());
- assert(!y.tags.empty());
- // This sorts by the section number (e.g. 23.5.1) then by the section stable tag.
- // This is not redundant, because for e.g. Arrays TS the entire paper has section num 99,
- // so including the tag orders [arrays.ts::dynarray] before [arrays.ts::dynarray.cons].
- return std::tie(section_db[x.tags.front()], x.tags.front()) < std::tie(section_db[y.tags.front()], y.tags.front());
+ return ordered_section(section_db, x) < ordered_section(section_db, y);
}
private:
@@ -696,10 +708,10 @@ sorted by priority.
void report_generator::make_sort_by_status(std::vector& issues, fs::path const & filename) {
- sort(issues.begin(), issues.end(), order_by_issue_number{});
- stable_sort(issues.begin(), issues.end(), [](issue const & x, issue const & y) { return x.mod_date > y.mod_date; } );
- stable_sort(issues.begin(), issues.end(), order_by_section{section_db});
- stable_sort(issues.begin(), issues.end(), order_by_status{});
+ auto proj = [this](const auto& i) {
+ return std::make_tuple(lwg::get_status_priority(i.stat), ordered_section(section_db, i), ordered_date(i), i.num);
+ };
+ std::ranges::sort(issues.begin(), issues.end(), {}, proj);
std::ofstream out{filename};
if (!out)
@@ -733,10 +745,10 @@ This document is the Index by Status and Section for the
void report_generator::make_sort_by_section(std::vector& issues, fs::path const & filename, bool active_only) {
- sort(issues.begin(), issues.end(), order_by_issue_number{});
- stable_sort(issues.begin(), issues.end(), [](issue const & x, issue const & y) { return x.mod_date > y.mod_date; } );
- stable_sort(issues.begin(), issues.end(), order_by_status{});
+ auto proj = [this](const auto& i) {
+ return std::make_tuple(lwg::get_status_priority(i.stat), ordered_date(i), i.num);
+ };
+ std::ranges::sort(issues.begin(), issues.end(), {}, proj);
+
auto b = issues.begin();
auto e = issues.end();
if(active_only) {