Boost logo

Boost Users :

Subject: Re: [Boost-users] [preprocessor] BOOST_PP_VARIADIC_SIZE() and g++ in 1.52
From: Edward Diener (eldiener_at_[hidden])
Date: 2012-12-12 23:23:55


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.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net