I understand C11 generics for one-parameter functions, like this: (from here)
#define acos(X) _Generic((X), \\
long double complex: cacosl, \\
double
I really feel like the above solutions are not much easier or cleaner than the OP's original implementation. I think the best approach is to keep it simple and just abstract macros with more macros. The following is an example.
#include
double multiply_id ( int a, double b )
{
return a * b;
}
double multiply_di ( double a, int b )
{
return a * b;
}
double multiply_dd ( double a, double b )
{
return a * b;
}
int multiply_ii ( int a, int b )
{
return a * b;
}
/*
#define multiply(a,b) _Generic((a), \
int: _Generic((b), \
int: multiply_ii, \
double: multiply_id), \
double: _Generic((b), \
int: multiply_di, \
double: multiply_dd) ) (a,b)
*/
#define _G2(ParamB,ParamA_Type, TypeB1, TypeB1_Func, TypeB2, TypeB2_Func) \
ParamA_Type: _Generic((ParamB), \
TypeB1: TypeB1_Func, \
TypeB2: TypeB2_Func)
#define multiply(a,b) _Generic((a), \
_G2(b,int,int,multiply_ii,double,multiply_id), \
_G2(b,double,int,multiply_di,double,multiply_dd) ) (a,b)
int main(int argc, const char * argv[]) {
int i;
double d;
i = 5;
d = 5.5;
d = multiply( multiply(d, multiply(d,i) ) ,multiply(i,i) );
printf("%f\n", d);
return 0;
}
_G2
is a macro for two parameter generics. This could be extended to a _G3
or more quite easily. The trick is to just do it normally, then build a macro from it's form.