Boost logo

Boost Users :

Subject: Re: [Boost-users] [preprocessor] removing parentheses
From: Edward Diener (eldiener_at_[hidden])
Date: 2010-08-06 13:35:41


On 8/6/2010 12:40 PM, Steven Watanabe wrote:
> AMDG
>
> Edward Diener wrote:
>> On 8/5/2010 1:50 PM, Steven Watanabe wrote:
>>> The processor library doesn't support it, since the solution requires
>>> variadic macros. The preprocessor output from the following seems
>>> to be correct with msvc 2005 and gcc 4.4.1
>>>
>>> #define CAT(x, y) CAT_I(x, y)
>>> #define CAT_I(x, y) x ## y
>>>
>>> #define APPLY(macro, args) APPLY_I(macro, args)
>>> #define APPLY_I(macro, args) macro args
>>>
>>> #define STRIP_PARENS(x) EVAL((STRIP_PARENS_I x), x)
>>> #define STRIP_PARENS_I(...) 1,1
>>>
>>> #define EVAL(test, x) EVAL_I(test, x)
>>> #define EVAL_I(test, x) MAYBE_STRIP_PARENS(TEST_ARITY test, x)
>>>
>>> #define TEST_ARITY(...) APPLY(TEST_ARITY_I, (__VA_ARGS__, 2, 1))
>>> #define TEST_ARITY_I(a,b,c,...) c
>>>
>>> #define MAYBE_STRIP_PARENS(cond, x) MAYBE_STRIP_PARENS_I(cond, x)
>>> #define MAYBE_STRIP_PARENS_I(cond, x) CAT(MAYBE_STRIP_PARENS_, cond)(x)
>>>
>>> #define MAYBE_STRIP_PARENS_1(x) x
>>> #define MAYBE_STRIP_PARENS_2(x) APPLY(MAYBE_STRIP_PARENS_2_I, x)
>>> #define MAYBE_STRIP_PARENS_2_I(...) __VA_ARGS__
>>>
>>> STRIP_PARENS(this is a test)
>>> STRIP_PARENS((a,b,c))
>>
>> I can not figure out how this code works. Evidently the rules for
>> recursive macro invocation eludes me, no matter how many times I have
>> read the 16.13.1 in the C++ working draft.
>
> Alright. Here's stepping through the evaluation
> of the two macro invocations. (I may have the evaluation
> order slightly wrong, but it doesn't affect the final
> result.)
>
> STRIP_PARENS(this is a test)
> EVAL((STRIP_PARENS_I this is a test), this is a test)
> At this point the first argument is either STRIP_PARENS_I
> followed by the original argument or it is 1,1. We can distinguish
> the two by checking the size as a tuple.
> EVAL_I((STRIP_PARENS_I this is a test), this is a test)
> MAYBE_STRIP_PARENS(TEST_ARITY (STRIP_PARENS_I this is a test), this is a
> test)
> Now we expand TEST_ARITY which returns the number of elements in its
> argument. In this case, the result will be 1.
> APPLY(TEST_ARITY_I, (STRIP_PARENS_I this is a test, 2, 1))
> APPLY_I(TEST_ARITY_I, (STRIP_PARENS_I this is a test, 2, 1))
> TEST_ARITY_I (STRIP_PARENS_I this is a test, 2, 1)
> TEST_ARITY_I (STRIP_PARENS_I this is a test, 2, 1)
> 1
> Now we can go back to MAYBE_STRIP_PARENS.
> We're going to switch on the tuple size (which we just
> found)to decide whether we need to remove parentheses.
> MAYBE_STRIP_PARENS(1, this is a test)
> MAYBE_STRIP_PARENS_I(1, this is a test)
> CAT(MAYBE_STRIP_PARENS_, 1)(this is a test)
> MAYBE_STRIP_PARENS_1(this is a test)
> this is a test.
>
> In the second case we get
> EVAL((STRIP_PARENS_I (a,b,c)), (a,b,c))
> STRIP_PARENS_I can be expanded to get
> EVAL((1,1), (a,b,c))
> Now we we check the arity, we end up with
> TEST_ARITY_I (1,1, 2, 1)
> which expands to 2, and we select
> MAYBE_STRIP_PARENS_2((a,b,c))
> the expansion of which should be straightforward

Many thanks !


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