This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Perl_isinf and Perl_isfinite enhancements.
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 54f6dca..bc4209f 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1677,7 +1677,8 @@ typedef UVTYPE UV;
 #  endif
 #endif
 
-#define SSize_t_MAX (SSize_t)(~(size_t)0 >> 1)
+#define Size_t_MAX (~(Size_t)0)
+#define SSize_t_MAX (SSize_t)(~(Size_t)0 >> 1)
 
 #define IV_DIG (BIT_DIGITS(IVSIZE * 8))
 #define UV_DIG (BIT_DIGITS(UVSIZE * 8))
@@ -1847,6 +1848,12 @@ typedef NVTYPE NV;
 #   ifdef LDBL_MAX
 #       define NV_MAX LDBL_MAX
 #   endif
+#   ifdef LDBL_MIN_EXP
+#       define NV_MIN_EXP LDBL_MIN_EXP
+#   endif
+#   ifdef LDBL_MAX_EXP
+#       define NV_MAX_EXP LDBL_MAX_EXP
+#   endif
 #   ifdef LDBL_MIN_10_EXP
 #       define NV_MIN_10_EXP LDBL_MIN_10_EXP
 #   endif
@@ -1902,16 +1909,30 @@ EXTERN_C long double modfl(long double, long double *);
 #           define Perl_frexp(x,y) Perl_my_frexpl(x,y)
 #       endif
 #   endif
+#   ifdef HAS_LDEXPL
+#       define Perl_ldexp(x, y) ldexpl(x,y)
+#   else
+#       if defined(HAS_SCALBNL) && FLT_RADIX == 2
+#           define Perl_ldexp(x,y) scalbnl(x,y)
+#       endif
+#   endif
 #   ifndef Perl_isnan
 #       ifdef HAS_ISNANL
 #           define Perl_isnan(x) isnanl(x)
 #       endif
 #   endif
 #   ifndef Perl_isinf
-#       ifdef HAS_FINITEL
-#           define Perl_isinf(x) !(finitel(x)||Perl_isnan(x))
+#       if defined(HAS_ISINFL)
+#           define Perl_isinf(x) isinfl(x)
 #       endif
 #   endif
+#   ifndef Perl_isfinite
+#     ifdef HAS_ISFINITEL
+#       define Perl_isfinite(x) isfinitel(x)
+#     elif defined(HAS_FINITEL)
+#       define Perl_isfinite(x) finitel(x)
+#     endif
+#   endif
 #else
 #   define NV_DIG DBL_DIG
 #   ifdef DBL_MANT_DIG
@@ -1923,6 +1944,12 @@ EXTERN_C long double modfl(long double, long double *);
 #   ifdef DBL_MAX
 #       define NV_MAX DBL_MAX
 #   endif
+#   ifdef DBL_MIN_EXP
+#       define NV_MIN_EXP DBL_MIN_EXP
+#   endif
+#   ifdef DBL_MAX_EXP
+#       define NV_MAX_EXP DBL_MAX_EXP
+#   endif
 #   ifdef DBL_MIN_10_EXP
 #       define NV_MIN_10_EXP DBL_MIN_10_EXP
 #   endif
@@ -1952,18 +1979,18 @@ EXTERN_C long double modfl(long double, long double *);
 #   define Perl_fmod fmod
 #   define Perl_modf(x,y) modf(x,y)
 #   define Perl_frexp(x,y) frexp(x,y)
+#   define Perl_ldexp(x,y) ldexp(x,y)
 #endif
 
-/* rumor has it that Win32 has _fpclass() */
-
-/* SGI has fpclassl... but not with the same result values,
- * and it's via a typedef (not via #define), so will need to redo Configure
- * to use. Not worth the trouble, IMO, at least until the below is used
- * more places. Also has fp_class_l, BTW, via fp_class.h. Feel free to check
- * with me for the SGI manpages, SGI testing, etcetera, if you want to
- * try getting this to work with IRIX. - Allen <allens@cpan.org> */
+/* Solaris and IRIX have fpclass/fpclassl, but they are using
+ * an enum typedef, not cpp symbols, and Configure doesn't detect that.
+ * Define one symbol also as a cpp symbol so we can detect it. */
+#if defined(__sun) || defined(__irix__) /* XXX Configure test instead */
+# define FP_SNAN FP_SNAN
+#endif
 
 #if !defined(Perl_fp_class) && (defined(HAS_FPCLASS)||defined(HAS_FPCLASSL))
+#    include <math.h>
 #    ifdef I_IEEFP
 #        include <ieeefp.h>
 #    endif
@@ -1971,55 +1998,72 @@ EXTERN_C long double modfl(long double, long double *);
 #        include <fp.h>
 #    endif
 #    if defined(USE_LONG_DOUBLE) && defined(HAS_FPCLASSL)
-#        define Perl_fp_class()                fpclassl(x)
+#        define Perl_fp_class(x)       fpclassl(x)
 #    else
-#        define Perl_fp_class()                fpclass(x)
+#        define Perl_fp_class(x)       fpclass(x)
+#    endif
+#    ifdef FP_CLASS_SNAN
+#        define Perl_fp_class_snan(x)  (Perl_fp_class(x)==FP_CLASS_SNAN)
+#        define Perl_fp_class_qnan(x)  (Perl_fp_class(x)==FP_CLASS_QNAN)
+#        define Perl_fp_class_ninf(x)  (Perl_fp_class(x)==FP_CLASS_NINF)
+#        define Perl_fp_class_pinf(x)  (Perl_fp_class(x)==FP_CLASS_PINF)
+#        define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_CLASS_NNORM)
+#        define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_CLASS_PNORM)
+#        define Perl_fp_class_ndenorm(x)       (Perl_fp_class(x)==FP_CLASS_NDENORM)
+#        define Perl_fp_class_pdenorm(x)       (Perl_fp_class(x)==FP_CLASS_PDENORM)
+#        define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_CLASS_NZERO)
+#        define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_CLASS_PZERO)
+#    elif defined(FP_SNAN)
+#        define Perl_fp_class_snan(x)  (Perl_fp_class(x)==FP_SNAN)
+#        define Perl_fp_class_qnan(x)  (Perl_fp_class(x)==FP_QNAN)
+#        define Perl_fp_class_ninf(x)  (Perl_fp_class(x)==FP_NINF)
+#        define Perl_fp_class_pinf(x)  (Perl_fp_class(x)==FP_PINF)
+#        define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_NNORM)
+#        define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_PNORM)
+#        define Perl_fp_class_ndenorm(x)       (Perl_fp_class(x)==FP_NDENORM)
+#        define Perl_fp_class_pdenorm(x)       (Perl_fp_class(x)==FP_PDENORM)
+#        define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_NZERO)
+#        define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_PZERO)
 #    endif
-#    define Perl_fp_class_snan(x)      (Perl_fp_class(x)==FP_CLASS_SNAN)
-#    define Perl_fp_class_qnan(x)      (Perl_fp_class(x)==FP_CLASS_QNAN)
-#    define Perl_fp_class_nan(x)       (Perl_fp_class(x)==FP_CLASS_SNAN||Perl_fp_class(x)==FP_CLASS_QNAN)
-#    define Perl_fp_class_ninf(x)      (Perl_fp_class(x)==FP_CLASS_NINF)
-#    define Perl_fp_class_pinf(x)      (Perl_fp_class(x)==FP_CLASS_PINF)
-#    define Perl_fp_class_inf(x)       (Perl_fp_class(x)==FP_CLASS_NINF||Perl_fp_class(x)==FP_CLASS_PINF)
-#    define Perl_fp_class_nnorm(x)     (Perl_fp_class(x)==FP_CLASS_NNORM)
-#    define Perl_fp_class_pnorm(x)     (Perl_fp_class(x)==FP_CLASS_PNORM)
-#    define Perl_fp_class_norm(x)      (Perl_fp_class(x)==FP_CLASS_NNORM||Perl_fp_class(x)==FP_CLASS_PNORM)
-#    define Perl_fp_class_ndenorm(x)   (Perl_fp_class(x)==FP_CLASS_NDENORM)
-#    define Perl_fp_class_pdenorm(x)   (Perl_fp_class(x)==FP_CLASS_PDENORM)
-#    define Perl_fp_class_denorm(x)    (Perl_fp_class(x)==FP_CLASS_NDENORM||Perl_fp_class(x)==FP_CLASS_PDENORM)
-#    define Perl_fp_class_nzero(x)     (Perl_fp_class(x)==FP_CLASS_NZERO)
-#    define Perl_fp_class_pzero(x)     (Perl_fp_class(x)==FP_CLASS_PZERO)
-#    define Perl_fp_class_zero(x)      (Perl_fp_class(x)==FP_CLASS_NZERO||Perl_fp_class(x)==FP_CLASS_PZERO)
 #endif
 
+/* Feel free to check with me for the SGI manpages, SGI testing,
+ * etcetera, if you want to try getting this to work with IRIX.
+ *
+ * - Allen <allens@cpan.org> */
+
 #if !defined(Perl_fp_class) && defined(HAS_FP_CLASS)
 #    include <math.h>
 #    if !defined(FP_SNAN) && defined(I_FP_CLASS)
 #        include <fp_class.h>
 #    endif
-#    define Perl_fp_class(x)           fp_class(x)
+#    ifdef __irix__ /* XXX Configure test instead */
+#        ifdef USE_LONG_DOUBLE
+#            define Perl_fp_class(x)   fp_class_l(x)
+#        else
+#            define Perl_fp_class(x)   fp_class_d(x)
+#        endif
+#    else
+#        define Perl_fp_class(x)       fp_class(x)
+#    endif
 #    define Perl_fp_class_snan(x)      (fp_class(x)==FP_SNAN)
 #    define Perl_fp_class_qnan(x)      (fp_class(x)==FP_QNAN)
-#    define Perl_fp_class_nan(x)       (fp_class(x)==FP_SNAN||fp_class(x)==FP_QNAN)
 #    define Perl_fp_class_ninf(x)      (fp_class(x)==FP_NEG_INF)
 #    define Perl_fp_class_pinf(x)      (fp_class(x)==FP_POS_INF)
-#    define Perl_fp_class_inf(x)       (fp_class(x)==FP_NEG_INF||fp_class(x)==FP_POS_INF)
 #    define Perl_fp_class_nnorm(x)     (fp_class(x)==FP_NEG_NORM)
 #    define Perl_fp_class_pnorm(x)     (fp_class(x)==FP_POS_NORM)
-#    define Perl_fp_class_norm(x)      (fp_class(x)==FP_NEG_NORM||fp_class(x)==FP_POS_NORM)
 #    define Perl_fp_class_ndenorm(x)   (fp_class(x)==FP_NEG_DENORM)
 #    define Perl_fp_class_pdenorm(x)   (fp_class(x)==FP_POS_DENORM)
-#    define Perl_fp_class_denorm(x)    (fp_class(x)==FP_NEG_DENORM||fp_class(x)==FP_POS_DENORM)
 #    define Perl_fp_class_nzero(x)     (fp_class(x)==FP_NEG_ZERO)
 #    define Perl_fp_class_pzero(x)     (fp_class(x)==FP_POS_ZERO)
-#    define Perl_fp_class_zero(x)      (fp_class(x)==FP_NEG_ZERO||fp_class(x)==FP_POS_ZERO)
 #endif
 
 #if !defined(Perl_fp_class) && defined(HAS_FPCLASSIFY)
 #    include <math.h>
 #    define Perl_fp_class(x)           fpclassify(x)
-#    define Perl_fp_class_nan(x)       (fp_classify(x)==FP_SNAN||fp_classify(x)==FP_QNAN)
 #    define Perl_fp_class_inf(x)       (fp_classify(x)==FP_INFINITE)
+#    define Perl_fp_class_snan(x)      (fp_classify(x)==FP_SNAN)
+#    define Perl_fp_class_qnan(x)      (fp_classify(x)==FP_QNAN)
 #    define Perl_fp_class_norm(x)      (fp_classify(x)==FP_NORMAL)
 #    define Perl_fp_class_denorm(x)    (fp_classify(x)==FP_SUBNORMAL)
 #    define Perl_fp_class_zero(x)      (fp_classify(x)==FP_ZERO)
@@ -2034,26 +2078,75 @@ EXTERN_C long double modfl(long double, long double *);
 #    endif
 #    define Perl_fp_class_snan(x)      (Perl_fp_class(x)==FP_NANS)
 #    define Perl_fp_class_qnan(x)      (Perl_fp_class(x)==FP_NANQ)
-#    define Perl_fp_class_nan(x)       (Perl_fp_class(x)==FP_SNAN||Perl_fp_class(x)==FP_QNAN)
 #    define Perl_fp_class_ninf(x)      (Perl_fp_class(x)==FP_MINUS_INF)
 #    define Perl_fp_class_pinf(x)      (Perl_fp_class(x)==FP_PLUS_INF)
-#    define Perl_fp_class_inf(x)       (Perl_fp_class(x)==FP_MINUS_INF||Perl_fp_class(x)==FP_PLUS_INF)
 #    define Perl_fp_class_nnorm(x)     (Perl_fp_class(x)==FP_MINUS_NORM)
 #    define Perl_fp_class_pnorm(x)     (Perl_fp_class(x)==FP_PLUS_NORM)
-#    define Perl_fp_class_norm(x)      (Perl_fp_class(x)==FP_MINUS_NORM||Perl_fp_class(x)==FP_PLUS_NORM)
 #    define Perl_fp_class_ndenorm(x)   (Perl_fp_class(x)==FP_MINUS_DENORM)
 #    define Perl_fp_class_pdenorm(x)   (Perl_fp_class(x)==FP_PLUS_DENORM)
-#    define Perl_fp_class_denorm(x)    (Perl_fp_class(x)==FP_MINUS_DENORM||Perl_fp_class(x)==FP_PLUS_DENORM)
 #    define Perl_fp_class_nzero(x)     (Perl_fp_class(x)==FP_MINUS_ZERO)
 #    define Perl_fp_class_pzero(x)     (Perl_fp_class(x)==FP_PLUS_ZERO)
-#    define Perl_fp_class_zero(x)      (Perl_fp_class(x)==FP_MINUS_ZERO||Perl_fp_class(x)==FP_PLUS_ZERO)
 #endif
 
-/* rumor has it that Win32 has _isnan() */
+#ifdef WIN32
+#  ifndef Perl_isnan
+#    define Perl_isnan(x) _isnan(x)
+#  endif
+#  ifndef Perl_isfinite
+#    define Perl_isfinite(x) _finite(x)
+#  endif
+#  ifndef Perl_fp_class_snan
+#    define Perl_fp_class_snan(x) (_fpclass(x) & _FPCLASS_SNAN)
+#    define Perl_fp_class_qnan(x) (_fpclass(x) & _FPCLASS_QNAN)
+#    define Perl_fp_class_nan(x) (_fpclass(x) & (_FPCLASS_QNAN|_FPCLASS_QNAN))
+#    define Perl_fp_class_ninf(x) (_fpclass(x) & _FPCLASS_NINF))
+#    define Perl_fp_class_pinf(x) (_fpclass(x) & _FPCLASS_PINF))
+#    define Perl_fp_class_inf(x) (_fpclass(x) & (_FPCLASS_NINF|_FPCLASS_PINF))
+#    define Perl_fp_class_nnorm(x) (_fpclass(x) & _FPCLASS_NN)
+#    define Perl_fp_class_pnorm(x) (_fpclass(x) & _FPCLASS_PN)
+#    define Perl_fp_class_norm(x) (_fpclass(x) & (_FPCLASS_NN|_FPCLASS_PN))
+#    define Perl_fp_class_ndenorm(x) (_fpclass(x) & _FPCLASS_ND)
+#    define Perl_fp_class_pdenorm(x) (_fpclass(x) & _FPCLASS_PD)
+#    define Perl_fp_class_denorm(x) (_fpclass(x) & (_FPCLASS_ND|_FPCLASS_PD))
+#    define Perl_fp_class_nzero(x) (_fpclass(x) & _FPCLASS_NZ)
+#    define Perl_fp_class_pzero(x) (_fpclass(x) & _FPCLASS_PZ)
+#    define Perl_fp_class_zero(x) (_fpclass(x) & (_FPCLASS_NZ|_FPCLASS_PZ))
+#  endif
+#endif
+
+#if !defined(Perl_fp_class_inf) && \
+  defined(Perl_fp_class_pinf) && defined(Perl_fp_class_ninf)
+#  define Perl_fp_class_inf(x) \
+    (Perl_fp_class_pinf(x) || Perl_fp_class_ninf(x))
+#endif
+
+#if !defined(Perl_fp_class_nan) && \
+  defined(Perl_fp_class_snan) && defined(Perl_fp_class_qnan)
+#  define Perl_fp_class_nan(x) \
+    (Perl_fp_class_snan(x) || Perl_fp_class_qnan(x))
+#endif
+
+#if !defined(Perl_fp_class_zero) && \
+  defined(Perl_fp_class_pzero) && defined(Perl_fp_class_nzero)
+#  define Perl_fp_class_zero(x) \
+    (Perl_fp_class_pzero(x) || Perl_fp_class_nzero(x))
+#endif
+
+#if !defined(Perl_fp_class_norm) && \
+  defined(Perl_fp_class_pnorm) && defined(Perl_fp_class_nnorm)
+#  define Perl_fp_class_norm(x) \
+    (Perl_fp_class_pnorm(x) || Perl_fp_class_nnorm(x))
+#endif
+
+#if !defined(Perl_fp_class_denorm) && \
+  defined(Perl_fp_class_pdenorm) && defined(Perl_fp_class_ndenorm)
+#  define Perl_fp_class_denorm(x) \
+    (Perl_fp_class_pdenorm(x) || Perl_fp_class_ndenorm(x))
+#endif
 
 #ifndef Perl_isnan
 #   ifdef HAS_ISNAN
-#       define Perl_isnan(x) isnan((NV)x)
+#       define Perl_isnan(x) isnan((double)x)
 #   else
 #       ifdef Perl_fp_class_nan
 #           define Perl_isnan(x) Perl_fp_class_nan(x)
@@ -2071,31 +2164,24 @@ EXTERN_C long double modfl(long double, long double *);
 int isnan(double d);
 #endif
 
-#ifndef Perl_isinf
-#   ifdef HAS_ISINF
-#       define Perl_isinf(x) isinf((NV)x)
+#ifndef Perl_isfinite
+#   ifdef HAS_ISFINITE
+#     define Perl_isfinite(x) isfinite((double)x)
+#   elif defined(HAS_FINITE)
+#       define Perl_isfinite(x) finite((double)x)
+#   elif defined(Perl_fp_class_finite)
+#     define Perl_isfinite(x) Perl_fp_class_finite(x)
+#   elif defined(Perl_is_inf) && defined(Perl_is_nan)
+#     define Perl_isfinite(x) !(Perl_is_inf(x)||Perl_is_nan(x))
 #   else
-#       ifdef Perl_fp_class_inf
-#           define Perl_isinf(x) Perl_fp_class_inf(x)
-#       else
-#           define Perl_isinf(x) ((x)==NV_INF)
-#       endif
+/* NaN*0 is NaN, [+-]Inf*0 is NaN, zero for anything else. */
+#     define Perl_isfinite(x) (((x) * 0) == 0)
 #   endif
 #endif
 
-#ifndef Perl_isfinite
-#   ifdef HAS_FINITE
-#       define Perl_isfinite(x) finite((NV)x)
-#   else
-#       ifdef HAS_ISFINITE
-#           define Perl_isfinite(x) isfinite(x)
-#       else
-#           ifdef Perl_fp_class_finite
-#               define Perl_isfinite(x) Perl_fp_class_finite(x)
-#           else
-#               define Perl_isfinite(x) !(Perl_is_inf(x)||Perl_is_nan(x))
-#           endif
-#       endif
+#ifndef Perl_isinf
+#   if defined(Perl_isfinite) && defined(Perl_isnan)
+#       define Perl_isinf(x) !(Perl_isfinite(x)||Perl_isnan(x))
 #   endif
 #endif
 
@@ -4642,6 +4728,9 @@ EXTCONST char PL_bincompat_options[] =
 #  ifdef PERL_GLOBAL_STRUCT
                             " PERL_GLOBAL_STRUCT"
 #  endif
+#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+                            " PERL_GLOBAL_STRUCT_PRIVATE"
+#  endif
 #  ifdef PERL_IMPLICIT_CONTEXT
                             " PERL_IMPLICIT_CONTEXT"
 #  endif
@@ -4793,6 +4882,7 @@ typedef enum {
     XATTRBLOCK,
     XATTRTERM,
     XTERMBLOCK,
+    XBLOCKTERM,
     XPOSTDEREF,
     XTERMORDORDOR /* evil hack */
     /* update exp_name[] in toke.c if adding to this enum */