From f619ff7713cc60a7e6e63c3b5ebe61ba1ec8757b Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sat, 1 Jun 2013 23:51:25 -0700 Subject: [PATCH] Add . Obtained-from: FreeBSD --- include/Makefile | 2 +- include/tgmath.h | 210 ++++++++++++++++++++++++++++++++++++++++ share/man/man3/Makefile | 2 +- share/man/man3/tgmath.3 | 162 +++++++++++++++++++++++++++++++ 4 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 include/tgmath.h create mode 100644 share/man/man3/tgmath.3 diff --git a/include/Makefile b/include/Makefile index 9e6272ad16..3e65b899f2 100644 --- a/include/Makefile +++ b/include/Makefile @@ -23,7 +23,7 @@ INCS= a.out.h ar.h assert.h bitstring.h cpio.h ctype.h db.h \ signal.h spawn.h stab.h stdarg.h stdbool.h \ stddef.h stdint.h stdio.h stdlib.h \ string.h stringlist.h strings.h struct.h sysexits.h \ - tar.h time.h \ + tar.h tgmath.h time.h \ timeconv.h \ timers.h ttyent.h tzfile.h unistd.h ulimit.h utime.h utmp.h utmpx.h \ uuid.h vis.h \ diff --git a/include/tgmath.h b/include/tgmath.h new file mode 100644 index 0000000000..9a203f88cb --- /dev/null +++ b/include/tgmath.h @@ -0,0 +1,210 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder. + * All rights reserved. + * + * Copyright (c) 2012 Ed Schouten + * 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: head/include/tgmath.h 249995 2013-04-27 21:18:34Z ed $ + */ + +#ifndef _TGMATH_H_ +#define _TGMATH_H_ + +#include +#include + +/* + * This implementation of uses the two following macros, + * which are based on the macros described in C11 proposal N1404: + * __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) + * Invokes fnl() if the corresponding real type of x, y or z is long + * double, fn() if it is double or any has an integer type, and fnf() + * otherwise. + * __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) + * Invokes [c]fnl() if the corresponding real type of x or y is long + * double, [c]fn() if it is double or any has an integer type, and + * [c]fnf() otherwise. The function with the 'c' prefix is called if + * any of x or y is a complex number. + * Both macros call the chosen function with all additional arguments passed + * to them, as given by __VA_ARGS__. + * + * Note that these macros cannot be implemented with C's ?: operator, + * because the return type of the whole expression would incorrectly be long + * double complex regardless of the argument types. + * + * The structure of the C11 implementation of these macros can in + * principle be reused for non-C11 compilers, but due to an integer + * promotion bug for complex types in GCC 4.2, simply let non-C11 + * compilers use an inefficient yet reliable version. + */ + +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ + __has_extension(c_generic_selections) +#define __tg_generic(x, cfnl, cfn, cfnf, fnl, fn, fnf) \ + _Generic(x, \ + long double _Complex: cfnl, \ + double _Complex: cfn, \ + float _Complex: cfnf, \ + long double: fnl, \ + default: fn, \ + float: fnf \ + ) +#define __tg_type(x) \ + __tg_generic(x, (long double _Complex)0, (double _Complex)0, \ + (float _Complex)0, (long double)0, (double)0, (float)0) +#define __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) \ + __tg_generic( \ + __tg_type(x) + __tg_type(y) + __tg_type(z), \ + fnl, fn, fnf, fnl, fn, fnf)(__VA_ARGS__) +#define __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) \ + __tg_generic( \ + __tg_type(x) + __tg_type(y), \ + cfnl, cfn, cfnf, fnl, fn, fnf)(__VA_ARGS__) +#elif defined(__generic) +#define __tg_generic_simple(x, fnl, fn, fnf) \ + __generic(x, long double _Complex, fnl, \ + __generic(x, double _Complex, fn, \ + __generic(x, float _Complex, fnf, \ + __generic(x, long double, fnl, \ + __generic(x, float, fnf, fn))))) +#define __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) \ + __tg_generic_simple(x, \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fnl, fnl)), \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fn , fn ), \ + __tg_generic_simple(z, fnl, fn , fn )), \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fn , fn ), \ + __tg_generic_simple(z, fnl, fn , fnf)))(__VA_ARGS__) +#define __tg_generic_full(x, cfnl, cfn, cfnf, fnl, fn, fnf) \ + __generic(x, long double _Complex, cfnl, \ + __generic(x, double _Complex, cfn, \ + __generic(x, float _Complex, cfnf, \ + __generic(x, long double, fnl, \ + __generic(x, float, fnf, fn))))) +#define __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) \ + __tg_generic_full(x, \ + __tg_generic_full(y, cfnl, cfnl, cfnl, cfnl, cfnl, cfnl), \ + __tg_generic_full(y, cfnl, cfn , cfn , cfnl, cfn , cfn ), \ + __tg_generic_full(y, cfnl, cfn , cfnf, cfnl, cfn , cfnf), \ + __tg_generic_full(y, cfnl, cfnl, cfnl, fnl , fnl , fnl ), \ + __tg_generic_full(y, cfnl, cfn , cfn , fnl , fn , fn ), \ + __tg_generic_full(y, cfnl, cfn , cfnf, fnl , fn , fnf )) \ + (__VA_ARGS__) +#else +#error " not implemented for this compiler" +#endif + +/* Macros to save lots of repetition below */ +#define __tg_simple(x, fn) \ + __tg_impl_simple(x, x, x, fn##l, fn, fn##f, x) +#define __tg_simple2(x, y, fn) \ + __tg_impl_simple(x, x, y, fn##l, fn, fn##f, x, y) +#define __tg_simple3(x, y, z, fn) \ + __tg_impl_simple(x, y, z, fn##l, fn, fn##f, x, y, z) +#define __tg_simplev(x, fn, ...) \ + __tg_impl_simple(x, x, x, fn##l, fn, fn##f, __VA_ARGS__) +#define __tg_full(x, fn) \ + __tg_impl_full(x, x, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x) +#define __tg_full2(x, y, fn) \ + __tg_impl_full(x, y, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x, y) + +/* 7.22#4 -- These macros expand to real or complex functions, depending on + * the type of their arguments. */ +#define acos(x) __tg_full(x, acos) +#define asin(x) __tg_full(x, asin) +#define atan(x) __tg_full(x, atan) +#define acosh(x) __tg_full(x, acosh) +#define asinh(x) __tg_full(x, asinh) +#define atanh(x) __tg_full(x, atanh) +#define cos(x) __tg_full(x, cos) +#define sin(x) __tg_full(x, sin) +#define tan(x) __tg_full(x, tan) +#define cosh(x) __tg_full(x, cosh) +#define sinh(x) __tg_full(x, sinh) +#define tanh(x) __tg_full(x, tanh) +#define exp(x) __tg_full(x, exp) +#define log(x) __tg_full(x, log) +#define pow(x, y) __tg_full2(x, y, pow) +#define sqrt(x) __tg_full(x, sqrt) + +/* "The corresponding type-generic macro for fabs and cabs is fabs." */ +#define fabs(x) __tg_impl_full(x, x, cabsl, cabs, cabsf, \ + fabsl, fabs, fabsf, x) + +/* 7.22#5 -- These macros are only defined for arguments with real type. */ +#define atan2(x, y) __tg_simple2(x, y, atan2) +#define cbrt(x) __tg_simple(x, cbrt) +#define ceil(x) __tg_simple(x, ceil) +#define copysign(x, y) __tg_simple2(x, y, copysign) +#define erf(x) __tg_simple(x, erf) +#define erfc(x) __tg_simple(x, erfc) +#define exp2(x) __tg_simple(x, exp2) +#define expm1(x) __tg_simple(x, expm1) +#define fdim(x, y) __tg_simple2(x, y, fdim) +#define floor(x) __tg_simple(x, floor) +#define fma(x, y, z) __tg_simple3(x, y, z, fma) +#define fmax(x, y) __tg_simple2(x, y, fmax) +#define fmin(x, y) __tg_simple2(x, y, fmin) +#define fmod(x, y) __tg_simple2(x, y, fmod) +#define frexp(x, y) __tg_simplev(x, frexp, x, y) +#define hypot(x, y) __tg_simple2(x, y, hypot) +#define ilogb(x) __tg_simple(x, ilogb) +#define ldexp(x, y) __tg_simplev(x, ldexp, x, y) +#define lgamma(x) __tg_simple(x, lgamma) +#define llrint(x) __tg_simple(x, llrint) +#define llround(x) __tg_simple(x, llround) +#define log10(x) __tg_simple(x, log10) +#define log1p(x) __tg_simple(x, log1p) +#define log2(x) __tg_simple(x, log2) +#define logb(x) __tg_simple(x, logb) +#define lrint(x) __tg_simple(x, lrint) +#define lround(x) __tg_simple(x, lround) +#define nearbyint(x) __tg_simple(x, nearbyint) +#define nextafter(x, y) __tg_simple2(x, y, nextafter) +#define nexttoward(x, y) __tg_simplev(x, nexttoward, x, y) +#define remainder(x, y) __tg_simple2(x, y, remainder) +#define remquo(x, y, z) __tg_impl_simple(x, x, y, remquol, remquo, \ + remquof, x, y, z) +#define rint(x) __tg_simple(x, rint) +#define round(x) __tg_simple(x, round) +#define scalbn(x, y) __tg_simplev(x, scalbn, x, y) +#define scalbln(x, y) __tg_simplev(x, scalbln, x, y) +#define tgamma(x) __tg_simple(x, tgamma) +#define trunc(x) __tg_simple(x, trunc) + +/* 7.22#6 -- These macros always expand to complex functions. */ +#define carg(x) __tg_simple(x, carg) +#define cimag(x) __tg_simple(x, cimag) +#define conj(x) __tg_simple(x, conj) +#define cproj(x) __tg_simple(x, cproj) +#define creal(x) __tg_simple(x, creal) + +#endif /* !_TGMATH_H_ */ diff --git a/share/man/man3/Makefile b/share/man/man3/Makefile index c9c29ce728..b98df95f03 100644 --- a/share/man/man3/Makefile +++ b/share/man/man3/Makefile @@ -3,7 +3,7 @@ # $DragonFly: src/share/man/man3/Makefile,v 1.6 2007/01/28 14:52:02 swildner Exp $ MAN= assert.3 bitstring.3 end.3 fpgetround.3 intro.3 queue.3 \ - stdarg.3 sysexits.3 tree.3 + stdarg.3 sysexits.3 tgmath.3 tree.3 MLINKS+=bitstring.3 bit_alloc.3 bitstring.3 bit_clear.3 \ bitstring.3 bit_decl.3 bitstring.3 bit_ffc.3 bitstring.3 bit_ffs.3 \ bitstring.3 bit_nclear.3 bitstring.3 bit_nset.3 bitstring.3 bit_set.3 \ diff --git a/share/man/man3/tgmath.3 b/share/man/man3/tgmath.3 new file mode 100644 index 0000000000..88ebb73828 --- /dev/null +++ b/share/man/man3/tgmath.3 @@ -0,0 +1,162 @@ +.\" 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 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 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: head/share/man/man3/tgmath.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd January 4, 2012 +.Dt TGMATH 3 +.Os +.Sh NAME +.Nm tgmath +.Nd "type-generic macros" +.Sh SYNOPSIS +.In tgmath.h +.Sh DESCRIPTION +The header +.In tgmath.h +provides type-generic macros +for +.In math.h +and +.In complex.h +functions that have +.Vt float +(suffixed with +.Sy f ) , +.Vt double +and +.Vt "long double" +(suffixed with +.Sy l ) +versions. +The arguments that vary across the three functions and have type +.Vt float , double +and +.Vt "long double" , +respectively, are called +.Em "generic arguments" . +.Pp +The following rules describe which function is actually called if a +type-generic macro is invoked. +If any generic argument has type +.Vt "long double" +or +.Vt "long double complex" , +the +.Vt "long double" +function is called. +Else, if any generic argument has type +.Vt double , "double complex" +or an integer type, the +.Vt double +version is invoked. +Otherwise, the macro expands to the +.Vt float +implementation. +.Pp +For the macros in the following table, both real and complex functions +exist. +The real functions are prototyped in +.In math.h +and the complex equivalents in +.In complex.h . +The complex function is called if any of the generic arguments is a +complex value. +Otherwise, the real equivalent is called. +.Bl -column -offset indent ".Fn acosh" "Sy real function" ".Sy complex function" +.It Sy Macro Ta Sy real function Ta Sy complex function +.It Fn acos Ta Fn acos Ta Fn cacos +.It Fn asin Ta Fn asin Ta Fn casin +.It Fn atan Ta Fn atan Ta Fn catan +.It Fn acosh Ta Fn acosh Ta Fn cacosh +.It Fn asinh Ta Fn asinh Ta Fn casinh +.It Fn atanh Ta Fn atanh Ta Fn catanh +.It Fn cos Ta Fn cos Ta Fn ccos +.It Fn sin Ta Fn sin Ta Fn csin +.It Fn tan Ta Fn tan Ta Fn ctan +.It Fn cosh Ta Fn cosh Ta Fn ccosh +.It Fn sinh Ta Fn sinh Ta Fn csinh +.It Fn tanh Ta Fn tanh Ta Fn ctanh +.It Fn exp Ta Fn exp Ta Fn cexp +.It Fn log Ta Fn log Ta Fn clog +.It Fn pow Ta Fn pow Ta Fn cpow +.It Fn sqrt Ta Fn sqrt Ta Fn csqrt +.It Fn fabs Ta Fn fabs Ta Fn cabs +.El +.Pp +No complex functions exist for the following macros, so passing a +complex value to a generic argument invokes undefined behaviour: +.Bl -column -offset indent ".Fn nexttoward" ".Fn nexttoward" ".Fn nexttoward" ".Fn nexttoward" +.It Fn atan2 Ta Fn fma Ta Fn llround Ta Fn remainder +.It Fn cbrt Ta Fn fmax Ta Fn log10 Ta Fn remquo +.It Fn ceil Ta Fn fmin Ta Fn log1p Ta Fn rint +.It Fn copysign Ta Fn fmod Ta Fn log2 Ta Fn round +.It Fn erf Ta Fn frexp Ta Fn logb Ta Fn scalbn +.It Fn erfc Ta Fn hypot Ta Fn lrint Ta Fn scalbln +.It Fn exp2 Ta Fn ilogb Ta Fn lround Ta Fn tgamma +.It Fn expm1 Ta Fn ldexp Ta Fn nextbyint Ta Fn trunc +.It Fn fdim Ta Fn lgamma Ta Fn nextafter Ta \& +.It Fn floor Ta Fn llrint Ta Fn nexttoward Ta \& +.El +.Pp +The following macros always expand to a complex function: +.Bl -column -offset indent ".Fn cimag" ".Fn cimag" ".Fn cimag" ".Fn cimag" ".Fn cimag" +.It Fn carg Ta Fn cimag Ta Fn conj Ta Fn cproj Ta Fn creal +.El +.Pp +This header includes +.In complex.h +and +.In math.h . +.Sh STANDARDS +The header +.In tgmath.h +conforms to +.St -isoC-99 . +.Sh HISTORY +The header +.In tgmath.h +first appeared in +.Fx 5.3 . +.Sh COMPILER SUPPORT +Before +.St -isoC-2011 , +the header +.In tgmath.h +could not be implemented with strictly conforming C code and needed +special compiler support. +As of +.St -isoC-2011 , +this header file can be implemented using the +.Fn _Generic +language keyword. +In addition to compilers that support this keyword, this header file +works with GCC. +.Sh BUGS +Many of the functions mentioned here are not prototyped in +.In math.h +or +.In complex.h +as they are not yet implemented. +This prevents the corresponding type-generic macro from working at all. -- 2.41.0