Martin Fehrs
Martin Fehrs

Reputation: 1091

Achieve the opposite of __VA_OPT__ in variadic preprocessor function-like macros

How can I achieve the opposite effect of VA_OPT(), expanding only, if there are no variadic arguments in VA_ARGS. Something like VA_NOT_OPT().

Example:

#define MY_MACRO(...) __VA_NOT_OPT__(default) __VA_ARGS__

MY_MACRO() expands to default

MY_MACRO(arg) expands to arg

What I really want is a single optional parameter with a default value. But I think the C-Preprocessor doesn't support this. But maybe someone knows better than me.

Upvotes: 1

Views: 779

Answers (1)

Artyer
Artyer

Reputation: 40911

You can build a little conditional expansion macro pretty easily, so that VALUE_IFNOT(1, args) expands to nothing and VALUE_IF(0, args) (or in this case VALUE_IF(, args) too) expands to args:

#define VALUE_IFNOT_TEST(...) __VA_ARGS__
#define VALUE_IFNOT_TEST0(...) __VA_ARGS__
#define VALUE_IFNOT_TEST1(...)
#define VALUE_IFNOT(COND, ...) VALUE_IFNOT_TEST ## COND ( __VA_ARGS__ )

Then your "opposite of __VA_OPT__" macro looks like VALUE_IF(__VA_OPT__(1), value). This will expand to VALUE_IF(1, value) and nothing if there were variadic arguments and VALUE_IF(, value) and value if there weren't.

For example https://godbolt.org/z/Kbc5jxEKf

#define TEST(...) VALUE_IFNOT(__VA_OPT__(1), std::printf("Test expanded on line %d with args '%s'\n", __LINE__, #__VA_ARGS__); )

int main() {
    TEST()      // TEST expanded on line 12 with args ''
    TEST(1)     // (no output)
    TEST(1, 2)  // (no output)
}

Upvotes: 5

Related Questions