#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;
}
I2luY2x1ZGUgPHR1cGxlPgoKc3RydWN0IENhY2hlOwoKdGVtcGxhdGU8aW50LCB0eXBlbmFtZT4gc3RydWN0IGNhY2hlX2dldHRlcjsKdGVtcGxhdGU8aW50LCB0eXBlbmFtZS4uLj4gc3RydWN0IHR1cGxlX3dhbGtlcjsKCnRlbXBsYXRlPGludCBJLCB0eXBlbmFtZS4uLiBUcz4gc3RydWN0IGNhY2hlX2dldHRlcjxJLCBzdGQ6OnR1cGxlPFRzLi4uPiA+IHsKICAgIHN0YXRpYyBzdGQ6OnR1cGxlPFRzLi4uPiBnZXQoQ2FjaGUgJiBjKTsKfTsKCnN0cnVjdCBDYWNoZSB7CnByb3RlY3RlZDoKCXRlbXBsYXRlPGludCwgdHlwZW5hbWUuLi4+IGZyaWVuZCBzdHJ1Y3QgdHVwbGVfd2Fsa2VyOwpwcml2YXRlOgoJLyogaGVyZSBUIGlzIGEgdHlwZSBmcm9tIHdpdGhpbiBhIHN0ZDo6dHVwbGU8Li4uPiAqLwoJdGVtcGxhdGU8aW50IEksIHR5cGVuYW1lIFQ+IHN0ZDo6dHVwbGU8VD4gZ2V0X2V4KCkgewoJCXJldHVybiBzdGQ6OnR1cGxlPFQ+KCk7Cgl9CnB1YmxpYzoKCS8qIGhlcmUgVCBpcyBhY3R1YWxseSBhIHN0ZDo6dHVwbGU8Li4uPiAqLwoJdGVtcGxhdGU8dHlwZW5hbWUgVD4gVCBnZXQoKSB7CgkJcmV0dXJuIGNhY2hlX2dldHRlcjwwLCBUPjo6Z2V0KCp0aGlzKTsKCX0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lLi4uPiBzdHJ1Y3QgbXlfdHVwbGVfY2F0Owp0ZW1wbGF0ZTx0eXBlbmFtZSBILCB0eXBlbmFtZS4uLiBUPiBzdHJ1Y3QgbXlfdHVwbGVfY2F0PEgsIFQuLi4+IHsKCXN0YXRpYyBhdXRvIGNhdChIIGgsIFQuLi4gdCkgLT4gZGVjbHR5cGUoc3RkOjp0dXBsZV9jYXQoaCwgbXlfdHVwbGVfY2F0PFQuLi4+OjpjYXQodC4uLikpKQoJeyByZXR1cm4gc3RkOjp0dXBsZV9jYXQoaCwgbXlfdHVwbGVfY2F0PFQuLi4+OjpjYXQodC4uLikpOyB9Cn07CnRlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBteV90dXBsZV9jYXQ8VD4gewoJc3RhdGljIFQgY2F0KFQgdCkgeyByZXR1cm4gdDsgfQp9OwoKCnRlbXBsYXRlPGludCBJLCB0eXBlbmFtZSBILCB0eXBlbmFtZS4uLiBUPiBzdHJ1Y3QgdHVwbGVfd2Fsa2VyPEksIEgsIFQuLi4+IHsKCXN0YXRpYyBzdGQ6OnR1cGxlPEgsIFQuLi4+IGdldChDYWNoZSAmIGMpIHsKCQlyZXR1cm4gbXlfdHVwbGVfY2F0PHN0ZDo6dHVwbGU8SD4sIHN0ZDo6dHVwbGU8VC4uLj4+OjpjYXQoYy5nZXRfZXg8SSwgSD4oKSwgdHVwbGVfd2Fsa2VyPEkgKyAxLCBULi4uPjo6Z2V0KGMpKTsKCX0KfTsKdGVtcGxhdGU8aW50IEksIHR5cGVuYW1lIEg+IHN0cnVjdCB0dXBsZV93YWxrZXI8SSwgSD4gewoJc3RhdGljIHN0ZDo6dHVwbGU8SD4gZ2V0KENhY2hlICYgYykgewoJCXJldHVybiBjLmdldF9leDxJLCBIPigpOwoJfQp9OwoKdGVtcGxhdGU8aW50IEksIHR5cGVuYW1lLi4uIFRzPiBzdGQ6OnR1cGxlPFRzLi4uPiBjYWNoZV9nZXR0ZXI8SSwgc3RkOjp0dXBsZTxUcy4uLj4gPjo6Z2V0KENhY2hlICYgYykgewoJcmV0dXJuIHR1cGxlX3dhbGtlcjxJLCBUcy4uLj46OmdldChjKTsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiogYXJndikgewoJQ2FjaGUgY2FjaGU7Cgl0eXBlZGVmIHN0ZDo6dHVwbGU8aW50LCBkb3VibGUsIGJvb2w+IEluc3RydW1lbnRUdXBsZTsKCUluc3RydW1lbnRUdXBsZSB0dXBsZSA9IGNhY2hlLmdldDxJbnN0cnVtZW50VHVwbGU+KCk7CglyZXR1cm4gMDsKfQ==