indexed_iterator.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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
  15. : public facade<indexed_iterator<It>> {
  16. public:
  17. using reference = std::pair<size_t, DEREF_TYPE(It)>;
  18. using difference_type = typename std::iterator_traits<It>::difference_type;
  19. private:
  20. using super_t = facade<indexed_iterator<It>>;
  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 increment() requires(std::forward_iterator<It>) {
  30. ++base_;
  31. ++index_;
  32. }
  33. void decrement() requires(std::bidirectional_iterator<It>) {
  34. --base_;
  35. --index_;
  36. }
  37. void advance(difference_type off) requires(std::random_access_iterator<It>) {
  38. base_ += off;
  39. index_ += off;
  40. }
  41. bool equal_to(indexed_iterator const & other) const {
  42. return base_ == other.base_;
  43. }
  44. difference_type distance_to(indexed_iterator const & other) const requires(std::random_access_iterator<It>) {
  45. return other.base_ - base_;
  46. }
  47. SFINAE(detail::has_sentinel_type_v<It>) bool at_end() const {
  48. return base_ == typename It::sentinel_type();
  49. }
  50. private:
  51. template <typename O> friend class indexed_iterator;
  52. It base_;
  53. size_t index_{0};
  54. };
  55. template <typename It> indexed_iterator(It) -> indexed_iterator<It>;
  56. template <typename It> indexed_iterator(It, size_t) -> indexed_iterator<It>;
  57. }
  58. MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator);