// // counting_iterator.hpp // // Created by Joshua Moerman on 05/22/11. // Copyright 2011 Vadovas. All rights reserved. // /* USAGE: "for(auto x : counted(v)) { ... x.value ... x.index ... }" x.value is a reference to the element in the container (so you can change it's value), x.index is what it is. Container should havae forward iterators. NOTE: This headers is purely a handy tool for the "for(auto x : counter(v))"-syntax. Using it explicitly with iterators is not recommended! NOTE: There is no const version of it. Doing "for(const auto x : counted(v))" doesn't make it impossible to change x (so the element in the container can be modified). */ #ifndef COUNTING_ITERATOR_HPP #define COUNTING_ITERATOR_HPP #include // A reference is a struct, yuk... // Maybe a proxy is better template struct counting_pair{ private: typedef counting_pair self; public: T& value; Integer index; counting_pair(T& v, Integer i) : value(v), index(i) {} counting_pair(const self& copy) : value(copy.value), index(copy.index) {} }; // It's only forward for the moment template struct counting_iterator : public std::iterator::value_type, Integer>> { private: typedef counting_iterator self; typedef counting_pair::value_type, Integer> value_type; Iterator it; Integer count; public: counting_iterator(Iterator it) : it(it), count(0) {} counting_iterator(const self& copy) : it(copy.it), count(copy.count) {} self& operator++(){ ++it; ++count; return *this; } self operator++(int){ self copy(*this); ++*this; return copy; } bool operator==(const self& rhs){ return it == rhs.it; } bool operator!=(const self& rhs){ return it != rhs.it; } typename self::value_type operator*() { return counting_pair::value_type, Integer>(*it, count); } }; template struct counting_container { private: typedef counting_container self; typedef typename Container::iterator backing_iterator; Container* backing_container; public: typedef counting_iterator iterator; counting_container(Container& v) : backing_container(std::addressof(v)) {} counting_container(const self& x) : backing_container(x.backing_container) {} iterator begin() { return iterator(backing_container->begin()); } iterator end() { return iterator(backing_container->end()); } }; template counting_container counted(Container& c){ return counting_container(c); } #endif // COUNTING_ITERATOR_HPP