#include <tuple>

struct Cache;

template<int, typename> struct cache_getter;
template<int, typename...> struct tuple_walker;

template<int I, typename... Ts> struct cache_getter<I, std::tuple<Ts...> > {
    static std::tuple<Ts...> get(Cache & c);
};

struct Cache {
protected:
	template<int, typename...> friend struct tuple_walker;
private:
	/* here T is a type from within a std::tuple<...> */
	template<int I, typename T> std::tuple<T> get_ex() {
		return std::tuple<T>();
	}
public:
	/* here T is actually a std::tuple<...> */
	template<typename T> T get() {
		return cache_getter<0, T>::get(*this);
	}
};

template<typename...> struct my_tuple_cat;
template<typename H, typename... T> struct my_tuple_cat<H, T...> {
	static auto cat(H h, T... t) -> decltype(std::tuple_cat(h, my_tuple_cat<T...>::cat(t...)))
	{ return std::tuple_cat(h, my_tuple_cat<T...>::cat(t...)); }
};
template<typename T> struct my_tuple_cat<T> {
	static T cat(T t) { return t; }
};


template<int I, typename H, typename... T> struct tuple_walker<I, H, T...> {
	static std::tuple<H, T...> get(Cache & c) {
		return my_tuple_cat<std::tuple<H>, std::tuple<T...>>::cat(c.get_ex<I, H>(), tuple_walker<I + 1, T...>::get(c));
	}
};
template<int I, typename H> struct tuple_walker<I, H> {
	static std::tuple<H> get(Cache & c) {
		return c.get_ex<I, H>();
	}
};

template<int I, typename... Ts> std::tuple<Ts...> cache_getter<I, std::tuple<Ts...> >::get(Cache & c) {
	return tuple_walker<I, Ts...>::get(c);
}

int main(int argc, char ** argv) {
	Cache cache;
	typedef std::tuple<int, double, bool> InstrumentTuple;
	InstrumentTuple tuple = cache.get<InstrumentTuple>();
	return 0;
}