indexed_iterator.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. //
  2. // indexed_iterator.h
  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. #include <iterator/forwards.h>
  11. #include <iterator/detail/macro.h>
  12. namespace iterator {
  13. // TODO: I should be respecting the underlying type
  14. template <typename It>
  15. class indexed_iterator
  16. : public facade<indexed_iterator<It>, category::random_access> {
  17. public:
  18. using reference =
  19. std::pair<size_t, typename std::iterator_traits<It>::reference>;
  20. using difference_type = typename std::iterator_traits<It>::difference_type;
  21. public:
  22. indexed_iterator() = default;
  23. indexed_iterator(It base) : base_(base) {}
  24. indexed_iterator(It base, size_t idx) : base_(base), index_(idx) {}
  25. template <typename O>
  26. indexed_iterator(indexed_iterator<O> const & oiter)
  27. : base_(oiter.base_), index_(oiter.index_) {}
  28. reference dereference() const { return {index_, *base_}; }
  29. void advance(difference_type off) {
  30. base_ += off;
  31. index_ += off;
  32. }
  33. // SFINAE means that if Iterator is not random access, then this still works
  34. // TODO: Investigate using _index for comparisons instead of _base
  35. bool equal_to(indexed_iterator const & other) const {
  36. return base_ == other.base_;
  37. }
  38. difference_type distance_to(indexed_iterator const & other) const {
  39. return other.base_ - base_;
  40. }
  41. SFINAE(detail::has_sentinel_type_v<It>) bool at_end() const {
  42. return base_ == typename It::sentinel_type();
  43. }
  44. private:
  45. template <typename O> friend class indexed_iterator;
  46. It base_;
  47. size_t index_{0};
  48. };
  49. template <typename It> indexed_iterator(It) -> indexed_iterator<It>;
  50. template <typename It> indexed_iterator(It, size_t) -> indexed_iterator<It>;
  51. }
  52. MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator);