| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- #pragma once
- #include <iterator>
- #include <tuple>
- #include "facade.h"
- namespace iterator::detail {
- template <typename Tuple, typename IS> class zip_iterator_impl;
- template <typename... Ts, size_t... Is>
- class zip_iterator_impl<std::tuple<Ts...>, std::index_sequence<Is...>> {
- public:
- using difference_type =
- std::common_type_t<typename std::iterator_traits<Ts>::difference_type...>;
- public:
- zip_iterator_impl() = default;
- zip_iterator_impl(Ts... iters) : _data(iters...) {}
- auto dereference() const {
- return std::forward_as_tuple(*std::get<Is>(_data)...);
- }
- void increment() {
- [[maybe_unused]] auto l = {((++std::get<Is>(_data)), 0)...};
- }
- void decrement() {
- [[maybe_unused]] auto l = {((++std::get<Is>(_data)), 0)...};
- }
- void advance(difference_type d) {
- [[maybe_unused]] auto l = {((std::get<Is>(_data) += d), 0)...};
- }
- bool equal_to(zip_iterator_impl const & other) const {
- return _data == other._data;
- }
- auto distance_to(zip_iterator_impl const & other) const {
- return std::get<0>(other._data) - std::get<0>(_data);
- }
- private:
- std::tuple<Ts...> _data;
- };
- }
- namespace iterator {
- template <typename... Ts>
- using index_sequence = decltype(std::make_index_sequence<sizeof...(Ts)>{});
- template <typename... Ts>
- using zip_impl =
- detail::zip_iterator_impl<std::tuple<Ts...>, index_sequence<Ts...>>;
- template <typename... Iters>
- class zip_iterator : public zip_impl<Iters...>,
- public facade<zip_iterator<Iters...>> {
- public:
- zip_iterator() = default;
- zip_iterator(Iters... iters) : zip_impl<Iters...>(iters...) {}
- };
- template <typename... It> zip_iterator(It...) -> zip_iterator<It...>;
- }
- template <typename... T>
- struct std::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...>;
- };
|