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