// // indexed_iterator.hpp // iterator // // Created by Sam Jaffe on 3/5/17. // #pragma once #include namespace iterator { template class indexed_iterator { private: using base_value_type = typename std::iterator_traits::value_type; using base_reference = typename std::iterator_traits::reference; public: using index_type = std::size_t; using value_type = std::pair; using reference = std::pair; using pointer = void; using difference_type = typename std::iterator_traits::difference_type; using iterator_category = typename std::iterator_traits::iterator_category; indexed_iterator() : _base(), _index(0) {} indexed_iterator(Iterator base, index_type idx = 0) : _base(base), _index(idx) {} template indexed_iterator(indexed_iterator const & oiter) : _base(oiter._base), _index(oiter._index) { } reference operator*() const { return reference{ _index, *_base }; } indexed_iterator & operator++() { ++_base; ++_index; return *this; } indexed_iterator operator++(int) { indexed_iterator tmp{*this}; operator++(); return tmp; } bool operator==(indexed_iterator const & other) const { return _base == other._base; } bool operator!=(indexed_iterator const & other) const { return _base != other._base; } // Requires: iterator_category = bidirectional_iterator_tag indexed_iterator & operator--() { --_base; --_index; return *this; } indexed_iterator operator--(int) { indexed_iterator tmp{*this}; operator--(); return tmp; } // Requires: iterator_category = random_access_iterator_tag indexed_iterator operator+(difference_type n) const { return indexed_iterator{*this} += n; } indexed_iterator & operator+=(difference_type n) { _index += n; _base += n; return *this; } indexed_iterator operator-(difference_type n) const { return indexed_iterator{*this} -= n; } indexed_iterator & operator-=(difference_type n) { _index -= n; _base -= n;return *this; } bool operator<=(indexed_iterator const & other) const { return _base <= other._base; } bool operator< (indexed_iterator const & other) const { return _base < other._base; } bool operator>=(indexed_iterator const & other) const { return _base >= other._base; } bool operator> (indexed_iterator const & other) const { return _base > other._base; } private: template friend class ::iterator::indexed_iterator; Iterator _base; index_type _index; }; }