enumerate_iterator.h 1.8 KB

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