Skip to content

Instantly share code, notes, and snippets.

@MisanthropicBit
Created November 28, 2013 17:17
Show Gist options
  • Save MisanthropicBit/7695333 to your computer and use it in GitHub Desktop.
Save MisanthropicBit/7695333 to your computer and use it in GitHub Desktop.
C++11 convenience class that mimics the Python enumerate function for range-based for-loops.
#include <iterator>
#include <type_traits>
// Inspired by:
// http://stackoverflow.com/questions/10962290/find-position-of-element-in-c11-range-based-for-loop
template<typename T>
class Enumerator final {
public:
class iterator {
private:
typedef typename std::conditional<std::is_const<T>::value, typename T::const_iterator, typename T::iterator>::type inner_iterator;
typedef typename std::iterator_traits<inner_iterator>::reference inner_reference;
public:
typedef std::pair<size_t, inner_reference> reference;
iterator(inner_iterator it) : _pos(0), _it(it) {}
reference operator*() const {
return reference(_pos, *_it);
}
iterator& operator++() {
++_pos;
++_it;
return *this;
}
iterator operator++(int) {
iterator tmp(*this);
operator++();
return tmp;
}
bool operator== (const iterator& it) const {
return _it == it._it;
}
bool operator!= (const iterator& it) const {
return _it != it._it;
}
private:
size_t _pos;
inner_iterator _it;
};
Enumerator(T& t) : _container(t) {}
iterator begin() const { return iterator(_container.begin()); }
iterator end() const { return iterator(_container.end()); }
private:
T& _container;
};
// Example usage:
int main(int argc, char** argv) {
std::string test = "Can_I_be_enumerated?";
for (auto p : enumerate(test))
// p.first is the index, p.second the current value
std::cout << p.first << ", " << p.second << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment