Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics for multiparameter C functions in C11

Tags:

I understand C11 generics for one-parameter functions, like this: (from here)

#define acos(X) _Generic((X), \     long double complex: cacosl, \     double complex: cacos, \     float complex: cacosf, \     long double: acosl, \     float: acosf, \     default: acos \     )(X) 

But, it seems to be a pain for functions with two arguments, you need to nest calls to _Generic, which is really ugly; Excerpt from the same blog:

#define pow(x, y) _Generic((x), \ long double complex: cpowl, \  double complex: _Generic((y), \ long double complex: cpowl, \ default: cpow), \  float complex: _Generic((y), \ long double complex: cpowl, \ double complex: cpow, \ default: cpowf), \  long double: _Generic((y), \ long double complex: cpowl, \ double complex: cpow, \ float complex: cpowf, \ default: powl), \  default: _Generic((y), \ long double complex: cpowl, \ double complex: cpow, \ float complex: cpowf, \ long double: powl, \ default: pow), \  float: _Generic((y), \ long double complex: cpowl, \ double complex: cpow, \ float complex: cpowf, \ long double: powl, \ float: powf, \ default: pow) \ )(x, y) 

Is there a way to have more human being-readable generics for multiparameter functions, like this for instance :

#define plop(a,b) _Generic((a,b), \       (int,long): plopii, \       (double,short int): plopdd)(a,b) 

Thanks in advance for your replies. The basic idea would be having a macro wrapper for _Generic.

like image 582
Mathuin Avatar asked Jun 25 '13 16:06

Mathuin


1 Answers

Given that the controlling expression of _Generic is not evaluated, I'd suggested applying some arithmetic operation that does the appropriate type-combining, and switching on the result. Thus:

#define OP(x, y) _Generic((x) + (y), \     long double complex: LDC_OP(x, y), \     double complex: DC_OP(x, y), \     ... ) 

Of course this only works for certain cases, but you can always expand out those for which the "collapsed" type is not helpful. (This would let one take care of array-N-of-char vs char *, for instance, as with the linked printnl example, and then if the combined type is int, one can go back and check for char and short.)

like image 86
torek Avatar answered Oct 18 '22 12:10

torek