
On 12/12/2012 11:59 AM, Nathan Ridge wrote:
In fact, when I change the definition of the intercept() macro below to:
#define intercept(FIRST, ARGS...) \ targetfunc(transform(FIRST) \ , boost::lexical_cast<std::string>(BOOST_PP_VARIADIC_SIZE(ARGS)))
I see that BOOST_PP_VARIADIC_SIZE() expands to 1 for intercept("first") as well as for intercept("first", "second").
As I understand it, it is impossible to reliably detect an empty argument list in all cases, so BOOST_PP_VARIADIC_SIZE() returns 1 for an empty argument list. Take a look at this thread [1] for an explanation and a workaround.
Hmm, am I trying to solve the wrong problem?
The briefest explanation of what I want is to take a macro argument list with zero or more arguments and construct a function argument list with one more (initial) argument than that.
I just need MACRO() to expand to function(first), but MACRO(anything) to expand to function(first, anything).
Is there some more reliable way than BOOST_PP_COMMA_IF(BOOST_PP_VARIADIC_SIZE()) to make the comma appear only when required?
The preprocessor only really understand commas and parentheses. So, as far as it's concerned, the definition of "the size of a variadic argument list" is "the number of (top-level) commas in the list plus one".
You want to make an additional distinction - in the case where there are no top-level commas, you want to distinguish between the case where there are some tokens present, and the case where there are none. As Paul Mensonides explains in the thread I linked to, this is not possible in the general case.
It *is* possible to write a version of BOOST_PP_VARIADIC_SIZE() that works the way you want in many cases, quite possibly including your use cases. I believe Boost.Preprocessor does not provide such a version on principle (because it would not work in all cases). However, nothing stops you from using your own version that does this. Gennadiy Rozental posted such a version in the first post of the thread I linked to.
Something like: #include <boost/preprocessor/control/iif.hpp> #include <boost/preprocessor/variadic/size.hpp> #include <boost/variadic_macro_data/vmd_is_empty.hpp> #define ALTERNATIVE_VARIADIC_SIZE(...) BOOST_PP_IIF(BOOST_VMD_IS_EMPTY(__VA_ARGS__), 0, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)) ( The above should be all on one line ) will give an alternate macro for finding out the size of the variadic data. But of course it is flawed because there is no perfect way to test for emptiness. I think the VMD macro for "emptiness", which is taken directly from a post by Paul Mensonides with some minor tweaks for VC++, is pretty good. But Paul did not want to include it in Boost PP, probably because he did not want to rely on a macro with flaws and because variadic data, by its nature, is never considered "empty", ie. is never considered to have a 0 size. I do understand Gennady's POV in his post in the link you gave as well as the OP's query.