indexed_iterator.hpp 1.4 KB

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