Reputation: 48058
Using c11 _Generic
is there a way to map multiple types to a single value?
eg:
_Generic(e, \
A *: foo_expression, \
B **: foo_expression, \
C: foo_expression, \
enum D: bar_expression, \
void *: bar_expression)
Is there a way to group types? (this isn't valid syntax just to express the intent)
_Generic(e, \
A *: B **: C: foo_expression, \
enum D: void *: bar_expression)
The reason I ask is args foo
and baz
can end up being large expressions (which can't necessarily be refactored into functions), so a way to avoid a lot of duplication would be good.
Note:
If there is no supported way using _Generic
, I _could_ make a varargs macro to glue multiple args to a single value...
#define GENERIC_TYPE_GLUE3(answer, arg0, arg1) \
arg0: answer, arg1: answer
#define GENERIC_TYPE_GLUE4(answer, arg0, arg1, arg2) \
arg0: answer, arg1: answer, arg2: answer
....
... have many of these macros, then use a varargs wrapper to automatically use the right one, see: https://stackoverflow.com/a/24837037/432509
_Generic(e, \
GENERIC_TYPE_GLUE(foo_expression, short int, long),
GENERIC_TYPE_GLUE(bar_expression, float, double))
(See working example: https://gist.github.com/ideasman42/4426f255880ff6a53080)
Upvotes: 1
Views: 782
Reputation: 78923
No, similar to switch
there is no syntax foreseen to regroup multiple cases for _Generic
. Your regrouping macro approach is probably the correct one for your purpose, then. You may have a look into macro meta programming as is done by boost or my package P99 that allow you to have just one such macro that also does the counting of the cases for.
Upvotes: 3
Reputation: 78923
For your use case you can use the type promotion rules
_Generic((e)+0ULL, \
unsigned long long: foo, \
default: bar)
If you have other cases than floating point, you may even go one step further
_Generic((e)+0ULL, \
unsigned long long: foo, \
default: _Generic((e)+0.0L,\
long double: bar, \
default: blur))
This supposes that all your expressions e
have arithmetic type. Remaining for the default
in would then be _Complex
types and all pointer types.
For the kind of usage you have in mind you should do such promotions, anyhow, because compilers currently interpret the controlling expression of _Generic
differently. Some would also consider an object of type double const
differently from double
, for example. So this would really give you a lot of cases to consider, if you'd have to differentiate all possible type qualifications.
Upvotes: 0