#define FOO(...) DETAIL_FOO1( DETAIL_FOO0 __VA_ARGS__ ) )#define DETAIL_FOO0(...) DETAIL_FOO0_ __VA_ARGS__#define DETAIL_FOO1(...) DETAIL_FOO2(__VA_ARGS__)#define DETAIL_FOO2(...) DETAIL_FOO3_##__VA_ARGS__#define DETAIL_FOO3_DETAIL_FOO0 (#define DETAIL_FOO3_DETAIL_FOO0_ bar(FOO(1) // (1)FOO((1,2,3)) // bar(1,2,3)
In this case FOO(1)
expands to (1)
and not 1
, but this is probably more desirable.
Turns out this incorrectly accepts FOO((1,2)3)
, expanding it to bar(1,2 3)
. With additional macro gymnastics you can reject that:
#define FOO(...) DETAIL_FOO1( DETAIL_FOOA(__VA_ARGS__) ) )#define DETAIL_FOOA(...) DETAIL_FOO0 __VA_ARGS__ )#define DETAIL_FOO0(...) DETAIL_FOO0_ __VA_ARGS__ REQUIRE_EMPTY(#define DETAIL_FOO1(...) DETAIL_FOO2(__VA_ARGS__)#define DETAIL_FOO2(...) DETAIL_FOO3_##__VA_ARGS__#define DETAIL_FOO3_DETAIL_FOO0 ( IDENTITY(#define DETAIL_FOO3_DETAIL_FOO0_ bar(#define REQUIRE_EMPTY()#define IDENTITY(...) __VA_ARGS__