Date: Thu, 29 Apr 2004 22:33:05 +0200 From: Stefan Farfeleder <stefan@fafoe.narf.at> To: freebsd-standards@FreeBSD.org Subject: <tgmath.h> Message-ID: <20040429203303.GH691@wombat.fafoe.narf.at>
next in thread | raw e-mail | index | archive | help
--nmemrqcdn5VTmUEE Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, here's an implementation of the C99 header <tgmath.h>. The macros cimag, cimagf, creal and crealf are currently conflicting with the ones from <complex.h>. Cheers, Stefan --nmemrqcdn5VTmUEE Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="tgmath.h" /*- * Copyright (c) 2004 Stefan Farfeleder. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _TGMATH_H_ #define _TGMATH_H_ #include <complex.h> #include <math.h> extern double __tg_d; extern long double __tg_ld; extern complex float __tg_cf; extern complex double __tg_cd; extern complex long double __tg_cld; /* * We require three magic predicates to be available. * * - __tg_same_type(exp1, exp2) returns 1 if the expressions exp1 and exp2 * have the same type, 0 otherwise. Neither expression shall be evaluated. * - __tg_integer_type(exp) returns 1 if the expression exp has integer type, * 0 otherwise. exp shall not be evaluated. * - __tg_cond_expr(c, exp1, exp2) returns exp1 if c evaluates to * non-zero, exp2 otherwise. Note that exp1's and exp2's types must not * be converted (like ?: does). */ #ifdef __GNUC__ #define __tg_same_type(e1, e2) \ __builtin_types_compatible_p(__typeof__(e1), __typeof__(e2)) #define __tg_integer_type(e) ((__typeof__(e))1.5 == 1) #define __tg_cond_expr(c, e1, e2) __builtin_choose_expr(c, e1, e2) #else #error "need compiler support for __tg_same_type(), __tg_integer_type() and __tg_cond_expr()" #endif #define __tg_use_long(x) \ (__tg_same_type(x, __tg_ld) || __tg_same_type(x, __tg_cld)) #define __tg_use_long2(x, y) (__tg_use_long(x) || __tg_use_long(y)) #define __tg_use_double(x) \ (__tg_same_type(x, __tg_d) || __tg_same_type(x, __tg_cd) || \ __tg_integer_type(x)) #define __tg_use_double2(x, y) (__tg_use_double(x) || __tg_use_double(y)) #define __tg_use_complex(x) \ (__tg_same_type(x, __tg_cf) || __tg_same_type(x, __tg_cd) || \ __tg_same_type(x, __tg_cld)) #define __tg_fnv(x, fn, ...) \ __tg_cond_expr(__tg_use_long(x), fn##l(__VA_ARGS__), \ __tg_cond_expr(__tg_use_double(x), fn(__VA_ARGS__), \ fn##f(__VA_ARGS__))) #define __tg_fn(x, fn) __tg_fnv(x, fn, x) #define __tg_fn2v(x, y, fn, ...) \ __tg_cond_expr(__tg_use_long2(x, y), fn##l(__VA_ARGS__), \ __tg_cond_expr(__tg_use_double2(x, y), fn(__VA_ARGS__), \ fn##f(__VA_ARGS__))) #define __tg_fn2(x, y, fn) __tg_fn2v(x, y, fn, x, y) #define __tg_fn3(x, y, z, fn) \ __tg_cond_expr(__tg_use_long2(x, y) || __tg_use_long(z), \ fn##l(x, y, z), __tg_cond_expr(__tg_use_double2(x, y) || \ __tg_use_double(z), fn(x, y, z), fn##f(x, y, z))) #define __tg_fn_both(x, fn) \ __tg_cond_expr(__tg_use_complex(x), __tg_fn(x, c##fn), __tg_fn(x, fn)) #define __tg_fn_both2(x, y, fn) \ __tg_cond_expr(__tg_use_complex(x) || __tg_use_complex(y), \ __tg_fn2(x, y, c##fn), __tg_fn2(x, y, fn)) /* 7.22#4 */ #define acos(x) __tg_fn_both(x, acos) #define asin(x) __tg_fn_both(x, asin) #define atan(x) __tg_fn_both(x, atan) #define acosh(x) __tg_fn_both(x, acosh) #define asinh(x) __tg_fn_both(x, asinh) #define atanh(x) __tg_fn_both(x, atanh) #define cos(x) __tg_fn_both(x, cos) #define sin(x) __tg_fn_both(x, sin) #define tan(x) __tg_fn_both(x, tan) #define cosh(x) __tg_fn_both(x, cosh) #define sinh(x) __tg_fn_both(x, sinh) #define tanh(x) __tg_fn_both(x, tanh) #define exp(x) __tg_fn_both(x, exp) #define log(x) __tg_fn_both(x, log) #define pow(x, y) __tg_fn_both2(x, y, pow) #define sqrt(x) __tg_fn_both(x, sqrt) /* "The corresponding type-generic macro for fabs and cabs is fabs." */ #define fabs(x) __tg_cond_expr(__tg_use_complex(x), \ __tg_fn(x, cabs), __tg_fn(x, fabs)) /* 7.22#5 */ #define atan2(x, y) __tg_fn2(x, y, atan2) #define cbrt(x) __tg_fn(x, cbrt) #define ceil(x) __tg_fn(x, ceil) #define copysign(x, y) __tg_fn2(x, y, copysign) #define erf(x) __tg_fn(x, erf) #define erfc(x) __tg_fn(x, erfc) #define exp2(x) __tg_fn(x, exp2) #define expm1(x) __tg_fn(x, expm1) #define fdim(x, y) __tg_fn2(x, y, fdim) #define floor(x) __tg_fn(x, floor) #define fma(x, y, z) __tg_fn3(x, y, z, fma) #define fmax(x, y) __tg_fn2(x, y, fmax) #define fmin(x, y) __tg_fn2(x, y, fmin) #define fmod(x, y) __tg_fn2(x, y, fmod) #define frexp(x, y) __tg_fnv(x, frexp, x, y) #define hypot(x, y) __tg_fn2(x, y, hypot) #define ilogb(x) __tg_fn(x, ilogb) #define ldexp(x, y) __tg_fnv(x, ldexp, x, y) #define lgamma(x) __tg_fn(x, lgamma) #define llrint(x) __tg_fn(x, llrint) #define llround(x) __tg_fn(x, llround) #define log10(x) __tg_fn(x, log10) #define log1p(x) __tg_fn(x, log1p) #define log2(x) __tg_fn(x, log2) #define logb(x) __tg_fn(x, logb) #define lrint(x) __tg_fn(x, lrint) #define lround(x) __tg_fn(x, lround) #define nextbyint(x) __tg_fn(x, nextbyint) #define nextafter(x, y) __tg_fn2(x, y, nextafter) #define nexttoward(x, y) __tg_fnv(x, nexttoward, x, y) #define remainder(x, y) __tg_fn2(x, y, remainder) #define remquo(x, y, z) __tg_fn2v(x, y, remquo, x, y, z) #define rint(x) __tg_fn(x, rint) #define round(x) __tg_fn(x, round) #define scalbn(x, y) __tg_fnv(x, scalbn, x, y) #define scalbln(x, y) __tg_fnv(x, scalbln, x, y) #define tgamma(x) __tg_fn(x, tgamma) #define trunc(x) __tg_fn(x, trunc) /* 7.22#6 */ #define carg(x) __tg_fn(x, carg) #define cimag(x) __tg_fn(x, cimag) #define conj(x) __tg_fn(x, conj) #define cproj(x) __tg_fn(x, cproj) #define creal(x) __tg_fn(x, creal) #endif /* !_TGMATH_H_ */ --nmemrqcdn5VTmUEE--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040429203303.GH691>