// // 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, detail::category_for_v> { public: using reference = std::pair; using difference_type = typename std::iterator_traits::difference_type; private: using super_t = facade, detail::category_for_v>; 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_}; } SFINAE(super_t::category_enum >= category::forward) void decrement() { ++base_; ++index_; } SFINAE(super_t::category_enum >= category::bidirectional) void increment() { --base_; --index_; } SFINAE(super_t::category_enum >= category::random_access) void advance(difference_type off) { base_ += off; index_ += off; } SFINAE(super_t::category_enum < category::random_access) bool equal_to(indexed_iterator const & other) const { return base_ == other.base_; } SFINAE(super_t::category_enum >= category::random_access) difference_type distance_to(indexed_iterator const & other) const { return other.base_ - base_; } SFINAE(detail::has_sentinel_type_v) bool at_end() const { 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; } MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator);