isfinite, isinf, isnan, signbit: Don't define as a macro in C++.
authorBruno Haible <bruno@clisp.org>
Sat, 22 Oct 2011 11:52:56 +0000 (13:52 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 22 Oct 2011 11:52:56 +0000 (13:52 +0200)
* 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>.

ChangeLog
lib/math.in.h
tests/test-math-c++.cc

index a52e2aa..cb0385f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+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.
index c92703f..e0742ec 100644 (file)
 
 /* 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,
@@ -1030,6 +1068,13 @@ _GL_EXTERN_C int gl_isfinitel (long double x);
     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);
@@ -1050,6 +1095,13 @@ _GL_EXTERN_C int gl_isinfl (long double x);
     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);
@@ -1161,9 +1213,17 @@ _GL_EXTERN_C int rpl_isnanl (long double x);
     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
@@ -1227,6 +1287,13 @@ _GL_EXTERN_C int gl_signbitl (long double arg);
     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);
index 0a22fdd..8fee843 100644 (file)
 
 #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));
@@ -76,6 +88,24 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::frexpf, float, (float, int *));
 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));
@@ -211,6 +241,13 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::round, double, (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