1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/src/num_put_float.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,867 @@
1.4 +/*
1.5 + * Copyright (c) 1999
1.6 + * Silicon Graphics Computer Systems, Inc.
1.7 + *
1.8 + * Copyright (c) 1999
1.9 + * Boris Fomitchev
1.10 + *
1.11 + * This material is provided "as is", with absolutely no warranty expressed
1.12 + * or implied. Any use is at your own risk.
1.13 + *
1.14 + * Permission to use or copy this software for any purpose is hereby granted
1.15 + * without fee, provided the above notices are retained on all copies.
1.16 + * Permission to modify the code and to distribute modified code is granted,
1.17 + * provided the above notices are retained, and a notice that the code was
1.18 + * modified is included with the above copyright notice.
1.19 + *
1.20 + */
1.21 +
1.22 +#include "stlport_prefix.h"
1.23 +
1.24 +#include <cmath>
1.25 +#include <ios>
1.26 +#include <locale>
1.27 +
1.28 +#if defined (__DECCXX)
1.29 +# define NDIG 400
1.30 +#else
1.31 +# define NDIG 82
1.32 +#endif
1.33 +
1.34 +#if defined (_STLP_NO_LONG_DOUBLE)
1.35 +# define MAXECVT 17
1.36 +# define MAXFCVT 18
1.37 +typedef double max_double_type;
1.38 +#else
1.39 +# define MAXECVT 35
1.40 +# define MAXFCVT 36
1.41 +typedef long double max_double_type;
1.42 +#endif
1.43 +
1.44 +#define MAXFSIG MAXECVT
1.45 +#define MAXESIZ 5
1.46 +
1.47 +#define todigit(x) ((x)+'0')
1.48 +
1.49 +#if defined (_STLP_UNIX)
1.50 +
1.51 +# if defined (__sun)
1.52 +# include <floatingpoint.h>
1.53 +# endif
1.54 +
1.55 +# if defined (__sun) || defined (__digital__) || defined (__sgi) || defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
1.56 +// DEC, SGI & Solaris need this
1.57 +# include <values.h>
1.58 +# include <nan.h>
1.59 +# endif
1.60 +
1.61 +# if defined (__QNXNTO__) || ( defined(__GNUC__) && defined(__APPLE__) ) || defined(_STLP_USE_UCLIBC) /* 0.9.26 */ || \
1.62 + defined(__FreeBSD__)
1.63 +# define USE_SPRINTF_INSTEAD
1.64 +# endif
1.65 +
1.66 +# if defined( _AIX ) // JFA 3-Aug-2000
1.67 +# include <math.h>
1.68 +# include <float.h>
1.69 +# endif
1.70 +
1.71 +#endif
1.72 +
1.73 +#include <cstdio>
1.74 +#include <cstdlib>
1.75 +
1.76 +//#if defined(_CRAY)
1.77 +//# include <stdlib.h>
1.78 +//#endif
1.79 +
1.80 +#if defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) || defined (__DJGPP) || \
1.81 + defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
1.82 +# include <float.h>
1.83 +#endif
1.84 +
1.85 +#if defined(__MRC__) || defined(__SC__) || defined(_CRAY) //*TY 02/24/2000 - added support for MPW
1.86 +# include <fp.h>
1.87 +#endif
1.88 +
1.89 +#if defined (__CYGWIN__)
1.90 +# include <ieeefp.h>
1.91 +#endif
1.92 +
1.93 +#if defined (__MSL__)
1.94 +# include <cstdlib> // for atoi
1.95 +# include <cstdio> // for snprintf
1.96 +# include <algorithm>
1.97 +# include <cassert>
1.98 +#endif
1.99 +
1.100 +#if defined (__ISCPP__)
1.101 +# include <cfloat>
1.102 +#endif
1.103 +
1.104 +#include <algorithm>
1.105 +
1.106 +#if defined (__DMC__)
1.107 +# define snprintf _snprintf
1.108 +#endif
1.109 +
1.110 +#if defined(__hpux) && (!defined(_INCLUDE_HPUX_SOURCE) || defined(__GNUC__))
1.111 +extern "C" double erf(double);
1.112 +extern "C" double erfc(double);
1.113 +extern "C" double gamma(double); /* obsolescent */
1.114 +extern "C" double hypot(double, double);
1.115 +extern "C" int isnan(double);
1.116 +extern "C" double j0(double);
1.117 +extern "C" double j1(double);
1.118 +extern "C" double jn(int, double);
1.119 +extern "C" double lgamma(double);
1.120 +extern "C" double y0(double);
1.121 +extern "C" double y1(double);
1.122 +extern "C" double yn(int, double);
1.123 +
1.124 +# define HUGE_VALF _SINFINITY
1.125 +# define INFINITY _SINFINITY
1.126 +# define NAN _SQNAN
1.127 +
1.128 +# define isnan(x) _ISNAN(x)
1.129 +# define isinf(x) _ISINF(x)
1.130 +# define signbit(x) _SIGNBIT(x)
1.131 +# define isfinite(x) _ISFINITE(x)
1.132 +# define isnormal(x) _ISNORMAL(x)
1.133 +# define fpclassify(x) _FPCLASSIFY(x)
1.134 +# define isunordered(x,y) _ISUNORDERED(x,y)
1.135 +# define isgreater(x,y) _ISGREATER(x,y)
1.136 +# define isgreaterequal(x,y) _ISGREATEREQUAL(x,y)
1.137 +# define isless(x,y) _ISLESS(x,y)
1.138 +# define islessequal(x,y) _ISLESSEQUAL(x,y)
1.139 +# define islessgreater(x,y) _ISLESSGREATER(x,y)
1.140 +
1.141 +# define FP_NORMAL 0
1.142 +# define FP_ZERO 1
1.143 +# define FP_INFINITE 2
1.144 +# define FP_SUBNORMAL 3
1.145 +# define FP_NAN 4
1.146 +
1.147 +# define DECIMAL_DIG 17
1.148 +
1.149 +# define _IS64(x) (sizeof(x) == sizeof(double))
1.150 +# define _IS32(x) (sizeof(x) == sizeof(float))
1.151 +
1.152 +extern "C" {
1.153 + extern double copysign(double, double);
1.154 + extern const float _SINFINITY;
1.155 + extern const float _SQNAN;
1.156 +# if defined (_PA_RISC)
1.157 +# define _ISNAN(x) (_IS32(x)?_Isnanf(x):(isnan)(x))
1.158 +# define _ISINF(x) (_IS32(x)?_Isinff(x):_Isinf(x))
1.159 +# define _SIGNBIT(x) (_IS32(x)?_Signbitf(x):_Signbit(x))
1.160 +# define _ISFINITE(x) (_IS32(x)?_Isfinitef(x):_Isfinite(x))
1.161 +# define _ISNORMAL(x) (_IS32(x)?_Isnormalf(x):_Isnormal(x))
1.162 +# define _FPCLASSIFY(x) (_IS32(x)?_Fpclassifyf(x)>>1:_Fpclassify(x)>>1)
1.163 +# define _ISUNORDERED(x,y) (_IS32(x)&&_IS32(y)?_Isunorderedf(x,y):_Isunordered(x,y))
1.164 + extern int _Signbit(double);
1.165 + extern int _Signbitf(float);
1.166 + extern int _Isnanf(float);
1.167 + extern int _Isfinite(double);
1.168 + extern int _Isfinitef(float);
1.169 + extern int _Isinf(double);
1.170 + extern int _Isinff(float);
1.171 + extern int _Isnormal(double);
1.172 + extern int _Isnormalf(float);
1.173 + extern int _Isunordered(double, double);
1.174 + extern int _Isunorderedf(float, float);
1.175 + extern int _Fpclassify(double);
1.176 + extern int _Fpclassifyf(float);
1.177 +# else
1.178 +# include "math_ia64_internal.h"
1.179 +# define _FPCLASSIFY(x) (_IS32(x)?_Fpclassf(x):_Fpclass(x))
1.180 + extern int _Fpclass(double);
1.181 + extern int _Fpclassf(float);
1.182 +# endif
1.183 +}
1.184 +
1.185 +# if !defined (_INCLUDE_XOPEN_SOURCE_EXTENDED)
1.186 +extern "C" char *fcvt(double, int, int *, int *);
1.187 +extern "C" char *ecvt(double, int, int *, int *);
1.188 +# endif
1.189 +# if !defined (_INCLUDE_HPUX_SOURCE)
1.190 +# if !defined (_LONG_DOUBLE)
1.191 +# define _LONG_DOUBLE
1.192 +typedef struct {
1.193 + uint32_t word1, word2, word3, word4;
1.194 +} long_double;
1.195 +# endif /* _LONG_DOUBLE */
1.196 +extern "C" char *_ldecvt(long_double, int, int *, int *);
1.197 +extern "C" char *_ldfcvt(long_double, int, int *, int *);
1.198 +
1.199 +# endif
1.200 +#endif /* __hpux */
1.201 +
1.202 +_STLP_BEGIN_NAMESPACE
1.203 +_STLP_MOVE_TO_PRIV_NAMESPACE
1.204 +
1.205 +#if defined (__MWERKS__) || defined(__BEOS__)
1.206 +# define USE_SPRINTF_INSTEAD
1.207 +#endif
1.208 +
1.209 +#if defined (_AIX) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
1.210 +// Some OS'es only provide non-reentrant primitives, so we have to use additional synchronization here
1.211 +
1.212 +# if !defined(_REENTRANT) && !defined(_THREAD_SAFE) && !(defined(_POSIX_THREADS) && defined(__OpenBSD__))
1.213 +# define LOCK_CVT
1.214 +# define RETURN_CVT(ecvt, x, n, pt, sign, buf) return ecvt(x, n, pt, sign);
1.215 +# else
1.216 +static _STLP_STATIC_MUTEX __put_float_mutex _STLP_MUTEX_INITIALIZER;
1.217 +# define LOCK_CVT _STLP_auto_lock lock(__put_float_mutex);
1.218 +# define RETURN_CVT(ecvt, x, n, pt, sign, buf) strcpy(buf, ecvt(x, n, pt, sign)); return buf;
1.219 +# endif // !_REENTRANT
1.220 +#endif // _AIX || __FreeBSD__ || __NetBSD__ || __OpenBSD__
1.221 +
1.222 +// Tests for infinity and NaN differ on different OSs. We encapsulate
1.223 +// these differences here.
1.224 +
1.225 +#if !defined (USE_SPRINTF_INSTEAD)
1.226 +# if defined (__hpux) || defined (__DJGPP) || (defined (_STLP_USE_GLIBC) && ! defined (__MSL__)) || \
1.227 + defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__)
1.228 +static inline bool _Stl_is_nan_or_inf(double x)
1.229 +# if defined (isfinite)
1.230 +{ return !isfinite(x); }
1.231 +# else
1.232 +{ return !finite(x); }
1.233 +# endif
1.234 +static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); }
1.235 +static inline bool _Stl_is_inf(double x) { return isinf(x); }
1.236 +// inline bool _Stl_is_neg_inf(double x) { return isinf(x) < 0; }
1.237 +static inline bool _Stl_is_neg_inf(double x) { return isinf(x) && x < 0; }
1.238 +# elif (defined (__unix) || defined (__unix__)) && \
1.239 + !defined (__APPLE__) && !defined (__DJGPP) && !defined(__osf__) && \
1.240 + !defined (_CRAY)
1.241 +static inline bool _Stl_is_nan_or_inf(double x) { return IsNANorINF(x); }
1.242 +static inline bool _Stl_is_inf(double x) { return IsNANorINF(x) && IsINF(x); }
1.243 +static inline bool _Stl_is_neg_inf(double x) { return (IsINF(x)) && (x < 0.0); }
1.244 +static inline bool _Stl_is_neg_nan(double x) { return IsNegNAN(x); }
1.245 +# elif defined (__BORLANDC__) && ( __BORLANDC__ < 0x540 )
1.246 +static inline bool _Stl_is_nan_or_inf(double x) { return !_finite(x); }
1.247 +static inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && ! _isnan(x);}
1.248 +static inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; }
1.249 +static inline bool _Stl_is_neg_nan(double x) { return _isnan(x) && x < 0 ; }
1.250 +# elif defined (_STLP_MSVC_LIB) || (defined (__MINGW32__) && !(defined(__SYMBIAN32__) && defined(__GCCXML__)) ) || defined (__BORLANDC__)
1.251 +static inline bool _Stl_is_nan_or_inf(double x) { return !_finite(x); }
1.252 +static inline bool _Stl_is_inf(double x) {
1.253 + int fclass = _fpclass(x);
1.254 + return fclass == _FPCLASS_NINF || fclass == _FPCLASS_PINF;
1.255 +}
1.256 +static inline bool _Stl_is_neg_inf(double x) { return _fpclass(x) == _FPCLASS_NINF; }
1.257 +static inline bool _Stl_is_neg_nan(double x) { return _isnan(x) && _copysign(1., x) < 0 ; }
1.258 +# elif defined (__MRC__) || defined (__SC__) //*TY 02/24/2000 - added support for MPW
1.259 +static bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !isfinite(x); }
1.260 +static bool _Stl_is_inf(double x) { return !isfinite(x); }
1.261 +static bool _Stl_is_neg_inf(double x) { return !isfinite(x) && signbit(x); }
1.262 +static bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); }
1.263 +# elif /* defined(__FreeBSD__) || defined(__OpenBSD__) || */ (defined(__GNUC__) && defined(__APPLE__))
1.264 +static inline bool _Stl_is_nan_or_inf(double x) { return !finite(x); }
1.265 +static inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && ! isnan(x); }
1.266 +static inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; }
1.267 +static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && copysign(1., x) < 0 ; }
1.268 +# elif defined( _AIX ) // JFA 11-Aug-2000
1.269 +static bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !finite(x); }
1.270 +static bool _Stl_is_inf(double x) { return !finite(x); }
1.271 +// bool _Stl_is_neg_inf(double x) { return _class(x) == FP_MINUS_INF; }
1.272 +static bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && ( copysign(1., x) < 0 ); }
1.273 +static bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); }
1.274 +# elif defined (__ISCPP__)
1.275 +static inline bool _Stl_is_nan_or_inf (double x) { return _fp_isINF(x) || _fp_isNAN(x); }
1.276 +static inline bool _Stl_is_inf (double x) { return _fp_isINF(x); }
1.277 +static inline bool _Stl_is_neg_inf (double x) { return _fp_isINF(x) && x < 0; }
1.278 +static inline bool _Stl_is_neg_nan (double x) { return _fp_isNAN(x) && x < 0; }
1.279 +# elif defined (_CRAY)
1.280 +# if defined (_CRAYIEEE)
1.281 +static inline bool _Stl_is_nan_or_inf(double x) { return isnan(x) || isinf(x); }
1.282 +static inline bool _Stl_is_inf(double x) { return isinf(x); }
1.283 +static inline bool _Stl_is_neg_inf(double x) { return isinf(x) && signbit(x); }
1.284 +static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); }
1.285 +# else
1.286 +static inline bool _Stl_is_nan_or_inf(double x) { return false; }
1.287 +static inline bool _Stl_is_inf(double x) { return false; }
1.288 +static inline bool _Stl_is_neg_inf(double x) { return false; }
1.289 +static inline bool _Stl_is_neg_nan(double x) { return false; }
1.290 +# endif
1.291 +# else // nothing from above
1.292 +# define USE_SPRINTF_INSTEAD
1.293 +# endif
1.294 +#endif // !USE_SPRINTF_INSTEAD
1.295 +
1.296 +#if !defined (USE_SPRINTF_INSTEAD)
1.297 +// Reentrant versions of floating-point conversion functions. The argument
1.298 +// lists look slightly different on different operating systems, so we're
1.299 +// encapsulating the differences here.
1.300 +
1.301 +# if defined (__CYGWIN__) || defined(__DJGPP)
1.302 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.303 +{ return ecvtbuf(x, n, pt, sign, buf); }
1.304 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.305 +{ return fcvtbuf(x, n, pt, sign, buf); }
1.306 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.307 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.308 +{ return ecvtbuf(x, n, pt, sign, buf); }
1.309 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.310 +{ return fcvtbuf(x, n, pt, sign, buf); }
1.311 +# endif
1.312 +# elif defined (_STLP_USE_GLIBC)
1.313 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.314 +{ return buf + ecvt_r(x, n, pt, sign, buf, NDIG+2); }
1.315 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.316 +{ return buf + fcvt_r(x, n, pt, sign, buf, NDIG+2); }
1.317 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.318 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.319 +{ return buf + qecvt_r(x, n, pt, sign, buf, NDIG+2); }
1.320 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.321 +{ return buf + qfcvt_r(x, n, pt, sign, buf, NDIG+2); }
1.322 +# endif
1.323 +# elif defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
1.324 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.325 +{ return ecvt(x, n, pt, sign); }
1.326 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.327 +{ return fcvt(x, n, pt, sign); }
1.328 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.329 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.330 +{ return ecvtl(x, n, pt, sign); }
1.331 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.332 +{ return fcvtl(x, n, pt, sign); }
1.333 +# endif
1.334 +# elif defined (__sun)
1.335 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.336 +{ return econvert(x, n, pt, sign, buf); }
1.337 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.338 +{ return fconvert(x, n, pt, sign, buf); }
1.339 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.340 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.341 +{ return qeconvert(&x, n, pt, sign, buf); }
1.342 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.343 +{ return qfconvert(&x, n, pt, sign, buf); }
1.344 +# endif
1.345 +# elif defined (__DECCXX)
1.346 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.347 +{ return (ecvt_r(x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
1.348 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.349 +{ return (fcvt_r(x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
1.350 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.351 +// fbp : no "long double" conversions !
1.352 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.353 +{ return (ecvt_r((double)x, n, pt, sign, buf, NDIG)==0 ? buf : 0) ; }
1.354 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.355 +{ return (fcvt_r((double)x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
1.356 +# endif
1.357 +# elif defined (__hpux)
1.358 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.359 +{ return ecvt(x, n, pt, sign); }
1.360 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.361 +{ return fcvt(x, n, pt, sign); }
1.362 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.363 +
1.364 +# if defined( _REENTRANT ) && (defined(_PTHREADS_DRAFT4) || defined(PTHREAD_THREADS_MAX))
1.365 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.366 +{ return (_ldecvt_r(*(long_double*)&x, n, pt, sign, buf, NDIG+2)==0 ? buf : 0); }
1.367 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.368 +{ return (_ldfcvt_r(*(long_double*)&x, n, pt, sign, buf, NDIG+2)==0 ? buf : 0); }
1.369 +# else
1.370 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.371 +{ return _ldecvt(*(long_double*)&x, n, pt, sign); }
1.372 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.373 +{ return _ldfcvt(*(long_double*)&x, n, pt, sign); }
1.374 +# endif
1.375 +# endif
1.376 +# elif defined (_AIX) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__)
1.377 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.378 +{ LOCK_CVT RETURN_CVT(ecvt, x, n, pt, sign, buf) }
1.379 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.380 +{ LOCK_CVT RETURN_CVT(fcvt, x, n, pt, sign, buf) }
1.381 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.382 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.383 +{ LOCK_CVT RETURN_CVT(ecvt, x, n, pt, sign, buf) }
1.384 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.385 +{ LOCK_CVT RETURN_CVT(fcvt, x, n, pt, sign, buf) }
1.386 +# endif
1.387 +# elif defined (__unix) && !defined (__APPLE__) && !defined (_CRAY)
1.388 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.389 +{ return ecvt_r(x, n, pt, sign, buf); }
1.390 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.391 +{ return fcvt_r(x, n, pt, sign, buf); }
1.392 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.393 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.394 +{ return qecvt_r(x, n, pt, sign, buf); }
1.395 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.396 +{ return qfcvt_r(x, n, pt, sign, buf); }
1.397 +# endif
1.398 +# elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__)
1.399 +// those guys claim _cvt functions being reentrant.
1.400 +# if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
1.401 +# define _STLP_APPEND(a, b) a##b
1.402 +# define _STLP_BUF_PARAMS , char* buf, size_t bsize
1.403 +# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) _STLP_APPEND(F, _s)(buf, bsize, X, N, PT, SIGN); return buf
1.404 +# else
1.405 +# define _STLP_CVT_DONT_NEED_BUF
1.406 +# define _STLP_BUF_PARAMS
1.407 +# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) return F(X, N, PT, SIGN)
1.408 +# endif
1.409 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
1.410 +{ _STLP_SECURE_FUN(_ecvt, x, n, pt, sign); }
1.411 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
1.412 +{ _STLP_SECURE_FUN(_fcvt, x, n, pt, sign); }
1.413 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.414 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
1.415 +{ _STLP_SECURE_FUN(_ecvt, (double)x, n, pt, sign); }
1.416 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
1.417 +{ _STLP_SECURE_FUN(_fcvt, (double)x, n, pt, sign); }
1.418 +# endif
1.419 +# undef _STLP_SECURE_FUN
1.420 +# undef _STLP_BUF_PARAMS
1.421 +# undef _STLP_APPEND
1.422 +# elif defined (__ISCPP__)
1.423 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
1.424 +{ return _fp_ecvt( x, n, pt, sign, buf); }
1.425 +
1.426 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
1.427 +{ return _fp_fcvt(x, n, pt, sign, buf); }
1.428 +
1.429 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.430 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
1.431 +{ return _fp_ecvt( x, n, pt, sign, buf); }
1.432 +
1.433 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
1.434 +{ return _fp_fcvt(x, n, pt, sign, buf); }
1.435 +# endif
1.436 +# elif defined (__MRC__) || defined (__SC__) || defined (_CRAY)
1.437 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* )
1.438 +{ return ecvt( x, n, pt, sign ); }
1.439 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* )
1.440 +{ return fcvt(x, n, pt, sign); }
1.441 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.442 +static inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* )
1.443 +{ return ecvt( x, n, pt, sign ); }
1.444 +static inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* )
1.445 +{ return fcvt(x, n, pt, sign); }
1.446 +# endif
1.447 +# endif
1.448 +
1.449 +# if defined (_STLP_CVT_DONT_NEED_BUF)
1.450 +# define _STLP_CVT_BUFFER(B)
1.451 +# elif !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
1.452 +# define _STLP_CVT_BUFFER(B) , B
1.453 +# else
1.454 +# define _STLP_CVT_BUFFER(B) , _STLP_ARRAY_AND_SIZE(B)
1.455 +# endif
1.456 +
1.457 +# if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
1.458 +# define _STLP_BUFFER(B) B
1.459 +# else
1.460 +# define _STLP_BUFFER(B) _STLP_ARRAY_AND_SIZE(B)
1.461 +# endif
1.462 +
1.463 +//----------------------------------------------------------------------
1.464 +// num_put
1.465 +
1.466 +// __format_float formats a mantissa and exponent as returned by
1.467 +// one of the conversion functions (ecvt_r, fcvt_r, qecvt_r, qfcvt_r)
1.468 +// according to the specified precision and format flags. This is
1.469 +// based on doprnt but is much simpler since it is concerned only
1.470 +// with floating point input and does not consider all formats. It
1.471 +// also does not deal with blank padding, which is handled by
1.472 +// __copy_float_and_fill.
1.473 +
1.474 +static size_t __format_float_scientific( __iostring& buf, const char *bp,
1.475 + int decpt, int sign, bool is_zero,
1.476 + ios_base::fmtflags flags,
1.477 + int precision, bool /* islong */)
1.478 +{
1.479 + // sign if required
1.480 + if (sign)
1.481 + buf += '-';
1.482 + else if (flags & ios_base::showpos)
1.483 + buf += '+';
1.484 +
1.485 + // first digit of mantissa
1.486 + buf += *bp++;
1.487 +
1.488 + // start of grouping position, grouping won't occur in scientific notation
1.489 + // as it is impossible to have something like 1234.0e04 but we return a correct
1.490 + // group position for coherency with __format_float_fixed.
1.491 + size_t __group_pos = buf.size();
1.492 +
1.493 + // decimal point if required
1.494 + if (precision != 0 || flags & ios_base::showpoint) {
1.495 + buf += '.';
1.496 + }
1.497 +
1.498 + // rest of mantissa
1.499 + int rz = precision;
1.500 + while (rz-- > 0 && *bp != 0)
1.501 + buf += *bp++;
1.502 +
1.503 + // exponent
1.504 + char expbuf[MAXESIZ + 2];
1.505 + char *suffix = expbuf + MAXESIZ;
1.506 + *suffix = 0;
1.507 + if (!is_zero) {
1.508 + int nn = decpt - 1;
1.509 + if (nn < 0)
1.510 + nn = -nn;
1.511 + for (; nn > 9; nn /= 10)
1.512 + *--suffix = (char) todigit(nn % 10);
1.513 + *--suffix = (char) todigit(nn);
1.514 + }
1.515 +
1.516 + // prepend leading zeros to exponent
1.517 + while (suffix > &expbuf[MAXESIZ - 2])
1.518 + *--suffix = '0';
1.519 +
1.520 + // put in the exponent sign
1.521 + *--suffix = (char) ((decpt > 0 || is_zero ) ? '+' : '-');
1.522 +
1.523 + // put in the e
1.524 + *--suffix = flags & ios_base::uppercase ? 'E' : 'e';
1.525 +
1.526 + // copy the suffix
1.527 + buf += suffix;
1.528 + return __group_pos;
1.529 +}
1.530 +
1.531 +static size_t __format_float_fixed( __iostring &buf, const char *bp,
1.532 + int decpt, int sign, bool /* x */,
1.533 + ios_base::fmtflags flags,
1.534 + int precision, bool islong )
1.535 +{
1.536 + if ( sign && (decpt > -precision) && (*bp != 0) )
1.537 + buf += '-';
1.538 + else if ( flags & ios_base::showpos )
1.539 + buf += '+';
1.540 +
1.541 + int k = 0;
1.542 + int maxfsig = islong ? 2*MAXFSIG : MAXFSIG;
1.543 +
1.544 + // digits before decimal point
1.545 + int nnn = decpt;
1.546 + do {
1.547 + buf += ((nnn <= 0 || *bp == 0 || k >= maxfsig) ? '0' : (++k, *bp++));
1.548 + } while ( --nnn > 0 );
1.549 +
1.550 + // start of grouping position
1.551 + size_t __group_pos = buf.size();
1.552 +
1.553 + // decimal point if needed
1.554 + if ( flags & ios_base::showpoint || precision > 0 ) {
1.555 + buf += '.';
1.556 + }
1.557 +
1.558 + // digits after decimal point if any
1.559 + nnn = (min) (precision, MAXFCVT);
1.560 +
1.561 + while ( --nnn >= 0 ) {
1.562 + buf += (++decpt <= 0 || *bp == 0 || k >= maxfsig) ? '0' : (++k, *bp++);
1.563 + }
1.564 +
1.565 + // trailing zeros if needed
1.566 + if ( precision > MAXFCVT ) {
1.567 + buf.append( precision - MAXFCVT, '0' );
1.568 + }
1.569 +
1.570 + return __group_pos;
1.571 +}
1.572 +
1.573 +static void __format_nan_or_inf(__iostring& buf, double x, ios_base::fmtflags flags)
1.574 +{
1.575 + static const char* inf[2] = { "inf", "Inf" };
1.576 + static const char* nan[2] = { "nan", "NaN" };
1.577 + const char** inf_or_nan;
1.578 + if (_Stl_is_inf(x)) { // Infinity
1.579 + inf_or_nan = inf;
1.580 + if (_Stl_is_neg_inf(x))
1.581 + buf += '-';
1.582 + else if (flags & ios_base::showpos)
1.583 + buf += '+';
1.584 + } else { // NaN
1.585 + inf_or_nan = nan;
1.586 + if (_Stl_is_neg_nan(x))
1.587 + buf += '-';
1.588 + else if (flags & ios_base::showpos)
1.589 + buf += '+';
1.590 + }
1.591 + buf += inf_or_nan[flags & ios_base::uppercase ? 1 : 0];
1.592 +}
1.593 +
1.594 +template <class max_double_type>
1.595 +static inline size_t __format_float( __iostring &buf, const char * bp,
1.596 + int decpt, int sign, max_double_type x,
1.597 + ios_base::fmtflags flags,
1.598 + int precision, bool islong)
1.599 +{
1.600 + size_t __group_pos = 0;
1.601 + // Output of infinities and NANs does not depend on the format flags
1.602 + if (_Stl_is_nan_or_inf((double)x)) { // Infinity or NaN
1.603 + __format_nan_or_inf(buf, (double)x, flags);
1.604 + } else { // representable number
1.605 + switch (flags & ios_base::floatfield) {
1.606 + case ios_base::scientific:
1.607 + __group_pos = __format_float_scientific( buf, bp, decpt, sign, x == 0.0,
1.608 + flags, precision, islong);
1.609 + break;
1.610 + case ios_base::fixed:
1.611 + __group_pos = __format_float_fixed( buf, bp, decpt, sign, true,
1.612 + flags, precision, islong);
1.613 + break;
1.614 + default: // g format
1.615 + // establish default precision
1.616 + if (flags & ios_base::showpoint || precision > 0) {
1.617 + if (precision == 0) precision = 1;
1.618 + } else
1.619 + precision = 6;
1.620 +
1.621 + // reset exponent if value is zero
1.622 + if (x == 0)
1.623 + decpt = 1;
1.624 +
1.625 + int kk = precision;
1.626 + if (!(flags & ios_base::showpoint)) {
1.627 + size_t n = strlen(bp);
1.628 + if (n < (size_t)kk)
1.629 + kk = (int)n;
1.630 + while (kk >= 1 && bp[kk-1] == '0')
1.631 + --kk;
1.632 + }
1.633 +
1.634 + if (decpt < -3 || decpt > precision) {
1.635 + precision = kk - 1;
1.636 + __group_pos = __format_float_scientific( buf, bp, decpt, sign, x == 0,
1.637 + flags, precision, islong);
1.638 + } else {
1.639 + precision = kk - decpt;
1.640 + __group_pos = __format_float_fixed( buf, bp, decpt, sign, true,
1.641 + flags, precision, islong);
1.642 + }
1.643 + break;
1.644 + } /* switch */
1.645 + } /* else is_nan_or_inf */
1.646 + return __group_pos;
1.647 +}
1.648 +
1.649 +#else /* USE_SPRINTF_INSTEAD */
1.650 +
1.651 +struct GroupPos {
1.652 + bool operator () (char __c) const {
1.653 + return __c == '.' ||
1.654 + __c == 'e' || __c == 'E';
1.655 + }
1.656 +};
1.657 +
1.658 +// Creates a format string for sprintf()
1.659 +static int __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier) {
1.660 + fmtbuf[0] = '%';
1.661 + int i = 1;
1.662 +
1.663 + if (flags & ios_base::showpos)
1.664 + fmtbuf[i++] = '+';
1.665 +
1.666 + if (flags & ios_base::showpoint)
1.667 + fmtbuf[i++] = '#';
1.668 +
1.669 + fmtbuf[i++] = '.';
1.670 + fmtbuf[i++] = '*';
1.671 +
1.672 + if (long_modifier)
1.673 + fmtbuf[i++] = long_modifier;
1.674 +
1.675 + switch (flags & ios_base::floatfield)
1.676 + {
1.677 + case ios_base::scientific:
1.678 + fmtbuf[i++] = (flags & ios_base::uppercase) ? 'E' : 'e';
1.679 + break;
1.680 + case ios_base::fixed:
1.681 +# if defined (__FreeBSD__)
1.682 + fmtbuf[i++] = 'f';
1.683 +# else
1.684 + fmtbuf[i++] = (flags & ios_base::uppercase) ? 'F' : 'f';
1.685 +# endif
1.686 + break;
1.687 + default:
1.688 + fmtbuf[i++] = (flags & ios_base::uppercase) ? 'G' : 'g';
1.689 + break;
1.690 + }
1.691 +
1.692 + fmtbuf[i] = 0;
1.693 + return i;
1.694 +}
1.695 +
1.696 +#endif /* USE_SPRINTF_INSTEAD */
1.697 +
1.698 +_STLP_DECLSPEC size_t _STLP_CALL
1.699 +__write_float(__iostring &buf, ios_base::fmtflags flags, int precision,
1.700 + double x) {
1.701 +#if defined (USE_SPRINTF_INSTEAD)
1.702 + /* If we want 'abitrary' precision, we should use 'abitrary' buffer size
1.703 + * below. - ptr
1.704 + */
1.705 + char static_buf[128];
1.706 + // char *static_buf = new char [128+precision];
1.707 + char fmtbuf[32];
1.708 + __fill_fmtbuf(fmtbuf, flags, 0);
1.709 + // snprintf(static_buf, 128+precision, fmtbuf, precision, x);
1.710 +# if !defined (N_PLAT_NLM)
1.711 + snprintf(_STLP_ARRAY_AND_SIZE(static_buf), fmtbuf, precision, x);
1.712 +# else
1.713 + sprintf(static_buf, fmtbuf, precision, x);
1.714 +# endif
1.715 + buf = static_buf;
1.716 + // delete [] static_buf;
1.717 + return find_if(buf.begin(), buf.end(), GroupPos()) - buf.begin();
1.718 +#else
1.719 +# if !defined (_STLP_CVT_DONT_NEED_BUF)
1.720 + char cvtbuf[NDIG + 2];
1.721 +# endif
1.722 + char * bp;
1.723 + int decpt, sign;
1.724 +
1.725 + switch (flags & ios_base::floatfield) {
1.726 + case ios_base::fixed:
1.727 + bp = _Stl_fcvtR(x, (min) (precision, MAXFCVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.728 + break;
1.729 + case ios_base::scientific :
1.730 + bp = _Stl_ecvtR(x, (min) (precision + 1, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.731 + break;
1.732 + default :
1.733 + bp = _Stl_ecvtR(x, (min) (precision, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.734 + break;
1.735 + }
1.736 + return __format_float(buf, bp, decpt, sign, x, flags, precision, false);
1.737 +#endif
1.738 +}
1.739 +
1.740 +#if !defined (_STLP_NO_LONG_DOUBLE)
1.741 +_STLP_DECLSPEC size_t _STLP_CALL
1.742 +__write_float(__iostring &buf, ios_base::fmtflags flags, int precision,
1.743 + long double x) {
1.744 +# if defined (USE_SPRINTF_INSTEAD)
1.745 + /* If we want 'abitrary' precision, we should use 'abitrary' buffer size
1.746 + * below. - ptr
1.747 + */
1.748 + char static_buf[128];
1.749 + // char *static_buf = new char [128+precision];
1.750 + char fmtbuf[64];
1.751 + int i = __fill_fmtbuf(fmtbuf, flags, 'L');
1.752 + // snprintf(static_buf, 128+precision, fmtbuf, precision, x);
1.753 +# if !defined (N_PLAT_NLM)
1.754 + snprintf(_STLP_ARRAY_AND_SIZE(static_buf), fmtbuf, precision, x);
1.755 +# else
1.756 + sprintf(static_buf, fmtbuf, precision, x);
1.757 +# endif
1.758 + // we should be able to return buf + sprintf(), but we do not trust'em...
1.759 + buf = static_buf;
1.760 + // delete [] static_buf;
1.761 + return find_if(buf.begin(), buf.end(), GroupPos()) - buf.begin();
1.762 +# else
1.763 +# if !defined (_STLP_CVT_DONT_NEED_BUF)
1.764 + char cvtbuf[NDIG + 2];
1.765 +# endif
1.766 + char * bp;
1.767 + int decpt, sign;
1.768 +
1.769 + switch (flags & ios_base::floatfield) {
1.770 + case ios_base::fixed:
1.771 + bp = _Stl_qfcvtR(x, (min) (precision, MAXFCVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.772 + break;
1.773 + case ios_base::scientific:
1.774 + bp = _Stl_qecvtR(x, (min) (precision + 1, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.775 + break;
1.776 + default :
1.777 + bp = _Stl_qecvtR(x, (min) (precision, MAXECVT), &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.778 + break;
1.779 + }
1.780 + return __format_float(buf, bp, decpt, sign, x, flags, precision, true);
1.781 +# endif /* USE_SPRINTF_INSTEAD */
1.782 +}
1.783 +#endif /* _STLP_NO_LONG_DOUBLE */
1.784 +
1.785 +_STLP_DECLSPEC void _STLP_CALL __get_floor_digits(__iostring &out, _STLP_LONGEST_FLOAT_TYPE __x) {
1.786 +#if defined (USE_SPRINTF_INSTEAD)
1.787 + char cvtbuf[128];
1.788 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.789 +# if !defined (N_PLAT_NLM)
1.790 + snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%Lf", __x); // check for 1234.56!
1.791 +# else
1.792 + sprintf(cvtbuf, "%Lf", __x); // check for 1234.56!
1.793 +# endif
1.794 +# else
1.795 + snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%f", __x); // check for 1234.56!
1.796 +# endif
1.797 + char *p = strchr( cvtbuf, '.' );
1.798 + if ( p == 0 ) {
1.799 + out.append( cvtbuf );
1.800 + } else {
1.801 + out.append( cvtbuf, p );
1.802 + }
1.803 +#else
1.804 +# if !defined (_STLP_CVT_DONT_NEED_BUF)
1.805 + char cvtbuf[NDIG + 2];
1.806 +# endif
1.807 + char * bp;
1.808 + int decpt, sign;
1.809 +# if !defined (_STLP_NO_LONG_DOUBLE)
1.810 + bp = _Stl_qfcvtR(__x, 0, &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.811 +# else
1.812 + bp = _Stl_fcvtR(__x, 0, &decpt, &sign _STLP_CVT_BUFFER(cvtbuf));
1.813 +# endif
1.814 +
1.815 + if (sign) {
1.816 + out += '-';
1.817 + }
1.818 + out.append(bp, bp + decpt);
1.819 +#endif // USE_PRINTF_INSTEAD
1.820 +}
1.821 +
1.822 +
1.823 +#if !defined (_STLP_NO_WCHAR_T)
1.824 +_STLP_DECLSPEC void _STLP_CALL __convert_float_buffer( __iostring const& str, __iowstring &out,
1.825 + const ctype<wchar_t>& ct, wchar_t dot, bool __check_dot)
1.826 +{
1.827 + string::const_iterator str_ite(str.begin()), str_end(str.end());
1.828 +
1.829 + //First loop, check the dot char
1.830 + if (__check_dot) {
1.831 + while (str_ite != str_end) {
1.832 + if (*str_ite != '.') {
1.833 + out += ct.widen(*str_ite++);
1.834 + } else {
1.835 + out += dot;
1.836 + break;
1.837 + }
1.838 + }
1.839 + } else {
1.840 + if (str_ite != str_end) {
1.841 + out += ct.widen(*str_ite);
1.842 + }
1.843 + }
1.844 +
1.845 + if (str_ite != str_end) {
1.846 + //Second loop, dot has been found, no check anymore
1.847 + while (++str_ite != str_end) {
1.848 + out += ct.widen(*str_ite);
1.849 + }
1.850 + }
1.851 +}
1.852 +
1.853 +#endif
1.854 +
1.855 +void _STLP_CALL
1.856 +__adjust_float_buffer(__iostring &str, char dot) {
1.857 + if ('.' != dot) {
1.858 + size_t __dot_pos = str.find('.');
1.859 + if (__dot_pos != string::npos) {
1.860 + str[__dot_pos] = dot;
1.861 + }
1.862 + }
1.863 +}
1.864 +
1.865 +_STLP_MOVE_TO_STD_NAMESPACE
1.866 +_STLP_END_NAMESPACE
1.867 +
1.868 +// Local Variables:
1.869 +// mode:C++
1.870 +// End: