lundi 23 mars 2015

Wrap each element in variadic macro with an expression


Problem:


I'm looking to write a variadic macro



#define WRAP(token, ...)


which, when called with a token and N arguments



WRAP(decltype, a, b, c)


will expand into a comma-separated list of the arguments wrapped in the token



decltype(a), decltype(b), decltype(c)


This would allow me to write something like the following:



#define MACRO(...) \
Class< WRAP(decltype, __VA_ARGS__) >::Function();


If I call it as follows:



MACRO(a, b, c)


it would result in:



Class<decltype(a), decltype(b), decltype(c)>::Function(0;


I have no idea how to achieve this. Is it possible? Perhaps with BOOST_PP or some such?


Motivation:


I have a macro for logging:



#define LOG(fmt, ...) \
logger::instance().push(__FUNCTION__, fmt, __VA_ARGS__);


I have a variadic class template which is able to verify the arguments match the provided format string



template<typename... Ts>
struct Format
{
template<std::size_t N>
static constexpr bool check(const char (&fmt)[N], std::size_t n);
};


If I define a macro with a fixed number of arguments I can call my format checking function:



#define LOG(fmt, a) \
static_assert(Format<decltype(a1)>::check(fmt, 0), ""); \
logger::instance().push(__FUNCTION__, fmt, a);


However, if I use a variadic macro, this won't work for more than 1 argument:



#define LOG(fmt, ...) \
static_assert(Format<decltype(__VA_ARGS__)>::check(fmt, 0), ""); \
logger::instance().push(__FUNCTION__, fmt, __VA_ARGS__);


That's because decltype(__VA_ARGS__) is obviously invalid syntax.


to fix it, I need to expand __VA_ARGS__ into decltype(a1), decltype(a2), decltype(a3)




Aucun commentaire:

Enregistrer un commentaire