5 the return types are only correct with gcc (__GNUC__)
6 otherwise they are long double or long double complex
8 the long double version of a function is never chosen when
9 sizeof(double) == sizeof(long double)
10 (but the return type is set correctly with gcc)
16 #define __IS_FP(x) !!((1?1:(x))/2)
17 #define __IS_CX(x) (__IS_FP(x) && sizeof(x) == sizeof((x)+I))
18 #define __IS_REAL(x) (__IS_FP(x) && 2*sizeof(x) == sizeof((x)+I))
20 #define __FLT(x) (__IS_REAL(x) && sizeof(x) == sizeof(float))
21 #define __LDBL(x) (__IS_REAL(x) && sizeof(x) == sizeof(long double) && sizeof(long double) != sizeof(double))
23 #define __FLTCX(x) (__IS_CX(x) && sizeof(x) == sizeof(float complex))
24 #define __DBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(double complex))
25 #define __LDBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(long double complex) && sizeof(long double) != sizeof(double))
31 the conditional expression (that selects the right function
32 for evaluation) should be casted to the return type of the
33 selected function (otherwise the result type is determined
34 by the conversion rules applied to all the function return
35 types so it is long double or long double _Complex)
37 this cannot be done in c99 (c11 has _Generic that would help
38 but is not yet widely supported), so the typeof extension of
39 gcc is used and that ?: has special semantics when one of
40 the operands is a null pointer constant
42 unfortunately the standard is overly strict about the
43 definition of null pointer constants (current gcc does not
44 follow the standard but clang does) so we have to use a hack
45 to be able to tell integer and floating-point types apart:
46 both gcc and clang evaluate sizeof(void) to 1 even though it
47 is a constraint violation, we only use this on clang for now
49 /* predicates that evaluate to integer constant expressions */
51 /* TODO: __c_IS_FP(1.0) is a constraint violation */
52 #define __c_IS_FP(x) (!(sizeof*(__typeof__(0?(int*)0:(void*)__IS_FP(x)))0-1))
54 #define __c_IS_FP(x) __IS_FP(x)
56 #define __c_IS_CX(x) (__c_IS_FP(x) && sizeof(x) == sizeof((x)+I))
57 #define __c_FLTCX(x) (__c_IS_CX(x) && sizeof(x) == sizeof(float complex))
58 #define __c_DBLCX(x) (__c_IS_CX(x) && sizeof(x) == sizeof(double complex))
59 #define __c_LDBLCX(x) (__c_IS_CX(x) && sizeof(x) == sizeof(long double complex) && sizeof(long double) != sizeof(double))
60 /* if c then t else void */
61 #define __type1(c,t) __typeof__(*(0?(t*)0:(void*)!(c)))
62 /* if c then t1 else t2 */
63 #define __type2(c,t1,t2) __typeof__(*(0?(__type1(c,t1)*)0:(__type1(!(c),t2)*)0))
64 /* cast to double when x is integral, otherwise use typeof(x) */
65 #define __RETCAST(x) ( \
66 __type2(__c_IS_FP(x), __typeof__(x), double))
67 /* 2 args case, should work for complex types (cpow) */
68 #define __RETCAST_2(x, y) ( \
69 __type2(__c_IS_FP(x) && __c_IS_FP(y), \
70 __typeof__((x)+(y)), \
71 __typeof__((x)+(y)+1.0)))
72 /* 3 args case (fma only) */
73 #define __RETCAST_3(x, y, z) ( \
74 __type2(__c_IS_FP(x) && __c_IS_FP(y) && __c_IS_FP(z), \
75 __typeof__((x)+(y)+(z)), \
76 __typeof__((x)+(y)+(z)+1.0)))
77 /* drop complex from the type of x */
78 /* TODO: wrong when sizeof(long double)==sizeof(double) */
79 #define __RETCAST_REAL(x) ( \
80 __type2(sizeof(__RETCAST(x)0+I)==sizeof(float complex), float, \
81 __type2(sizeof(__RETCAST(x)0+I)==sizeof(double complex), double, \
83 /* add complex to the type of x */
84 #define __RETCAST_CX(x) (__typeof__(__RETCAST(x)0+I))
87 #define __RETCAST_2(x, y)
88 #define __RETCAST_3(x, y, z)
89 #define __RETCAST_REAL(x)
90 #define __RETCAST_CX(x)
93 /* function selection */
95 #define __tg_real_nocast(fun, x) ( \
96 __FLT(x) ? fun ## f (x) : \
97 __LDBL(x) ? fun ## l (x) : \
100 #define __tg_real(fun, x) (__RETCAST(x)__tg_real_nocast(fun, x))
102 #define __tg_real_2_1(fun, x, y) (__RETCAST(x)( \
103 __FLT(x) ? fun ## f (x, y) : \
104 __LDBL(x) ? fun ## l (x, y) : \
107 #define __tg_real_2(fun, x, y) (__RETCAST_2(x, y)( \
108 __FLT(x) && __FLT(y) ? fun ## f (x, y) : \
109 __LDBL((x)+(y)) ? fun ## l (x, y) : \
112 #define __tg_complex(fun, x) (__RETCAST_CX(x)( \
113 __FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
114 __LDBLCX((x)+I) ? fun ## l (x) : \
117 #define __tg_complex_retreal(fun, x) (__RETCAST_REAL(x)( \
118 __FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
119 __LDBLCX((x)+I) ? fun ## l (x) : \
122 #define __tg_real_complex(fun, x) (__RETCAST(x)( \
123 __FLTCX(x) ? c ## fun ## f (x) : \
124 __DBLCX(x) ? c ## fun (x) : \
125 __LDBLCX(x) ? c ## fun ## l (x) : \
126 __FLT(x) ? fun ## f (x) : \
127 __LDBL(x) ? fun ## l (x) : \
132 #define __tg_real_remquo(x, y, z) (__RETCAST_2(x, y)( \
133 __FLT(x) && __FLT(y) ? remquof(x, y, z) : \
134 __LDBL((x)+(y)) ? remquol(x, y, z) : \
137 #define __tg_real_fma(x, y, z) (__RETCAST_3(x, y, z)( \
138 __FLT(x) && __FLT(y) && __FLT(z) ? fmaf(x, y, z) : \
139 __LDBL((x)+(y)+(z)) ? fmal(x, y, z) : \
142 #define __tg_real_complex_pow(x, y) (__RETCAST_2(x, y)( \
143 __FLTCX((x)+(y)) && __IS_FP(x) && __IS_FP(y) ? cpowf(x, y) : \
144 __FLTCX((x)+(y)) ? cpow(x, y) : \
145 __DBLCX((x)+(y)) ? cpow(x, y) : \
146 __LDBLCX((x)+(y)) ? cpowl(x, y) : \
147 __FLT(x) && __FLT(y) ? powf(x, y) : \
148 __LDBL((x)+(y)) ? powl(x, y) : \
151 #define __tg_real_complex_fabs(x) (__RETCAST_REAL(x)( \
152 __FLTCX(x) ? cabsf(x) : \
153 __DBLCX(x) ? cabs(x) : \
154 __LDBLCX(x) ? cabsl(x) : \
155 __FLT(x) ? fabsf(x) : \
156 __LDBL(x) ? fabsl(x) : \
159 /* suppress any macros in math.h or complex.h */
224 #define acos(x) __tg_real_complex(acos, (x))
225 #define acosh(x) __tg_real_complex(acosh, (x))
226 #define asin(x) __tg_real_complex(asin, (x))
227 #define asinh(x) __tg_real_complex(asinh, (x))
228 #define atan(x) __tg_real_complex(atan, (x))
229 #define atan2(x,y) __tg_real_2(atan2, (x), (y))
230 #define atanh(x) __tg_real_complex(atanh, (x))
231 #define carg(x) __tg_complex_retreal(carg, (x))
232 #define cbrt(x) __tg_real(cbrt, (x))
233 #define ceil(x) __tg_real(ceil, (x))
234 #define cimag(x) __tg_complex_retreal(cimag, (x))
235 #define conj(x) __tg_complex(conj, (x))
236 #define copysign(x,y) __tg_real_2(copysign, (x), (y))
237 #define cos(x) __tg_real_complex(cos, (x))
238 #define cosh(x) __tg_real_complex(cosh, (x))
239 #define cproj(x) __tg_complex(cproj, (x))
240 #define creal(x) __tg_complex_retreal(creal, (x))
241 #define erf(x) __tg_real(erf, (x))
242 #define erfc(x) __tg_real(erfc, (x))
243 #define exp(x) __tg_real_complex(exp, (x))
244 #define exp2(x) __tg_real(exp2, (x))
245 #define expm1(x) __tg_real(expm1, (x))
246 #define fabs(x) __tg_real_complex_fabs(x)
247 #define fdim(x,y) __tg_real_2(fdim, (x), (y))
248 #define floor(x) __tg_real(floor, (x))
249 #define fma(x,y,z) __tg_real_fma((x), (y), (z))
250 #define fmax(x,y) __tg_real_2(fmax, (x), (y))
251 #define fmin(x,y) __tg_real_2(fmin, (x), (y))
252 #define fmod(x,y) __tg_real_2(fmod, (x), (y))
253 #define frexp(x,y) __tg_real_2_1(frexp, (x), (y))
254 #define hypot(x,y) __tg_real_2(hypot, (x), (y))
255 #define ilogb(x) __tg_real_nocast(ilogb, (x))
256 #define ldexp(x,y) __tg_real_2_1(ldexp, (x), (y))
257 #define lgamma(x) __tg_real(lgamma, (x))
258 #define llrint(x) __tg_real_nocast(llrint, (x))
259 #define llround(x) __tg_real_nocast(llround, (x))
260 #define log(x) __tg_real_complex(log, (x))
261 #define log10(x) __tg_real(log10, (x))
262 #define log1p(x) __tg_real(log1p, (x))
263 #define log2(x) __tg_real(log2, (x))
264 #define logb(x) __tg_real(logb, (x))
265 #define lrint(x) __tg_real_nocast(lrint, (x))
266 #define lround(x) __tg_real_nocast(lround, (x))
267 #define nearbyint(x) __tg_real(nearbyint, (x))
268 #define nextafter(x,y) __tg_real_2(nextafter, (x), (y))
269 #define nexttoward(x,y) __tg_real_2(nexttoward, (x), (y))
270 #define pow(x,y) __tg_real_complex_pow((x), (y))
271 #define remainder(x,y) __tg_real_2(remainder, (x), (y))
272 #define remquo(x,y,z) __tg_real_remquo((x), (y), (z))
273 #define rint(x) __tg_real(rint, (x))
274 #define round(x) __tg_real(round, (x))
275 #define scalbln(x,y) __tg_real_2_1(scalbln, (x), (y))
276 #define scalbn(x,y) __tg_real_2_1(scalbn, (x), (y))
277 #define sin(x) __tg_real_complex(sin, (x))
278 #define sinh(x) __tg_real_complex(sinh, (x))
279 #define sqrt(x) __tg_real_complex(sqrt, (x))
280 #define tan(x) __tg_real_complex(tan, (x))
281 #define tanh(x) __tg_real_complex(tanh, (x))
282 #define tgamma(x) __tg_real(tgamma, (x))
283 #define trunc(x) __tg_real(trunc, (x))