indexed_iterator.hpp 2.8 KB

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