[1.43.0][preprocessor] BOOST_PP_SEQ_FOR_EACH doesn't work recursively

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. A simple test is:
>>>>>>>>>>>>>> #include <boost/preprocessor.hpp>
#define SEQ \ ( ( n1 )( n2 )( n3 ) ) \ ( ( n4 )( n5 )( n6 ) ) #define CAT( _r, _data, _elem ) \ BOOST_PP_CAT( _data, _elem ) #define JOIN( _r, _seq ) \ BOOST_PP_SEQ_FOR_EACH_R( _r, CAT, ::, _seq ) #define MAKE( _r, _data, _elem ) \ JOIN( _r, _elem ) BOOST_PP_SEQ_FOR_EACH( MAKE, nil, SEQ ) <<<<<<<<<<<<<<<<<<<< The expected result is something like:
>>>>>>>>>>>>>> ::n1 ::n2 ::n3 ::n4 ::n5 ::n6 <<<<<<<<<<<<<<<<<<<<
while it is not. Instead we get something like:
>>>>>>>>>>>>>> BOOST_PP_SEQ_FOR_EACH_M(3, (CAT, ::, ( n1 )( n2 )( n3 ) (nil))) BOOST_PP_SEQ_FOR_EACH_M(4, (CAT, ::, ( n2 )( n3 ) (nil))) BOOST_PP_SEQ_FOR_EACH_M(5, (CAT, ::, ( n3 ) (nil))) BOOST_PP_SEQ_FOR_EACH_M(4, (CAT, ::, ( n4 )( n5 )( n6 ) (nil))) BOOST_PP_SEQ_FOR_EACH_M(5, (CAT, ::, ( n5 )( n6 ) (nil))) BOOST_PP_SEQ_FOR_EACH_M(6, (CAT, ::, ( n6 ) (nil))) <<<<<<<<<<<<<<<<<<<<
It seems to me that something is wrong with BOOST_PP_SEQ_FOR_EACH(_R) because following JOIN macro works well in this test case:
>>>>>>>>>>>>>> #define JOIN( _r, _seq ) \ BOOST_PP_LIST_FOR_EACH_R( \ _r, \ CAT, \ ::, \ BOOST_PP_TUPLE_TO_LIST( BOOST_PP_SEQ_SIZE( _seq ), BOOST_PP_SEQ_TO_TUPLE( _seq ) ) \ ) <<<<<<<<<<<<<<<<<<<<
While all it does it to use BOOST_PP_LIST_FOR_EACH_R instead of BOOST_PP_SEQ_FOR_EACH_R and change the given sequence to a tuple and then that tuple to a list. Adam Badura

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
participants (2)
-
Adam Badura
-
Jeffrey Lee Hellrung, Jr.