#pragma once #include #include #include "proxy.h" namespace iterator::zip { template struct impl { public: using difference_type = std::common_type_t< typename std::iterator_traits::difference_type...>; public: std::tuple data; public: impl() = default; impl(Iters &&... iters) : data(iters...) {} auto operator*() const { return std::make_tuple(*std::get(data)...); } void operator++(int) { [[maybe_unused]] auto l = {(++(std::get(data)), 0)...}; } void operator--(int) { [[maybe_unused]] auto l = {(--(std::get(data)), 0)...}; } void operator+=(difference_type d) { [[maybe_unused]] auto l = {((std::get(data) += d), 0)...}; } bool operator==(impl const & other) const { return data == other.data; } auto operator-(impl const & other) const { return std::get<0>(data) - std::get<0>(other.data); } }; } namespace std { template struct iterator_traits<::iterator::zip::impl> { using difference_type = common_type_t::difference_type...>; using iterator_category = common_type_t::iterator_category...>; }; } namespace iterator { template class zip_iterator : public proxy, zip_iterator> { private: using super = proxy, zip_iterator>; public: zip_iterator() = default; zip_iterator(Iters &&... iters) : super(std::forward(iters)...) {} }; } namespace std { template struct iterator_traits<::iterator::zip_iterator> : std::iterator_traits< ::iterator::facade<::iterator::zip_iterator>> { // This shouldn't need to be implemented, but for some reason my traits // are not correctly deducing here. using iterator_category = common_type_t::iterator_category...>; }; } template iterator::zip_iterator make_zip_iterator(Is &&... iters) { return {std::forward(iters)...}; }