Reputation: 19487
How do you add extra types to c11 _Generic Functions?
Do you have to #undef/re-#define it?(if so would the following work) or is there a nicer way?
#define to_str(X) _Generic((X), \
long double: ld_str, \
double: d_str, \
float: f_str, \
)(X)
#undef to_str
#define to_str(X) _Generic((X), \
long double: ld_str, \
double: d_str, \
float: f_str, \
int: i_str, \
)(X)
Upvotes: 4
Views: 2383
Reputation: 461
One thing you can do is:
#define to_str(X) _Generic((X), \
long double: ld_str, \
double: d_str, \
float: f_str \
EXTRA_TYPES \
)(X)
#define EXTRA_TYPES \
,int: i_str, \
char: c_str
notice how the comma is part of the EXTRA_TYPES
and not the to_str
macro. This is to make to_str
work even if EXTRA_TYPES
was empty.
Now all you have to do is define EXTRA_TYPES
with the types you need.
Upvotes: 3
Reputation: 78923
I am not sure that I understand your question completely. You mean that you have a type generic macro that is given by some library and you want to amend it with a new type of your own?
What you always could do is to give it another name and use the default case to obtain the provided behavior:
#define to_str2(X) _Generic((X), default: to_str(X), int: i_str(X))
Edit:
This will not work perfectly because you'd have to put the function argument evaluation inside the _Generic
. This means in particular that the type of X
has to be compatible with all branches of the nested generic expressions.
It would be easier if the library in question had a macro that would just return the function itself, without the (X)
, say to_strGen
, and that never would evaluate X
. Then you could do
#define to_str2Gen(X) _Generic((X), default: to_strGen(X), int: i_str)
#define to_str2(X) to_str2Gen(X)(X)
Upvotes: 8
Reputation: 4809
If it's your code, you would have to #undef
it and re#define
it, yes. There's no way to extend a type-generic expression (AFAIK).
If it's not your code I'd introduce a second expression with the extension like Jens suggested.
Upvotes: 3