I need to be able to get the following:
#define MY_MACRO(PARAM1,PARAM2) \\
MY_OTHER_MACRO(TYPENAME_OF(PARAM1),PARAMNAME_OF(PARAM1));\\
MY_OTHER_MACRO(TYPEN
You can do this, but only with the extremely difficult limitation that you must know all of the type names in advance: it won't work with any user-defined types unless the user adds them to the list of known types too - that's admittedly not hard.
Accepting this limitation, you can do something like this:
#define LPAREN (
#define RPAREN )
#define COMMA ,
#define CAT(L, R) CAT_(L, R)
#define CAT_(L, R) L ## R
#define EXPAND(...) __VA_ARGS__
#define SPLIT(OP, D) EXPAND(OP CAT(SPLIT_, D) RPAREN)
#define SPLIT_int LPAREN int COMMA
#define SPLIT_char LPAREN char COMMA
#define SPLIT_float LPAREN float COMMA
#define SPLIT_double LPAREN double COMMA
#define MY_MACRO(A, B) \
SPLIT(MY_OTHER_MACRO, A); SPLIT(MY_OTHER_MACRO, B);
MY_MACRO(int x, char * z) // emits MY_OTHER_MACRO ( int , x ); MY_OTHER_MACRO ( char , * z );
Adding a type to the list of known types is, as above, a one-liner (#define SPLIT_myType LPAREN myType COMMA
), and can be done anywhere in the program as long as it comes before the type is actually used by SPLIT
, so it's not the end of the world, although it is highly intrusive.
There is no easy way to get the asterisk to be on the left of the split. It could probably be done, but it would be much more complicated, and involve placing the restriction on the list of allowed variable names, which IMO is much, much worse. Probably more intrusive too, since you're almost certain to have more variables than types in a working program.