* lib/math.in.h: Declare totalorderf, totalorder, totalorderl. * lib/totalorder.c, lib/totalorderf.c, lib/totalorderl.c: * m4/totalorder.m4, modules/totalorder, modules/totalorder-tests: * modules/totalorderf, modules/totalorderf-tests: * modules/totalorderl, modules/totalorderl-tests: * tests/test-totalorder.c, tests/test-totalorderf.c: * tests/test-totalorderl.c: New files. * m4/math_h.m4 (gl_MATH_H, gl_MATH_H_REQUIRE_DEFAULTS) (gl_MATH_H_DEFAULTS): * modules/math (math.h): Set up totalorder, totalorderf, totalorderl. * m4/mathfunc.m4 (gl_MATHFUNC): Also support pointer-to-const. --- ChangeLog | 15 +++++ doc/posix-functions/totalorder.texi | 12 ++-- doc/posix-functions/totalorderf.texi | 12 ++-- doc/posix-functions/totalorderl.texi | 12 ++-- lib/math.in.h | 76 ++++++++++++++++++++++++ lib/totalorder.c | 45 +++++++++++++++ lib/totalorderf.c | 45 +++++++++++++++ lib/totalorderl.c | 63 ++++++++++++++++++++ m4/math_h.m4 | 11 +++- m4/mathfunc.m4 | 11 ++-- m4/totalorder.m4 | 86 ++++++++++++++++++++++++++++ modules/math | 9 +++ modules/totalorder | 36 ++++++++++++ modules/totalorder-tests | 15 +++++ modules/totalorderf | 36 ++++++++++++ modules/totalorderf-tests | 16 ++++++ modules/totalorderl | 37 ++++++++++++ modules/totalorderl-tests | 16 ++++++ tests/test-totalorder.c | 57 ++++++++++++++++++ tests/test-totalorderf.c | 6 ++ tests/test-totalorderl.c | 6 ++ 21 files changed, 598 insertions(+), 24 deletions(-) create mode 100644 lib/totalorder.c create mode 100644 lib/totalorderf.c create mode 100644 lib/totalorderl.c create mode 100644 m4/totalorder.m4 create mode 100644 modules/totalorder create mode 100644 modules/totalorder-tests create mode 100644 modules/totalorderf create mode 100644 modules/totalorderf-tests create mode 100644 modules/totalorderl create mode 100644 modules/totalorderl-tests create mode 100644 tests/test-totalorder.c create mode 100644 tests/test-totalorderf.c create mode 100644 tests/test-totalorderl.c
diff --git a/ChangeLog b/ChangeLog index 463a44ffbb..19e1a21d72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2023-10-01 Paul Eggert <egg...@cs.ucla.edu> + + totalorder, totalorderf, totalorderl: new modules + * lib/math.in.h: Declare totalorderf, totalorder, totalorderl. + * lib/totalorder.c, lib/totalorderf.c, lib/totalorderl.c: + * m4/totalorder.m4, modules/totalorder, modules/totalorder-tests: + * modules/totalorderf, modules/totalorderf-tests: + * modules/totalorderl, modules/totalorderl-tests: + * tests/test-totalorder.c, tests/test-totalorderf.c: + * tests/test-totalorderl.c: New files. + * m4/math_h.m4 (gl_MATH_H, gl_MATH_H_REQUIRE_DEFAULTS) + (gl_MATH_H_DEFAULTS): + * modules/math (math.h): Set up totalorder, totalorderf, totalorderl. + * m4/mathfunc.m4 (gl_MATHFUNC): Also support pointer-to-const. + 2023-09-30 Paul Eggert <egg...@cs.ucla.edu> regex-quote: fix recently-introduced typo diff --git a/doc/posix-functions/totalorder.texi b/doc/posix-functions/totalorder.texi index 4687d9ba90..a7f8524718 100644 --- a/doc/posix-functions/totalorder.texi +++ b/doc/posix-functions/totalorder.texi @@ -10,18 +10,18 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/FP-Comparison-Functions.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: totalorder Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item -This function is missing on all non-glibc platforms: +This function is missing on many platforms: glibc 2.24, macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0. @item This function has a different signature on some platforms: glibc 2.30. @end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/doc/posix-functions/totalorderf.texi b/doc/posix-functions/totalorderf.texi index 4e3928c1d8..115fbfdf5b 100644 --- a/doc/posix-functions/totalorderf.texi +++ b/doc/posix-functions/totalorderf.texi @@ -10,18 +10,18 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/FP-Comparison-Functions.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: totalorderf Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item -This function is missing on all non-glibc platforms: +This function is missing on many platforms: glibc 2.24, macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0. @item This function has a different signature on some platforms: glibc 2.30. @end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/doc/posix-functions/totalorderl.texi b/doc/posix-functions/totalorderl.texi index 927597882e..cc07d0e080 100644 --- a/doc/posix-functions/totalorderl.texi +++ b/doc/posix-functions/totalorderl.texi @@ -10,18 +10,18 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/FP-Comparison-Functions.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: totalorderl Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item -This function is missing on all non-glibc platforms: +This function is missing on many platforms: glibc 2.24, macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0. @item This function has a different signature on some platforms: glibc 2.30. @end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/lib/math.in.h b/lib/math.in.h index 75d5013cf1..b18627ae0a 100644 --- a/lib/math.in.h +++ b/lib/math.in.h @@ -2761,6 +2761,82 @@ _GL_WARN_REAL_FLOATING_DECL (signbit); # endif #endif + +#if @GNULIB_TOTALORDERF@ +# if @REPLACE_TOTALORDERF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef totalorderf +# define totalorderf rpl_totalorderf +# endif +_GL_FUNCDECL_RPL (totalorderf, int, (float const *, float const *)); +_GL_CXXALIAS_RPL (totalorderf, int, (float const *, float const *)); +# else +# if !@HAVE_TOTALORDERF@ +_GL_FUNCDECL_SYS (totalorderf, int, (float const *, float const *)); +# endif +_GL_CXXALIAS_SYS (totalorderf, int, (float const *, float const *)); +# endif +_GL_CXXALIASWARN (totalorderf); +#elif defined GNULIB_POSIXCHECK +# undef totalorderf +# if HAVE_RAW_DECL_TOTALORDERF +_GL_WARN_ON_USE (totalorderf, "totalorderf is unportable - " + "use gnulib module totalorderf for portability"); +# endif +#endif + +#if @GNULIB_TOTALORDER@ +# if @REPLACE_TOTALORDER@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef totalorder +# define totalorder rpl_totalorder +# endif +_GL_FUNCDECL_RPL (totalorder, int, (double const *, double const *)); +_GL_CXXALIAS_RPL (totalorder, int, (double const *, double const *)); +# else +# if !@HAVE_TOTALORDER@ +_GL_FUNCDECL_SYS (totalorder, int, (double const *, double const *)); +# endif +_GL_CXXALIAS_SYS (totalorder, int, (double const *, double const *)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (totalorder, int, (double const *, double const *)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef totalorder +# if HAVE_RAW_DECL_TOTALORDER +_GL_WARN_ON_USE (totalorder, "totalorder is unportable - " + "use gnulib module totalorder for portability"); +# endif +#endif + +#if @GNULIB_TOTALORDERL@ +# if @REPLACE_TOTALORDERL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef totalorderl +# define totalorderl rpl_totalorderl +# endif +_GL_FUNCDECL_RPL (totalorderl, int, + (long double const *, long double const *)); +_GL_CXXALIAS_RPL (totalorderl, int, + (long double const *, long double const *)); +# else +# if !@HAVE_TOTALORDERL@ +_GL_FUNCDECL_SYS (totalorderl, int, + (long double const *, long double const *)); +# endif +_GL_CXXALIAS_SYS (totalorderl, int, + (long double const *, long double const *)); +# endif +_GL_CXXALIASWARN (totalorderl); +#elif defined GNULIB_POSIXCHECK +# undef totalorderl +# if HAVE_RAW_DECL_TOTALORDERL +_GL_WARN_ON_USE (totalorderl, "totalorderl is unportable - " + "use gnulib module totalorderl for portability"); +# endif +#endif + _GL_INLINE_HEADER_END #endif /* _@GUARD_PREFIX@_MATH_H */ diff --git a/lib/totalorder.c b/lib/totalorder.c new file mode 100644 index 0000000000..4c861f971c --- /dev/null +++ b/lib/totalorder.c @@ -0,0 +1,45 @@ +/* Total order for 'double' + Copyright 2023 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include <math.h> + +int +totalorder (double const *x, double const *y) +{ + /* Although the following is not strictly portable, and won't work + on some obsolete platforms (e.g., PA-RISC, MIPS before alignment + to IEEE 754-2008), it should be good enough nowadays. */ + int xs = signbit (*x); + int ys = signbit (*y); + if (!xs != !ys) + return xs; + int xn = isnand (*x); + int yn = isnand (*y); + if (!xn != !yn) + return !xn == !xs; + if (!xn) + return *x <= *y; + + unsigned long long extended_sign = -!!xs; + union { unsigned long long i; double f; } volatile xu = {0}, yu = {0}; + xu.f = *x; + yu.f = *y; + return (xu.i ^ extended_sign) <= (yu.i ^ extended_sign); +} diff --git a/lib/totalorderf.c b/lib/totalorderf.c new file mode 100644 index 0000000000..d86299ff09 --- /dev/null +++ b/lib/totalorderf.c @@ -0,0 +1,45 @@ +/* Total order for 'float' + Copyright 2023 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include <math.h> + +int +totalorderf (float const *x, float const *y) +{ + /* Although the following is not strictly portable, and won't work + on some obsolete platforms (e.g., PA-RISC, MIPS before alignment + to IEEE 754-2008), it should be good enough nowadays. */ + int xs = signbit (*x); + int ys = signbit (*y); + if (!xs != !ys) + return xs; + int xn = isnanf (*x); + int yn = isnanf (*y); + if (!xn != !yn) + return !xn == !xs; + if (!xn) + return *x <= *y; + + unsigned long extended_sign = -!!xs; + union { unsigned long i; float f; } volatile xu = {0}, yu = {0}; + xu.f = *x; + yu.f = *y; + return (xu.i ^ extended_sign) <= (yu.i ^ extended_sign); +} diff --git a/lib/totalorderl.c b/lib/totalorderl.c new file mode 100644 index 0000000000..03aba3adf7 --- /dev/null +++ b/lib/totalorderl.c @@ -0,0 +1,63 @@ +/* Total order for 'long double' + Copyright 2023 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include <math.h> + +int +totalorderl (long double const *x, long double const *y) +{ + /* Although the following is not strictly portable, and won't work + on some obsolete platforms (e.g., PA-RISC, MIPS before alignment + to IEEE 754-2008), it should be good enough nowadays. */ + int xs = signbit (*x); + int ys = signbit (*y); + if (!xs != !ys) + return xs; + int xn = isnanl (*x); + int yn = isnanl (*y); + if (!xn != !yn) + return !xn == !xs; + if (!xn) + return *x <= *y; + + unsigned long long extended_sign = -!!xs; + + if (sizeof (long double) <= sizeof (unsigned long long)) + { + union { unsigned long long i; long double f; } volatile + xu = {0}, yu = {0}; + xu.f = *x; + yu.f = *y; + return (xu.i ^ extended_sign) <= (yu.i ^ extended_sign); + } + + union { unsigned long long i[2]; long double f; } volatile + xu = {0}, yu = {0}, zu = {0}; + xu.f = *x; + yu.f = *y; + zu.f = -zu.f; + bool bigendian = !!zu.i[0]; + unsigned long long + xhi = xu.i[!bigendian] ^ extended_sign, + yhi = yu.i[!bigendian] ^ extended_sign, + xlo = xu.i[ bigendian] ^ extended_sign, + ylo = yu.i[ bigendian] ^ extended_sign; + return (xhi < yhi) | ((xhi == yhi) & (xlo <= ylo)); +} diff --git a/m4/math_h.m4 b/m4/math_h.m4 index c214f8efa8..008dd6fa3b 100644 --- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -50,7 +50,7 @@ AC_DEFUN_ONCE([gl_MATH_H], modf modff modfl powf remainder remainderf remainderl rint rintf rintl round roundf roundl sinf sinl sinhf sqrtf sqrtl - tanf tanl tanhf trunc truncf truncl]) + tanf tanl tanhf totalorder totalorderf totalorderl trunc truncf truncl]) ]) # gl_MATH_MODULE_INDICATOR([modulename]) @@ -165,6 +165,9 @@ AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TANF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TANL]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TANHF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TOTALORDER]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TOTALORDERF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TOTALORDERL]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNC]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNCF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNCL]) @@ -243,6 +246,9 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], HAVE_TANF=1; AC_SUBST([HAVE_TANF]) HAVE_TANL=1; AC_SUBST([HAVE_TANL]) HAVE_TANHF=1; AC_SUBST([HAVE_TANHF]) + HAVE_TOTALORDER=1; AC_SUBST([HAVE_TOTALORDER]) + HAVE_TOTALORDERF=1; AC_SUBST([HAVE_TOTALORDERF]) + HAVE_TOTALORDERL=1; AC_SUBST([HAVE_TOTALORDERL]) HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) @@ -356,6 +362,9 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], REPLACE_SQRTL=0; AC_SUBST([REPLACE_SQRTL]) REPLACE_TANF=0; AC_SUBST([REPLACE_TANF]) REPLACE_TANHF=0; AC_SUBST([REPLACE_TANHF]) + REPLACE_TOTALORDER=0; AC_SUBST([REPLACE_TOTALORDER]) + REPLACE_TOTALORDERF=0; AC_SUBST([REPLACE_TOTALORDERF]) + REPLACE_TOTALORDERL=0; AC_SUBST([REPLACE_TOTALORDERL]) REPLACE_TRUNC=0; AC_SUBST([REPLACE_TRUNC]) REPLACE_TRUNCF=0; AC_SUBST([REPLACE_TRUNCF]) REPLACE_TRUNCL=0; AC_SUBST([REPLACE_TRUNCL]) diff --git a/m4/mathfunc.m4 b/m4/mathfunc.m4 index 4cdd0a9001..00216ceae6 100644 --- a/m4/mathfunc.m4 +++ b/m4/mathfunc.m4 @@ -1,4 +1,4 @@ -# mathfunc.m4 serial 12 +# mathfunc.m4 serial 13 dnl Copyright (C) 2010-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -40,10 +40,11 @@ AC_DEFUN([gl_MATHFUNC], [m4_bpatsubst( [m4_bpatsubst( [$3], - [int \*], [&i_ret])], - [float \*], [&f_ret])], - [double \*], [&d_ret])], - [long double \*], [&l_ret])], + [int\( const\)? \*], + [&i_ret])], + [float\( const\)? \*], [&f_ret])], + [double\( const\)? \*], [&d_ret])], + [long double\( const\)? \*], [&l_ret])], [int], [2])], [float], [1.618034f])], [long double], [1.618033988749894848L])], diff --git a/m4/totalorder.m4 b/m4/totalorder.m4 new file mode 100644 index 0000000000..4d065dc0eb --- /dev/null +++ b/m4/totalorder.m4 @@ -0,0 +1,86 @@ +# totalorder.m4 +dnl Copyright 2023 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_TOTALORDERF], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + gl_MATHFUNC([totalorderf], [int], + [(float const *, float const *)], + [extern + #ifdef __cplusplus + "C" + #endif + int totalorderf (float const *, float const *); + ]) + AS_IF([test $gl_cv_func_totalorderf_no_libm != yes && + test $gl_cv_func_totalorderf_in_libm != yes], + [gl_saved_LIBS=$LIBS + AC_SEARCH_LIBS([totalorderf], [m]) + LIBS=$gl_saved_LIBS + if test "$ac_cv_search_totalorderf" = no; then + HAVE_TOTALORDERF=0 + else + REPLACE_TOTALORDERF=1 + fi + TOTALORDER_LIBM='$(ISNANF_LIBM)']) + AC_SUBST([TOTALORDERF_LIBM]) +]) + +AC_DEFUN([gl_FUNC_TOTALORDER], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + gl_MATHFUNC([totalorder], [int], + [(double const *, double const *)], + [extern + #ifdef __cplusplus + "C" + #endif + int totalorder (double const *, double const *); + ]) + AS_IF([test $gl_cv_func_totalorder_no_libm != yes && + test $gl_cv_func_totalorder_in_libm != yes], + [gl_saved_LIBS=$LIBS + AC_SEARCH_LIBS([totalorder], [m]) + LIBS=$gl_saved_LIBS + if test "$ac_cv_search_totalorder" = no; then + HAVE_TOTALORDER=0 + else + REPLACE_TOTALORDER=1 + fi + TOTALORDER_LIBM='$(ISNAND_LIBM)']) + AC_SUBST([TOTALORDER_LIBM]) +]) + +AC_DEFUN([gl_FUNC_TOTALORDERL], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + gl_MATHFUNC([totalorderl], [int], + [(long double const *, long double const *)], + [extern + #ifdef __cplusplus + "C" + #endif + int totalorderl (long double const *, long double const *); + ]) + AS_IF([test $gl_cv_func_totalorderl_no_libm != yes && + test $gl_cv_func_totalorderl_in_libm != yes], + [gl_saved_LIBS=$LIBS + AC_SEARCH_LIBS([totalorderl], [m]) + LIBS=$gl_saved_LIBS + if test "$ac_cv_search_totalorderl" = no; then + HAVE_TOTALORDERL=0 + else + REPLACE_TOTALORDERL=1 + fi + TOTALORDERL_LIBM='$(ISNANL_LIBM)']) + AC_SUBST([TOTALORDERL_LIBM]) +]) diff --git a/modules/math b/modules/math index f107141533..f816d64cd2 100644 --- a/modules/math +++ b/modules/math @@ -132,6 +132,9 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_TRUNC''@/$(GNULIB_TRUNC)/g' \ -e 's/@''GNULIB_TRUNCF''@/$(GNULIB_TRUNCF)/g' \ -e 's/@''GNULIB_TRUNCL''@/$(GNULIB_TRUNCL)/g' \ + -e 's/@''GNULIB_TOTALORDER''@/$(GNULIB_TOTALORDER)/g' \ + -e 's/@''GNULIB_TOTALORDERF''@/$(GNULIB_TOTALORDERF)/g' \ + -e 's/@''GNULIB_TOTALORDERL''@/$(GNULIB_TOTALORDERL)/g' \ -e 's/@''GNULIB_MDA_J0''@/$(GNULIB_MDA_J0)/g' \ -e 's/@''GNULIB_MDA_J1''@/$(GNULIB_MDA_J1)/g' \ -e 's/@''GNULIB_MDA_JN''@/$(GNULIB_MDA_JN)/g' \ @@ -200,6 +203,9 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_TANF''@|$(HAVE_TANF)|g' \ -e 's|@''HAVE_TANL''@|$(HAVE_TANL)|g' \ -e 's|@''HAVE_TANHF''@|$(HAVE_TANHF)|g' \ + -e 's|@''HAVE_TOTALORDER''@|$(HAVE_TOTALORDER)|g' \ + -e 's|@''HAVE_TOTALORDERF''@|$(HAVE_TOTALORDERF)|g' \ + -e 's|@''HAVE_TOTALORDERL''@|$(HAVE_TOTALORDERL)|g' \ < $@-t2 > $@-t3 $(AM_V_at)sed \ -e 's|@''HAVE_DECL_ACOSL''@|$(HAVE_DECL_ACOSL)|g' \ @@ -320,6 +326,9 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''REPLACE_SQRTL''@|$(REPLACE_SQRTL)|g' \ -e 's|@''REPLACE_TANF''@|$(REPLACE_TANF)|g' \ -e 's|@''REPLACE_TANHF''@|$(REPLACE_TANHF)|g' \ + -e 's|@''REPLACE_TOTALORDER''@|$(REPLACE_TOTALORDER)|g' \ + -e 's|@''REPLACE_TOTALORDERF''@|$(REPLACE_TOTALORDERF)|g' \ + -e 's|@''REPLACE_TOTALORDERL''@|$(REPLACE_TOTALORDERL)|g' \ -e 's|@''REPLACE_TRUNC''@|$(REPLACE_TRUNC)|g' \ -e 's|@''REPLACE_TRUNCF''@|$(REPLACE_TRUNCF)|g' \ -e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|g' \ diff --git a/modules/totalorder b/modules/totalorder new file mode 100644 index 0000000000..c74fa383b2 --- /dev/null +++ b/modules/totalorder @@ -0,0 +1,36 @@ +Description: +totalorder function: total order on float + +Files: +lib/totalorder.c +m4/mathfunc.m4 +m4/totalorder.m4 + +Depends-on: +math +extensions +isnand [test $HAVE_TOTALORDER = 0 || test $REPLACE_TOTALORDER = 0] +signbit [test $HAVE_TOTALORDER = 0 || test $REPLACE_TOTALORDER = 0] + +configure.ac: +gl_FUNC_TOTALORDER +gl_CONDITIONAL([GL_COND_OBJ_TOTALORDER], + [test $HAVE_TOTALORDER = 0 || test $REPLACE_TOTALORDER = 1]) +gl_MATH_MODULE_INDICATOR([totalorder]) + +Makefile.am: +if GL_COND_OBJ_TOTALORDER +lib_SOURCES += totalorder.c +endif + +Include: +<math.h> + +Link: +$(TOTALORDER_LIBM) + +License: +LGPL + +Maintainer: +all diff --git a/modules/totalorder-tests b/modules/totalorder-tests new file mode 100644 index 0000000000..fbcfb11a99 --- /dev/null +++ b/modules/totalorder-tests @@ -0,0 +1,15 @@ +Files: +tests/test-totalorder.c +tests/minus-zero.h +tests/infinity.h +tests/nan.h +tests/macros.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-totalorder +check_PROGRAMS += test-totalorder +test_totalorder_LDADD = $(LDADD) @TOTALORDER_LIBM@ diff --git a/modules/totalorderf b/modules/totalorderf new file mode 100644 index 0000000000..b3fb5d99e2 --- /dev/null +++ b/modules/totalorderf @@ -0,0 +1,36 @@ +Description: +totalorderf function: total order on float + +Files: +lib/totalorderf.c +m4/mathfunc.m4 +m4/totalorder.m4 + +Depends-on: +math +extensions +isnanf [test $HAVE_TOTALORDERF = 0 || test $REPLACE_TOTALORDERF = 0] +signbit [test $HAVE_TOTALORDERF = 0 || test $REPLACE_TOTALORDERF = 0] + +configure.ac: +gl_FUNC_TOTALORDERF +gl_CONDITIONAL([GL_COND_OBJ_TOTALORDERF], + [test $HAVE_TOTALORDERF = 0 || test $REPLACE_TOTALORDERF = 1]) +gl_MATH_MODULE_INDICATOR([totalorderf]) + +Makefile.am: +if GL_COND_OBJ_TOTALORDERF +lib_SOURCES += totalorderf.c +endif + +Include: +<math.h> + +Link: +$(TOTALORDERF_LIBM) + +License: +LGPL + +Maintainer: +all diff --git a/modules/totalorderf-tests b/modules/totalorderf-tests new file mode 100644 index 0000000000..e76c9fda38 --- /dev/null +++ b/modules/totalorderf-tests @@ -0,0 +1,16 @@ +Files: +tests/test-totalorderf.c +tests/test-totalorder.c +tests/minus-zero.h +tests/infinity.h +tests/nan.h +tests/macros.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-totalorderf +check_PROGRAMS += test-totalorderf +test_totalorderf_LDADD = $(LDADD) @TOTALORDERF_LIBM@ diff --git a/modules/totalorderl b/modules/totalorderl new file mode 100644 index 0000000000..407b243bb3 --- /dev/null +++ b/modules/totalorderl @@ -0,0 +1,37 @@ +Description: +totalorderl function: total order on long double + +Files: +lib/totalorderl.c +m4/mathfunc.m4 +m4/totalorder.m4 + +Depends-on: +math +extensions +stdbool [test $HAVE_TOTALORDERL = 0 || test $REPLACE_TOTALORDERL = 0] +isnanl [test $HAVE_TOTALORDERL = 0 || test $REPLACE_TOTALORDERL = 0] +signbit [test $HAVE_TOTALORDERL = 0 || test $REPLACE_TOTALORDERL = 0] + +configure.ac: +gl_FUNC_TOTALORDERL +gl_CONDITIONAL([GL_COND_OBJ_TOTALORDERL], + [test $HAVE_TOTALORDERL = 0 || test $REPLACE_TOTALORDERL = 1]) +gl_MATH_MODULE_INDICATOR([totalorderl]) + +Makefile.am: +if GL_COND_OBJ_TOTALORDERL +lib_SOURCES += totalorderl.c +endif + +Include: +<math.h> + +Link: +$(TOTALORDERL_LIBM) + +License: +LGPL + +Maintainer: +all diff --git a/modules/totalorderl-tests b/modules/totalorderl-tests new file mode 100644 index 0000000000..cfc50e21e9 --- /dev/null +++ b/modules/totalorderl-tests @@ -0,0 +1,16 @@ +Files: +tests/test-totalorderl.c +tests/test-totalorder.c +tests/minus-zero.h +tests/infinity.h +tests/nan.h +tests/macros.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-totalorderl +check_PROGRAMS += test-totalorderl +test_totalorderl_LDADD = $(LDADD) @TOTALORDERL_LIBM@ diff --git a/tests/test-totalorder.c b/tests/test-totalorder.c new file mode 100644 index 0000000000..1fc1b84568 --- /dev/null +++ b/tests/test-totalorder.c @@ -0,0 +1,57 @@ +/* Test totalorder. + Copyright 2023 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <math.h> + +#include "infinity.h" +#include "macros.h" +#include "minus-zero.h" +#include "nan.h" + +#ifndef TOTALORDER +# define TOTALORDER totalorder +# define TOTALORDER_INF Infinityd +# define TOTALORDER_MINUS_ZERO minus_zerod +# define TOTALORDER_NAN NaNd +# define TOTALORDER_TYPE double +#endif + +int +main () +{ + TOTALORDER_TYPE x[] = + { + -TOTALORDER_NAN (), -TOTALORDER_INF (), -1e37, -1, -1e-5, + TOTALORDER_MINUS_ZERO, 0, + 1e-5, 1, 1e37, TOTALORDER_INF (), TOTALORDER_NAN () + }; + int n = sizeof x / sizeof *x; + + /* TOTALORDER_NAN () yields a NaN of unknown sign, so fix the + first NaN to be negative and the last NaN to be nonnegative. + Do this via volatile accesses, to work around GCC bug 111655. */ + TOTALORDER_TYPE volatile a = x[0], z = x[n - 1]; + if (! signbit (a)) a = -a; + if ( signbit (z)) z = -z; + x[0] = a, x[n - 1] = z; + + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + ASSERT (!!TOTALORDER (&x[i], &x[j]) == (i <= j)); + return 0; +} diff --git a/tests/test-totalorderf.c b/tests/test-totalorderf.c new file mode 100644 index 0000000000..2dcb47aca4 --- /dev/null +++ b/tests/test-totalorderf.c @@ -0,0 +1,6 @@ +#define TOTALORDER totalorderf +#define TOTALORDER_INF Infinityf +#define TOTALORDER_MINUS_ZERO minus_zerof +#define TOTALORDER_NAN NaNf +#define TOTALORDER_TYPE float +#include "test-totalorder.c" diff --git a/tests/test-totalorderl.c b/tests/test-totalorderl.c new file mode 100644 index 0000000000..ac454ad848 --- /dev/null +++ b/tests/test-totalorderl.c @@ -0,0 +1,6 @@ +#define TOTALORDER totalorderl +#define TOTALORDER_INF Infinityl +#define TOTALORDER_MINUS_ZERO minus_zerol +#define TOTALORDER_NAN NaNl +#define TOTALORDER_TYPE long double +#include "test-totalorder.c" -- 2.41.0