Skip to content

Commit 15cc908

Browse files
committed
Change loops over equivalent issues to use C++23 views::chunk_by
As suggested by Tomasz in #533 Use a helper function for C++20.
1 parent 442fd55 commit 15cc908

File tree

1 file changed

+58
-23
lines changed

1 file changed

+58
-23
lines changed

src/report_generator.cpp

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,26 @@ R"(<h1>C++ Standard Library Issues List (Revision )" << lwg_issues_xml.get_revis
680680
print_file_trailer(out);
681681
}
682682

683+
#ifndef __cpp_lib_ranges_chunk_by
684+
template<typename T>
685+
auto chop(std::span<T>& s, std::size_t n)
686+
{
687+
auto first = s.first(n);
688+
s = s.subspan(n);
689+
return first;
690+
}
691+
692+
// Chop off and return a subspan from the front of `issues`,
693+
// consisting of all values that are equivalent under `pred`.
694+
auto chunk_by(std::span<issue>& issues, auto pred) -> std::span<const issue> {
695+
std::size_t n = 0;
696+
if (!issues.empty()) {
697+
auto end = std::ranges::find_if_not(issues, std::bind_front(pred, std::ref(issues.front())));
698+
n = end - issues.begin();
699+
}
700+
return chop(issues, n);
701+
}
702+
#endif
683703

684704
void report_generator::make_sort_by_priority(std::span<issue> issues, fs::path const & filename) {
685705
auto proj = [this](const auto& i) {
@@ -704,21 +724,26 @@ sorted by priority.</p>
704724

705725
// print_table(out, issues, section_db);
706726

707-
while (!issues.empty())
727+
auto same_prio = [](const issue& lhs, const issue& rhs) {
728+
return lhs.priority == rhs.priority;
729+
};
730+
#ifdef __cpp_lib_ranges_chunk_by
731+
for (auto chunk : issues | std::views::chunk_by(same_prio))
732+
#else
733+
for (auto chunk = chunk_by(issues, same_prio); !chunk.empty();
734+
chunk = chunk_by(issues, same_prio))
735+
#endif
708736
{
709-
int px = issues.front().priority;
710-
auto end = std::ranges::find_if(issues, std::bind_front(std::ranges::not_equal_to{}, px), &issue::priority);
737+
const int px = chunk.front().priority;
711738
out << "<h2 id=\"Priority_" << px << "\">";
712739
if (px == 99) {
713740
out << "Not Prioritized";
714741
}
715742
else {
716743
out << "Priority " << px;
717744
}
718-
auto count = end - issues.begin();
719-
out << " (" << count << " issues)</h2>\n";
720-
print_table(out, issues.first(count), section_db);
721-
issues = issues.subspan(count);
745+
out << " (" << chunk.size() << " issues)</h2>\n";
746+
print_table(out, chunk, section_db);
722747
}
723748

724749
print_file_trailer(out);
@@ -743,15 +768,21 @@ This document is the Index by )" << title << R"( for the <a href="lwg-active.htm
743768
)";
744769
out << "<p>" << build_timestamp << "</p>";
745770

746-
while (!issues.empty())
771+
auto same_status = [](const issue& lhs, const issue& rhs) {
772+
return lhs.stat == rhs.stat;
773+
};
774+
#ifdef __cpp_lib_ranges_chunk_by
775+
for (auto chunk : issues | std::views::chunk_by(same_status))
776+
#else
777+
for (auto chunk = chunk_by(issues, same_status); !chunk.empty();
778+
chunk = chunk_by(issues, same_status))
779+
#endif
747780
{
748-
auto const & current_status = issues.front().stat;
781+
std::string current_status = chunk.front().stat;
749782
auto idattr = spaces_to_underscores(current_status);
750-
auto end = std::ranges::find_if(issues, std::bind_front(std::ranges::not_equal_to{}, current_status), &issue::stat);
751-
auto count = end - issues.begin();
752-
out << "<h2 id=\"" << idattr << "\">" << current_status << " (" << count << " issues)</h2>\n";
753-
print_table(out, issues.first(count), section_db);
754-
issues = issues.subspan(count);
783+
out << "<h2 id=\"" << idattr << "\">" << current_status
784+
<< " (" << chunk.size() << " issues)</h2>\n";
785+
print_table(out, chunk, section_db);
755786
}
756787

757788
print_file_trailer(out);
@@ -832,25 +863,29 @@ void report_generator::make_sort_by_section(std::span<issue> issues, fs::path co
832863
return lookup_major_section(section_db, i);
833864
};
834865

835-
while (!issues.empty())
866+
auto same_section = [&](const issue& lhs, const issue& rhs) {
867+
return lookup_section(lhs) == lookup_section(rhs);
868+
};
869+
#ifdef __cpp_lib_ranges_chunk_by
870+
for (auto chunk : issues | std::views::chunk_by(same_section))
871+
#else
872+
for (auto chunk = chunk_by(issues, same_section); !chunk.empty();
873+
chunk = chunk_by(issues, same_section))
874+
#endif
836875
{
837-
const issue& i = issues.front();
876+
const issue& i = chunk.front();
838877
major_section_key current = lookup_section(i);
839-
auto is_same_section = std::bind_front(std::ranges::equal_to{}, current);
840-
auto j = std::ranges::find_if_not(issues, is_same_section, lookup_section);
841-
auto count = j - issues.begin();
842878
std::string const msn = to_string(current);
843879
auto idattr = spaces_to_underscores(msn);
844-
out << "<h2 id=\"Section_" << idattr << "\">Section " << msn << " (" << count << " issues)</h2>\n";
880+
out << "<h2 id=\"Section_" << idattr << "\">Section " << msn
881+
<< " (" << chunk.size() << " issues)</h2>\n";
845882
if (active_only) {
846883
out << "<p><a href=\"lwg-index.html#Section_" << idattr << "\">(view all issues)</a></p>\n";
847884
}
848885
else if (mjr_section_open.count(i) > 0) {
849886
out << "<p><a href=\"lwg-index-open.html#Section_" << idattr << "\">(view only non-Ready open issues)</a></p>\n";
850887
}
851-
852-
print_table(out, issues.first(count), section_db, true);
853-
issues = issues.subspan(count);
888+
print_table(out, chunk, section_db, true);
854889
}
855890

856891
print_file_trailer(out);

0 commit comments

Comments
 (0)