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