tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

tgmath



Hi folks,

warning, if you like C for its simplicity, do not read the below post.

while looking at the stdatomic nonsense versions, I noticed we are using
tgmath.h from gcc, but no tgmath.h from clang, if the set lists are to
believed.

randomly poking it turned out that in C99 you probably had to be a
compiler/extensions to implement tgmath*. with C11 generics, you don't.

attached is a version that could use more testing & careful reading of
is standard.

thoughts?

* sizeof(double) == sizeof(complex float)
/* 
 * Type-generic mathematics
 *
 * Public domain
 */

#ifndef _TGMATH_H_
#define _TGMATH_H_

#include <math.h>
#include <complex.h>

#define __tgcomplex_unary(__name, __x) _Generic((__x),	\
	complex long double: __name ## l,		\
	             double: __name,			\
	      complex float: __name ## f,		\
)(__x)

#define __tgreal_unary(__name, __x) _Generic((__x),	\
	long double: __name ## l,			\
	     double: __name,				\
	      float: __name ## f			\
)(__x)

#define __tgreal_binary(__name, __x, __y) _Generic((__x),	\
	long double: __name ## l,				\
	     double: __name,					\
	      float: __name ## f				\
)(__x, __y)

#define __tgreal_ternary(__name, __x, __y, __z) _Generic((__x),	\
	long double: __name ## l,				\
	     double: __name,					\
	      float: __name ## f				\
)(__x, __y, __z)


#define __tgfloat_unary(__name, __x) _Generic((__x),	\
	complex long double: c ## __name ## l,		\
	     complex double: c ## __name,		\
	      complex float: c ## __name ## f,		\
	        long double: __name ## l,		\
	             double: __name,			\
	              float: __name ## f		\
)(__x)

/* real only */
#define atan2(__x, __y)		__tgreal_binary(atan2, __x, __y)
#define cbrt(__x)		__tgreal_unary(cbrt, __x)
#define ceil(__x)		__tgreal_unary(ceil, __x)
#define copysign(__x)		__tgreal_unary(copysign, __x) /* XXX in math.h already */
#define erf(__x)		__tgreal_unary(erf, __x)
#define erfc(__x)		__tgreal_unary(erfc, __x)
#define exp2(__x)		__tgreal_unary(exp2, __x)
#define expm1(__x)		__tgreal_unary(expm1, __x)
#define fdim(__x)		__tgreal_unary(fdim, __x)
#define floor(__x)		__tgreal_unary(floor, __x)
#define fma(__x, __y, __z)	__tgreal_ternary(fma __x, __y, __z)
#define fmax(__x, __y)		__tgreal_binary(fmax, __x, __y)
#define fmin(__x, __y)		__tgreal_binary(fmin, __x, __y)
#define fmod(__x, __y)		__tgreal_binary(fmod, __x, __y)
#define frexp(__x, __y)		__tgreal_binary(frexp, __x, __y)
#define hypot(__x, __y)		__tgreal_binary(hypot, __x, __y)
#define ilogb(__x)		__tgreal_unary(ilogb, __x)
#define ldexp(__x, __y)		__tgreal_binary(ldexp, __x, __y)
#define lgamma(__x)		__tgreal_unary(lgamma, __x)
#define llrint(__x)		__tgreal_unary(llrint , __x)
#define llround(__x)		__tgreal_unary(llround, __x)
#define log10(__x)		__tgreal_unary(log10 , __x)
#define log1p(__x)		__tgreal_unary(log1p, __x)
#define logb(__x)		__tgreal_unary(logb, __x)
#define lrint(__x)		__tgreal_unary(lrint, __x)
#define lround(__x)		__tgreal_unary(lround, __x)
#define nearbyint(__x)		__tgreal_unary(nearbyint, __x)
#define nextafter(__x)		__tgreal_unary(nextafter, __x)
#define nexttoward(__x)		__tgreal_unary(nexttoward, __x)
#define remainder(__x)		__tgreal_unary(remainder, __x)
#define remquo(__x)		__tgreal_unary(remquo, __x)
#define rint(__x)		__tgreal_unary(rint, __x)
#define round(__x)		__tgreal_unary(round, __x)
#define scalbn(__x)		__tgreal_unary(scalbn, __x)
#define scalbln(__x)		__tgreal_unary(scalbln, __x)
#define tgamma(__x)		__tgreal_unary(tgamma, __x)
#define trunc(__x)		__tgreal_unary(trunc, __x)

/* complex only */
#define cacos(__x)	__tgcomplex_unary(cacos, __x)
#define casin(__x)	__tgcomplex_unary(casin, __x)
#define catan(__x)	__tgcomplex_unary(catan, __x)
#define cacosh(__x)	__tgcomplex_unary(cacosh, __x)
#define casinh(__x)	__tgcomplex_unary(casinh, __x)
#define catanh(__x)	__tgcomplex_unary(catanh, __x)
#define ccos(__x)	__tgcomplex_unary(ccos, __x)
#define csin(__x)	__tgcomplex_unary(csin, __x)
#define ctan(__x)	__tgcomplex_unary(ctan, __x)
#define ccosh(__x)	__tgcomplex_unary(ccosh, __x)
#define csinh(__x)	__tgcomplex_unary(csinh, __x)
#define ctanh(__x)	__tgcomplex_unary(ctanh, __x)
#define cexp(__x)	__tgcomplex_unary(cexp, __x)
#define clog(__x)	__tgcomplex_unary(clog, __x)
#define cabs(__x)	__tgcomplex_unary(cabs, __x)
#define cpow(__x)	__tgcomplex_unary(cpow, __x)
#define csqrt(__x)	__tgcomplex_unary(csqrt, __x)
#define carg(__x)	__tgcomplex_unary(carg, __x)
#define cimag(__x)	__tgcomplex_unary(cimag, __x)
#define conj(__x)	__tgcomplex_unary(conj, __x)
#define cproj(__x)	__tgcomplex_unary(cproj, __x)
#define creal(__x)	__tgcomplex_unary(creal, __x)


/* real & complex */
#define acos(__x)	__tgfloat_unary(acos, __x)
#define asin(__x)	__tgfloat_unary(asin, __x)
#define atan(__x)	__tgfloat_unary(atan, __x)
#define acosh(__x)	__tgfloat_unary(acosh, __x)
#define asinh(__x)	__tgfloat_unary(asinh, __x)
#define atanh(__x)	__tgfloat_unary(atanh, __x)
#define cos(__x)	__tgfloat_unary(cos, __x)
#define sin(__x)	__tgfloat_unary(sin, __x)
#define tan(__x)	__tgfloat_unary(tan, __x)
#define cosh(__x)	__tgfloat_unary(cosh, __x)
#define sinh(__x)	__tgfloat_unary(sinh, __x)
#define tanh(__x)	__tgfloat_unary(tanh, __x)
#define exp(__x)	__tgfloat_unary(exp, __x)
#define log(__x)	__tgfloat_unary(log, __x)
#define pow(__x)	__tgfloat_unary(pow, __x)
#define sqrt(__x)	__tgfloat_unary(sqrt, __x)
#define fabs(__x)	__tgfloat_unary(fabs, __x)

#endif


Home | Main Index | Thread Index | Old Index