// // indexed_iterator.h // iterator // // Created by Sam Jaffe on 3/5/17. // #pragma once #include #include #include #include namespace iterator { template class indexed_iterator : public facade> { public: using reference = std::pair; using difference_type = typename std::iterator_traits::difference_type; private: using super_t = facade>; public: indexed_iterator() = default; indexed_iterator(It base) : base_(base) {} indexed_iterator(It base, size_t idx) : base_(base), index_(idx) {} template indexed_iterator(indexed_iterator 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(indexed_iterator const & other) const { return base_ == other.base_; } difference_type distance_to(indexed_iterator 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 indexed_iterator; It base_; size_t index_{0}; }; template indexed_iterator(It) -> indexed_iterator; template indexed_iterator(It, size_t) -> indexed_iterator; }