
On Thu, 29 Mar 2012 14:39:20 +0100, Rob Desbois wrote:
I'm unable to use the reentrant macros for iteration currently..I think I'm probably misunderstanding their usage, and a push in the right direction would be much appreciated.
My need is to iterate through a sequence, then iterate through a sequence nested within each element. As I understand, I should be able to call (e.g.): * BOOST_PP_SEQ_FOR_EACH(OP, data, seq) to iterate through the outer sequence * then in OP(r, data, elem) call BOOST_PP_SEQ_FOR_EACH_R(r, OP2, data, elem)
Neither BOOST_PP_SEQ_FOR_EACH nor BOOST_PP_SEQ_TRANSFORM are reentrant algorithms. In fact, only a relative few of the core algorithms in the pp- lib are reentrant. In the cases of SEQ_FOR_EACH and SEQ_TRANSFORM, the SEQ_FOR_EACH_R and SEQ_TRANSFORM_S variants of those macros reenter BOOST_PP_FOR and BOOST_PP_SEQ_FOLD_LEFT efficiently. They do not reenter SEQ_FOR_EACH and SEQ_TRANSFORM. Unfortunately, it isn't realistic to implement everything in a reentrant way (i.e. explosion of # of macros). With Chaos--which requires a really good preprocessor (such as gcc)-- rather than the Boost.Preprocessor), all higher-order algorithms are reentrant. E.g. // 1.cpp #include <chaos/preprocessor/recursion/expr.h> #include <chaos/preprocessor/seq/transform.h> #define I(s, e) <e> #define M(s, is) CHAOS_PP_EXPR(CHAOS_PP_SEQ_TRANSFORM(I, is)) #define O(os) CHAOS_PP_EXPR(CHAOS_PP_SEQ_TRANSFORM(M, os)) O( ((a) (b) (c)) ((i) (j) (k)) ((x) (y) (z)) ) // w/gcc 4.7 $ g++ -std=c++11 -E -P -I $CHAOS_ROOT 1.cpp ((<a>)(<b>)(<c>))((<i>)(<j>)(<k>))((<x>)(<y>)(<z>)) With gcc earlier than 4.7 (e.g. 4.6.x), you'd use: g++ -std=c++0x -E -P -I $CHAOS_ROOT -D CHAOS_PP_VARIADICS 1.cpp Of course, if you want to get fancy: // 2.cpp #include <chaos/preprocessor/control/iif.h> #include <chaos/preprocessor/detection/is_variadic.h> #include <chaos/preprocessor/recursion/basic.h> #include <chaos/preprocessor/recursion/expr.h> #include <chaos/preprocessor/seq/for_each.h> #define MACRO(s, ...) \ CHAOS_PP_IIF(CHAOS_PP_IS_VARIADIC(__VA_ARGS__))( \ MACRO_A, MACRO_B \ )(CHAOS_PP_OBSTRUCT(), CHAOS_PP_NEXT(s), __VA_ARGS__) \ /**/ #define MACRO_ID() MACRO #define MACRO_A(_, s, ...) \ CHAOS_PP_EXPR_S _(s)(CHAOS_PP_SEQ_FOR_EACH_S _( \ s, MACRO_ID _(), __VA_ARGS__ \ )) \ /**/ #define MACRO_B(_, s, ...) (__VA_ARGS__) #define FLATTEN(seq) \ CHAOS_PP_EXPR(CHAOS_PP_SEQ_FOR_EACH( \ MACRO, seq \ )) \ /**/ FLATTEN( ((a) (b) (c)) ((i) (j) (k)) ((x) (y) (z)) (1) ((2)) (((3))) ) $ g++ -std=c++11 -E -P -I $CHAOS_ROOT 2.cpp (a)(b)(c)(i)(j)(k)(x)(y)(z)(1)(2)(3) Here we have a recursive SEQ_FOR_EACH and a recursive target MACRO. Regards, Paul Mensonides