// // indexed_iterator.hpp // iterator // // Created by Sam Jaffe on 3/5/17. // #pragma once #include #include "iterator/facade.h" namespace iterator { template class indexed_iterator : public facade> { public: using reference = std::pair::reference>; using difference_type = typename std::iterator_traits::difference_type; 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 advance(difference_type off) { base_ += off; index_ += off; } // SFINAE means that if Iterator is not random access, then this still works // TODO: Investigate using _index for comparisons instead of _base bool equal_to(indexed_iterator const & other) const { return base_ == other.base_; } difference_type distance_to(indexed_iterator const & other) const { return other.base_ - base_; } 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; } MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator);