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