Boost logo

Boost :

Subject: Re: [boost] [1.43.0][preprocessor] BOOST_PP_SEQ_FOR_EACH doesn't work recursively
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-05-21 12:34:55


On 5/21/2010 3:20 AM, Adam Badura wrote:
> BOOST_PP_SEQ_FOR_EACH macro when used within another
> BOOST_PP_SEQ_FOR_EACH does not expand at all (and the same happens with
> _R versions). I use Visual Studio 2005.

Yes, I've run into this problem, too. It occurs with some of the *_R,
*_S, etc. Boost.PP macros when the "macro" argument (perhaps indirectly)
contains the same Boost.PP macro. The workaround I've been using is to
create variants which actually accept the "r" parameter as a
concatenation, to avoid nested calls to the same macro:

#define BOOST_EXT_PP_SEQ_FOR_EACH_0_for_macro( r, state )
BOOST_PP_TUPLE_ELEM( 4, 1, state ) ( r, BOOST_PP_TUPLE_ELEM( 4, 2, state
), BOOST_PP_SEQ_HEAD( BOOST_PP_TUPLE_ELEM( 4, 3, state ) ) )
#define BOOST_EXT_PP_SEQ_FOR_EACH_1_for_macro( r, state )
BOOST_PP_TUPLE_ELEM( 4, 1, state ) ( r, BOOST_PP_TUPLE_ELEM( 4, 2, state
), BOOST_PP_SEQ_HEAD( BOOST_PP_TUPLE_ELEM( 4, 3, state ) ) )
#define BOOST_EXT_PP_SEQ_FOR_EACH_2_for_macro( r, state )
BOOST_PP_TUPLE_ELEM( 4, 1, state ) ( r, BOOST_PP_TUPLE_ELEM( 4, 2, state
), BOOST_PP_SEQ_HEAD( BOOST_PP_TUPLE_ELEM( 4, 3, state ) ) )
...
#define BOOST_EXT_PP_SEQ_FOR_EACH_0( macro, data, seq ) BOOST_PP_FOR_0(
( BOOST_PP_SEQ_SIZE( seq ), macro, data, seq ),
BOOST_EXT_PP_SEQ_FOR_EACH_for_pred, BOOST_EXT_PP_SEQ_FOR_EACH_for_op,
BOOST_EXT_PP_SEQ_FOR_EACH_0_for_macro )
#define BOOST_EXT_PP_SEQ_FOR_EACH_1( macro, data, seq ) BOOST_PP_FOR_1(
( BOOST_PP_SEQ_SIZE( seq ), macro, data, seq ),
BOOST_EXT_PP_SEQ_FOR_EACH_for_pred, BOOST_EXT_PP_SEQ_FOR_EACH_for_op,
BOOST_EXT_PP_SEQ_FOR_EACH_1_for_macro )
#define BOOST_EXT_PP_SEQ_FOR_EACH_2( macro, data, seq ) BOOST_PP_FOR_2(
( BOOST_PP_SEQ_SIZE( seq ), macro, data, seq ),
BOOST_EXT_PP_SEQ_FOR_EACH_for_pred, BOOST_EXT_PP_SEQ_FOR_EACH_for_op,
BOOST_EXT_PP_SEQ_FOR_EACH_2_for_macro )
...

and so on (generated with a script), with

#define BOOST_EXT_PP_SEQ_FOR_EACH_for_pred( r, state ) \
     BOOST_PP_TUPLE_ELEM( 4, 0, state )
#define BOOST_EXT_PP_SEQ_FOR_EACH_for_op( r, state ) \
     ( \
         BOOST_PP_DEC( BOOST_PP_TUPLE_ELEM( 4, 0, state ) ), \
         BOOST_PP_TUPLE_ELEM( 4, 1, state ), \
         BOOST_PP_TUPLE_ELEM( 4, 2, state ), \
         BOOST_PP_SEQ_TAIL( BOOST_PP_TUPLE_ELEM( 4, 3, state ) ) \
     )

I don't know if this is the optimal solution, but it's worked fine for
me. I have a similar thing built for SEQ_TRANSFORM[_S].

- Jeff


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