indexed_iterator.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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>
  11. 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 = void;
  20. using difference_type = typename std::iterator_traits<Iterator>::difference_type;
  21. using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
  22. indexed_iterator() : _base(), _index(0) {}
  23. indexed_iterator(Iterator base, index_type idx = 0) : _base(base), _index(idx) {}
  24. template <typename OtherIterator>
  25. indexed_iterator(indexed_iterator<OtherIterator> const & oiter) :
  26. _base(oiter._base), _index(oiter._index) {
  27. }
  28. reference operator*() const { return reference{ _index, *_base }; }
  29. indexed_iterator & operator++() { ++_base; ++_index; return *this; }
  30. indexed_iterator operator++(int) { indexed_iterator tmp{*this}; operator++(); return tmp; }
  31. bool operator==(indexed_iterator const & other) const { return _base == other._base; }
  32. bool operator!=(indexed_iterator const & other) const { return _base != other._base; }
  33. // Requires: iterator_category = bidirectional_iterator_tag
  34. indexed_iterator & operator--() { --_base; --_index; return *this; }
  35. indexed_iterator operator--(int) { indexed_iterator tmp{*this}; operator--(); return tmp; }
  36. // Requires: iterator_category = random_access_iterator_tag
  37. indexed_iterator operator+(difference_type n) const { return indexed_iterator{*this} += n; }
  38. indexed_iterator & operator+=(difference_type n) { _index += n; _base += n; return *this; }
  39. indexed_iterator operator-(difference_type n) const { return indexed_iterator{*this} -= n; }
  40. indexed_iterator & operator-=(difference_type n) { _index -= n; _base -= n;return *this; }
  41. bool operator<=(indexed_iterator const & other) const { return _base <= other._base; }
  42. bool operator< (indexed_iterator const & other) const { return _base < other._base; }
  43. bool operator>=(indexed_iterator const & other) const { return _base >= other._base; }
  44. bool operator> (indexed_iterator const & other) const { return _base > other._base; }
  45. private:
  46. template <typename It> friend class ::iterator::indexed_iterator;
  47. Iterator _base;
  48. index_type _index;
  49. };
  50. }