// // end_aware_iterator.hpp // iterator // // Created by Sam Jaffe on 2/7/17. // #pragma once #include "iterator_fwd.hpp" #include "facade.h" 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 value_type = typename It::value_type; struct sentinel_type {}; static constexpr sentinel_type sentinel; public: end_aware_iterator() = default; end_aware_iterator(It it, It end) : curr_(it), end_(end) {} end_aware_iterator(It end) : curr_(end), end_(end) {} template end_aware_iterator(end_aware_iterator const & other) : 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(It) -> end_aware_iterator; template end_aware_iterator(It, It) -> end_aware_iterator; } MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::end_aware_iterator); template auto make_end_aware_iterator(C & collect) { return iterator::end_aware_iterator(std::begin(collect), std::end(collect)); } template auto make_end_aware_iterator(C const & collect) { return iterator::end_aware_iterator(std::begin(collect), std::end(collect)); }