indexed_iterator.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. template <typename It>
  14. class indexed_iterator : public Facade<indexed_iterator<It>> {
  15. public:
  16. using reference = std::pair<size_t, DEREF_TYPE(It)>;
  17. using difference_type = typename std::iterator_traits<It>::difference_type;
  18. private:
  19. using super_t = Facade<indexed_iterator<It>>;
  20. public:
  21. indexed_iterator() = default;
  22. indexed_iterator(It base) : base_(base) {}
  23. indexed_iterator(It base, size_t idx) : base_(base), index_(idx) {}
  24. template <typename O>
  25. indexed_iterator(indexed_iterator<O> const & oiter)
  26. : base_(oiter.base_), index_(oiter.index_) {}
  27. reference dereference() const { return {index_, *base_}; }
  28. void increment()
  29. requires(std::forward_iterator<It>)
  30. {
  31. ++base_;
  32. ++index_;
  33. }
  34. void decrement()
  35. requires(std::bidirectional_iterator<It>)
  36. {
  37. --base_;
  38. --index_;
  39. }
  40. void advance(difference_type off)
  41. requires(std::random_access_iterator<It>)
  42. {
  43. base_ += off;
  44. index_ += off;
  45. }
  46. bool equal_to(indexed_iterator const & other) const {
  47. return base_ == other.base_;
  48. }
  49. difference_type distance_to(indexed_iterator const & other) const
  50. requires(std::random_access_iterator<It>)
  51. {
  52. return other.base_ - base_;
  53. }
  54. bool at_end() const
  55. requires(has_sentinel<It>)
  56. {
  57. return base_ == typename It::sentinel_type();
  58. }
  59. private:
  60. template <typename O> friend class indexed_iterator;
  61. It base_;
  62. size_t index_{0};
  63. };
  64. template <typename It> indexed_iterator(It) -> indexed_iterator<It>;
  65. template <typename It> indexed_iterator(It, size_t) -> indexed_iterator<It>;
  66. }