This all started when I tried to store the results of an enumerate range into a vector and then sort according to the value. In doing so, I found out that enumerate was insufficiently generic, as it did not support iterator_facade_base and so you couldn't even call std::distance() on two of its iterators.
Ideally, one should not have to write this code:
std::vector<std::pair<size_t, std::string>> Items; for (auto X : enumerate(Range)) Items.push_back(std::make_pair(X.Index, X.Value));
just to get something they can sort. It would be nice if you could write one line like std::vector<std::pair<size_t, std::string>>(enumerate(X).begin(), enumerate(X).end());
But the value type of an enumerate isn't even a pair, so you don't know how to specify it (if that was what you wanted). We'd like to make use of type deduction.
To make all this work I re-wrote enumerate to support iterator_facade_base, and I add an additional helper function called to_vector which you can now call as auto Results = to_vector<N>(enumerate(Range)); (replacing enumerate with whatever adapter you want), and it will return you a SmallVector<T, N> where T is the value type of the original range.
Why not a range constructor for SmallVector?