1*a1550574Ssevan /* $NetBSD: tgmath.h,v 1.2 2017/04/04 12:25:40 sevan Exp $ */ 2*a1550574Ssevan 399a8c5caSmatt /*- 499a8c5caSmatt * Copyright (c) 2008 The NetBSD Foundation, Inc. 599a8c5caSmatt * All rights reserved. 699a8c5caSmatt * 799a8c5caSmatt * This code is derived from software contributed to The NetBSD Foundation 899a8c5caSmatt * by Matt Thomas <matt@3am-software.com> 999a8c5caSmatt * 1099a8c5caSmatt * Redistribution and use in source and binary forms, with or without 1199a8c5caSmatt * modification, are permitted provided that the following conditions 1299a8c5caSmatt * are met: 1399a8c5caSmatt * 1. Redistributions of source code must retain the above copyright 1499a8c5caSmatt * notice, this list of conditions and the following disclaimer. 1599a8c5caSmatt * 2. Redistributions in binary form must reproduce the above copyright 1699a8c5caSmatt * notice, this list of conditions and the following disclaimer in the 1799a8c5caSmatt * documentation and/or other materials provided with the distribution. 1899a8c5caSmatt * 1999a8c5caSmatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2099a8c5caSmatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2199a8c5caSmatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2299a8c5caSmatt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2399a8c5caSmatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2499a8c5caSmatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2599a8c5caSmatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2699a8c5caSmatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2799a8c5caSmatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2899a8c5caSmatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2999a8c5caSmatt * POSSIBILITY OF SUCH DAMAGE. 3099a8c5caSmatt */ 3199a8c5caSmatt 3299a8c5caSmatt #ifndef _TGMATH_H_ 3399a8c5caSmatt #define _TGMATH_H_ 3499a8c5caSmatt 3599a8c5caSmatt #include <math.h> 3699a8c5caSmatt #include <complex.h> 3799a8c5caSmatt 3899a8c5caSmatt /* 3999a8c5caSmatt * C99 Type-generic math (7.22) 4099a8c5caSmatt */ 4199a8c5caSmatt #ifdef __GNUC__ 4299a8c5caSmatt #define __TG_CHOOSE(p, a, b) __builtin_choose_expr((p), (a), (b)) 4399a8c5caSmatt #define __TG_IS_EQUIV_TYPE_P(v, t) \ 4499a8c5caSmatt __builtin_types_compatible_p(__typeof__(v), t) 4599a8c5caSmatt #else 4699a8c5caSmatt #error how does this compler do type-generic macros? 4799a8c5caSmatt #endif 4899a8c5caSmatt 4999a8c5caSmatt #define __TG_IS_FCOMPLEX_P(t) __TG_IS_EQUIV_TYPE_P(t, float complex) 5099a8c5caSmatt #define __TG_IS_DCOMPLEX_P(t) __TG_IS_EQUIV_TYPE_P(t, double complex) 5199a8c5caSmatt #define __TG_IS_LCOMPLEX_P(t) __TG_IS_EQUIV_TYPE_P(t, long double complex) 5299a8c5caSmatt #define __TG_IS_FLOAT_P(t) __TG_IS_EQUIV_TYPE_P(t, float) 5399a8c5caSmatt #define __TG_IS_LDOUBLE_P(t) __TG_IS_EQUIV_TYPE_P(t, long double) 5499a8c5caSmatt #define __TG_IS_FREAL_P(t) (__TG_IS_FLOAT_P(t) || __TG_IS_FCOMPLEX_P(t)) 5599a8c5caSmatt #define __TG_IS_LREAL_P(t) (__TG_IS_LDOUBLE_P(t) || __TG_IS_LCOMPLEX_P(t)) 5699a8c5caSmatt 5799a8c5caSmatt #define __TG_IS_COMPLEX_P(t) \ 5899a8c5caSmatt (__TG_IS_FCOMPLEX_P(t) \ 5999a8c5caSmatt || __TG_IS_DCOMPLEX_P(t) \ 6099a8c5caSmatt || __TG_IS_LCOMPLEX_P(t)) 6199a8c5caSmatt 6299a8c5caSmatt #define __TG_GFN1(fn, a, ftype, ltype) \ 6399a8c5caSmatt __TG_CHOOSE(__TG_IS_##ftype##_P(a), \ 6499a8c5caSmatt fn##f(a), \ 6599a8c5caSmatt __TG_CHOOSE(__TG_IS_##ltype##_P(a), \ 6699a8c5caSmatt fn##l(a), \ 6799a8c5caSmatt fn(a))) 6899a8c5caSmatt 6999a8c5caSmatt #define __TG_GFN1x(fn, a, b, ftype, ltype) \ 7099a8c5caSmatt __TG_CHOOSE(__TG_IS_##ftype##_P(a), \ 7199a8c5caSmatt fn##f((a), (b)), \ 7299a8c5caSmatt __TG_CHOOSE(__TG_IS_##ltype##_P(a), \ 7399a8c5caSmatt fn##l((a), (b)), \ 7499a8c5caSmatt fn((a), (b)))) 7599a8c5caSmatt 7699a8c5caSmatt #define __TG_GFN2(fn, a, b, ftype, ltype) \ 7799a8c5caSmatt __TG_CHOOSE(__TG_IS_##ftype##_P(a) \ 7899a8c5caSmatt && __TG_IS_##ftype##_P(b), \ 7999a8c5caSmatt fn##f((a), (b)), \ 8099a8c5caSmatt __TG_CHOOSE(__TG_IS_##ltype##_P(a) \ 8199a8c5caSmatt || __TG_IS_##ltype##_P(b), \ 8299a8c5caSmatt fn##l((a), (b)), \ 8399a8c5caSmatt fn((a), (b)))) 8499a8c5caSmatt 8599a8c5caSmatt #define __TG_GFN2x(fn, a, b, c, ftype, ltype) \ 8699a8c5caSmatt __TG_CHOOSE(__TG_IS_##ftype##_P(a) \ 8799a8c5caSmatt && __TG_IS_##ftype##_P(b), \ 8899a8c5caSmatt fn##f((a), (b), (c)), \ 8999a8c5caSmatt __TG_CHOOSE(__TG_IS_##ltype##_P(a) \ 9099a8c5caSmatt || __TG_IS_##ltype##_P(b), \ 9199a8c5caSmatt fn##l((a), (b), (c)), \ 9299a8c5caSmatt fn((a), (b), (c)))) 9399a8c5caSmatt 9499a8c5caSmatt #define __TG_GFN3(fn, a, b, c, ftype, ltype) \ 9599a8c5caSmatt __TG_CHOOSE(__TG_IS_##ftype##_P(a) \ 9699a8c5caSmatt && __TG_IS_##ftype##_P(b) \ 9799a8c5caSmatt && __TG_IS_##ftype##_P(c), \ 9899a8c5caSmatt fn##f((a), (b), (c)), \ 9999a8c5caSmatt __TG_CHOOSE(__TG_IS_##ltype##_P(a) \ 10099a8c5caSmatt || __TG_IS_##ltype##_P(b) \ 10199a8c5caSmatt || __TG_IS_##ltype##_P(c), \ 10299a8c5caSmatt fn##l((a), (b), (c)), \ 10399a8c5caSmatt fn((a), (b), (c)))) 10499a8c5caSmatt 10599a8c5caSmatt 10699a8c5caSmatt #define __TG_CFN1(cfn, a) __TG_GFN1(cfn, a, FREAL, LREAL) 10799a8c5caSmatt #define __TG_CFN2(cfn, a, b) __TG_GFN2(cfn, a, b, FREAL, LREAL) 10899a8c5caSmatt 10999a8c5caSmatt #define __TG_FN1(fn, a) __TG_GFN1(fn, a, FLOAT, LDOUBLE) 11099a8c5caSmatt #define __TG_FN1x(fn, a, b) __TG_GFN1x(fn, a, b, FLOAT, LDOUBLE) 11199a8c5caSmatt #define __TG_FN2(fn, a, b) __TG_GFN2(fn, a, b, FLOAT, LDOUBLE) 11299a8c5caSmatt #define __TG_FN2x(fn, a, b, c) __TG_GFN2x(fn, a, b, c, FLOAT, LDOUBLE) 11399a8c5caSmatt #define __TG_FN3(fn, a, b, c) __TG_GFN3(fn, a, b, c, FLOAT, LDOUBLE) 11499a8c5caSmatt 11599a8c5caSmatt #define __TG_COMPLEX(a, fn) \ 11699a8c5caSmatt __TG_CHOOSE(__TG_IS_COMPLEX_P(a), \ 11799a8c5caSmatt __TG_CFN1(c##fn, (a)), \ 11899a8c5caSmatt __TG_FN1(fn, (a))) 11999a8c5caSmatt 12099a8c5caSmatt #define __TG_COMPLEX1(a, cfn, fn) \ 12199a8c5caSmatt __TG_CHOOSE(__TG_IS_COMPLEX_P(a), \ 12299a8c5caSmatt __TG_CFN1(cfn, (a)), \ 12399a8c5caSmatt __TG_FN1(fn, (a))) 12499a8c5caSmatt 12599a8c5caSmatt #define __TG_COMPLEX2(a, b, fn) \ 12699a8c5caSmatt __TG_CHOOSE(__TG_IS_COMPLEX_P(a) \ 12799a8c5caSmatt || __TG_IS_COMPLEX_P(b), \ 12899a8c5caSmatt __TG_CFN2(c##fn, (a), (b)), \ 12999a8c5caSmatt __TG_FN2(fn, (a), (b))) 13099a8c5caSmatt 13199a8c5caSmatt #define acos(a) __TG_COMPLEX((a), acos) 13299a8c5caSmatt #define asin(a) __TG_COMPLEX((a), asin) 13399a8c5caSmatt #define atan(a) __TG_COMPLEX((a), atan) 13499a8c5caSmatt #define acosh(a) __TG_COMPLEX((a), acosh) 13599a8c5caSmatt #define asinh(a) __TG_COMPLEX((a), asinh) 13699a8c5caSmatt #define atanh(a) __TG_COMPLEX((a), atanh) 13799a8c5caSmatt #define cos(a) __TG_COMPLEX((a), cos) 13899a8c5caSmatt #define sin(a) __TG_COMPLEX((a), sin) 13999a8c5caSmatt #define tan(a) __TG_COMPLEX((a), tan) 14099a8c5caSmatt #define cosh(a) __TG_COMPLEX((a), cosh) 14199a8c5caSmatt #define sinh(a) __TG_COMPLEX((a), sinh) 14299a8c5caSmatt #define tanh(a) __TG_COMPLEX((a), tanh) 14399a8c5caSmatt #define exp(a) __TG_COMPLEX((a), exp) 14499a8c5caSmatt #define log(a) __TG_COMPLEX((a), log) 14599a8c5caSmatt #define pow(a,b) __TG_COMPLEX2((a), (b), pow) 14699a8c5caSmatt #define sqrt(a) __TG_COMPLEX((a), sqrt) 14799a8c5caSmatt #define fabs(a) __TG_COMPLEX1((a), cabs, fabs) 14899a8c5caSmatt 14999a8c5caSmatt #define atan2(a,b) __TG_FN2(atan2, (a), (b)) 15099a8c5caSmatt #define cbrt(a) __TG_FN1(cbrt, (a)) 15199a8c5caSmatt #define ceil(a) __TG_FN1(ceil, (a)) 15299a8c5caSmatt #define copysign(a,b) __TG_FN2(copysign, (a), (b)) 15399a8c5caSmatt #define erf(a) __TG_FN1(erf, (a)) 15499a8c5caSmatt #define erfc(a) __TG_FN1(erfc, (a)) 15599a8c5caSmatt #define exp2(a) __TG_FN1(exp2, (a)) 15699a8c5caSmatt #define expm1(a) __TG_FN1(expm1, (a)) 15799a8c5caSmatt #define fdim(a,b) __TG_FN2(fdim, (a), (b)) 15899a8c5caSmatt #define floor(a) __TG_FN1(floor, (a)) 15999a8c5caSmatt #define fma(a,b,c) __TG_FN3(fma, (a), (b), (c)) 16099a8c5caSmatt #define fmax(a,b) __TG_FN2(fmax, (a), (b)) 16199a8c5caSmatt #define fmin(a,b) __TG_FN2(fmin, (a), (b)) 16299a8c5caSmatt #define fmod(a,b) __TG_FN2(fmod, (a), (b)) 16399a8c5caSmatt #define frexp(a,b) __TG_FN1x(frexp, (a), (b)) 16499a8c5caSmatt #define hypot(a,b) __TG_FN2(hypot, (a), (b)) 16599a8c5caSmatt #define ilogb(a) __TG_FN1(ilogb, (a)) 16699a8c5caSmatt #define ldexp(a,b) __TG_FN1x(ldexp, (a), (b)) 16799a8c5caSmatt #define lgamma(a) __TG_FN1(lgamma, (a)) 16899a8c5caSmatt #define llrint(a) __TG_FN1(llrint, (a)) 16999a8c5caSmatt #define llround(a) __TG_FN1(llround, (a)) 17099a8c5caSmatt #define log10(a) __TG_FN1(log10, (a)) 17199a8c5caSmatt #define log1p(a) __TG_FN1(log1p, (a)) 17299a8c5caSmatt #define log2(a) __TG_FN1(log2, (a)) 17399a8c5caSmatt #define logb(a) __TG_FN1(logb, (a)) 17499a8c5caSmatt #define lrint(a) __TG_FN1(lrint, (a)) 17599a8c5caSmatt #define lround(a) __TG_FN1(lround, (a)) 17699a8c5caSmatt #define nearbyint(a) __TG_FN1(nearbyint, (a)) 17799a8c5caSmatt #define nextafter(a,b) __TG_FN2(nextafter, (a), (b)) 17899a8c5caSmatt #define nexttoward(a,b) __TG_FN2(nexttoward, (a), (b)) 17999a8c5caSmatt #define remainder(a,b) __TG_FN2(remainder, (a), (b)) 18099a8c5caSmatt #define remquo(a,b,c) __TG_FN2x(remquo, (a), (b), (c)) 18199a8c5caSmatt #define rint(a) __TG_FN1(rint, (a)) 18299a8c5caSmatt #define round(a) __TG_FN1(round, (a)) 18399a8c5caSmatt #define scalbn(a,b) __TG_FN1x(scalbn, (a), (b)) 18499a8c5caSmatt #define scalb1n(a,b) __TG_FN1x(scalb1n, (a), (b)) 18599a8c5caSmatt #define tgamma(a) __TG_FN1(tgamma, (a)) 18699a8c5caSmatt #define trunc(a) __TG_FN1(trunc, (a)) 18799a8c5caSmatt 18899a8c5caSmatt #define carg(a) __TG_CFN1(carg, (a)) 18999a8c5caSmatt #define cimag(a) __TG_CFN1(cimag, (a)) 19099a8c5caSmatt #define conj(a) __TG_CFN1(conj, (a)) 19199a8c5caSmatt #define cproj(a) __TG_CFN1(cproj, (a)) 19299a8c5caSmatt #define creal(a) __TG_CFN1(creal, (a)) 19399a8c5caSmatt 19499a8c5caSmatt #endif /* !_TGMATH_H_ */ 195