// // end_aware_iterator.hpp // iterator // // Created by Sam Jaffe on 2/7/17. // #pragma once #include #include #include #include namespace iterator { /** * @class end_aware_iterator * @brief An iterator that keeps track of the relative end of the range. * * @tparam It The underlying iterator type */ template class end_aware_iterator : public facade> { public: using sentinel_type = sentinel_t; public: end_aware_iterator() = default; end_aware_iterator(It it, It end) : curr_(it), end_(end) {} template >> end_aware_iterator(C && container) : curr_(std::begin(container)), end_(std::end(container)) { static_assert(std::is_reference_v, "Cannot access iterator of a temporary"); } template end_aware_iterator(end_aware_iterator const & other) : curr_(other.curr_), end_(other.end_) {} end_aware_iterator(end_aware_iterator other, end_aware_iterator) : curr_(other.curr_), end_(other.end_) {} decltype(auto) dereference() const { return *curr_; } void increment() { ++curr_; } bool at_end() const { return curr_ == end_; } bool equal_to(end_aware_iterator const & other) const { // TODO: Fix this clause return (at_end() && other.at_end()) || curr_ == other.curr_; } private: template friend class end_aware_iterator; It curr_, end_; }; template end_aware_iterator(C &&) -> end_aware_iterator>; template end_aware_iterator(It, It) -> end_aware_iterator; template end_aware_iterator(end_aware_iterator, end_aware_iterator) -> end_aware_iterator; } MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::end_aware_iterator);