stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From far...@apache.org
Subject svn commit: r646396 - /stdcxx/trunk/src/num_put.cpp
Date Wed, 09 Apr 2008 15:10:29 GMT
Author: faridz
Date: Wed Apr  9 08:10:18 2008
New Revision: 646396

URL: http://svn.apache.org/viewvc?rev=646396&view=rev
Log:
2008-04-09  Farid Zaripov  <farid_zaripov@epam.com>

	STDCXX-51
	* src/num_put.cpp (__rw_isfinite): New function to detect inf and nan values.
	(__rw_signbit): New function to detect the sign of floating point value.
	(__rw_isinf): New function to detect inf values.
	(__rw_isnan): New function to detect nan values.
	(__rw_isqnan): New function to detect quiet nan values.
	(__rw_issnan): New function to detect signaling nan values.
	(__rw_fmat_infinite): New function to format inf and nan values.
	(__rw_put_num): Use __rw_isfinite() and __rw_fmat_infinite() to format inf and nan values.

Modified:
    stdcxx/trunk/src/num_put.cpp

Modified: stdcxx/trunk/src/num_put.cpp
URL: http://svn.apache.org/viewvc/stdcxx/trunk/src/num_put.cpp?rev=646396&r1=646395&r2=646396&view=diff
==============================================================================
--- stdcxx/trunk/src/num_put.cpp (original)
+++ stdcxx/trunk/src/num_put.cpp Wed Apr  9 08:10:18 2008
@@ -34,6 +34,13 @@
 #include <stdio.h>    // for snprintf()
 #include <string.h>   // for memmove(), memset()
 
+#include <float.h>   // for _finite(), _fpclass(), _isnan(), _copysign()
+#include <math.h>    // for isfinite(), isnan(), isinf(), signbit()
+
+#ifndef _RWSTD_NO_IEEEFP_H
+#  include <ieeefp.h>   // for fpclass(), isnan()
+#endif   // _RWSTD_NO_IEEEFP_H
+
 #include <loc/_num_put.h>
 
 #include "strtol.h"   // for __rw_digit_map
@@ -65,6 +72,7 @@
 #  endif   // _RWSTD_NO_SNPRINTF_IN_LIBC
 #endif   // _RWSTD_NO_SNPRINTF
 
+
 _RWSTD_NAMESPACE (__rw) { 
 
 static const char __rw_digits[] =
@@ -72,6 +80,155 @@
     "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
 
+#if defined (_MSC_VER)
+
+inline bool __rw_isfinite (double val) { return !!_finite (val); }
+
+inline bool __rw_signbit (double val) { return 0 > _copysign (1., val); }
+
+inline bool __rw_isinf (double val) {
+    const int fpc = _fpclass (val);
+
+    if (_FPCLASS_NINF == fpc) {
+        // verify that __rw_signbit() correctly determines
+        // the sign of negative infinity
+        _RWSTD_ASSERT (__rw_signbit (val));
+        return true;
+    }
+    else if (_FPCLASS_PINF == fpc) {
+        // verify that __rw_signbit() correctly determines
+        // the sign of positive infinity
+        _RWSTD_ASSERT (!__rw_signbit (val));
+        return true;
+    }
+
+    return false;
+}
+
+inline bool __rw_isnan (double val) { return !!_isnan (val); }
+
+inline bool __rw_isqnan (double val) {
+    return _FPCLASS_QNAN == _fpclass (val);
+}
+
+inline bool __rw_issnan (double val) {
+    return _FPCLASS_SNAN == _fpclass (val);
+}
+
+#elif defined (_RWSTD_OS_SUNOS)
+
+inline bool __rw_isfinite (double val) { return !!finite (val); }
+
+inline bool __rw_signbit (double val) { return !!signbit (val); }
+
+inline bool __rw_isinf (double val) {
+    const int fpc = fpclass (val);
+
+    if (FP_NINF == fpc) {
+        // verify that __rw_signbit() correctly determines
+        // the sign of negative infinity
+        _RWSTD_ASSERT (__rw_signbit (val));
+        return true;
+    }
+    else if (FP_PINF == fpc) {
+        // verify that __rw_signbit() correctly determines
+        // the sign of positive infinity
+        _RWSTD_ASSERT (!__rw_signbit (val));
+        return true;
+    }
+
+    return false;
+}
+
+inline bool __rw_isnan (double val) { return 0 != isnan (val); }
+
+inline bool __rw_isqnan (double val) { return FP_QNAN == fpclass (val); }
+
+inline bool __rw_issnan (double val) { return FP_SNAN == fpclass (val); }
+
+#elif defined (fpclassify)
+
+inline bool __rw_isfinite (double val) { return !!isfinite (val); }
+
+inline bool __rw_signbit (double val) { return !!signbit (val); }
+
+inline bool __rw_isinf (double val) { return !!isinf (val); }
+
+inline bool __rw_isnan (double val) { return !!isnan (val); }
+
+inline bool __rw_isqnan (double val) { return false; }
+
+inline bool __rw_issnan (double val) { return false; }
+
+#else
+
+inline bool __rw_isfinite (double) { return true; }
+
+inline bool __rw_signbit (double) { return false; }
+
+inline bool __rw_isinf (double) { return false; }
+
+inline bool __rw_isnan (double) { return false; }
+
+inline bool __rw_isqnan (double) { return false; }
+
+inline bool __rw_issnan (double) { return false; }
+
+#endif
+
+
+static int
+__rw_fmat_infinite (char *buf, size_t bufsize, double val, unsigned flags)
+{
+    _RWSTD_ASSERT (!__rw_isfinite (val));
+    _RWSTD_ASSERT (5 <= bufsize);
+
+    char* end = buf;
+    const bool cap = !!(flags & _RWSTD_IOS_UPPERCASE);
+
+    if (__rw_isinf (val)) {
+        if (__rw_signbit (val)) {
+            *end++ = '-';
+        }
+        else if (flags & _RWSTD_IOS_SHOWPOS) {
+            *end++ = '+';
+        }
+
+        const char str [] = "iInNfF";
+        *end++ = str [cap + 0];
+        *end++ = str [cap + 2];
+        *end++ = str [cap + 4];
+    }
+    else {
+        _RWSTD_ASSERT (__rw_isnan (val));
+#if 0
+        // disabled since not all platforms correctly handling sign of NaN's
+        if (__rw_signbit (val)) {
+            *end++ = '-';
+        }
+        else if (flags & _RWSTD_IOS_SHOWPOS) {
+            *end++ = '+';
+        }
+#endif
+
+        const char str [] = "nNaAqQsS";
+        *end++ = str [cap + 0];
+        *end++ = str [cap + 2];
+        *end++ = str [cap + 0];
+#if 0
+        // disabled since not all platforms supporting 
+        // the quiet and signaling NaN's
+        if (__rw_isqnan (val))
+            *end++ = str [cap + 4];
+        else if (__rw_issnan (val))
+            *end++ = str [cap + 6];
+#endif
+    }
+
+    return int (end - buf);
+}
+
+
 #ifdef _RWSTD_LONG_LONG
 
 
@@ -778,88 +935,112 @@
 
 #endif   // _RWSTD_LONG_LONG
 
-    case __rw_facet::_C_float | __rw_facet::_C_ptr:
-        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
-        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
-                                   flags, fpr);
-        for (; ;) {
-            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
-                                    *(const float*)pval));
-
-            if (len >= bufsize) {
-                if (*pbuf != buf)
-                    delete[] *pbuf;
-
-                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
+    case __rw_facet::_C_float | __rw_facet::_C_ptr: {
+            const float fval = *(const float*)pval;
+            if (!__rw_isfinite (fval)) {
+                len = __rw_fmat_infinite (*pbuf, bufsize, fval, flags);
+                end = *pbuf + len;
             }
             else {
-                _RWSTD_ASSERT (len > 0);
-
-                break;
-            }
-        }
+                fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
+                fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
+                                           flags, fpr);
+                for (; ;) {
+                    len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt, fval));
 
-        end = *pbuf + len;
+                    if (len >= bufsize) {
+                        if (*pbuf != buf)
+                            delete[] *pbuf;
 
-        // fix up output to conform to C99
-        __rw_fix_flt (end, len, flags, fpr);
-        break;
+                        bufsize = len + 1 ? len + 1 : bufsize * 2;
+                        *pbuf = new char [bufsize];
+                    }
+                    else {
+                        _RWSTD_ASSERT (len > 0);
 
-    case __rw_facet::_C_double | __rw_facet::_C_ptr:
-        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
-        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
-                                   flags, fpr);
+                        break;
+                    }
+                }
 
-        for ( ; ; ) {
-            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
-                                    *(const double*)pval));
+                end = *pbuf + len;
 
-            if (len >= bufsize) {
-                if (*pbuf != buf)
-                    delete[] *pbuf;
+                // fix up output to conform to C99
+                __rw_fix_flt (end, len, flags, fpr);
+            }
+        }
+        break;
 
-                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
+    case __rw_facet::_C_double | __rw_facet::_C_ptr: {
+            const double dval = *(const double*)pval;
+            if (!__rw_isfinite (dval)) {
+                len = __rw_fmat_infinite (*pbuf, bufsize, dval, flags);
+                end = *pbuf + len;
             }
             else {
-                _RWSTD_ASSERT (len > 0);
+                fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
+                fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
+                                           flags, fpr);
+
+                for ( ; ; ) {
+                    len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt, dval));
+
+                    if (len >= bufsize) {
+                        if (*pbuf != buf)
+                            delete[] *pbuf;
+
+                        bufsize = len + 1 ? len + 1 : bufsize * 2;
+                        *pbuf = new char [bufsize];
+                    }
+                    else {
+                        _RWSTD_ASSERT (len > 0);
+
+                        break;
+                    }
+                }
 
-                break;
+                end = *pbuf + len;
+
+                // fix up output to conform to C99
+                __rw_fix_flt (end, len, flags, fpr);
             }
         }
-
-        end = *pbuf + len;
-
-        // fix up output to conform to C99
-        __rw_fix_flt (end, len, flags, fpr);
         break;
 
 #ifndef _RWSTD_NO_LONG_DOUBLE
 
-    case __rw_facet::_C_ldouble | __rw_facet::_C_ptr:
-        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
-        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
-                                   flags, fpr);
-
-        for ( ; ; ) {
-            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
-                                    *(const long double*)pval));
-            if (len >= bufsize) {
-                if (*pbuf != buf)
-                    delete[] *pbuf;
-
-                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
+    case __rw_facet::_C_ldouble | __rw_facet::_C_ptr: {
+            const long double ldval = *(const long double*)pval;
+            if (!__rw_isfinite (ldval)) {
+                len = __rw_fmat_infinite (*pbuf, bufsize, ldval, flags);
+                end = *pbuf + len;
             }
             else {
-                _RWSTD_ASSERT (len > 0);
+                fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
+                fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
+                                           flags, fpr);
+
+                for ( ; ; ) {
+                    len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt, ldval));
+                    if (len >= bufsize) {
+                        if (*pbuf != buf)
+                            delete[] *pbuf;
+
+                        bufsize = len + 1 ? len + 1 : bufsize * 2;
+                        *pbuf = new char [bufsize];
+                    }
+                    else {
+                        _RWSTD_ASSERT (len > 0);
+
+                        break;
+                    }
+                }
 
-                break;
+                end = *pbuf + len;
+
+                // fix up output to conform to C99
+                __rw_fix_flt (end, len, flags, fpr);
             }
         }
-
-        end = *pbuf + len;
-
-        // fix up output to conform to C99
-        __rw_fix_flt (end, len, flags, fpr);
         break;
 
 #endif   // _RWSTD_NO_LONG_DOUBLE



Mime
View raw message