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