Boost logo

Boost :

From: Vesa Karvonen (vesa.karvonen_at_[hidden])
Date: 2001-06-30 14:22:00


From: "Douglas Gregor" <gregod_at_[hidden]>
> #define REAL_GET_FUNCTION_IMPL_SPEC(i,A,B) \
> template<> \
> struct real_get_function_impl<i> \
> { \
> template< \
> typename R BOOST_PREPROCESSOR_IF(BOOST_FUNCTION_NUM_ARGS, \
> BOOST_PREPROCESSOR_COMMA, \
> BOOST_PREPROCESSOR_EMPTY)() \
> BOOST_PREPROCESSOR_ENUM_SHIFTED_PARAMS( \
> BOOST_FUNCTION_NUM_ARGS_P1, \
> typename T), \
> typename Policy, \
> typename Mixin, \
> typename Allocator \
> > \
> struct params { \
> typedef BOOST_PREPROCESSOR_CAT(function,i)<R \
> BOOST_PREPROCESSOR_IF(i, \
> BOOST_PREPROCESSOR_COMMA, \
> BOOST_PREPROCESSOR_EMPTY)() \
> BOOST_PREPROCESSOR_ENUM_SHIFTED_PARAMS( \
> BOOST_PREPROCESSOR_INC(i), \
> T), \
> Policy, Mixin, Allocator> type; \
> }; \
> };
> --
>
> This took me about an hour to construct. Most of that time was spent chasing
> down the extra "()" strings that occurred in the output. The culprit? I
> didn't realize the difference bettween BOOST_PREPROCESSOR_UNUSED and
> BOOST_PREPROCESSOR_EMPTY. The format is just replaced with space, whereas
the
> latter needs to be evaluated (i.e., BOOST_PREPROCESSOR_EMPTY()) to get the
> empty space. Since BOOST_PREPROCESSOR_IF evaluates its result,
> BOOST_PREPROCESSOR_EMPTY must be used. This was a _huge_ hurdle and I humbly
> request an addition to the documentation.

BTW, It is not necessary to invoke/evaluate the result of
BOOST_PREPROCESSOR_IF. In other words, the () is not required. This makes it
possible to write code as follows:

    BOOST_PREPROCESSOR_IF(0,true,false) == false;
                                     ^^^
You specifically need to invoke the result of BOOST_PREPROCESSOR_IF when:
- the result may be "empty" (or actually a space).
- the result may contain commas, that are not inside {[()]}.

This point needs to be covered in the documentation in more detail, but the
documentation under review actually makes a short note of this.

BTW, I just today read clause 16.3.1 carefully enough to realize that the
depth of "in-place delay" does not affect the results of macro replacement.
All macros that take parameters completely "evaluate" their parameters unless
the macro uses the # or ## operators.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk