zip_iterator.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #pragma once
  2. #include <iterator>
  3. #include <tuple>
  4. #include <iterator/facade.h>
  5. #include <iterator/forwards.h>
  6. namespace iterator::detail {
  7. template <typename Tuple, typename IS> class ZipImpl;
  8. template <typename... Ts, size_t... Is>
  9. class ZipImpl<std::tuple<Ts...>, std::index_sequence<Is...>> {
  10. public:
  11. using difference_type =
  12. std::common_type_t<typename std::iterator_traits<Ts>::difference_type...>;
  13. public:
  14. ZipImpl() = default;
  15. ZipImpl(Ts... iters) : _data(iters...) {}
  16. auto dereference() const {
  17. return std::forward_as_tuple(*std::get<Is>(_data)...);
  18. }
  19. void increment() {
  20. [[maybe_unused]] auto l = {((++std::get<Is>(_data)), 0)...};
  21. }
  22. void decrement()
  23. requires(std::bidirectional_iterator<Ts> && ...)
  24. {
  25. [[maybe_unused]] auto l = {((--std::get<Is>(_data)), 0)...};
  26. }
  27. void advance(difference_type d)
  28. requires(std::random_access_iterator<Ts> && ...)
  29. {
  30. [[maybe_unused]] auto l = {((std::get<Is>(_data) += d), 0)...};
  31. }
  32. bool equal_to(ZipImpl const & other) const { return _data == other._data; }
  33. auto distance_to(ZipImpl const & other) const
  34. requires(std::random_access_iterator<Ts> && ...)
  35. {
  36. return std::get<0>(other._data) - std::get<0>(_data);
  37. }
  38. private:
  39. std::tuple<Ts...> _data;
  40. };
  41. }
  42. namespace iterator {
  43. template <typename... Ts>
  44. using index_sequence = decltype(std::make_index_sequence<sizeof...(Ts)>{});
  45. template <typename... Ts>
  46. using ZipImpl = detail::ZipImpl<std::tuple<Ts...>, index_sequence<Ts...>>;
  47. template <typename... Iters>
  48. class ZipIterator : public ZipImpl<Iters...>,
  49. public Facade<ZipIterator<Iters...>> {
  50. public:
  51. ZipIterator() = default;
  52. ZipIterator(Iters... iters) : ZipImpl<Iters...>(iters...) {}
  53. };
  54. template <typename... It> ZipIterator(It...) -> ZipIterator<It...>;
  55. }