Zip Iterator


Iterates over several containers simultaneously. The dereferenced value is a tuple of the dereferenced values of the involved iterators.


#include "tbb/iterators.h"


template <typename... Types>
class zip_iterator {
    typedef typename std::make_signed<std::size_t>::type difference_type;
    typedef std::tuple<typename std::iterator_traits<Types>::value_type...> value_type;
    typedef std::tuple<typename std::iterator_traits<Types>::reference...> reference;
    typedef std::tuple<typename std::iterator_traits<Types>::pointer...> pointer;
    explicit zip_iterator(Types... args);
    reference operator*() const;
    reference operator[](difference_type i) const;
    difference_type operator-(const zip_iterator& it) const;
    zip_iterator& operator+=(difference_type forward);
    zip_iterator& operator-=(difference_type backward);
    zip_iterator& operator++();
    zip_iterator& operator--();
    zip_iterator operator++(int);
    zip_iterator operator--(int);
    zip_iterator operator-(difference_type backward) const;
    zip_iterator operator+(difference_type forward) const;
    friend zip_iterator operator+(difference_type forward, const zip_iterator& it);
    bool operator==(const zip_iterator& it) const;
    bool operator!=(const zip_iterator& it) const;
    bool operator<(const zip_iterator& it) const;
    bool operator>(const zip_iterator& it) const;
    bool operator<=(const zip_iterator& it) const;
    bool operator>=(const zip_iterator& it) const;

template<typename... T>
zip_iterator<T...> make_zip_iterator(T&&... args);


zip_iterator is a random access iterator used for iterating over several containers simultaneously in STL algorithms. The operator*() function returns a tuple of the dereferenced values of the individual iterators used in parallel iterating of the containers. The individual iterators must have equal iteration space sizes and their initial values must be the same points in the iteration spaces. Otherwise, behavior is undefined. make_zip_iterator creates a zip_iterator object, deducing the target type from the types of arguments.


The following example illustrates calculations performed by getting data from arrays a, b, and storing it to array c.

#include <algorithm>
#include <tuple>
#include <vector>
#include <tbb/iterators.h>

int main() {
    const int N = 100000;
    std::vector<float> a(N), b(N), c(N);

    tbb::counting_iterator<int> cnt0(0), cntN(N);
    std::for_each(cnt0, cntN, [&a](int i){ a[i] = i*i; });
    std::for_each(cnt0, cntN, [&b](int i){ b[i] = i*i*i; });

    auto start = tbb::make_zip_iterator(a.begin(), b.begin(), c.begin());
    auto end   = tbb::make_zip_iterator(a.end(), b.end(), c.end());

    std::for_each(start, end, [](const std::tuple<float&, float&, float&>& v) {
          std::get<2>(v) = std::get<0>(v) + std::get<1>(v);

    return 0;