Skip to content

Instantly share code, notes, and snippets.

@B1Z0N
Created June 30, 2019 23:16
Show Gist options
  • Save B1Z0N/b3fe47478b9eb26c38c399f13ab0cf89 to your computer and use it in GitHub Desktop.
Save B1Z0N/b3fe47478b9eb26c38c399f13ab0cf89 to your computer and use it in GitHub Desktop.
generic zip iterator for simple zipping in c++
#include <vector>
#include <tuple>
#include <iostream>
using namespace std;
template <
typename T1,
typename T2,
template <typename> typename Container1,
template <typename> typename Container2
>
class zip_iterator
{
using cont_t1 = Container1<T1>;
using cont_t2 = Container2<T2>;
using it_t1 = typename cont_t1::iterator;
using it_t2 = typename cont_t2::iterator;
using self_t = zip_iterator<T1, T2, Container1, Container2>;
it_t1 it1;
it_t2 it2;
public:
explicit zip_iterator(it_t1 fst, it_t2 snd) : it1{fst}, it2{snd} {}
auto& operator++()
{
++it1; ++it2;
return *this;
}
auto operator++(int)
{
auto prev {this};
++*this;
return *prev;
}
bool operator!=(const self_t& other) const
{
return it1 != other.it1 && it2 != other.it2;
}
bool operator==(const self_t& other) const
{
return !operator!=(other);
}
pair<T1, T2> operator*() const
{
return {*it1, *it2};
}
};
namespace std {
template <
typename T1,
typename T2,
template <typename> typename Container1,
template <typename> typename Container2
>
class iterator_traits<zip_iterator<T1, T2, Container1, Container2>>
{
using iterator_category = forward_iterator_tag;
using difference_type = long int;
using value_type = pair<T1, T2>;
};
};
template <
typename T1,
typename T2,
template <typename> typename Container1,
template <typename> typename Container2
>
class zipper
{
using cont_t1 = Container1<T1>;
using cont_t2 = Container2<T2>;
using it_t1 = typename cont_t1::iterator;
using it_t2 = typename cont_t2::iterator;
using it_t = zip_iterator<T1, T2, Container1, Container2>;
cont_t1 &a;
cont_t2 &b;
public:
zipper(cont_t1 &fst, cont_t2 &snd) : a{fst}, b{snd} {}
it_t begin() const { return it_t {std::begin(a), std::begin(b)}; }
it_t end() const { return it_t {std::end(a) , std::end(b) }; }
};
template <
typename T1,
typename T2,
template <typename> typename Container1,
template <typename> typename Container2
>
auto make_zip(Container1<T1>& fst, Container2<T2>& snd)
{
return zipper<T1, T2, Container1, Container2> {fst, snd};
}
int main()
{
vector<int> a {1, 2, 3};
vector<double> b {3.14, 2.92, 0.577, 1.292};
vector<string> c {"s1", "s2"};
for(auto [i, d] : make_zip(a, b))
{
cout << i << "--" << d << " ";
}
cout << endl;
for(auto [i, s] : make_zip(a, c))
{
cout << i << "--" << s << " ";
}
cout << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment