// // end_aware_iterator.h // iterator // // Created by Sam Jaffe on 2/7/17. // #pragma once #include #include #include #include namespace iterator { /** * @class EndAwareIterator * @brief An iterator that keeps track of the relative end of the range. * * @tparam It The underlying iterator type */ template class EndAwareIterator : public Proxy> { public: using super_t = Proxy>; using sentinel_type = sentinel_t; public: EndAwareIterator() = default; EndAwareIterator(It it, It end) : super_t(it), end_(end) {} EndAwareIterator(Range auto & container) : super_t(std::begin(container)), end_(std::end(container)) {} template EndAwareIterator(EndAwareIterator const & other) : super_t(other.impl()), end_(other.end_) {} operator std::ranges::subrange() const { return {super_t::impl(), end()}; } bool at_end() const { if constexpr (std::random_access_iterator) { return super_t::impl() >= end_; } else { return super_t::impl() == end_; } } friend auto operator-(sentinel_type, EndAwareIterator const & self) requires(std::random_access_iterator) { return self.end() - self.impl(); } protected: It end() const { return end_; } private: template friend class EndAwareIterator; It end_; }; template EndAwareIterator(C &&) -> EndAwareIterator>; template EndAwareIterator(It, It) -> EndAwareIterator; template EndAwareIterator(EndAwareIterator, EndAwareIterator) -> EndAwareIterator; }