Is it possible to use the boost::iterators library to create iterators that show the combined results of 2 ranges? Note that for usage, we need the output to be iterators. Nor do we expect to first manually create a vector of all combinations. (Note: We compile with C++17)
A contrived example:
auto v = std::vector<int>({1,2,3});
auto s = std::set<double>({0.5, 1.5});
auto range = combineElements(v.begin(), v.end(), s.begin(), s.end(), [](int i, double d){ return std::pair{i, d}; });
for (auto [i, d] : range)
std::cout << std::to_string(i) << ',' <<std::to_string(d) << ";";
// Expected output: 1,0.5;1,1.5;2,0.5;2,1.5;3,0.5;3,1.5;
I've checked the documentation of boost::iterators and found:
- Zip: This combined the nth element of the first range, with the nth of the second. However, doesn't combine nth with mth element.
- Generator: The generator that needs to be provided could do manual bookkeeping keeping 6 iterators: begin, end, and current for both ranges. However, it doesn't have a way to stop it.
- Function input: Similar to Generator, we could put those iterators in the state and create an end-state for the end-iterator using the end-iterators. However, the state ain't provided to the generator to calculate the value of the iterator.
- Permutation: Works on a single range
- Transform: Works on a single range
Am I correct to conclude that in this situation the only option is to write customer iterator by hand?
Pretty much yes. You might want to decompose it into an iterator adaptor that repeats each element N times, and one that repeats the whole range M times, which would allow you to
zipthe pair of those.