indexed_iterator.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // indexed_iterator.hpp
  3. // iterator
  4. //
  5. // Created by Sam Jaffe on 3/5/17.
  6. //
  7. #pragma once
  8. #include <iterator>
  9. #include "detail/arrow_proxy.h"
  10. namespace iterator {
  11. template <typename Iterator> class indexed_iterator {
  12. private:
  13. using base_value_type = typename std::iterator_traits<Iterator>::value_type;
  14. using base_reference = typename std::iterator_traits<Iterator>::reference;
  15. public:
  16. using index_type = std::size_t;
  17. using value_type = std::pair<index_type, base_value_type>;
  18. using reference = std::pair<index_type, base_reference>;
  19. using pointer = detail::arrow_proxy<reference>;
  20. using difference_type =
  21. typename std::iterator_traits<Iterator>::difference_type;
  22. using iterator_category =
  23. typename std::iterator_traits<Iterator>::iterator_category;
  24. indexed_iterator() : _base(), _index(0) {}
  25. indexed_iterator(Iterator base, index_type idx = 0)
  26. : _base(base), _index(idx) {}
  27. template <typename OtherIterator>
  28. indexed_iterator(indexed_iterator<OtherIterator> const & oiter)
  29. : _base(oiter._base), _index(oiter._index) {}
  30. reference operator*() const { return reference{_index, *_base}; }
  31. pointer operator->() const { return {operator*()}; }
  32. indexed_iterator & operator++() {
  33. ++_base;
  34. ++_index;
  35. return *this;
  36. }
  37. indexed_iterator operator++(int) {
  38. indexed_iterator tmp{*this};
  39. operator++();
  40. return tmp;
  41. }
  42. bool operator==(indexed_iterator const & other) const {
  43. return _base == other._base;
  44. }
  45. bool operator!=(indexed_iterator const & other) const {
  46. return _base != other._base;
  47. }
  48. // Requires: iterator_category = bidirectional_iterator_tag
  49. indexed_iterator & operator--() {
  50. --_base;
  51. --_index;
  52. return *this;
  53. }
  54. indexed_iterator operator--(int) {
  55. indexed_iterator tmp{*this};
  56. operator--();
  57. return tmp;
  58. }
  59. // Requires: iterator_category = random_access_iterator_tag
  60. indexed_iterator operator+(difference_type n) const {
  61. return indexed_iterator{*this} += n;
  62. }
  63. indexed_iterator & operator+=(difference_type n) {
  64. _index += n;
  65. _base += n;
  66. return *this;
  67. }
  68. difference_type operator-(indexed_iterator const & it) const {
  69. return _base - it._base;
  70. }
  71. indexed_iterator operator-(difference_type n) const {
  72. return indexed_iterator{*this} -= n;
  73. }
  74. indexed_iterator & operator-=(difference_type n) {
  75. _index -= n;
  76. _base -= n;
  77. return *this;
  78. }
  79. bool operator<=(indexed_iterator const & other) const {
  80. return _base <= other._base;
  81. }
  82. bool operator<(indexed_iterator const & other) const {
  83. return _base < other._base;
  84. }
  85. bool operator>=(indexed_iterator const & other) const {
  86. return _base >= other._base;
  87. }
  88. bool operator>(indexed_iterator const & other) const {
  89. return _base > other._base;
  90. }
  91. private:
  92. template <typename It> friend class ::iterator::indexed_iterator;
  93. Iterator _base;
  94. index_type _index;
  95. };
  96. }