
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 In Christ, Steven Watanabe