
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Markus Schöpflin
Is there a way to get this:
scope().attr("foo") = 1; scope().attr("bar") = 2;
or this:
scope().attr("foo") = foo; scope().attr("bar") = bar;
IOW, how can I prevent macro expansion for X when invoked from PY_DEFINE_CONSTANTS()?
The only way to prevent expansion is with # and ##--and that's all about timing. #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/facilities/intercept.hpp> #include <boost/preprocessor/seq/for_each.hpp> #include <boost/preprocessor/tuple/elem.hpp> #define PY_DEFINE_CONSTANTS_NO_EXPANSION_HELPER(r, data, x) \ scope().attr(BOOST_PP_TUPLE_ELEM(2, 0, x)) = BOOST_PP_TUPLE_ELEM(2, 1, x); \ /**/ #define PY_DEFINE_CONSTANTS_NO_EXPANSION(seq) \ BOOST_PP_SEQ_FOR_EACH( \ PY_DEFINE_CONSTANTS_NO_EXPANSION_HELPER, ~, \ BOOST_PP_CAT(PY_DEFINE_CONSTANTS_NO_EXPANSION_A seq ## 0, 0) \ ) \ /**/ #define PY_DEFINE_CONSTANTS_NO_EXPANSION_A(x) ((#x, x)) PY_DEFINE_CONSTANTS_NO_EXPANSION_B #define PY_DEFINE_CONSTANTS_NO_EXPANSION_B(x) ((#x, x)) PY_DEFINE_CONSTANTS_NO_EXPANSION_A #define PY_DEFINE_CONSTANTS_NO_EXPANSION_A0 #define PY_DEFINE_CONSTANTS_NO_EXPANSION_B0 #define foo 1 #define bar 2 PY_DEFINE_CONSTANTS_NO_EXPANSION((foo)(bar) BOOST_PP_INTERCEPT_) The trick here is to get the sequence inside the machinery in a way that allows the machinery to prevent it from expanding. That's the trailing 'INTERCEPT_ and the 'seq ## 0'. From there, it can be immediately processed with custom sequential iteration to make a new sequence with a argument/string pairs. This is about the best way that you can do it, but I won't guarantee that it will work on buggy preprocessors. In fact, I know it won't work on VC. The timing is tricky, and it's intrusive on the interface, but that's about the only way that it can be done. Regards, Paul Mensonides