|
Boost : |
From: John Eddy (johneddy_at_[hidden])
Date: 2005-02-03 10:56:57
Many thanks. That worked perfectly. I did not catch the acceptance of
0 sized tupes in BOOST_PP_TUPLE_REM_CTOR.
Thanks,
John
Paul Mensonides wrote:
>
>
>
>
>>-----Original Message-----
>>From: boost-bounces_at_[hidden]
>>[mailto:boost-bounces_at_[hidden]] On Behalf Of John Eddy
>>Sent: Wednesday, February 02, 2005 12:35 PM
>>To: boost_at_[hidden]
>>Subject: [boost] BOOST_PP_EXPR_IF Behavior
>>
>>I am not terribly familiar with the rules of the
>>preprocessor. Is it the case that the expression of the
>>BOOST_PP_EXPR_IF macro is expanded regardless of the
>>resulting value of the condition?
>>
>>
>
>For EXPR_IF, yes. If and only if an argument to a macro appears in the
>replacement list of that macro without being an operand of # or ##, then that
>argument should be expanded on input to the macro--regardless of whether the
>argument is relevant to the final result of macro expansion. Note the "and only
>if" part above in particular. Minus all the workarounds, EXPR_IF is defined
>like this:
>
>#define EXPR_IF(cond, expr) EXPR_IIF(BOOL(cond), expr)
>
>I.e. it simply defers to EXPR_IIF after converting the condition to 0 or 1.
>Note that 'expr' appears in the replacement list without being an operand of #
>or ##. EXPR_IIF is the same way, but defined differently:
>
>#define EXPR_IIF(bit, expr) CAT(EXPR_IIF_, bit)(expr)
>#define EXPR_IIF_0(expr)
>#define EXPR_IIF_1(expr) expr
>
>In other words, in both cases, 'expr' will be expanded regardless of 'cond' or
>'bit'.
>
>With that said, EXPR_IF (etc.) is only defined that the way it is because
>preprocessors are non-conformant. If I could encapsulate their problems (which
>I can't), I would do it this way:
>
>#define EXPR_IF(cond) CAT(EXPR_IF_, BOOL(cond))
>#define EXPR_IF_0(expr)
>#define EXPR_IF_1(expr) expr
>
>The usage syntax would then be:
>
>EXPR_IF ( condition ) ( expression )
>
>instead of
>
>EXPR_IF ( condition , expression )
>
>The difference is that the former is lazy. If 'cond' is 0, 'expr' is passed to
>a macro that does not mention 'expr' in its replacement list and thus should not
>be expanded. Unfortunately, I cannot effectively encapsulate preprocessor bugs
>with this kind of "combination" syntax.
>
>[As an aside, to those who may be interested: with placemarkers (i.e. empty
>arguments) from C99, macros can propogate "lack of evaluation" by placemarker
>concatenation--which does not change the tokens in the argument but does prevent
>them from expanding on input.]
>
>
>
>>The warning is:
>>
>>C4003: not enough actual parameters for macro 'BOOST_PP_EXPR_IIF_0'
>>
>>The macro expands correctly.
>>
>>
>
>Don't rely on that. It's a VC misfeature; it should be an error.
>
>
>
>>Perhaps there is a better way to do what I am after. I would
>>like to create a comma separated list (no parenthesis as
>>would be the case if I only took the array data) from a
>>possibly empty set.
>>
>>
>
>Okay, let me see if I understand correctly. You have an array (as in the pp
>data structure) which looks like (e.g.):
>
>(0, ())
>(1, (a))
>(2, (a, b))
>(3, (a, b, c))
>// etc.
>
>And you want this transformation:
>
>(0, ()) ->
>(1, (a)) -> a
>(2, (a, b)) -> a, b
>(3, (a, b, c)) -> a, b, c
>
>Assuming that that is what you want...
>
>#include <boost/preprocessor/array/data.hpp>
>#include <boost/preprocessor/array/size.hpp>
>#include <boost/preprocessor/tuple/rem.hpp>
>
>#define ARRAY_ENUM(array) \
> BOOST_PP_TUPLE_REM_CTOR( \
> BOOST_PP_ARRAY_SIZE(array), \
> BOOST_PP_ARRAY_DATA(array) \
> ) \
> /**/
>
>ARRAY_ENUM( (0, ()) ) // ->
>ARRAY_ENUM( (1, (a)) ) // -> a
>ARRAY_ENUM( (2, (a, b)) ) // -> a, b
>ARRAY_ENUM( (3, (a, b, c)) ) // -> a, b, c
>
>Regards,
>Paul Mensonides
>
>_______________________________________________
>Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk