Boost logo

Boost Users :

Subject: Re: [Boost-users] [preprocessor] removing parentheses
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2010-08-05 13:50:22


AMDG

Edward Diener wrote:
> 1) I do not know ( or normally care ) how many commas are in the
> parenthesized value ( ie. size of the tuple )
>
> 2) The value can be passed without any parentheses and therefore not
> be a tuple. For this second problem I can force the end-user always to
> put parentheses around the passed value, even if it does not need it
> to form a single macro value. But 1) would still remain a problem. Of
> course I could solve 1) by forcing the end-user to also pass the
> number of commas in the parenthesized value as a separate template
> parameter, but I think that is too much of a burden for the end-user.
>
> I just want the end-user to pass the value as a single macro
> parameter, and to use the value without the outer parentheses if the
> value contains commas. But perhaps this is just impossible to do with
> C++'s macro facilities. The preprocessing library is so great I was
> hoping it could even solve this problem. In reality I may not need to
> strip off the parentheses from the value ( which in my particular case
> forms part of a C++ declaration ), since redundant parentheses almost
> ( possibly ) never causes a syntax error in C++.
>
> It does seems as if the preprocessor library should have the
> functionality I require since it is able to extract a value from a
> sequence via BOOST_PP_SEQ_ELEM, and a sequence can be in the simple
> form of '(value)'. However my tests show that if I pass a
> non-sequence, such as just 'value' to BOOST_PP_SEQ_ELEM, the compiler
> gives a warning and the result is bogus.

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))

In Christ,
Steven Watanabe


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