25ad0071d4e8cfe592e7891f02a7f77f7a8152e4
[musl] / include / tgmath.h
1 #ifndef _TGMATH_H
2 #define _TGMATH_H
3
4 /*
5 the return types are only correct with gcc (__GNUC__)
6 otherwise they are long double or long double complex
7
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)
11 */
12
13 #include <math.h>
14 #include <complex.h>
15
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))
19
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))
22
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))
26
27 /* return type */
28
29 #ifdef __GNUC__
30 /*
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)
36
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
41
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
48 */
49 /* predicates that evaluate to integer constant expressions */
50 #ifdef __clang__
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))
53 #else
54 #define __c_IS_FP(x) __IS_FP(x)
55 #endif
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, \
82                 long double)))
83 /* add complex to the type of x */
84 #define __RETCAST_CX(x) (__typeof__(__RETCAST(x)0+I))
85 #else
86 #define __RETCAST(x)
87 #define __RETCAST_2(x, y)
88 #define __RETCAST_3(x, y, z)
89 #define __RETCAST_REAL(x)
90 #define __RETCAST_CX(x)
91 #endif
92
93 /* function selection */
94
95 #define __tg_real_nocast(fun, x) ( \
96         __FLT(x) ? fun ## f (x) : \
97         __LDBL(x) ? fun ## l (x) : \
98         fun(x) )
99
100 #define __tg_real(fun, x) (__RETCAST(x)__tg_real_nocast(fun, x))
101
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) : \
105         fun(x, y) ))
106
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) : \
110         fun(x, y) ))
111
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) : \
115         fun(x) ))
116
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) : \
120         fun(x) ))
121
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) : \
128         fun(x) ))
129
130 /* special cases */
131
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) : \
135         remquo(x, y, z) ))
136
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) : \
140         fma(x, y, z) ))
141
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) : \
149         pow(x, y) ))
150
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) : \
157         fabs(x) ))
158
159 /* suppress any macros in math.h or complex.h */
160
161 #undef acos
162 #undef acosh
163 #undef asin
164 #undef asinh
165 #undef atan
166 #undef atan2
167 #undef atanh
168 #undef carg
169 #undef cbrt
170 #undef ceil
171 #undef cimag
172 #undef conj
173 #undef copysign
174 #undef cos
175 #undef cosh
176 #undef cproj
177 #undef creal
178 #undef erf
179 #undef erfc
180 #undef exp
181 #undef exp2
182 #undef expm1
183 #undef fabs
184 #undef fdim
185 #undef floor
186 #undef fma
187 #undef fmax
188 #undef fmin
189 #undef fmod
190 #undef frexp
191 #undef hypot
192 #undef ilogb
193 #undef ldexp
194 #undef lgamma
195 #undef llrint
196 #undef llround
197 #undef log
198 #undef log10
199 #undef log1p
200 #undef log2
201 #undef logb
202 #undef lrint
203 #undef lround
204 #undef nearbyint
205 #undef nextafter
206 #undef nexttoward
207 #undef pow
208 #undef remainder
209 #undef remquo
210 #undef rint
211 #undef round
212 #undef scalbln
213 #undef scalbn
214 #undef sin
215 #undef sinh
216 #undef sqrt
217 #undef tan
218 #undef tanh
219 #undef tgamma
220 #undef trunc
221
222 /* tg functions */
223
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))
284
285 #endif