Skip to content

Commit 81282c2

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 26a9070 commit 81282c2

File tree

1 file changed

+51
-23
lines changed

1 file changed

+51
-23
lines changed

src/report_generator.cpp

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,19 @@ 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+
// Split `issues` into an initial subspan where all values are equivalent under `pred`
685+
// and return that subspan, and adjust `issues` to not include that subspan.
686+
auto chunk_by(std::span<issue>& issues, auto pred) -> std::span<const issue> {
687+
if (issues.empty())
688+
return {};
689+
auto& first = issues.front();
690+
auto end = std::ranges::find_if_not(issues, std::bind_front(pred, first));
691+
auto chunk = issues.first(end - issues.begin());
692+
issues = issues.subspan(chunk.size());
693+
return chunk;
694+
}
695+
#endif
683696

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

705718
// print_table(out, issues, section_db);
706719

707-
while (!issues.empty())
720+
auto same_prio = [](const issue& lhs, const issue& rhs) {
721+
return lhs.priority == rhs.priority;
722+
};
723+
#ifdef __cpp_lib_ranges_chunk_by
724+
for (auto chunk : issues | std::views::chunk_by(same_prio))
725+
#else
726+
for (auto chunk = chunk_by(issues, same_prio); !chunk.empty();
727+
chunk = chunk_by(issues, same_prio))
728+
#endif
708729
{
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);
730+
const int px = chunk.front().priority;
711731
out << "<h2 id=\"Priority_" << px << "\">";
712732
if (px == 99) {
713733
out << "Not Prioritized";
714734
}
715735
else {
716736
out << "Priority " << px;
717737
}
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);
738+
out << " (" << chunk.size() << " issues)</h2>\n";
739+
print_table(out, chunk, section_db);
722740
}
723741

724742
print_file_trailer(out);
@@ -743,15 +761,21 @@ This document is the Index by )" << title << R"( for the <a href="lwg-active.htm
743761
)";
744762
out << "<p>" << build_timestamp << "</p>";
745763

746-
while (!issues.empty())
764+
auto same_status = [](const issue& lhs, const issue& rhs) {
765+
return lhs.stat == rhs.stat;
766+
};
767+
#ifdef __cpp_lib_ranges_chunk_by
768+
for (auto chunk : issues | std::views::chunk_by(same_status))
769+
#else
770+
for (auto chunk = chunk_by(issues, same_status); !chunk.empty();
771+
chunk = chunk_by(issues, same_status))
772+
#endif
747773
{
748-
auto const & current_status = issues.front().stat;
774+
std::string current_status = chunk.front().stat;
749775
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);
776+
out << "<h2 id=\"" << idattr << "\">" << current_status
777+
<< " (" << chunk.size() << " issues)</h2>\n";
778+
print_table(out, chunk, section_db);
755779
}
756780

757781
print_file_trailer(out);
@@ -832,25 +856,29 @@ void report_generator::make_sort_by_section(std::span<issue> issues, fs::path co
832856
return lookup_major_section(section_db, i);
833857
};
834858

835-
while (!issues.empty())
859+
auto same_section = [&](const issue& lhs, const issue& rhs) {
860+
return lookup_section(lhs) == lookup_section(rhs);
861+
};
862+
#ifdef __cpp_lib_ranges_chunk_by
863+
for (auto chunk : issues | std::views::chunk_by(same_section))
864+
#else
865+
for (auto chunk = chunk_by(issues, same_section); !chunk.empty();
866+
chunk = chunk_by(issues, same_section))
867+
#endif
836868
{
837-
const issue& i = issues.front();
869+
const issue& i = chunk.front();
838870
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();
842871
std::string const msn = to_string(current);
843872
auto idattr = spaces_to_underscores(msn);
844-
out << "<h2 id=\"Section_" << idattr << "\">Section " << msn << " (" << count << " issues)</h2>\n";
873+
out << "<h2 id=\"Section_" << idattr << "\">Section " << msn
874+
<< " (" << chunk.size() << " issues)</h2>\n";
845875
if (active_only) {
846876
out << "<p><a href=\"lwg-index.html#Section_" << idattr << "\">(view all issues)</a></p>\n";
847877
}
848878
else if (mjr_section_open.count(i) > 0) {
849879
out << "<p><a href=\"lwg-index-open.html#Section_" << idattr << "\">(view only non-Ready open issues)</a></p>\n";
850880
}
851-
852-
print_table(out, issues.first(count), section_db, true);
853-
issues = issues.subspan(count);
881+
print_table(out, chunk, section_db, true);
854882
}
855883

856884
print_file_trailer(out);

0 commit comments

Comments
 (0)