// // indexed_iterator.h // iterator // // Created by Sam Jaffe on 3/5/17. // #pragma once #include #include #include namespace iterator { template class EnumerateIterator : public Facade> { public: using reference = std::pair>; using difference_type = typename std::iterator_traits::difference_type; private: using super_t = Facade>; public: EnumerateIterator() = default; EnumerateIterator(It base) : base_(base) {} EnumerateIterator(It base, size_t idx) : base_(base), index_(idx) {} template EnumerateIterator(EnumerateIterator const & oiter) : base_(oiter.base_), index_(oiter.index_) {} reference dereference() const { return {index_, *base_}; } void increment() requires(std::forward_iterator) { ++base_; ++index_; } void decrement() requires(std::bidirectional_iterator) { --base_; --index_; } void advance(difference_type off) requires(std::random_access_iterator) { base_ += off; index_ += off; } bool equal_to(EnumerateIterator const & other) const { return base_ == other.base_; } difference_type distance_to(EnumerateIterator const & other) const requires(std::random_access_iterator) { return other.base_ - base_; } bool at_end() const requires(has_sentinel) { return base_ == typename It::sentinel_type(); } private: template friend class EnumerateIterator; It base_; size_t index_{0}; }; template EnumerateIterator(It) -> EnumerateIterator; template EnumerateIterator(It, size_t) -> EnumerateIterator; }