zip_iterator.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #pragma once
  2. #include <iterator>
  3. #include <tuple>
  4. #include "detail/arrow_proxy.h"
  5. namespace iterator {
  6. template <typename... Iterators> class zip_iterator {
  7. public:
  8. using value_type = std::tuple<typename Iterators::value_type...>;
  9. using reference = std::tuple<typename Iterators::reference...>;
  10. using pointer = void; // tuple cannot be accessed by member
  11. using difference_type =
  12. std::common_type_t<typename Iterators::difference_type...>;
  13. using iterator_category =
  14. std::common_type_t<typename Iterators::iterator_category...>;
  15. private:
  16. std::tuple<Iterators...> iterators_;
  17. public:
  18. zip_iterator() = default;
  19. zip_iterator(Iterators &&... iters) : iterators_(iters...) {}
  20. reference operator*() const {
  21. return reference(*std::get<Iterators>(iterators_)...);
  22. }
  23. pointer operator->() const;
  24. zip_iterator & operator++() {
  25. [[maybe_unused]] auto l = {(++(std::get<Iterators>(iterators_)), 0)...};
  26. return *this;
  27. }
  28. zip_iterator operator++(int) {
  29. zip_iterator tmp = *this;
  30. operator++();
  31. return tmp;
  32. }
  33. zip_iterator & operator--() {
  34. [[maybe_unused]] auto l = {(--(std::get<Iterators>(iterators_)), 0)...};
  35. return *this;
  36. }
  37. zip_iterator operator--(int) {
  38. zip_iterator tmp = *this;
  39. operator--();
  40. return tmp;
  41. }
  42. zip_iterator & operator+=(difference_type d) {
  43. [[maybe_unused]] auto l = {
  44. ((std::get<Iterators>(iterators_) += d), 0)...};
  45. return *this;
  46. }
  47. zip_iterator operator+(difference_type d) {
  48. return zip_iterator{*this} += d;
  49. }
  50. reference operator[](difference_type d) { return *(*this + d); }
  51. zip_iterator & operator-=(difference_type d) {
  52. [[maybe_unused]] auto l = {
  53. ((std::get<Iterators>(iterators_) -= d), 0)...};
  54. return *this;
  55. }
  56. zip_iterator operator-(difference_type d) {
  57. return zip_iterator{*this} -= d;
  58. }
  59. difference_type operator-(zip_iterator const & other) {
  60. return std::get<0>(iterators_) - std::get<0>(other.iterators_);
  61. }
  62. bool operator==(zip_iterator const & rhs) const {
  63. return iterators_ == rhs.iterators_;
  64. }
  65. bool operator!=(zip_iterator const & rhs) const {
  66. return iterators_ != rhs.iterators_;
  67. }
  68. bool operator<(zip_iterator const & rhs) const {
  69. return iterators_ < rhs.iterators_;
  70. }
  71. bool operator<=(zip_iterator const & rhs) const {
  72. return iterators_ <= rhs.iterators_;
  73. }
  74. bool operator>(zip_iterator const & rhs) const {
  75. return iterators_ > rhs.iterators_;
  76. }
  77. bool operator>=(zip_iterator const & rhs) const {
  78. return iterators_ >= rhs.iterators_;
  79. }
  80. };
  81. template <typename... Is>
  82. zip_iterator<Is...> operator+(typename zip_iterator<Is...>::difference_type d,
  83. zip_iterator<Is...> iter) {
  84. return iter += d;
  85. }
  86. }
  87. template <typename... Is>
  88. iterator::zip_iterator<Is...> make_zip_iterator(Is &&... iters) {
  89. return {std::forward<Is>(iters)...};
  90. }