indexed_iterator.hpp 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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 "iterator/facade.h"
  10. namespace iterator {
  11. template <typename It>
  12. class indexed_iterator : public facade<indexed_iterator<It>> {
  13. public:
  14. using reference = std::pair<size_t, typename std::iterator_traits<It>::reference>;
  15. using difference_type = typename std::iterator_traits<It>::difference_type;
  16. public:
  17. indexed_iterator() = default;
  18. explicit indexed_iterator(It base, size_t idx = 0) : _base(base), _index(idx) {}
  19. template <typename O> indexed_iterator(indexed_iterator<O> const & oiter)
  20. : _base(oiter._base), _index(oiter._index) {}
  21. reference dereference() const { return {_index, *_base}; }
  22. void advance(difference_type off) {
  23. _base += off;
  24. _index += off;
  25. }
  26. // SFINAE means that if Iterator is not random access, then this still works
  27. // TODO: Investigate using _index for comparisons instead of _base
  28. bool equal_to(indexed_iterator const & other) const { return _base == other._base; }
  29. difference_type distance_to(indexed_iterator const & other) const {
  30. return other._base - _base;
  31. }
  32. private:
  33. template <typename O> friend class indexed_iterator;
  34. It _base;
  35. size_t _index{0};
  36. };
  37. }
  38. MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator)