#include <iostream>
#include <functional>

template <size_t index, typename... Arg>
struct tuple_impl;

template <size_t index>
struct tuple_impl<index> {};

template <size_t index, typename T, typename... Arg>
struct tuple_impl<index, T, Arg...>: public tuple_impl<index + 1u, Arg...> {
    typedef tuple_impl<index + 1u, Arg...> parent;
	typedef T type;
	T value_;
	tuple_impl(T value, Arg... args): parent(args...), value_(value) {}
	tuple_impl() {}
};

template <typename... Arg>
struct tuple: public tuple_impl<0u, Arg...> {
	typedef tuple_impl<0u, Arg...> parent;
	tuple(Arg... args): parent(args...) {}
	tuple() {}
};

template <size_t index, typename Tuple>
struct tuple_element;

template <size_t index, typename T, typename... Arg>
struct tuple_element<index, tuple<T, Arg...> >: public tuple_element<index - 1u, tuple<Arg...> > {
};

template <typename T, typename... Arg>
struct tuple_element<0u, tuple<T, Arg...> > {
	typedef T type;
};

template <size_t index, typename T, typename... Arg>
typename std::add_lvalue_reference<T>::type _get(tuple_impl<index, T, Arg...> &t) {
	return t.value_;
}

template <size_t index, typename... Arg>
typename std::add_lvalue_reference<typename tuple_element<index, tuple<Arg...> >::type>::type get(tuple<Arg...> &t) {
	return _get<index>(t);
}

int main() {
	tuple<int, char, double> test;
	get<0>(test) = 123;
	get<1>(test) = 'x';
	get<2>(test) = 5.5;
	std::cout << get<0>(test) << std::endl;
	std::cout << get<1>(test) << std::endl;
	std::cout << get<2>(test) << std::endl;
}