indexed_iterator.hpp 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  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. indexed_iterator(It base) : base_(base) {}
  20. indexed_iterator(It base, size_t idx) : 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. template <typename It> indexed_iterator(It) -> indexed_iterator<It>;
  43. template <typename It> indexed_iterator(It, size_t) -> indexed_iterator<It>;
  44. }
  45. MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator);