Use an std::tuple without magic numbers and the stupid get<> interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment