xref: /dflybsd-src/contrib/openbsd_libm/include/global/tgmath.h (revision de03118d092c3b87f593a7c5ebd54ff2818d218c)
105a0b428SJohn Marino /*-
205a0b428SJohn Marino  * Copyright (c) 2004 Stefan Farfeleder.
305a0b428SJohn Marino  * All rights reserved.
405a0b428SJohn Marino  *
5*de03118dSSascha Wildner  * Copyright (c) 2012 Ed Schouten <ed@FreeBSD.org>
6*de03118dSSascha Wildner  * All rights reserved.
7*de03118dSSascha Wildner  *
805a0b428SJohn Marino  * Redistribution and use in source and binary forms, with or without
905a0b428SJohn Marino  * modification, are permitted provided that the following conditions
1005a0b428SJohn Marino  * are met:
1105a0b428SJohn Marino  * 1. Redistributions of source code must retain the above copyright
1205a0b428SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1305a0b428SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1405a0b428SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1505a0b428SJohn Marino  *    documentation and/or other materials provided with the distribution.
1605a0b428SJohn Marino  *
1705a0b428SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1805a0b428SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1905a0b428SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2005a0b428SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2105a0b428SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2205a0b428SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2305a0b428SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2405a0b428SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2505a0b428SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2605a0b428SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2705a0b428SJohn Marino  * SUCH DAMAGE.
2805a0b428SJohn Marino  *
29*de03118dSSascha Wildner  * $FreeBSD: head/include/tgmath.h 271155 2014-09-05 05:36:32Z ed $
3005a0b428SJohn Marino  */
3105a0b428SJohn Marino 
3205a0b428SJohn Marino #ifndef _TGMATH_H_
3305a0b428SJohn Marino #define	_TGMATH_H_
3405a0b428SJohn Marino 
3505a0b428SJohn Marino #include <complex.h>
3605a0b428SJohn Marino #include <math.h>
3705a0b428SJohn Marino 
3805a0b428SJohn Marino /*
39*de03118dSSascha Wildner  * This implementation of <tgmath.h> uses the two following macros,
40*de03118dSSascha Wildner  * which are based on the macros described in C11 proposal N1404:
41*de03118dSSascha Wildner  * __tg_impl_simple(x, y, z, fnl, fn, fnf, ...)
4205a0b428SJohn Marino  *	Invokes fnl() if the corresponding real type of x, y or z is long
4305a0b428SJohn Marino  *	double, fn() if it is double or any has an integer type, and fnf()
4405a0b428SJohn Marino  *	otherwise.
45*de03118dSSascha Wildner  * __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...)
46*de03118dSSascha Wildner  *	Invokes [c]fnl() if the corresponding real type of x or y is long
4705a0b428SJohn Marino  *	double, [c]fn() if it is double or any has an integer type, and
4805a0b428SJohn Marino  *	[c]fnf() otherwise.  The function with the 'c' prefix is called if
49*de03118dSSascha Wildner  *	any of x or y is a complex number.
5005a0b428SJohn Marino  * Both macros call the chosen function with all additional arguments passed
5105a0b428SJohn Marino  * to them, as given by __VA_ARGS__.
5205a0b428SJohn Marino  *
5305a0b428SJohn Marino  * Note that these macros cannot be implemented with C's ?: operator,
5405a0b428SJohn Marino  * because the return type of the whole expression would incorrectly be long
5505a0b428SJohn Marino  * double complex regardless of the argument types.
56*de03118dSSascha Wildner  *
57*de03118dSSascha Wildner  * The structure of the C11 implementation of these macros can in
58*de03118dSSascha Wildner  * principle be reused for non-C11 compilers, but due to an integer
59*de03118dSSascha Wildner  * promotion bug for complex types in GCC 4.2, simply let non-C11
60*de03118dSSascha Wildner  * compilers use an inefficient yet reliable version.
6105a0b428SJohn Marino  */
6205a0b428SJohn Marino 
63*de03118dSSascha Wildner #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
64*de03118dSSascha Wildner     __has_extension(c_generic_selections)
65*de03118dSSascha Wildner #define	__tg_generic(x, cfnl, cfn, cfnf, fnl, fn, fnf)			\
66*de03118dSSascha Wildner 	_Generic(x,							\
67*de03118dSSascha Wildner 		long double _Complex: cfnl,				\
68*de03118dSSascha Wildner 		double _Complex: cfn,					\
69*de03118dSSascha Wildner 		float _Complex: cfnf,					\
70*de03118dSSascha Wildner 		long double: fnl,					\
71*de03118dSSascha Wildner 		default: fn,						\
72*de03118dSSascha Wildner 		float: fnf						\
73*de03118dSSascha Wildner 	)
74*de03118dSSascha Wildner #define	__tg_type(x)							\
75*de03118dSSascha Wildner 	__tg_generic(x, (long double _Complex)0, (double _Complex)0,	\
76*de03118dSSascha Wildner 	    (float _Complex)0, (long double)0, (double)0, (float)0)
77*de03118dSSascha Wildner #define	__tg_impl_simple(x, y, z, fnl, fn, fnf, ...)			\
78*de03118dSSascha Wildner 	__tg_generic(							\
79*de03118dSSascha Wildner 	    __tg_type(x) + __tg_type(y) + __tg_type(z),			\
80*de03118dSSascha Wildner 	    fnl, fn, fnf, fnl, fn, fnf)(__VA_ARGS__)
81*de03118dSSascha Wildner #define	__tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...)	\
82*de03118dSSascha Wildner 	__tg_generic(							\
83*de03118dSSascha Wildner 	    __tg_type(x) + __tg_type(y),				\
84*de03118dSSascha Wildner 	    cfnl, cfn, cfnf, fnl, fn, fnf)(__VA_ARGS__)
85*de03118dSSascha Wildner #elif defined(__generic)
86*de03118dSSascha Wildner #define	__tg_generic_simple(x, fnl, fn, fnf)				\
87*de03118dSSascha Wildner 	__generic(x, long double _Complex, fnl,				\
88*de03118dSSascha Wildner 	    __generic(x, double _Complex, fn,				\
89*de03118dSSascha Wildner 	        __generic(x, float _Complex, fnf,			\
90*de03118dSSascha Wildner 	            __generic(x, long double, fnl,			\
91*de03118dSSascha Wildner 	                __generic(x, float, fnf, fn)))))
92*de03118dSSascha Wildner #define	__tg_impl_simple(x, y, z, fnl, fn, fnf, ...)			\
93*de03118dSSascha Wildner 	__tg_generic_simple(x,						\
94*de03118dSSascha Wildner 	    __tg_generic_simple(y,					\
95*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fnl, fnl),			\
96*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fnl, fnl),			\
97*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fnl, fnl)),			\
98*de03118dSSascha Wildner 	    __tg_generic_simple(y,					\
99*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fnl, fnl),			\
100*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fn , fn ),			\
101*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fn , fn )),			\
102*de03118dSSascha Wildner 	    __tg_generic_simple(y,					\
103*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fnl, fnl),			\
104*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fn , fn ),			\
105*de03118dSSascha Wildner 	        __tg_generic_simple(z, fnl, fn , fnf)))(__VA_ARGS__)
106*de03118dSSascha Wildner #define	__tg_generic_full(x, cfnl, cfn, cfnf, fnl, fn, fnf)		\
107*de03118dSSascha Wildner 	__generic(x, long double _Complex, cfnl,			\
108*de03118dSSascha Wildner 	    __generic(x, double _Complex, cfn,				\
109*de03118dSSascha Wildner 	        __generic(x, float _Complex, cfnf,			\
110*de03118dSSascha Wildner 	            __generic(x, long double, fnl,			\
111*de03118dSSascha Wildner 	                __generic(x, float, fnf, fn)))))
112*de03118dSSascha Wildner #define	__tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...)	\
113*de03118dSSascha Wildner 	__tg_generic_full(x,						\
114*de03118dSSascha Wildner 	    __tg_generic_full(y, cfnl, cfnl, cfnl, cfnl, cfnl, cfnl),	\
115*de03118dSSascha Wildner 	    __tg_generic_full(y, cfnl, cfn , cfn , cfnl, cfn , cfn ),	\
116*de03118dSSascha Wildner 	    __tg_generic_full(y, cfnl, cfn , cfnf, cfnl, cfn , cfnf),	\
117*de03118dSSascha Wildner 	    __tg_generic_full(y, cfnl, cfnl, cfnl, fnl , fnl , fnl ),	\
118*de03118dSSascha Wildner 	    __tg_generic_full(y, cfnl, cfn , cfn , fnl , fn  , fn  ),	\
119*de03118dSSascha Wildner 	    __tg_generic_full(y, cfnl, cfn , cfnf, fnl , fn  , fnf ))	\
120*de03118dSSascha Wildner 	    (__VA_ARGS__)
121*de03118dSSascha Wildner #else
12205a0b428SJohn Marino #error "<tgmath.h> not implemented for this compiler"
123*de03118dSSascha Wildner #endif
12405a0b428SJohn Marino 
12505a0b428SJohn Marino /* Macros to save lots of repetition below */
12605a0b428SJohn Marino #define	__tg_simple(x, fn)						\
127*de03118dSSascha Wildner 	__tg_impl_simple(x, x, x, fn##l, fn, fn##f, x)
12805a0b428SJohn Marino #define	__tg_simple2(x, y, fn)						\
129*de03118dSSascha Wildner 	__tg_impl_simple(x, x, y, fn##l, fn, fn##f, x, y)
130*de03118dSSascha Wildner #define	__tg_simple3(x, y, z, fn)					\
131*de03118dSSascha Wildner 	__tg_impl_simple(x, y, z, fn##l, fn, fn##f, x, y, z)
13205a0b428SJohn Marino #define	__tg_simplev(x, fn, ...)					\
133*de03118dSSascha Wildner 	__tg_impl_simple(x, x, x, fn##l, fn, fn##f, __VA_ARGS__)
13405a0b428SJohn Marino #define	__tg_full(x, fn)						\
135*de03118dSSascha Wildner 	__tg_impl_full(x, x, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x)
136*de03118dSSascha Wildner #define	__tg_full2(x, y, fn)						\
137*de03118dSSascha Wildner 	__tg_impl_full(x, y, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x, y)
13805a0b428SJohn Marino 
13905a0b428SJohn Marino /* 7.22#4 -- These macros expand to real or complex functions, depending on
14005a0b428SJohn Marino  * the type of their arguments. */
14105a0b428SJohn Marino #define	acos(x)		__tg_full(x, acos)
14205a0b428SJohn Marino #define	asin(x)		__tg_full(x, asin)
14305a0b428SJohn Marino #define	atan(x)		__tg_full(x, atan)
14405a0b428SJohn Marino #define	acosh(x)	__tg_full(x, acosh)
14505a0b428SJohn Marino #define	asinh(x)	__tg_full(x, asinh)
14605a0b428SJohn Marino #define	atanh(x)	__tg_full(x, atanh)
14705a0b428SJohn Marino #define	cos(x)		__tg_full(x, cos)
14805a0b428SJohn Marino #define	sin(x)		__tg_full(x, sin)
14905a0b428SJohn Marino #define	tan(x)		__tg_full(x, tan)
15005a0b428SJohn Marino #define	cosh(x)		__tg_full(x, cosh)
15105a0b428SJohn Marino #define	sinh(x)		__tg_full(x, sinh)
15205a0b428SJohn Marino #define	tanh(x)		__tg_full(x, tanh)
15305a0b428SJohn Marino #define	exp(x)		__tg_full(x, exp)
15405a0b428SJohn Marino #define	log(x)		__tg_full(x, log)
155*de03118dSSascha Wildner #define	pow(x, y)	__tg_full2(x, y, pow)
15605a0b428SJohn Marino #define	sqrt(x)		__tg_full(x, sqrt)
15705a0b428SJohn Marino 
15805a0b428SJohn Marino /* "The corresponding type-generic macro for fabs and cabs is fabs." */
159*de03118dSSascha Wildner #define	fabs(x)		__tg_impl_full(x, x, cabsl, cabs, cabsf,	\
160*de03118dSSascha Wildner     			    fabsl, fabs, fabsf, x)
16105a0b428SJohn Marino 
16205a0b428SJohn Marino /* 7.22#5 -- These macros are only defined for arguments with real type. */
16305a0b428SJohn Marino #define	atan2(x, y)	__tg_simple2(x, y, atan2)
16405a0b428SJohn Marino #define	cbrt(x)		__tg_simple(x, cbrt)
16505a0b428SJohn Marino #define	ceil(x)		__tg_simple(x, ceil)
16605a0b428SJohn Marino #define	copysign(x, y)	__tg_simple2(x, y, copysign)
16705a0b428SJohn Marino #define	erf(x)		__tg_simple(x, erf)
16805a0b428SJohn Marino #define	erfc(x)		__tg_simple(x, erfc)
16905a0b428SJohn Marino #define	exp2(x)		__tg_simple(x, exp2)
17005a0b428SJohn Marino #define	expm1(x)	__tg_simple(x, expm1)
17105a0b428SJohn Marino #define	fdim(x, y)	__tg_simple2(x, y, fdim)
17205a0b428SJohn Marino #define	floor(x)	__tg_simple(x, floor)
173*de03118dSSascha Wildner #define	fma(x, y, z)	__tg_simple3(x, y, z, fma)
17405a0b428SJohn Marino #define	fmax(x, y)	__tg_simple2(x, y, fmax)
17505a0b428SJohn Marino #define	fmin(x, y)	__tg_simple2(x, y, fmin)
17605a0b428SJohn Marino #define	fmod(x, y)	__tg_simple2(x, y, fmod)
17705a0b428SJohn Marino #define	frexp(x, y)	__tg_simplev(x, frexp, x, y)
17805a0b428SJohn Marino #define	hypot(x, y)	__tg_simple2(x, y, hypot)
17905a0b428SJohn Marino #define	ilogb(x)	__tg_simple(x, ilogb)
18005a0b428SJohn Marino #define	ldexp(x, y)	__tg_simplev(x, ldexp, x, y)
18105a0b428SJohn Marino #define	lgamma(x)	__tg_simple(x, lgamma)
18205a0b428SJohn Marino #define	llrint(x)	__tg_simple(x, llrint)
18305a0b428SJohn Marino #define	llround(x)	__tg_simple(x, llround)
18405a0b428SJohn Marino #define	log10(x)	__tg_simple(x, log10)
18505a0b428SJohn Marino #define	log1p(x)	__tg_simple(x, log1p)
18605a0b428SJohn Marino #define	log2(x)		__tg_simple(x, log2)
18705a0b428SJohn Marino #define	logb(x)		__tg_simple(x, logb)
18805a0b428SJohn Marino #define	lrint(x)	__tg_simple(x, lrint)
18905a0b428SJohn Marino #define	lround(x)	__tg_simple(x, lround)
19005a0b428SJohn Marino #define	nearbyint(x)	__tg_simple(x, nearbyint)
19105a0b428SJohn Marino #define	nextafter(x, y)	__tg_simple2(x, y, nextafter)
19205a0b428SJohn Marino #define	nexttoward(x, y) __tg_simplev(x, nexttoward, x, y)
19305a0b428SJohn Marino #define	remainder(x, y)	__tg_simple2(x, y, remainder)
194*de03118dSSascha Wildner #define	remquo(x, y, z)	__tg_impl_simple(x, x, y, remquol, remquo,	\
195*de03118dSSascha Wildner 			    remquof, x, y, z)
19605a0b428SJohn Marino #define	rint(x)		__tg_simple(x, rint)
19705a0b428SJohn Marino #define	round(x)	__tg_simple(x, round)
19805a0b428SJohn Marino #define	scalbn(x, y)	__tg_simplev(x, scalbn, x, y)
19905a0b428SJohn Marino #define	scalbln(x, y)	__tg_simplev(x, scalbln, x, y)
20005a0b428SJohn Marino #define	tgamma(x)	__tg_simple(x, tgamma)
20105a0b428SJohn Marino #define	trunc(x)	__tg_simple(x, trunc)
20205a0b428SJohn Marino 
20305a0b428SJohn Marino /* 7.22#6 -- These macros always expand to complex functions. */
20405a0b428SJohn Marino #define	carg(x)		__tg_simple(x, carg)
20505a0b428SJohn Marino #define	cimag(x)	__tg_simple(x, cimag)
20605a0b428SJohn Marino #define	conj(x)		__tg_simple(x, conj)
20705a0b428SJohn Marino #define	cproj(x)	__tg_simple(x, cproj)
20805a0b428SJohn Marino #define	creal(x)	__tg_simple(x, creal)
20905a0b428SJohn Marino 
21005a0b428SJohn Marino #endif /* !_TGMATH_H_ */
211