|
|
@@ -0,0 +1,60 @@
|
|
|
+//
|
|
|
+// indexed_iterator.hpp
|
|
|
+// iterator
|
|
|
+//
|
|
|
+// Created by Sam Jaffe on 3/5/17.
|
|
|
+//
|
|
|
+
|
|
|
+#pragma once
|
|
|
+
|
|
|
+#include <iterator>
|
|
|
+
|
|
|
+namespace iterator {
|
|
|
+ template <typename Iterator>
|
|
|
+ class indexed_iterator {
|
|
|
+ private:
|
|
|
+ using base_value_type = typename std::iterator_traits<Iterator>::value_type;
|
|
|
+ using base_reference = typename std::iterator_traits<Iterator>::reference;
|
|
|
+ public:
|
|
|
+ using index_type = typename std::iterator_traits<Iterator>::difference_type;
|
|
|
+ using value_type = std::pair<index_type, base_value_type>;
|
|
|
+ using reference = std::pair<index_type, base_reference>;
|
|
|
+ using pointer = void;
|
|
|
+ using difference_type = typename std::iterator_traits<Iterator>::difference_type;
|
|
|
+ using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
|
|
|
+
|
|
|
+ indexed_iterator() : _base(), _index(0) {}
|
|
|
+ indexed_iterator(Iterator base, index_type idx = 0) : _base(base), _index(idx) {}
|
|
|
+
|
|
|
+ template <typename OtherIterator>
|
|
|
+ indexed_iterator(indexed_iterator<OtherIterator> 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 <typename It> friend class ::iterator::indexed_iterator;
|
|
|
+ Iterator _base;
|
|
|
+ index_type _index;
|
|
|
+ };
|
|
|
+}
|