Roman A. Taycher
Roman A. Taycher

Reputation: 19487

c11 _Generic adding types

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

Answers (3)

Abdulmalek Almkainzi
Abdulmalek Almkainzi

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

Jens Gustedt
Jens Gustedt

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

hroptatyr
hroptatyr

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

Related Questions