How do I expand a macro containing commas inside a BOOST_PP_IF

后端 未结 2 1436
感动是毒
感动是毒 2021-01-21 07:00

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 Preprocesso

相关标签:
2条回答
  • 2021-01-21 07:23

    It turns out that you can do this without __VA_ARGS__. In this simple example I used a comma which is in the template argument of function toString<int,int>() Working demo:

    #include <boost/lexical_cast.hpp>
    #include <boost/preprocessor.hpp>
    #include <iostream>
    #include <string>
    
    #define SEQUENCE (1)(2)(3)(4)(5)(6)(7)(8)(9)(10)
    
    #define IGNORE_ARG(arg)
    #define GET_NAME(data) BOOST_PP_SEQ_ELEM(0, data)
    #define GET_BELOW(data) BOOST_PP_SEQ_ELEM(1, data)
    
    #define PARSE_SEQUENCE(r, data, elem)                  \
        BOOST_PP_IF(                                       \
            BOOST_PP_GREATER_EQUAL(elem, GET_BELOW(data)), \
                GET_NAME(data), IGNORE_ARG)                \
        (elem)
    
    #define SKIP_NUMBERS_BELOW(name, below)                \
        BOOST_PP_SEQ_FOR_EACH(PARSE_SEQUENCE, (name)(below), SEQUENCE)
    
    #define TEST(name) SKIP_NUMBERS_BELOW(name, 4)
    
    #define MACRO_CONTAINING_COMMA(N) toString<N, 2 * N>() <<
    
    template <int a, int b> // whatever, I just need a comma here.
    std::string toString() {
        return boost::lexical_cast<std::string>(a) + ":" + boost::lexical_cast<std::string>(b) + " ";
    }
    
    int main() {
        std::cout << TEST(MACRO_CONTAINING_COMMA) "\n";
    }
    
    0 讨论(0)
  • 2021-01-21 07:25

    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.

    0 讨论(0)
提交回复
热议问题