end_aware_iterator.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. //
  2. // end_aware_iterator.h
  3. // iterator
  4. //
  5. // Created by Sam Jaffe on 2/7/17.
  6. //
  7. #pragma once
  8. #include <iterator/forwards.h>
  9. #include <iterator/proxy.h>
  10. #include <iterator/sentinel.h>
  11. #include <iterator/detail/macro.h>
  12. namespace iterator {
  13. /**
  14. * @class end_aware_iterator
  15. * @brief An iterator that keeps track of the relative end of the range.
  16. *
  17. * @tparam It The underlying iterator type
  18. */
  19. template <typename It>
  20. class end_aware_iterator : public proxy<It, end_aware_iterator<It>> {
  21. public:
  22. using super_t = proxy<It, end_aware_iterator<It>>;
  23. using sentinel_type = sentinel_t;
  24. public:
  25. end_aware_iterator() = default;
  26. end_aware_iterator(It it, It end) : super_t(it), end_(end) {}
  27. end_aware_iterator(Range auto & container)
  28. : super_t(std::begin(container)), end_(std::end(container)) {}
  29. template <typename Ot>
  30. end_aware_iterator(end_aware_iterator<Ot> const & other)
  31. : super_t(other.impl()), end_(other.end_) {}
  32. bool at_end() const {
  33. if constexpr (std::random_access_iterator<It>) {
  34. return super_t::impl() >= end_;
  35. } else {
  36. return super_t::impl() == end_;
  37. }
  38. }
  39. friend auto operator-(sentinel_type, end_aware_iterator const & self)
  40. requires(std::random_access_iterator<It>)
  41. {
  42. return self.end() - self.impl();
  43. }
  44. protected:
  45. It end() const { return end_; }
  46. private:
  47. template <typename O> friend class end_aware_iterator;
  48. It end_;
  49. };
  50. template <typename C>
  51. end_aware_iterator(C &&) -> end_aware_iterator<iterator_t<C>>;
  52. template <typename It> end_aware_iterator(It, It) -> end_aware_iterator<It>;
  53. template <typename It>
  54. end_aware_iterator(end_aware_iterator<It>, end_aware_iterator<It>)
  55. -> end_aware_iterator<It>;
  56. }
  57. #include <iterator/detail/undef.h>