

#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;
	}
}
