// // 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; explicit indexed_iterator(It base, size_t idx = 0) : _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}; }; } MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator);