Suppose I have a range of T's called rng. I can do
auto groups = ranges::view::group_by(rng, bin_op);
groups now being a range of ranges of T's.
I can also do this
auto groups = ranges::view::group_by(rng, bin_op) | ranges::to_vector;
to get a vector of ranges of T's. However this
auto groups = ranges::view::group_by(rng, bin_op)
| ranges::to_vector
| ranges::action::transform([] (auto r) { return r | ranges::to_vector; };
as well as
auto groups = ranges::view::group_by(rng, bin_op)
| ranges::to_vector
| ranges::action::transform([] (auto r) { return std::vector<T>{} | ranges::action::push_back; };
won't work since apparently ranges::action::transform() returns void in this case and "The result type of the function passed to action::transform must be writable back into the source range".
So how do I turn my ranges of ranges into a vector of vectors?
Note: Sorry for the bad tags, but I couldn't find a ranges/ranges-ts/ranges-v3 tag, I am not allowed to create one and couldn't use it in the title.
Assuming you are using Rangesv3, my reading of the docs gives me something like this:
auto groups = ranges::view::group_by(rng, bin_op)
| ranges::view::transform( ranges::to_vector )
| ranges::to_vector;
or maybe
auto groups = ranges::view::group_by(rng, bin_op)
| ranges::view::transform( [] (auto r) { return r | ranges::to_vector; } )
| ranges::to_vector;
(I recall that ranges::to_vector
could be used in a function-style way, but I could be wrong, or things could have changed. The first one assumes it can be; the second doesn't.)
What this does is it first transforms the lazy range of ranges into a lazy range of vectors.
It then transforms the lazy range of vectors into a vector of vectors.
This works better (inside-out) because the intermediate products are lazy "on the outside". There may be a way to do it from the outside-in, but a vector of lazy ranges has to actually exist in a way that a lazy range of vectors does not.