I understand C11 generics for one-parameter functions, like this: (from here)
#define acos(X) _Generic((X), \\
long double complex: cacosl, \\
double
Since C doesn't have tuples, let's make our own tuples:
typedef struct {int _;} T_double_double;
typedef struct {int _;} T_double_int;
typedef struct {int _;} T_int_double;
typedef struct {int _;} T_int_int;
typedef struct { T_double_double Double; T_double_int Int;} T_double;
typedef struct { T_int_double Double; T_int_int Int;} T_int;
#define typeof1(X) \
_Generic( (X), \
int: (T_int){{0}}, \
double: (T_double){{0}} )
#define typeof2(X, Y) \
_Generic( (Y), \
int: typeof1(X).Int, \
double: typeof1(X).Double )
This is the client code:
#include
#include "generics.h"
#define typename(X, Y) \
_Generic( typeof2(X, Y), \
T_int_int: "int, int\n", \
T_int_double: "int, double\n", \
T_double_double: "double, double\n", \
T_double_int: "double, int\n", \
default: "Something else\n" )
int main() {
printf(typename(1, 2));
printf(typename(1, 2.0));
printf(typename(1.0, 2.0));
printf(typename(1.0, 2));
return 0;
}
And it works:
~/workspace$ clang -Wall -std=c11 temp.c
~/workspace$ ./a.out
int, int
int, double
double, double
double, int
Yes, you will still need to write code in an exponential size. But at least you will be able to reuse it.