I am wondering if C++20 ranges have some nice way for me to iterate over the equal ranges of sorted container(or in general case any sorted range).
I have this "manual" solution that works, but it is not nice in a sense that it is not really composable (I do not get some view of equal range views back, I just provide function to be called).
#include <vector>
#include <ranges>
#include <iostream>
#include <fmt/ranges.h>
template<typename Cont, typename Fn>
void for_each_equal_range(const Cont& cont, Fn fn){
auto current_begin = cont.begin();
while(true){
if (current_begin==cont.end()){
return;
}
auto [eq_begin, eq_end] = std::equal_range(current_begin, cont.end(), *current_begin);
fn(eq_begin, eq_end);
current_begin = eq_end;
}
}
int main() {
std::vector vals {1,2,2,3,3,3,47};
for_each_equal_range(vals, [](const auto b, const auto e){
std::cout << "size: " << std::distance(b,e) << std::endl;
std::ranges::subrange elems(b, e);
std::cout << fmt::format("{}",elems) << std::endl;
});
}
I wish I had something like:
vals | equal_range_split | std::ranges::for_each(...);
In case there is some confusion wrt what range means here:
- equal range is good old STL equal_range meaning
- ranges is C++20 ranges library.
Also I know C++20 has std::ranges::equal_range
algorithm, but it seems to be not that helpful for my use case.