Suppose I have a bunch of vectors:
vector v1;
vector v2;
vector v3;
all of the same length. Now, for ev
As an alternative similar to boost::zip_iterator
I wrote a zip
function with a very simple interface:
vector v1;
vector v2;
vector v3;
auto vec_of_tuples = zip(v1, v2, v3);
For example, iterate over these tuples:
for (auto tuple : zip(v1, v2, v3)) {
int x1; double x2; int x3;
std::tie(x1, x2, x3) = tuple;
//...
}
Here, zip()
takes any number of ranges of any type. It returns an adaptor which can be seen as a lazily evaluated range over a tuple of elements originating from the wrapped ranges.
The adaptor is part of my Haskell-style functional library "fn" and implemented using variadic templates.
Currently it doesn't support modification of the original ranges' values via the adaptor because of the design of the library (it's intended to be used with non-mutable ranges like in functional programming).
A brief explanation on how this is done is: zip(...)
returns an adaptor object which implements begin()
and end()
, returning an iterator object. The iterator holds a tuple of iterators to the wrapped ranges. Incrementing the iterator increments all wrapped iterators (which is implemented using an index list and unpacking an incrementing expression into a series of expressions: ++std::get(iterators)...
). Dereferencing the iterator will decrement all wrapped iterators and pass it to std::make_tuple
(which is also implemented as unpacking the expression *std::get(iterators)...
).
P.S. Its implementation is based on a lot of ideas coming from answers to this question.