| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- #pragma once
- #include <iterator>
- #include <tuple>
- #include <iterator/facade.h>
- #include <iterator/forwards.h>
- namespace iterator::detail {
- template <typename Tuple, typename IS> class ZipImpl;
- template <typename... Ts, size_t... Is>
- class ZipImpl<std::tuple<Ts...>, std::index_sequence<Is...>> {
- public:
- using difference_type =
- std::common_type_t<typename std::iterator_traits<Ts>::difference_type...>;
- public:
- ZipImpl() = default;
- ZipImpl(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()
- requires(std::bidirectional_iterator<Ts> && ...)
- {
- [[maybe_unused]] auto l = {((--std::get<Is>(_data)), 0)...};
- }
- void advance(difference_type d)
- requires(std::random_access_iterator<Ts> && ...)
- {
- [[maybe_unused]] auto l = {((std::get<Is>(_data) += d), 0)...};
- }
- bool equal_to(ZipImpl const & other) const { return _data == other._data; }
- auto distance_to(ZipImpl const & other) const
- requires(std::random_access_iterator<Ts> && ...)
- {
- 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 ZipImpl = detail::ZipImpl<std::tuple<Ts...>, index_sequence<Ts...>>;
- template <typename... Iters>
- class ZipIterator : public ZipImpl<Iters...>,
- public Facade<ZipIterator<Iters...>> {
- public:
- ZipIterator() = default;
- ZipIterator(Iters... iters) : ZipImpl<Iters...>(iters...) {}
- };
- template <typename... It> ZipIterator(It...) -> ZipIterator<It...>;
- }
|