HelloWorld
HelloWorld

Reputation: 1863

Parameter forwarding in preprocessor function macro

Is it possible to forward a parameter list to create a function declaration? The following pseudo-macro is given:

#define FUNCTION_DECLARATION(function_name, ...) \
void function_name(__VA_ARGS__) \
{ \
    other_function_but_gets_the_same_params(__VA_ARGS__); \
}

I want to create a function declaration using something similar to the following syntax:

FUNCTION_DECLARATION(MyFunction, char, char, int)

Upvotes: 1

Views: 245

Answers (1)

Quentin
Quentin

Reputation: 63144

Well, it's funny that you ask this, because I worked on exactly that last week.

Here is the bit that you're interested in. Uses Boost.Preprocessor.

#define STRIP_PARENS(...)   __VA_ARGS__

#define PARAM_PROTO(i, elem)                                            \
    STRIP_PARENS elem _ ## i

#define PARAM_FWD(i, elem)                                              \
    std::forward<STRIP_PARENS elem>(_ ## i)

#define MAKE_PARAM(r, macro, i, elem)                                   \
    STRIP_PARENS BOOST_PP_IF(                                           \
        BOOST_PP_IS_EMPTY(STRIP_PARENS elem),                           \
        (),                                                             \
        (BOOST_PP_COMMA_IF(i) macro(i, elem))                           \
    )

#define MAKE_PARAM_LIST(params, macro)                                  \
    BOOST_PP_SEQ_FOR_EACH_I(MAKE_PARAM, macro, params)

#define FUNCTION_DECLARATION(function_name, params)                     \
    void function_name(MAKE_PARAM_LIST(params, PARAM_PROTO)) {          \
        other_function(MAKE_PARAM_LIST(params, PARAM_FWD));             \
    }

Use as follows :

FUNCTION_DECLARATION(myFunction, ((int))((float))((std::string&)))

// Expands to :
void myFunction(int _0, float _1, std::string& _2) {
    other_function(
        std::forward<int>(_0),
        std::forward<float>(_1),
        std::forward<std::string&>(_2)
    );
}

FYI, the weird-looking parameters list is to cope with types containing commas (e.g std::array<int, 4>). The double-parenthesizing is because BOOST_PP_SEQ_SIZE also trips on commas, one level deeper...

Upvotes: 2

Related Questions