Search code examples
c++boost-preprocessor

How do I expand a macro containing commas inside a BOOST_PP_IF


I asked the following question earlier, but the solution doesn't seem to work in this particular case.

How do I print out a comma multiple times using Boost Preprocessor

I am trying to expand a macro containing a comma conditionally. Here is an example illustrating the problem:

#define TEST(...)\
    BOOST_PP_REPEAT( \
        BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
        MACRO, \
        BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))

#define MACRO(z, n, data) BOOST_PP_IF(1,MACRO_CONTAINING_COMMA(z, z),MACRO_CONTAINING_COMMA(z, z))

#define MACRO_CONTAINING_COMMA(_NAME, _NAME2) _NAME TIBRA_EATEN_COMMA() _NAME2

#define EATEN_COMMA BOOST_PP_IF(1,BOOST_PP_COMMA,BOOST_PP_TUPLE_EAT())
TEST(1,2,3,4)

This expands to

BOOST_PP_IIF BOOST_PP_IIF BOOST_PP_IIF BOOST_PP_IIF

When it should expand to

0,0 1,1 2,2 3,3


Solution

  • You can delay invoking your macro by first selecting it and then invoking it:

    #define TEST(...)\
        BOOST_PP_REPEAT( \
            BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
            MACRO, \
            BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
    
    #define MACRO(z, n, data) BOOST_PP_IF(1,MACRO_CONTAINING_COMMA,MACRO_CONTAINING_COMMA)(n, n)
    
    #define MACRO_CONTAINING_COMMA(_NAME, _NAME2) _NAME EATEN_COMMA _NAME2
    
    #define EATEN_COMMA BOOST_PP_IF(1,BOOST_PP_COMMA,BOOST_PP_TUPLE_EAT())()
    

    See it work

    The IF invocation expands to either your macro without an invocation or something that discard arguments when invoked. After one is chosen, the last parentheses invoke it with the desired arguments without the commas getting in the way.

    Apart from that, I changed z to n and TIBRA_EATEN_COMMA() to EATEN_COMMA. As some parts are redundant, you can find a simpler version here.