1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/stlport/src/num_put_float.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,919 @@ 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 +#define todigit(x) ((x)+'0') 1.35 + 1.36 +#if defined (_STLP_UNIX) 1.37 + 1.38 +# if defined (__sun) 1.39 +# include <floatingpoint.h> 1.40 +# endif 1.41 + 1.42 +# if defined (__sun) || defined (__digital__) || defined (__sgi) || defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR) 1.43 +// DEC, SGI & Solaris need this 1.44 +# include <values.h> 1.45 +# include <nan.h> 1.46 +# endif 1.47 + 1.48 +# if defined (__QNXNTO__) || ( defined(__GNUC__) && defined(__APPLE__) ) || defined(_STLP_USE_UCLIBC) /* 0.9.26 */ || \ 1.49 + defined(__FreeBSD__) 1.50 +# define USE_SPRINTF_INSTEAD 1.51 +# endif 1.52 + 1.53 +# if defined (_AIX) // JFA 3-Aug-2000 1.54 +# include <math.h> 1.55 +# include <float.h> 1.56 +# endif 1.57 + 1.58 +# include <math.h> 1.59 +#endif 1.60 + 1.61 +#include <cstdio> 1.62 +#include <cstdlib> 1.63 + 1.64 +#if defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) || defined (__DJGPP) || \ 1.65 + defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR) 1.66 +# include <float.h> 1.67 +#endif 1.68 + 1.69 +#if defined (__MRC__) || defined (__SC__) || defined (_CRAY) //*TY 02/24/2000 - added support for MPW 1.70 +# include <fp.h> 1.71 +#endif 1.72 + 1.73 +#if defined (__CYGWIN__) 1.74 +# include <ieeefp.h> 1.75 +#endif 1.76 + 1.77 +#if defined (__MSL__) 1.78 +# include <cstdlib> // for atoi 1.79 +# include <cstdio> // for snprintf 1.80 +# include <algorithm> 1.81 +# include <cassert> 1.82 +#endif 1.83 + 1.84 +#if defined (__ISCPP__) 1.85 +# include <cfloat> 1.86 +#endif 1.87 + 1.88 +#include <algorithm> 1.89 + 1.90 +#if defined (__DMC__) 1.91 +# define snprintf _snprintf 1.92 +#endif 1.93 + 1.94 +_STLP_BEGIN_NAMESPACE 1.95 + 1.96 +_STLP_MOVE_TO_PRIV_NAMESPACE 1.97 + 1.98 +#if defined (__MWERKS__) || defined(__BEOS__) 1.99 +# define USE_SPRINTF_INSTEAD 1.100 +#endif 1.101 + 1.102 +template <int N> 1.103 +struct _Dig 1.104 +{ 1.105 + enum { dig = _Dig<N/10>::dig + 1 }; 1.106 +}; 1.107 + 1.108 +_STLP_TEMPLATE_NULL 1.109 +struct _Dig<0> 1.110 +{ 1.111 + enum { dig = 0 }; 1.112 +}; 1.113 + 1.114 +#ifdef _STLP_NO_LONG_DOUBLE 1.115 +# define MAXEDIGITS int(_Dig<DBL_MAX_10_EXP>::dig) 1.116 +# define MAXFSIG DBL_DIG 1.117 +# define MAXFCVT (DBL_DIG + 1) 1.118 +#else 1.119 +# define MAXEDIGITS int(_Dig<LDBL_MAX_10_EXP>::dig) 1.120 +# define MAXFSIG LDBL_DIG 1.121 +# define MAXFCVT (LDBL_DIG + 1) 1.122 +#endif 1.123 + 1.124 +// Tests for infinity and NaN differ on different OSs. We encapsulate 1.125 +// these differences here. 1.126 +#if !defined (USE_SPRINTF_INSTEAD) 1.127 +# if defined (__hpux) && defined (__GNUC__) 1.128 +# define _STLP_USE_SIGN_HELPER 1.129 +# elif defined (__DJGPP) || (defined (_STLP_USE_GLIBC) && ! defined (__MSL__)) || \ 1.130 + defined (__CYGWIN__) || \ 1.131 + defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ 1.132 + defined (__HP_aCC) 1.133 +static inline bool _Stl_is_nan_or_inf(double x) 1.134 +# if defined (isfinite) 1.135 +{ return !isfinite(x); } 1.136 +# else 1.137 +{ return !finite(x); } 1.138 +# endif 1.139 +static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); } 1.140 +static inline bool _Stl_is_inf(double x) { return isinf(x); } 1.141 +// inline bool _Stl_is_neg_inf(double x) { return isinf(x) < 0; } 1.142 +static inline bool _Stl_is_neg_inf(double x) { return isinf(x) && x < 0; } 1.143 +# elif (defined (__unix) || defined (__unix__)) && \ 1.144 + !defined (__APPLE__) && !defined (__DJGPP) && !defined(__osf__) && \ 1.145 + !defined (_CRAY) && !defined (__ANDROID__) 1.146 +static inline bool _Stl_is_nan_or_inf(double x) { return IsNANorINF(x); } 1.147 +static inline bool _Stl_is_inf(double x) { return IsNANorINF(x) && IsINF(x); } 1.148 +static inline bool _Stl_is_neg_inf(double x) { return (IsINF(x)) && (x < 0.0); } 1.149 +static inline bool _Stl_is_neg_nan(double x) { return IsNegNAN(x); } 1.150 +# elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) 1.151 +static inline bool _Stl_is_nan_or_inf(double x) { return !_finite(x); } 1.152 +# if !defined (__BORLANDC__) 1.153 +static inline bool _Stl_is_inf(double x) { 1.154 + int fclass = _fpclass(x); 1.155 + return fclass == _FPCLASS_NINF || fclass == _FPCLASS_PINF; 1.156 +} 1.157 +static inline bool _Stl_is_neg_inf(double x) { return _fpclass(x) == _FPCLASS_NINF; } 1.158 +# else 1.159 +static inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && !_isnan(x);} 1.160 +static inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; } 1.161 +# endif 1.162 +static inline bool _Stl_is_neg_nan(double x) { return _isnan(x) && _copysign(1., x) < 0 ; } 1.163 +# if defined (__BORLANDC__) 1.164 +static inline bool _Stl_is_nan_or_inf(long double x) { return !_finitel(x); } 1.165 +static inline bool _Stl_is_inf(long double x) { return _Stl_is_nan_or_inf(x) && !_isnanl(x);} 1.166 +static inline bool _Stl_is_neg_inf(long double x) { return _Stl_is_inf(x) && x < 0 ; } 1.167 +static inline bool _Stl_is_neg_nan(long double x) { return _isnanl(x) && _copysignl(1.l, x) < 0 ; } 1.168 +# elif !defined (_STLP_NO_LONG_DOUBLE) 1.169 +// Simply there to avoid warning long double -> double implicit conversion: 1.170 +static inline bool _Stl_is_nan_or_inf(long double x) { return _Stl_is_nan_or_inf(__STATIC_CAST(double, x)); } 1.171 +static inline bool _Stl_is_inf(long double x) { return _Stl_is_inf(__STATIC_CAST(double, x));} 1.172 +static inline bool _Stl_is_neg_inf(long double x) { return _Stl_is_neg_inf(__STATIC_CAST(double, x)); } 1.173 +static inline bool _Stl_is_neg_nan(long double x) { return _Stl_is_neg_nan(__STATIC_CAST(double, x)); } 1.174 +# endif 1.175 +# elif defined (__MRC__) || defined (__SC__) || defined (__DMC__) 1.176 +static bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !isfinite(x); } 1.177 +static bool _Stl_is_inf(double x) { return !isfinite(x); } 1.178 +static bool _Stl_is_neg_inf(double x) { return !isfinite(x) && signbit(x); } 1.179 +static bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); } 1.180 +# elif /* defined(__FreeBSD__) || defined(__OpenBSD__) || */ (defined(__GNUC__) && defined(__APPLE__)) 1.181 +static inline bool _Stl_is_nan_or_inf(double x) { return !finite(x); } 1.182 +static inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && ! isnan(x); } 1.183 +static inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; } 1.184 +static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && copysign(1., x) < 0 ; } 1.185 +# elif defined( _AIX ) // JFA 11-Aug-2000 1.186 +static bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !finite(x); } 1.187 +static bool _Stl_is_inf(double x) { return !finite(x); } 1.188 +// bool _Stl_is_neg_inf(double x) { return _class(x) == FP_MINUS_INF; } 1.189 +static bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && ( copysign(1., x) < 0 ); } 1.190 +static bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); } 1.191 +# elif defined (__ISCPP__) 1.192 +static inline bool _Stl_is_nan_or_inf (double x) { return _fp_isINF(x) || _fp_isNAN(x); } 1.193 +static inline bool _Stl_is_inf (double x) { return _fp_isINF(x); } 1.194 +static inline bool _Stl_is_neg_inf (double x) { return _fp_isINF(x) && x < 0; } 1.195 +static inline bool _Stl_is_neg_nan (double x) { return _fp_isNAN(x) && x < 0; } 1.196 +# elif defined (_CRAY) 1.197 +# if defined (_CRAYIEEE) 1.198 +static inline bool _Stl_is_nan_or_inf(double x) { return isnan(x) || isinf(x); } 1.199 +static inline bool _Stl_is_inf(double x) { return isinf(x); } 1.200 +static inline bool _Stl_is_neg_inf(double x) { return isinf(x) && signbit(x); } 1.201 +static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); } 1.202 +# else 1.203 +static inline bool _Stl_is_nan_or_inf(double x) { return false; } 1.204 +static inline bool _Stl_is_inf(double x) { return false; } 1.205 +static inline bool _Stl_is_neg_inf(double x) { return false; } 1.206 +static inline bool _Stl_is_neg_nan(double x) { return false; } 1.207 +# endif 1.208 +# else // nothing from above 1.209 +# define USE_SPRINTF_INSTEAD 1.210 +# endif 1.211 +#endif // !USE_SPRINTF_INSTEAD 1.212 + 1.213 +#if !defined (USE_SPRINTF_INSTEAD) 1.214 +// Reentrant versions of floating-point conversion functions. The argument 1.215 +// lists look slightly different on different operating systems, so we're 1.216 +// encapsulating the differences here. 1.217 + 1.218 +# if defined (__CYGWIN__) || defined(__DJGPP) 1.219 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 1.220 +{ return ecvtbuf(x, n, pt, sign, buf); } 1.221 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 1.222 +{ return fcvtbuf(x, n, pt, sign, buf); } 1.223 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.224 +# if defined (__CYGWIN__) 1.225 +# define _STLP_EMULATE_LONG_DOUBLE_CVT 1.226 +# else 1.227 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 1.228 +{ return ecvtbuf(x, n, pt, sign, buf); } 1.229 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 1.230 +{ return fcvtbuf(x, n, pt, sign, buf); } 1.231 +# endif 1.232 +# endif 1.233 +# elif defined (_STLP_USE_GLIBC) 1.234 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.235 +{ return ecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 1.236 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.237 +{ return fcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 1.238 +# ifndef _STLP_NO_LONG_DOUBLE 1.239 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.240 +{ return qecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 1.241 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.242 +{ return qfcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; } 1.243 +# endif 1.244 +# define _STLP_NEED_CVT_BUFFER_SIZE 1.245 +# elif defined (__sun) 1.246 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 1.247 +{ return econvert(x, n, pt, sign, buf); } 1.248 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 1.249 +{ return fconvert(x, n, pt, sign, buf); } 1.250 +# ifndef _STLP_NO_LONG_DOUBLE 1.251 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 1.252 +{ return qeconvert(&x, n, pt, sign, buf); } 1.253 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 1.254 +{ return qfconvert(&x, n, pt, sign, buf); } 1.255 +# endif 1.256 +# elif defined (__DECCXX) 1.257 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.258 +{ return (ecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0); } 1.259 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.260 +{ return (fcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0); } 1.261 +# ifndef _STLP_NO_LONG_DOUBLE 1.262 +// fbp : no "long double" conversions ! 1.263 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.264 +{ return (ecvt_r((double)x, n, pt, sign, buf, bsize) == 0 ? buf : 0) ; } 1.265 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize) 1.266 +{ return (fcvt_r((double)x, n, pt, sign, buf, bsize) == 0 ? buf : 0); } 1.267 +# endif 1.268 +# define _STLP_NEED_CVT_BUFFER_SIZE 1.269 +# elif defined (__hpux) 1.270 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign) 1.271 +{ return ecvt(x, n, pt, sign); } 1.272 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign) 1.273 +{ return fcvt(x, n, pt, sign); } 1.274 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.275 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign) 1.276 +{ return _ldecvt(*(long_double*)&x, n, pt, sign); } 1.277 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign) 1.278 +{ return _ldfcvt(*(long_double*)&x, n, pt, sign); } 1.279 +# endif 1.280 +# define _STLP_CVT_NEED_SYNCHRONIZATION 1.281 +# elif defined (__unix) && !defined (__APPLE__) && !defined (_CRAY) && \ 1.282 + !defined (__ANDROID__) 1.283 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 1.284 +{ return ecvt_r(x, n, pt, sign, buf); } 1.285 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 1.286 +{ return fcvt_r(x, n, pt, sign, buf); } 1.287 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.288 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 1.289 +{ return qecvt_r(x, n, pt, sign, buf); } 1.290 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 1.291 +{ return qfcvt_r(x, n, pt, sign, buf); } 1.292 +# endif 1.293 +# elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) 1.294 +# if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 1.295 +# define _STLP_APPEND(a, b) a##b 1.296 +# define _STLP_BUF_PARAMS , char* buf, size_t bsize 1.297 +# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) _STLP_APPEND(F, _s)(buf, bsize, X, N, PT, SIGN); return buf 1.298 +# else 1.299 +# define _STLP_BUF_PARAMS 1.300 +# define _STLP_SECURE_FUN(F, X, N, PT, SIGN) return F(X, N, PT, SIGN) 1.301 +# define _STLP_CVT_NEED_SYNCHRONIZATION 1.302 +# endif 1.303 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 1.304 +{ _STLP_SECURE_FUN(_ecvt, x, n, pt, sign); } 1.305 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 1.306 +{ _STLP_SECURE_FUN(_fcvt, x, n, pt, sign); } 1.307 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.308 +# if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 1.309 +# define _STLP_PARAMS , buf, bsize 1.310 +# else 1.311 +# define _STLP_PARAMS 1.312 +# endif 1.313 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 1.314 +{ return _Stl_ecvtR(__STATIC_CAST(double, x), n, pt, sign _STLP_PARAMS); } 1.315 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS) 1.316 +{ return _Stl_fcvtR(__STATIC_CAST(double, x), n, pt, sign _STLP_PARAMS); } 1.317 +# undef _STLP_PARAMS 1.318 +# endif 1.319 +# undef _STLP_SECURE_FUN 1.320 +# undef _STLP_BUF_PARAMS 1.321 +# undef _STLP_APPEND 1.322 +# if defined (__BORLANDC__) /* || defined (__GNUC__) MinGW do not support 'L' modifier so emulation do not work */ 1.323 +# define _STLP_EMULATE_LONG_DOUBLE_CVT 1.324 +# endif 1.325 +# elif defined (__ISCPP__) 1.326 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) 1.327 +{ return _fp_ecvt( x, n, pt, sign, buf); } 1.328 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) 1.329 +{ return _fp_fcvt(x, n, pt, sign, buf); } 1.330 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.331 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) 1.332 +{ return _fp_ecvt( x, n, pt, sign, buf); } 1.333 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) 1.334 +{ return _fp_fcvt(x, n, pt, sign, buf); } 1.335 +# endif 1.336 +# elif defined (_AIX) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ 1.337 + defined (__MRC__) || defined (__SC__) || defined (_CRAY) || \ 1.338 + defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR) || \ 1.339 + defined (__DMC__) 1.340 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign) 1.341 +{ return ecvt(x, n, pt, sign ); } 1.342 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign) 1.343 +{ return fcvt(x, n, pt, sign); } 1.344 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.345 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign) 1.346 +{ return ecvt(x, n, pt, sign ); } 1.347 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign) 1.348 +{ return fcvt(x, n, pt, sign); } 1.349 +# endif 1.350 +# define _STLP_CVT_NEED_SYNCHRONIZATION 1.351 +# else 1.352 +# error Missing _Stl_ecvtR and _Stl_fcvtR implementations. 1.353 +# endif 1.354 + 1.355 +#if defined (_STLP_CVT_NEED_SYNCHRONIZATION) 1.356 +/* STLport synchronize access to *cvt functions but those methods might 1.357 + * be called from outside, in this case we will still have a race condition. */ 1.358 +# if defined (_STLP_THREADS) 1.359 +static _STLP_STATIC_MUTEX& put_float_mutex() { 1.360 + static _STLP_STATIC_MUTEX __put_float_mutex _STLP_MUTEX_INITIALIZER; 1.361 + return __put_float_mutex; 1.362 +} 1.363 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) { 1.364 + _STLP_auto_lock lock(put_float_mutex()); 1.365 + strcpy(buf, _Stl_ecvtR(x, n, pt, sign)); return buf; 1.366 +} 1.367 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) { 1.368 + _STLP_auto_lock lock(put_float_mutex()); 1.369 + strcpy(buf, _Stl_fcvtR(x, n, pt, sign)); return buf; 1.370 +} 1.371 +# if !defined (_STLP_NO_LONG_DOUBLE) && !defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 1.372 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) { 1.373 + _STLP_auto_lock lock(put_float_mutex()); 1.374 + strcpy(buf, _Stl_ecvtR(x, n, pt, sign)); return buf; 1.375 +} 1.376 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) { 1.377 + _STLP_auto_lock lock(put_float_mutex()); 1.378 + strcpy(buf, _Stl_fcvtR(x, n, pt, sign)); return buf; 1.379 +} 1.380 +# endif 1.381 +# else 1.382 +static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char*) 1.383 +{ return _Stl_ecvtR(x, n, pt, sign); } 1.384 +static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char*) 1.385 +{ return _Stl_fcvtR(x, n, pt, sign); } 1.386 +# if !defined (_STLP_NO_LONG_DOUBLE) && !defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 1.387 +static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char*) 1.388 +{ return _Stl_ecvtR(x, n, pt, sign); } 1.389 +static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char*) 1.390 +{ return _Stl_fcvtR(x, n, pt, sign); } 1.391 +# endif 1.392 +# endif 1.393 +#endif 1.394 + 1.395 +# if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) && !defined (_STLP_NEED_CVT_BUFFER_SIZE) 1.396 +# define _STLP_CVT_BUFFER(B) B 1.397 +# else 1.398 +# define _STLP_CVT_BUFFER(B) _STLP_ARRAY_AND_SIZE(B) 1.399 +# endif 1.400 + 1.401 +# if defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 1.402 +static void __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier); 1.403 + 1.404 +// Emulation of ecvt/fcvt functions using sprintf: 1.405 +static char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) { 1.406 + // If long double value can be safely converted to double without losing precision 1.407 + // we use the ecvt function for double: 1.408 + double y = __STATIC_CAST(double, x); 1.409 + if (x == y) 1.410 + return _Stl_ecvtR(y, n, pt, sign, buf); 1.411 + 1.412 + char fmtbuf[32]; 1.413 + __fill_fmtbuf(fmtbuf, 0, 'L'); 1.414 + sprintf(buf, fmtbuf, n, x < 0.0l ? -x : x); 1.415 + /* We are waiting for something having the form x.xxxe+yyyy */ 1.416 + *pt = 0; 1.417 + *sign = 0; 1.418 + int i = -1; 1.419 + int offset = 0; 1.420 + while (buf[++i] != 0 && n != 0) { 1.421 + if (buf[i] >= '0' && buf[i] <= '9') { 1.422 + --n; 1.423 + if (offset != 0) 1.424 + buf[i - offset] = buf[i]; 1.425 + } 1.426 + else { 1.427 + if (offset != 0) break; 1.428 + ++offset; 1.429 + *pt = i; 1.430 + } 1.431 + } 1.432 + if (offset != 0) 1.433 + buf[i - offset] = 0; 1.434 + // Extract exponent part in point position: 1.435 + int e = 0; 1.436 + while (buf[++i] != 0) { 1.437 + if (buf[i] >= '0' && buf[i] <= '9') { 1.438 + e = e * 10 + (buf[i] - '0'); 1.439 + } 1.440 + } 1.441 + *pt += e; 1.442 + return buf; 1.443 +} 1.444 + 1.445 +static char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) { 1.446 + // If long double value can be safely converted to double without losing precision 1.447 + // we use the fcvt function for double: 1.448 + double y = __STATIC_CAST(double, x); 1.449 + if (x == y) 1.450 + return _Stl_fcvtR(y, n, pt, sign, buf); 1.451 + 1.452 + char fmtbuf[32]; 1.453 + __fill_fmtbuf(fmtbuf, ios_base::fixed, 'L'); 1.454 + sprintf(buf, fmtbuf, n, x < 0.0l ? -x : x); 1.455 + *pt = 0; 1.456 + *sign = 0; 1.457 + int i = -1; 1.458 + int offset = 0; 1.459 + while (buf[++i] != 0 && (offset == 0 || n != 0)) { 1.460 + if (buf[i] >= '0' && buf[i] <= '9') { 1.461 + if (offset != 0) { 1.462 + --n; 1.463 + buf[i - offset] = buf[i]; 1.464 + } 1.465 + } 1.466 + else { 1.467 + ++offset; 1.468 + *pt = i; 1.469 + } 1.470 + } 1.471 + if (offset != 0) 1.472 + buf[i - offset] = 0; 1.473 + else 1.474 + *pt = i; 1.475 + return buf; 1.476 +} 1.477 +#endif 1.478 + 1.479 +//---------------------------------------------------------------------- 1.480 +// num_put 1.481 + 1.482 +// __format_float formats a mantissa and exponent as returned by 1.483 +// one of the conversion functions (ecvt_r, fcvt_r, qecvt_r, qfcvt_r) 1.484 +// according to the specified precision and format flags. This is 1.485 +// based on doprnt but is much simpler since it is concerned only 1.486 +// with floating point input and does not consider all formats. It 1.487 +// also does not deal with blank padding, which is handled by 1.488 +// __copy_float_and_fill. 1.489 + 1.490 +static size_t __format_float_scientific( __iostring& buf, const char *bp, 1.491 + int decpt, int sign, bool is_zero, 1.492 + ios_base::fmtflags flags, 1.493 + int precision) { 1.494 + // sign if required 1.495 + if (sign) 1.496 + buf += '-'; 1.497 + else if (flags & ios_base::showpos) 1.498 + buf += '+'; 1.499 + 1.500 + // first digit of mantissa 1.501 + buf += *bp++; 1.502 + 1.503 + // start of grouping position, grouping won't occur in scientific notation 1.504 + // as it is impossible to have something like 1234.0e04 but we return a correct 1.505 + // group position for coherency with __format_float_fixed. 1.506 + size_t __group_pos = buf.size(); 1.507 + 1.508 + // decimal point if required 1.509 + if (precision != 0 || flags & ios_base::showpoint) { 1.510 + buf += '.'; 1.511 + } 1.512 + 1.513 + // rest of mantissa 1.514 + while (*bp != 0 && precision--) 1.515 + buf += *bp++; 1.516 + 1.517 + // trailing 0 if needed 1.518 + if (precision > 0) 1.519 + buf.append(precision, '0'); 1.520 + 1.521 + // exponent size = number of digits + exponent sign + exponent symbol + trailing zero 1.522 + char expbuf[MAXEDIGITS + 3]; 1.523 + //We start filling at the buffer end 1.524 + char *suffix = expbuf + MAXEDIGITS + 2; 1.525 + *suffix = 0; 1.526 + if (!is_zero) { 1.527 + int nn = decpt - 1; 1.528 + if (nn < 0) 1.529 + nn = -nn; 1.530 + for (; nn > 9; nn /= 10) 1.531 + *--suffix = (char) todigit(nn % 10); 1.532 + *--suffix = (char) todigit(nn); 1.533 + } 1.534 + 1.535 + // prepend leading zeros to exponent 1.536 + // C89 Standard says that it should be at least 2 digits, C99 Standard says that 1.537 + // we stop prepend zeros if more than 3 digits. To repect both STLport prepend zeros 1.538 + // until it is 2 digits. 1.539 + while (suffix > &expbuf[MAXEDIGITS]) 1.540 + *--suffix = '0'; 1.541 + 1.542 + // put in the exponent sign 1.543 + *--suffix = (char) ((decpt > 0 || is_zero ) ? '+' : '-'); 1.544 + 1.545 + // put in the e 1.546 + *--suffix = flags & ios_base::uppercase ? 'E' : 'e'; 1.547 + 1.548 + // copy the suffix 1.549 + buf += suffix; 1.550 + return __group_pos; 1.551 +} 1.552 + 1.553 +static size_t __format_float_fixed( __iostring &buf, const char *bp, 1.554 + int decpt, int sign, 1.555 + ios_base::fmtflags flags, 1.556 + int precision) { 1.557 + if ( sign && (decpt > -precision) && (*bp != 0) ) 1.558 + buf += '-'; 1.559 + else if ( flags & ios_base::showpos ) 1.560 + buf += '+'; 1.561 + 1.562 + // digits before decimal point 1.563 + int nnn = decpt; 1.564 + do { 1.565 + buf += (nnn <= 0 || *bp == 0) ? '0' : *bp++; 1.566 + } while ( --nnn > 0 ); 1.567 + 1.568 + // start of grouping position 1.569 + size_t __group_pos = buf.size(); 1.570 + 1.571 + // decimal point if needed 1.572 + if ( flags & ios_base::showpoint || precision > 0 ) { 1.573 + buf += '.'; 1.574 + } 1.575 + 1.576 + // digits after decimal point if any 1.577 + while ( *bp != 0 && --precision >= 0 ) { 1.578 + buf += (++decpt <= 0) ? '0' : *bp++; 1.579 + } 1.580 + 1.581 + // trailing zeros if needed 1.582 + if (precision > 0) 1.583 + buf.append(precision, '0'); 1.584 + 1.585 + return __group_pos; 1.586 +} 1.587 + 1.588 +#if defined (_STLP_USE_SIGN_HELPER) 1.589 +template<class _FloatT> 1.590 +struct float_sign_helper { 1.591 + float_sign_helper(_FloatT __x) 1.592 + { _M_number._num = __x; } 1.593 + 1.594 + bool is_negative() const { 1.595 + const unsigned short sign_mask(1 << (sizeof(unsigned short) * CHAR_BIT - 1)); 1.596 + return (get_sign_word() & sign_mask) != 0; 1.597 + } 1.598 +private: 1.599 + union { 1.600 + unsigned short _Words[8]; 1.601 + _FloatT _num; 1.602 + } _M_number; 1.603 + 1.604 + unsigned short get_word_higher() const _STLP_NOTHROW 1.605 + { return _M_number._Words[0]; } 1.606 + unsigned short get_word_lower() const _STLP_NOTHROW 1.607 + { return _M_number._Words[(sizeof(_FloatT) >= 12 ? 10 : sizeof(_FloatT)) / sizeof(unsigned short) - 1]; } 1.608 + unsigned short get_sign_word() const _STLP_NOTHROW 1.609 +# if defined (_STLP_BIG_ENDIAN) 1.610 + { return get_word_higher(); } 1.611 +# else /* _STLP_LITTLE_ENDIAN */ 1.612 + { return get_word_lower(); } 1.613 +# endif 1.614 +}; 1.615 +#endif 1.616 + 1.617 +template <class _FloatT> 1.618 +static size_t __format_nan_or_inf(__iostring& buf, _FloatT x, ios_base::fmtflags flags) { 1.619 + static const char* inf[2] = { "inf", "Inf" }; 1.620 + static const char* nan[2] = { "nan", "NaN" }; 1.621 + const char** inf_or_nan; 1.622 +#if !defined (_STLP_USE_SIGN_HELPER) 1.623 + if (_Stl_is_inf(x)) { // Infinity 1.624 + inf_or_nan = inf; 1.625 + if (_Stl_is_neg_inf(x)) 1.626 + buf += '-'; 1.627 + else if (flags & ios_base::showpos) 1.628 + buf += '+'; 1.629 + } else { // NaN 1.630 + inf_or_nan = nan; 1.631 + if (_Stl_is_neg_nan(x)) 1.632 + buf += '-'; 1.633 + else if (flags & ios_base::showpos) 1.634 + buf += '+'; 1.635 + } 1.636 +#else 1.637 + typedef numeric_limits<_FloatT> limits; 1.638 + if (x == limits::infinity() || x == -limits::infinity()) { 1.639 + inf_or_nan = inf; 1.640 + } else { // NaN 1.641 + inf_or_nan = nan; 1.642 + } 1.643 + float_sign_helper<_FloatT> helper(x); 1.644 + if (helper.is_negative()) 1.645 + buf += '-'; 1.646 + else if (flags & ios_base::showpos) 1.647 + buf += '+'; 1.648 +#endif 1.649 + size_t ret = buf.size(); 1.650 + buf += inf_or_nan[flags & ios_base::uppercase ? 1 : 0]; 1.651 + return ret; 1.652 +} 1.653 + 1.654 +static inline size_t __format_float(__iostring &buf, const char * bp, 1.655 + int decpt, int sign, bool is_zero, 1.656 + ios_base::fmtflags flags, 1.657 + int precision) { 1.658 + size_t __group_pos = 0; 1.659 + switch (flags & ios_base::floatfield) { 1.660 + case ios_base::scientific: 1.661 + __group_pos = __format_float_scientific( buf, bp, decpt, sign, is_zero, 1.662 + flags, precision); 1.663 + break; 1.664 + case ios_base::fixed: 1.665 + __group_pos = __format_float_fixed( buf, bp, decpt, sign, 1.666 + flags, precision); 1.667 + break; 1.668 + default: // g format 1.669 + // establish default precision 1.670 + if (flags & ios_base::showpoint || precision > 0) { 1.671 + if (precision == 0) precision = 1; 1.672 + } else 1.673 + precision = 6; 1.674 + 1.675 + // reset exponent if value is zero 1.676 + if (is_zero) 1.677 + decpt = 1; 1.678 + 1.679 + int kk = precision; 1.680 + if (!(flags & ios_base::showpoint)) { 1.681 + size_t n = strlen(bp); 1.682 + if (n < (size_t)kk) 1.683 + kk = (int)n; 1.684 + while (kk >= 1 && bp[kk-1] == '0') 1.685 + --kk; 1.686 + } 1.687 + 1.688 + if (decpt < -3 || decpt > precision) { 1.689 + precision = kk - 1; 1.690 + __group_pos = __format_float_scientific( buf, bp, decpt, sign, is_zero, 1.691 + flags, precision); 1.692 + } else { 1.693 + precision = kk - decpt; 1.694 + __group_pos = __format_float_fixed( buf, bp, decpt, sign, 1.695 + flags, precision); 1.696 + } 1.697 + break; 1.698 + } /* switch */ 1.699 + return __group_pos; 1.700 +} 1.701 + 1.702 +#endif 1.703 + 1.704 +#if defined (USE_SPRINTF_INSTEAD) || defined (_STLP_EMULATE_LONG_DOUBLE_CVT) 1.705 +struct GroupPos { 1.706 + bool operator () (char __c) const { 1.707 + return __c == '.' || 1.708 + __c == 'e' || __c == 'E'; 1.709 + } 1.710 +}; 1.711 + 1.712 +// Creates a format string for sprintf() 1.713 +static void __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier) { 1.714 + fmtbuf[0] = '%'; 1.715 + int i = 1; 1.716 + 1.717 + if (flags & ios_base::showpos) 1.718 + fmtbuf[i++] = '+'; 1.719 + 1.720 + if (flags & ios_base::showpoint) 1.721 + fmtbuf[i++] = '#'; 1.722 + 1.723 + fmtbuf[i++] = '.'; 1.724 + fmtbuf[i++] = '*'; 1.725 + 1.726 + if (long_modifier) 1.727 + fmtbuf[i++] = long_modifier; 1.728 + 1.729 + switch (flags & ios_base::floatfield) 1.730 + { 1.731 + case ios_base::scientific: 1.732 + fmtbuf[i++] = (flags & ios_base::uppercase) ? 'E' : 'e'; 1.733 + break; 1.734 + case ios_base::fixed: 1.735 +# if defined (__FreeBSD__) 1.736 + fmtbuf[i++] = 'f'; 1.737 +# else 1.738 + fmtbuf[i++] = (flags & ios_base::uppercase) ? 'F' : 'f'; 1.739 +# endif 1.740 + break; 1.741 + default: 1.742 + fmtbuf[i++] = (flags & ios_base::uppercase) ? 'G' : 'g'; 1.743 + break; 1.744 + } 1.745 + 1.746 + fmtbuf[i] = 0; 1.747 +} 1.748 + 1.749 +#endif /* USE_SPRINTF_INSTEAD */ 1.750 + 1.751 +template <class _FloatT> 1.752 +static size_t __write_floatT(__iostring &buf, ios_base::fmtflags flags, int precision, 1.753 + _FloatT x 1.754 +#if defined (USE_SPRINTF_INSTEAD) 1.755 + , char modifier) { 1.756 + /* In theory, if we want 'arbitrary' precision, we should use 'arbitrary' 1.757 + * buffer size below, but really we limited by exponent part in double. 1.758 + * - ptr 1.759 + */ 1.760 + typedef numeric_limits<_FloatT> limits; 1.761 + char static_buf[limits::max_exponent10 + 6]; // 6: -xxx.yyyE-zzz (sign, dot, E, exp sign, \0) 1.762 + char fmtbuf[32]; 1.763 + __fill_fmtbuf(fmtbuf, flags, modifier); 1.764 + snprintf(_STLP_ARRAY_AND_SIZE(static_buf), fmtbuf, precision, x); 1.765 + buf = static_buf; 1.766 + return find_if(buf.begin(), buf.end(), GroupPos()) - buf.begin(); 1.767 +#else 1.768 + ) { 1.769 + typedef numeric_limits<_FloatT> limits; 1.770 + //If numeric_limits support is correct we use the exposed values to detect NaN and infinity: 1.771 + if (limits::has_infinity && limits::has_quiet_NaN) { 1.772 + if (!(x == x) || // NaN check 1.773 + (x == limits::infinity() || x == -limits::infinity())) { 1.774 + return __format_nan_or_inf(buf, x, flags); 1.775 + } 1.776 + } 1.777 + // numeric_limits support is not good enough, we rely on platform dependent function 1.778 + // _Stl_is_nan_or_inf that do not support long double. 1.779 + else if (_Stl_is_nan_or_inf(x)) { 1.780 + return __format_nan_or_inf(buf, x, flags); 1.781 + } 1.782 +# if defined (__MINGW32__) 1.783 + //For the moment MinGW is limited to display at most numeric_limits<double>::max() 1.784 + if (x > numeric_limits<double>::max() || 1.785 + x < -numeric_limits<double>::max()) { 1.786 + return __format_nan_or_inf(buf, x, flags); 1.787 + } 1.788 +# endif 1.789 + 1.790 + /* Buffer size is max number of digits which is the addition of: 1.791 + * - max_exponent10: max number of digits in fixed mode 1.792 + * - digits10 + 2: max number of significant digits 1.793 + * - trailing '\0' 1.794 + */ 1.795 + char cvtbuf[limits::max_exponent10 + limits::digits10 + 2 + 1]; 1.796 + char *bp; 1.797 + int decpt, sign; 1.798 + 1.799 + switch (flags & ios_base::floatfield) { 1.800 + case ios_base::fixed: 1.801 + { 1.802 + /* Here, number of digits represents digits _after_ decimal point. 1.803 + * In order to limit static buffer size we have to give 2 different values depending on x value. 1.804 + * For small values (abs(x) < 1) we need as many digits as requested by precision limited by the maximum number of digits 1.805 + * which is min_exponent10 + digits10 + 2 1.806 + * For bigger values we won't have more than limits::digits10 + 2 digits after decimal point. */ 1.807 + int digits10 = (x > -1.0 && x < 1.0 ? -limits::min_exponent10 + limits::digits10 + 2 1.808 + : limits::digits10 + 2); 1.809 + bp = _Stl_fcvtR(x, (min) (precision, digits10), &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf) ); 1.810 + } 1.811 + break; 1.812 + case ios_base::scientific: 1.813 + default: 1.814 + /* Here, number of digits is total number of digits which is limited to digits10 + 2. */ 1.815 + { 1.816 + int digits10 = limits::digits10 + 2; 1.817 + bp = _Stl_ecvtR(x, (min) (precision, digits10), &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf) ); 1.818 + } 1.819 + break; 1.820 + } 1.821 + return __format_float(buf, bp, decpt, sign, x == 0.0, flags, precision); 1.822 +#endif 1.823 +} 1.824 + 1.825 +size_t _STLP_CALL 1.826 +__write_float(__iostring &buf, ios_base::fmtflags flags, int precision, 1.827 + double x) { 1.828 + return __write_floatT(buf, flags, precision, x 1.829 +#if defined (USE_SPRINTF_INSTEAD) 1.830 + , 0 1.831 +#endif 1.832 + ); 1.833 +} 1.834 + 1.835 +#if !defined (_STLP_NO_LONG_DOUBLE) 1.836 +size_t _STLP_CALL 1.837 +__write_float(__iostring &buf, ios_base::fmtflags flags, int precision, 1.838 + long double x) { 1.839 + return __write_floatT(buf, flags, precision, x 1.840 +#if defined (USE_SPRINTF_INSTEAD) 1.841 + , 'L' 1.842 +#endif 1.843 + ); 1.844 +} 1.845 +#endif 1.846 + 1.847 +void _STLP_CALL __get_floor_digits(__iostring &out, _STLP_LONGEST_FLOAT_TYPE __x) { 1.848 + typedef numeric_limits<_STLP_LONGEST_FLOAT_TYPE> limits; 1.849 +#if defined (USE_SPRINTF_INSTEAD) 1.850 + char cvtbuf[limits::max_exponent10 + 6]; 1.851 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.852 + snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%Lf", __x); // check for 1234.56! 1.853 +# else 1.854 + snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%f", __x); // check for 1234.56! 1.855 +# endif 1.856 + char *p = strchr( cvtbuf, '.' ); 1.857 + if ( p == 0 ) { 1.858 + out.append( cvtbuf ); 1.859 + } else { 1.860 + out.append( cvtbuf, p ); 1.861 + } 1.862 +#else 1.863 + char cvtbuf[limits::max_exponent10 + 1]; 1.864 + char * bp; 1.865 + int decpt, sign; 1.866 + bp = _Stl_fcvtR(__x, 0, &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf)); 1.867 + 1.868 + if (sign) { 1.869 + out += '-'; 1.870 + } 1.871 + out.append(bp, bp + decpt); 1.872 +#endif 1.873 +} 1.874 + 1.875 + 1.876 +#if !defined (_STLP_NO_WCHAR_T) 1.877 +void _STLP_CALL __convert_float_buffer( __iostring const& str, __iowstring &out, 1.878 + const ctype<wchar_t>& ct, wchar_t dot, bool __check_dot) { 1.879 + string::const_iterator str_ite(str.begin()), str_end(str.end()); 1.880 + 1.881 + //First loop, check the dot char 1.882 + if (__check_dot) { 1.883 + while (str_ite != str_end) { 1.884 + if (*str_ite != '.') { 1.885 + out += ct.widen(*str_ite++); 1.886 + } else { 1.887 + out += dot; 1.888 + break; 1.889 + } 1.890 + } 1.891 + } else { 1.892 + if (str_ite != str_end) { 1.893 + out += ct.widen(*str_ite); 1.894 + } 1.895 + } 1.896 + 1.897 + if (str_ite != str_end) { 1.898 + //Second loop, dot has been found, no check anymore 1.899 + while (++str_ite != str_end) { 1.900 + out += ct.widen(*str_ite); 1.901 + } 1.902 + } 1.903 +} 1.904 + 1.905 +#endif 1.906 + 1.907 +void _STLP_CALL 1.908 +__adjust_float_buffer(__iostring &str, char dot) { 1.909 + if ('.' != dot) { 1.910 + size_t __dot_pos = str.find('.'); 1.911 + if (__dot_pos != string::npos) { 1.912 + str[__dot_pos] = dot; 1.913 + } 1.914 + } 1.915 +} 1.916 + 1.917 +_STLP_MOVE_TO_STD_NAMESPACE 1.918 +_STLP_END_NAMESPACE 1.919 + 1.920 +// Local Variables: 1.921 +// mode:C++ 1.922 +// End: