templates - C++ type registration at compile time trick -
i have following situation: suppose have bunch of types (functors) want register/compile in during compilation, preferably boost::mpl::vector. know trick nicely?
my desire have hpp file implements functor type , registration file, macro brings in type compilation.
for example
// registered.hpp register("functor1.hpp") // implementation register("functor2.hpp") ... boost::mpl::vector<...> types; // full registration vector
hopefully makes sense. thank you
there way register types 1 one , retrieve of them in form of mpl::vector or similar. i've learned trick on boost mailing lists (perhaps dave abrahams, although can't recall sure).
edit: learned slide 28 on https://github.com/boostcon/2011_presentations/raw/master/thu/boost.generic.pdf.
i won't use mpl in code make self contained.
// maximum number of types can registered same tag. enum { kmaxregisteredtypes = 10 }; template <int n> struct rank : rank<n - 1> {}; template <> struct rank<0> {}; // poor man's mpl vector. template <class... ts> struct typelist { static const int size = sizeof...(ts); }; template <class list, class t> struct append; template <class... ts, class t> struct append<typelist<ts...>, t> { typedef typelist<ts..., t> type; }; template <class tag> typelist<> gettypes(tag*, rank<0>) { return {}; } // evaluates typelist of types registered // register_type macro same tag. #define get_registered_types(tag) \ decltype(gettypes(static_cast<tag*>(nullptr), rank<kmaxregisteredtypes>())) // appends type get_registered_types(tag). #define register_type(tag, type) \ inline append<get_registered_types(tag), type>::type \ gettypes(tag*, rank<get_registered_types(tag)::size + 1>) { \ return {}; \ } \ static_assert(true, "")
usage example:
struct integraltypes; struct floatingpointtypes; // both type lists empty. static_assert(std::is_same<get_registered_types(integraltypes), typelist<>>::value, ""); static_assert(std::is_same<get_registered_types(floatingpointtypes), typelist<>>::value, ""); // add both lists. register_type(integraltypes, int); register_type(floatingpointtypes, float); static_assert(std::is_same<get_registered_types(integraltypes), typelist<int>>::value, ""); static_assert(std::is_same<get_registered_types(floatingpointtypes), typelist<float>>::value, ""); // add more types. register_type(integraltypes, long); register_type(floatingpointtypes, double); static_assert(std::is_same<get_registered_types(integraltypes), typelist<int, long>>::value, ""); static_assert(std::is_same<get_registered_types(floatingpointtypes), typelist<float, double>>::value, "");
Comments
Post a Comment