+/*
+the conditional expression (that selects the right function
+for evaluation) should be casted to the return type of the
+selected function (otherwise the result type is determined
+by the conversion rules applied to all the function return
+types so it is long double or long double _Complex)
+
+this cannot be done in c99 (c11 has _Generic that would help
+but is not yet widely supported), so the typeof extension of
+gcc is used and that ?: has special semantics when one of
+the operands is a null pointer constant
+
+unfortunately the standard is overly strict about the
+definition of null pointer constants (current gcc does not
+follow the standard but clang does) so we have to use a hack
+to be able to tell integer and floating-point types apart:
+both gcc and clang evaluate sizeof(void) to 1 even though it
+is a constraint violation, we only use this on clang for now
+*/
+/* predicates that evaluate to integer constant expressions */
+#ifdef __clang__
+/* TODO: __c_IS_FP(1.0) is a constraint violation */
+#define __c_IS_FP(x) (!(sizeof*(__typeof__(0?(int*)0:(void*)__IS_FP(x)))0-1))
+#else
+#define __c_IS_FP(x) __IS_FP(x)
+#endif
+#define __c_IS_CX(x) (__c_IS_FP(x) && sizeof(x) == sizeof((x)+I))
+#define __c_FLTCX(x) (__c_IS_CX(x) && sizeof(x) == sizeof(float complex))
+#define __c_DBLCX(x) (__c_IS_CX(x) && sizeof(x) == sizeof(double complex))
+#define __c_LDBLCX(x) (__c_IS_CX(x) && sizeof(x) == sizeof(long double complex) && sizeof(long double) != sizeof(double))
+/* if c then t else void */
+#define __type1(c,t) __typeof__(*(0?(t*)0:(void*)!(c)))
+/* if c then t1 else t2 */
+#define __type2(c,t1,t2) __typeof__(*(0?(__type1(c,t1)*)0:(__type1(!(c),t2)*)0))