| 1 | /*	$OpenBSD: tgmath.h,v 1.1 2011/07/08 19:28:06 martynas Exp $	*/ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 2004 Stefan Farfeleder. |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 | * SUCH DAMAGE. |
| 27 | * |
| 28 | * $FreeBSD: src/include/tgmath.h,v 1.5 2007/02/02 18:30:23 schweikh Exp $ |
| 29 | */ |
| 30 | |
| 31 | #ifndef _TGMATH_H_ |
| 32 | #define	_TGMATH_H_ |
| 33 | |
| 34 | #include <complex.h> |
| 35 | #include <math.h> |
| 36 | |
| 37 | /* |
| 38 | * This implementation of <tgmath.h> requires two implementation-dependent |
| 39 | * macros to be defined: |
| 40 | * __tg_impl_simple(x, y, z, fn, fnf, fnl, ...) |
| 41 | *	Invokes fnl() if the corresponding real type of x, y or z is long |
| 42 | *	double, fn() if it is double or any has an integer type, and fnf() |
| 43 | *	otherwise. |
| 44 | * __tg_impl_full(x, y, z, fn, fnf, fnl, cfn, cfnf, cfnl, ...) |
| 45 | *	Invokes [c]fnl() if the corresponding real type of x, y or z is long |
| 46 | *	double, [c]fn() if it is double or any has an integer type, and |
| 47 | *	[c]fnf() otherwise. The function with the 'c' prefix is called if |
| 48 | *	any of x, y or z is a complex number. |
| 49 | * Both macros call the chosen function with all additional arguments passed |
| 50 | * to them, as given by __VA_ARGS__. |
| 51 | * |
| 52 | * Note that these macros cannot be implemented with C's ?: operator, |
| 53 | * because the return type of the whole expression would incorrectly be long |
| 54 | * double complex regardless of the argument types. |
| 55 | */ |
| 56 | |
| 57 | #if __GNUC_PREREQ__(3, 1) |
| 58 | #define	__tg_type(e, t)	__builtin_types_compatible_p(__typeof__(e), t) |
| 59 | #define	__tg_type3(e1, e2, e3, t)					\ |
| 60 | 	(__tg_type(e1, t) || __tg_type(e2, t) || __tg_type(e3, t)) |
| 61 | #define	__tg_type_corr(e1, e2, e3, t)					\ |
| 62 | 	(__tg_type3(e1, e2, e3, t) || __tg_type3(e1, e2, e3, t _Complex)) |
| 63 | #define	__tg_integer(e1, e2, e3)					\ |
| 64 | 	(((__typeof__(e1))1.5 == 1) || ((__typeof__(e2))1.5 == 1) ||	\ |
| 65 | 	 ((__typeof__(e3))1.5 == 1)) |
| 66 | #define	__tg_is_complex(e1, e2, e3)					\ |
| 67 | 	(__tg_type3(e1, e2, e3, float _Complex) ||			\ |
| 68 | 	 __tg_type3(e1, e2, e3, double _Complex) ||			\ |
| 69 | 	 __tg_type3(e1, e2, e3, long double _Complex) ||		\ |
| 70 | 	 __tg_type3(e1, e2, e3, __typeof__(_Complex_I))) |
| 71 | |
| 72 | #define	__tg_impl_simple(x, y, z, fn, fnf, fnl, ...)			\ |
| 73 | 	__builtin_choose_expr(__tg_type_corr(x, y, z, long double),	\ |
| 74 | 	 fnl(__VA_ARGS__), __builtin_choose_expr(			\ |
| 75 | 		__tg_type_corr(x, y, z, double) || __tg_integer(x, y, z),\ |
| 76 | 		fn(__VA_ARGS__), fnf(__VA_ARGS__))) |
| 77 | |
| 78 | #define	__tg_impl_full(x, y, z, fn, fnf, fnl, cfn, cfnf, cfnl, ...)	\ |
| 79 | 	__builtin_choose_expr(__tg_is_complex(x, y, z),			\ |
| 80 | 	 __tg_impl_simple(x, y, z, cfn, cfnf, cfnl, __VA_ARGS__),	\ |
| 81 | 	 __tg_impl_simple(x, y, z, fn, fnf, fnl, __VA_ARGS__)) |
| 82 | |
| 83 | #else	/* __GNUC__ */ |
| 84 | #error "<tgmath.h> not implemented for this compiler" |
| 85 | #endif	/* !__GNUC__ */ |
| 86 | |
| 87 | /* Macros to save lots of repetition below */ |
| 88 | #define	__tg_simple(x, fn)						\ |
| 89 | 	__tg_impl_simple(x, x, x, fn, fn##f, fn##l, x) |
| 90 | #define	__tg_simple2(x, y, fn)						\ |
| 91 | 	__tg_impl_simple(x, x, y, fn, fn##f, fn##l, x, y) |
| 92 | #define	__tg_simplev(x, fn, ...)					\ |
| 93 | 	__tg_impl_simple(x, x, x, fn, fn##f, fn##l, __VA_ARGS__) |
| 94 | #define	__tg_full(x, fn)						\ |
| 95 | 	__tg_impl_full(x, x, x, fn, fn##f, fn##l, c##fn, c##fn##f, c##fn##l, x) |
| 96 | |
| 97 | /* 7.22#4 -- These macros expand to real or complex functions, depending on |
| 98 | * the type of their arguments. */ |
| 99 | #define	acos(x)		__tg_full(x, acos) |
| 100 | #define	asin(x)		__tg_full(x, asin) |
| 101 | #define	atan(x)		__tg_full(x, atan) |
| 102 | #define	acosh(x)	__tg_full(x, acosh) |
| 103 | #define	asinh(x)	__tg_full(x, asinh) |
| 104 | #define	atanh(x)	__tg_full(x, atanh) |
| 105 | #define	cos(x)		__tg_full(x, cos) |
| 106 | #define	sin(x)		__tg_full(x, sin) |
| 107 | #define	tan(x)		__tg_full(x, tan) |
| 108 | #define	cosh(x)		__tg_full(x, cosh) |
| 109 | #define	sinh(x)		__tg_full(x, sinh) |
| 110 | #define	tanh(x)		__tg_full(x, tanh) |
| 111 | #define	exp(x)		__tg_full(x, exp) |
| 112 | #define	log(x)		__tg_full(x, log) |
| 113 | #define	pow(x, y)	__tg_impl_full(x, x, y, pow, powf, powl,	\ |
| 114 | 			 cpow, cpowf, cpowl, x, y) |
| 115 | #define	sqrt(x)		__tg_full(x, sqrt) |
| 116 | |
| 117 | /* "The corresponding type-generic macro for fabs and cabs is fabs." */ |
| 118 | #define	fabs(x)		__tg_impl_full(x, x, x, fabs, fabsf, fabsl,	\ |
| 119 | 			 cabs, cabsf, cabsl, x) |
| 120 | |
| 121 | /* 7.22#5 -- These macros are only defined for arguments with real type. */ |
| 122 | #define	atan2(x, y)	__tg_simple2(x, y, atan2) |
| 123 | #define	cbrt(x)		__tg_simple(x, cbrt) |
| 124 | #define	ceil(x)		__tg_simple(x, ceil) |
| 125 | #define	copysign(x, y)	__tg_simple2(x, y, copysign) |
| 126 | #define	erf(x)		__tg_simple(x, erf) |
| 127 | #define	erfc(x)		__tg_simple(x, erfc) |
| 128 | #define	exp2(x)		__tg_simple(x, exp2) |
| 129 | #define	expm1(x)	__tg_simple(x, expm1) |
| 130 | #define	fdim(x, y)	__tg_simple2(x, y, fdim) |
| 131 | #define	floor(x)	__tg_simple(x, floor) |
| 132 | #define	fma(x, y, z)	__tg_impl_simple(x, y, z, fma, fmaf, fmal, x, y, z) |
| 133 | #define	fmax(x, y)	__tg_simple2(x, y, fmax) |
| 134 | #define	fmin(x, y)	__tg_simple2(x, y, fmin) |
| 135 | #define	fmod(x, y)	__tg_simple2(x, y, fmod) |
| 136 | #define	frexp(x, y)	__tg_simplev(x, frexp, x, y) |
| 137 | #define	hypot(x, y)	__tg_simple2(x, y, hypot) |
| 138 | #define	ilogb(x)	__tg_simple(x, ilogb) |
| 139 | #define	ldexp(x, y)	__tg_simplev(x, ldexp, x, y) |
| 140 | #define	lgamma(x)	__tg_simple(x, lgamma) |
| 141 | #define	llrint(x)	__tg_simple(x, llrint) |
| 142 | #define	llround(x)	__tg_simple(x, llround) |
| 143 | #define	log10(x)	__tg_simple(x, log10) |
| 144 | #define	log1p(x)	__tg_simple(x, log1p) |
| 145 | #define	log2(x)		__tg_simple(x, log2) |
| 146 | #define	logb(x)		__tg_simple(x, logb) |
| 147 | #define	lrint(x)	__tg_simple(x, lrint) |
| 148 | #define	lround(x)	__tg_simple(x, lround) |
| 149 | #define	nearbyint(x)	__tg_simple(x, nearbyint) |
| 150 | #define	nextafter(x, y)	__tg_simple2(x, y, nextafter) |
| 151 | #define	nexttoward(x, y) __tg_simplev(x, nexttoward, x, y) |
| 152 | #define	remainder(x, y)	__tg_simple2(x, y, remainder) |
| 153 | #define	remquo(x, y, z)	__tg_impl_simple(x, x, y, remquo, remquof,	\ |
| 154 | 			 remquol, x, y, z) |
| 155 | #define	rint(x)		__tg_simple(x, rint) |
| 156 | #define	round(x)	__tg_simple(x, round) |
| 157 | #define	scalbn(x, y)	__tg_simplev(x, scalbn, x, y) |
| 158 | #define	scalbln(x, y)	__tg_simplev(x, scalbln, x, y) |
| 159 | #define	tgamma(x)	__tg_simple(x, tgamma) |
| 160 | #define	trunc(x)	__tg_simple(x, trunc) |
| 161 | |
| 162 | /* 7.22#6 -- These macros always expand to complex functions. */ |
| 163 | #define	carg(x)		__tg_simple(x, carg) |
| 164 | #define	cimag(x)	__tg_simple(x, cimag) |
| 165 | #define	conj(x)		__tg_simple(x, conj) |
| 166 | #define	cproj(x)	__tg_simple(x, cproj) |
| 167 | #define	creal(x)	__tg_simple(x, creal) |
| 168 | |
| 169 | #endif /* !_TGMATH_H_ */ |