+2011-10-22 Bruno Haible <bruno@clisp.org>
+
+ isfinite, isinf, isnan, signbit: Don't define as a macro in C++.
+ * lib/math.in.h (_GL_MATH_CXX_REAL_FLOATING_DECL_1,
+ _GL_MATH_CXX_REAL_FLOATING_DECL_2): nEW MACROS.
+ (isfinite, isinf, isnan, signbit): In C++, define as overloaded
+ functions, not as a macro.
+ * tests/test-math-c++.cc (REAL_FLOATING_CHECK, OVERLOADED_CHECK): New
+ macros.
+ (isfinite, isinf, isnan, signbit): Check overloaded functions and
+ absence of macro.
+ Suggested by Eric Blake.
+ Reported by Michael Goffioul <michael.goffioul@gmail.com>.
+
2011-10-21 Bruno Haible <bruno@clisp.org>
relocatable-prog-wrapper: Don't leave object files behind.
/* The definition of _GL_WARN_ON_USE is copied here. */
+#ifdef __cplusplus
+/* Helper macros to define type-generic function FUNC as overloaded functions,
+ rather than as macros like in C. POSIX declares these with an argument of
+ real-floating (that is, one of float, double, or long double). */
+# define _GL_MATH_CXX_REAL_FLOATING_DECL_1(func) \
+static inline int \
+_gl_cxx_ ## func ## f (float f) \
+{ \
+ return func (f); \
+} \
+static inline int \
+_gl_cxx_ ## func ## d (double d) \
+{ \
+ return func (d); \
+} \
+static inline int \
+_gl_cxx_ ## func ## l (long double l) \
+{ \
+ return func (l); \
+}
+# define _GL_MATH_CXX_REAL_FLOATING_DECL_2(func) \
+inline int \
+func (float f) \
+{ \
+ return _gl_cxx_ ## func ## f (f); \
+} \
+inline int \
+func (double d) \
+{ \
+ return _gl_cxx_ ## func ## d (d); \
+} \
+inline int \
+func (long double l) \
+{ \
+ return _gl_cxx_ ## func ## l (l); \
+}
+#endif
+
/* Helper macros to define a portability warning for the
classification macro FUNC called with VALUE. POSIX declares the
classification macros with an argument of real-floating (that is,
sizeof (x) == sizeof (double) ? gl_isfinited (x) : \
gl_isfinitef (x))
# endif
+# ifdef __cplusplus
+# ifdef isfinite
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isfinite)
+# undef isfinite
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite)
+# endif
+# endif
#elif defined GNULIB_POSIXCHECK
# if defined isfinite
_GL_WARN_REAL_FLOATING_DECL (isfinite);
sizeof (x) == sizeof (double) ? gl_isinfd (x) : \
gl_isinff (x))
# endif
+# ifdef __cplusplus
+# ifdef isinf
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isinf)
+# undef isinf
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf)
+# endif
+# endif
#elif defined GNULIB_POSIXCHECK
# if defined isinf
_GL_WARN_REAL_FLOATING_DECL (isinf);
sizeof (x) == sizeof (double) ? __builtin_isnan ((double)(x)) : \
__builtin_isnanf ((float)(x)))
# endif
+# ifdef __cplusplus
+# ifdef isnan
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isnan)
+# undef isnan
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan)
+# endif
+# else
/* Ensure isnan is a macro. */
-# ifndef isnan
-# define isnan isnan
+# ifndef isnan
+# define isnan isnan
+# endif
# endif
#elif defined GNULIB_POSIXCHECK
# if defined isnan
sizeof (x) == sizeof (double) ? gl_signbitd (x) : \
gl_signbitf (x))
# endif
+# ifdef __cplusplus
+# ifdef signbit
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (signbit)
+# undef signbit
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit)
+# endif
+# endif
#elif defined GNULIB_POSIXCHECK
# if defined signbit
_GL_WARN_REAL_FLOATING_DECL (signbit);
#include "signature.h"
+/* Signature check for a function that takes a real-floating argument.
+ Check that each overloaded function with the specified signature exists. */
+#define REAL_FLOATING_CHECK(func,\
+ rettype1, parameters1,\
+ rettype2, parameters2,\
+ rettype3, parameters3) \
+ OVERLOADED_CHECK (func, rettype1, parameters1, _1); \
+ OVERLOADED_CHECK (func, rettype2, parameters2, _2); \
+ OVERLOADED_CHECK (func, rettype3, parameters3, _3)
+#define OVERLOADED_CHECK(func, rettype, parameters, suffix) \
+ static rettype (* _GL_UNUSED signature_check_ ## func ## suffix) parameters \
+ = static_cast<rettype(*)parameters>(func)
#if GNULIB_TEST_ACOSF
SIGNATURE_CHECK (GNULIB_NAMESPACE::acosf, float, (float));
SIGNATURE_CHECK (GNULIB_NAMESPACE::frexp, double, (double, int *));
#endif
//SIGNATURE_CHECK (GNULIB_NAMESPACE::hypot, double, (double, double));
+#if GNULIB_TEST_ISFINITE
+# ifdef isfinite
+# error "isfinite should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (isfinite, int, (float), int, (double), int, (long double));
+#endif
+#if GNULIB_TEST_ISINF
+# ifdef isinf
+# error "isinf should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (isinf, int, (float), int, (double), int, (long double));
+#endif
+#if GNULIB_TEST_ISNAN
+# ifdef isnan
+# error "isnan should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (isnan, int, (float), int, (double), int, (long double));
+#endif
//SIGNATURE_CHECK (GNULIB_NAMESPACE::j0, double, (double));
//SIGNATURE_CHECK (GNULIB_NAMESPACE::j1, double, (double));
//SIGNATURE_CHECK (GNULIB_NAMESPACE::jn, double, (int, double));
SIGNATURE_CHECK (GNULIB_NAMESPACE::roundl, long double, (long double));
#endif
+#if GNULIB_TEST_SIGNBIT
+# ifdef signbit
+# error "signbit should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (signbit, int, (float), int, (double), int, (long double));
+#endif
+
#if GNULIB_TEST_SINL
SIGNATURE_CHECK (GNULIB_NAMESPACE::sinl, long double, (long double));
#endif