#include <iostream>
#include <vector>
#include <tuple>
#include <functional>
template<typename C>
struct indexed_container
{
struct indexed_iterator
{
typedef typename C::value_type value_type;
typedef std::tuple<size_t, std::reference_wrapper<value_type>> tuple_type;
typename C::iterator _it;
size_t _index;
indexed_iterator(typename C::iterator it) : _it(it), _index(0) {}
indexed_iterator& operator++()
{
++_it;
++_index;
return *this;
}
bool operator == (indexed_iterator const & other)
{
return _it == other._it;
}
bool operator != (indexed_iterator const & other)
{
return _it != other._it;
}
tuple_type operator*()
{
return std::make_tuple(_index, std::ref(*_it));
}
};
indexed_container(C & c) : _c(c) {}
indexed_iterator begin()
{
return indexed_iterator(_c.begin());
}
indexed_iterator end()
{
return indexed_iterator(_c.end());
}
private:
C & _c;
};
template<typename C>
auto make_indexable(C & c) -> indexed_container<C>
{
return indexed_container<C>(c);
}
int main()
{
std::vector<int> v{1,2,3};
for(auto item : make_indexable(v))
{
std::cout << std::get<0>(item) << " => " << std::get<1>(item) << std::endl;
std::get<1>(item) *= 10; //modify value
}
std::cout << "\nModified\n";
for(auto item : make_indexable(v))
{
std::cout << std::get<0>(item) << " => " << std::get<1>(item) << std::endl;
}
}
CgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDx0dXBsZT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBDPgpzdHJ1Y3QgaW5kZXhlZF9jb250YWluZXIKewogICAgc3RydWN0IGluZGV4ZWRfaXRlcmF0b3IKCXsKCQl0eXBlZGVmIHR5cGVuYW1lIEM6OnZhbHVlX3R5cGUgdmFsdWVfdHlwZTsKCQl0eXBlZGVmIHN0ZDo6dHVwbGU8c2l6ZV90LCBzdGQ6OnJlZmVyZW5jZV93cmFwcGVyPHZhbHVlX3R5cGU+PiB0dXBsZV90eXBlOwoKCQl0eXBlbmFtZSBDOjppdGVyYXRvciBfaXQ7CgkJc2l6ZV90IF9pbmRleDsKCgkJaW5kZXhlZF9pdGVyYXRvcih0eXBlbmFtZSBDOjppdGVyYXRvciBpdCkgOiBfaXQoaXQpLCBfaW5kZXgoMCkge30KCgkJaW5kZXhlZF9pdGVyYXRvciYgb3BlcmF0b3IrKygpCgkJewoJCQkrK19pdDsKCQkJKytfaW5kZXg7CgkJCXJldHVybiAqdGhpczsKCQl9CgkJYm9vbCBvcGVyYXRvciA9PSAoaW5kZXhlZF9pdGVyYXRvciBjb25zdCAmIG90aGVyKQoJCXsKCQkJcmV0dXJuIF9pdCA9PSBvdGhlci5faXQ7CgkJfQoJCWJvb2wgb3BlcmF0b3IgIT0gKGluZGV4ZWRfaXRlcmF0b3IgY29uc3QgJiBvdGhlcikKCQl7CgkJCXJldHVybiBfaXQgIT0gb3RoZXIuX2l0OwoJCX0KCQl0dXBsZV90eXBlIG9wZXJhdG9yKigpCgkJewoJCQlyZXR1cm4gc3RkOjptYWtlX3R1cGxlKF9pbmRleCwgc3RkOjpyZWYoKl9pdCkpOwoJCX0KCX07CgoJaW5kZXhlZF9jb250YWluZXIoQyAmIGMpIDogX2MoYykge30KCglpbmRleGVkX2l0ZXJhdG9yIGJlZ2luKCkKCXsKCQlyZXR1cm4gaW5kZXhlZF9pdGVyYXRvcihfYy5iZWdpbigpKTsKCX0KCWluZGV4ZWRfaXRlcmF0b3IgZW5kKCkKCXsKCQlyZXR1cm4gaW5kZXhlZF9pdGVyYXRvcihfYy5lbmQoKSk7Cgl9CnByaXZhdGU6CglDICYgX2M7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBDPgphdXRvIG1ha2VfaW5kZXhhYmxlKEMgJiBjKSAtPiBpbmRleGVkX2NvbnRhaW5lcjxDPgp7CglyZXR1cm4gaW5kZXhlZF9jb250YWluZXI8Qz4oYyk7IAp9CgppbnQgbWFpbigpCnsKCXN0ZDo6dmVjdG9yPGludD4gdnsxLDIsM307Cglmb3IoYXV0byBpdGVtIDogbWFrZV9pbmRleGFibGUodikpCgl7CgkJc3RkOjpjb3V0IDw8IHN0ZDo6Z2V0PDA+KGl0ZW0pIDw8ICIgPT4gIiA8PCBzdGQ6OmdldDwxPihpdGVtKSA8PCBzdGQ6OmVuZGw7CgoJCXN0ZDo6Z2V0PDE+KGl0ZW0pICo9IDEwOyAvL21vZGlmeSB2YWx1ZQoJfQoJc3RkOjpjb3V0IDw8ICJcbk1vZGlmaWVkXG4iOwoJZm9yKGF1dG8gaXRlbSA6IG1ha2VfaW5kZXhhYmxlKHYpKQoJewoJCXN0ZDo6Y291dCA8PCBzdGQ6OmdldDwwPihpdGVtKSA8PCAiID0+ICIgPDwgc3RkOjpnZXQ8MT4oaXRlbSkgPDwgc3RkOjplbmRsOwoJfQp9Cg==