build/stlport/src/num_put_float.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright (c) 1999
michael@0 3 * Silicon Graphics Computer Systems, Inc.
michael@0 4 *
michael@0 5 * Copyright (c) 1999
michael@0 6 * Boris Fomitchev
michael@0 7 *
michael@0 8 * This material is provided "as is", with absolutely no warranty expressed
michael@0 9 * or implied. Any use is at your own risk.
michael@0 10 *
michael@0 11 * Permission to use or copy this software for any purpose is hereby granted
michael@0 12 * without fee, provided the above notices are retained on all copies.
michael@0 13 * Permission to modify the code and to distribute modified code is granted,
michael@0 14 * provided the above notices are retained, and a notice that the code was
michael@0 15 * modified is included with the above copyright notice.
michael@0 16 *
michael@0 17 */
michael@0 18
michael@0 19 #include "stlport_prefix.h"
michael@0 20
michael@0 21 #include <cmath>
michael@0 22 #include <ios>
michael@0 23 #include <locale>
michael@0 24
michael@0 25 #if defined (__DECCXX)
michael@0 26 # define NDIG 400
michael@0 27 #else
michael@0 28 # define NDIG 82
michael@0 29 #endif
michael@0 30
michael@0 31 #define todigit(x) ((x)+'0')
michael@0 32
michael@0 33 #if defined (_STLP_UNIX)
michael@0 34
michael@0 35 # if defined (__sun)
michael@0 36 # include <floatingpoint.h>
michael@0 37 # endif
michael@0 38
michael@0 39 # if defined (__sun) || defined (__digital__) || defined (__sgi) || defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
michael@0 40 // DEC, SGI & Solaris need this
michael@0 41 # include <values.h>
michael@0 42 # include <nan.h>
michael@0 43 # endif
michael@0 44
michael@0 45 # if defined (__QNXNTO__) || ( defined(__GNUC__) && defined(__APPLE__) ) || defined(_STLP_USE_UCLIBC) /* 0.9.26 */ || \
michael@0 46 defined(__FreeBSD__)
michael@0 47 # define USE_SPRINTF_INSTEAD
michael@0 48 # endif
michael@0 49
michael@0 50 # if defined (_AIX) // JFA 3-Aug-2000
michael@0 51 # include <math.h>
michael@0 52 # include <float.h>
michael@0 53 # endif
michael@0 54
michael@0 55 # include <math.h>
michael@0 56 #endif
michael@0 57
michael@0 58 #include <cstdio>
michael@0 59 #include <cstdlib>
michael@0 60
michael@0 61 #if defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__) || defined (__DJGPP) || \
michael@0 62 defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
michael@0 63 # include <float.h>
michael@0 64 #endif
michael@0 65
michael@0 66 #if defined (__MRC__) || defined (__SC__) || defined (_CRAY) //*TY 02/24/2000 - added support for MPW
michael@0 67 # include <fp.h>
michael@0 68 #endif
michael@0 69
michael@0 70 #if defined (__CYGWIN__)
michael@0 71 # include <ieeefp.h>
michael@0 72 #endif
michael@0 73
michael@0 74 #if defined (__MSL__)
michael@0 75 # include <cstdlib> // for atoi
michael@0 76 # include <cstdio> // for snprintf
michael@0 77 # include <algorithm>
michael@0 78 # include <cassert>
michael@0 79 #endif
michael@0 80
michael@0 81 #if defined (__ISCPP__)
michael@0 82 # include <cfloat>
michael@0 83 #endif
michael@0 84
michael@0 85 #include <algorithm>
michael@0 86
michael@0 87 #if defined (__DMC__)
michael@0 88 # define snprintf _snprintf
michael@0 89 #endif
michael@0 90
michael@0 91 _STLP_BEGIN_NAMESPACE
michael@0 92
michael@0 93 _STLP_MOVE_TO_PRIV_NAMESPACE
michael@0 94
michael@0 95 #if defined (__MWERKS__) || defined(__BEOS__)
michael@0 96 # define USE_SPRINTF_INSTEAD
michael@0 97 #endif
michael@0 98
michael@0 99 template <int N>
michael@0 100 struct _Dig
michael@0 101 {
michael@0 102 enum { dig = _Dig<N/10>::dig + 1 };
michael@0 103 };
michael@0 104
michael@0 105 _STLP_TEMPLATE_NULL
michael@0 106 struct _Dig<0>
michael@0 107 {
michael@0 108 enum { dig = 0 };
michael@0 109 };
michael@0 110
michael@0 111 #ifdef _STLP_NO_LONG_DOUBLE
michael@0 112 # define MAXEDIGITS int(_Dig<DBL_MAX_10_EXP>::dig)
michael@0 113 # define MAXFSIG DBL_DIG
michael@0 114 # define MAXFCVT (DBL_DIG + 1)
michael@0 115 #else
michael@0 116 # define MAXEDIGITS int(_Dig<LDBL_MAX_10_EXP>::dig)
michael@0 117 # define MAXFSIG LDBL_DIG
michael@0 118 # define MAXFCVT (LDBL_DIG + 1)
michael@0 119 #endif
michael@0 120
michael@0 121 // Tests for infinity and NaN differ on different OSs. We encapsulate
michael@0 122 // these differences here.
michael@0 123 #if !defined (USE_SPRINTF_INSTEAD)
michael@0 124 # if defined (__hpux) && defined (__GNUC__)
michael@0 125 # define _STLP_USE_SIGN_HELPER
michael@0 126 # elif defined (__DJGPP) || (defined (_STLP_USE_GLIBC) && ! defined (__MSL__)) || \
michael@0 127 defined (__CYGWIN__) || \
michael@0 128 defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \
michael@0 129 defined (__HP_aCC)
michael@0 130 static inline bool _Stl_is_nan_or_inf(double x)
michael@0 131 # if defined (isfinite)
michael@0 132 { return !isfinite(x); }
michael@0 133 # else
michael@0 134 { return !finite(x); }
michael@0 135 # endif
michael@0 136 static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); }
michael@0 137 static inline bool _Stl_is_inf(double x) { return isinf(x); }
michael@0 138 // inline bool _Stl_is_neg_inf(double x) { return isinf(x) < 0; }
michael@0 139 static inline bool _Stl_is_neg_inf(double x) { return isinf(x) && x < 0; }
michael@0 140 # elif (defined (__unix) || defined (__unix__)) && \
michael@0 141 !defined (__APPLE__) && !defined (__DJGPP) && !defined(__osf__) && \
michael@0 142 !defined (_CRAY) && !defined (__ANDROID__)
michael@0 143 static inline bool _Stl_is_nan_or_inf(double x) { return IsNANorINF(x); }
michael@0 144 static inline bool _Stl_is_inf(double x) { return IsNANorINF(x) && IsINF(x); }
michael@0 145 static inline bool _Stl_is_neg_inf(double x) { return (IsINF(x)) && (x < 0.0); }
michael@0 146 static inline bool _Stl_is_neg_nan(double x) { return IsNegNAN(x); }
michael@0 147 # elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__)
michael@0 148 static inline bool _Stl_is_nan_or_inf(double x) { return !_finite(x); }
michael@0 149 # if !defined (__BORLANDC__)
michael@0 150 static inline bool _Stl_is_inf(double x) {
michael@0 151 int fclass = _fpclass(x);
michael@0 152 return fclass == _FPCLASS_NINF || fclass == _FPCLASS_PINF;
michael@0 153 }
michael@0 154 static inline bool _Stl_is_neg_inf(double x) { return _fpclass(x) == _FPCLASS_NINF; }
michael@0 155 # else
michael@0 156 static inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && !_isnan(x);}
michael@0 157 static inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; }
michael@0 158 # endif
michael@0 159 static inline bool _Stl_is_neg_nan(double x) { return _isnan(x) && _copysign(1., x) < 0 ; }
michael@0 160 # if defined (__BORLANDC__)
michael@0 161 static inline bool _Stl_is_nan_or_inf(long double x) { return !_finitel(x); }
michael@0 162 static inline bool _Stl_is_inf(long double x) { return _Stl_is_nan_or_inf(x) && !_isnanl(x);}
michael@0 163 static inline bool _Stl_is_neg_inf(long double x) { return _Stl_is_inf(x) && x < 0 ; }
michael@0 164 static inline bool _Stl_is_neg_nan(long double x) { return _isnanl(x) && _copysignl(1.l, x) < 0 ; }
michael@0 165 # elif !defined (_STLP_NO_LONG_DOUBLE)
michael@0 166 // Simply there to avoid warning long double -> double implicit conversion:
michael@0 167 static inline bool _Stl_is_nan_or_inf(long double x) { return _Stl_is_nan_or_inf(__STATIC_CAST(double, x)); }
michael@0 168 static inline bool _Stl_is_inf(long double x) { return _Stl_is_inf(__STATIC_CAST(double, x));}
michael@0 169 static inline bool _Stl_is_neg_inf(long double x) { return _Stl_is_neg_inf(__STATIC_CAST(double, x)); }
michael@0 170 static inline bool _Stl_is_neg_nan(long double x) { return _Stl_is_neg_nan(__STATIC_CAST(double, x)); }
michael@0 171 # endif
michael@0 172 # elif defined (__MRC__) || defined (__SC__) || defined (__DMC__)
michael@0 173 static bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !isfinite(x); }
michael@0 174 static bool _Stl_is_inf(double x) { return !isfinite(x); }
michael@0 175 static bool _Stl_is_neg_inf(double x) { return !isfinite(x) && signbit(x); }
michael@0 176 static bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); }
michael@0 177 # elif /* defined(__FreeBSD__) || defined(__OpenBSD__) || */ (defined(__GNUC__) && defined(__APPLE__))
michael@0 178 static inline bool _Stl_is_nan_or_inf(double x) { return !finite(x); }
michael@0 179 static inline bool _Stl_is_inf(double x) { return _Stl_is_nan_or_inf(x) && ! isnan(x); }
michael@0 180 static inline bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && x < 0 ; }
michael@0 181 static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && copysign(1., x) < 0 ; }
michael@0 182 # elif defined( _AIX ) // JFA 11-Aug-2000
michael@0 183 static bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !finite(x); }
michael@0 184 static bool _Stl_is_inf(double x) { return !finite(x); }
michael@0 185 // bool _Stl_is_neg_inf(double x) { return _class(x) == FP_MINUS_INF; }
michael@0 186 static bool _Stl_is_neg_inf(double x) { return _Stl_is_inf(x) && ( copysign(1., x) < 0 ); }
michael@0 187 static bool _Stl_is_neg_nan(double x) { return isnan(x) && ( copysign(1., x) < 0 ); }
michael@0 188 # elif defined (__ISCPP__)
michael@0 189 static inline bool _Stl_is_nan_or_inf (double x) { return _fp_isINF(x) || _fp_isNAN(x); }
michael@0 190 static inline bool _Stl_is_inf (double x) { return _fp_isINF(x); }
michael@0 191 static inline bool _Stl_is_neg_inf (double x) { return _fp_isINF(x) && x < 0; }
michael@0 192 static inline bool _Stl_is_neg_nan (double x) { return _fp_isNAN(x) && x < 0; }
michael@0 193 # elif defined (_CRAY)
michael@0 194 # if defined (_CRAYIEEE)
michael@0 195 static inline bool _Stl_is_nan_or_inf(double x) { return isnan(x) || isinf(x); }
michael@0 196 static inline bool _Stl_is_inf(double x) { return isinf(x); }
michael@0 197 static inline bool _Stl_is_neg_inf(double x) { return isinf(x) && signbit(x); }
michael@0 198 static inline bool _Stl_is_neg_nan(double x) { return isnan(x) && signbit(x); }
michael@0 199 # else
michael@0 200 static inline bool _Stl_is_nan_or_inf(double x) { return false; }
michael@0 201 static inline bool _Stl_is_inf(double x) { return false; }
michael@0 202 static inline bool _Stl_is_neg_inf(double x) { return false; }
michael@0 203 static inline bool _Stl_is_neg_nan(double x) { return false; }
michael@0 204 # endif
michael@0 205 # else // nothing from above
michael@0 206 # define USE_SPRINTF_INSTEAD
michael@0 207 # endif
michael@0 208 #endif // !USE_SPRINTF_INSTEAD
michael@0 209
michael@0 210 #if !defined (USE_SPRINTF_INSTEAD)
michael@0 211 // Reentrant versions of floating-point conversion functions. The argument
michael@0 212 // lists look slightly different on different operating systems, so we're
michael@0 213 // encapsulating the differences here.
michael@0 214
michael@0 215 # if defined (__CYGWIN__) || defined(__DJGPP)
michael@0 216 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 217 { return ecvtbuf(x, n, pt, sign, buf); }
michael@0 218 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 219 { return fcvtbuf(x, n, pt, sign, buf); }
michael@0 220 # if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 221 # if defined (__CYGWIN__)
michael@0 222 # define _STLP_EMULATE_LONG_DOUBLE_CVT
michael@0 223 # else
michael@0 224 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 225 { return ecvtbuf(x, n, pt, sign, buf); }
michael@0 226 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 227 { return fcvtbuf(x, n, pt, sign, buf); }
michael@0 228 # endif
michael@0 229 # endif
michael@0 230 # elif defined (_STLP_USE_GLIBC)
michael@0 231 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 232 { return ecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; }
michael@0 233 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 234 { return fcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; }
michael@0 235 # ifndef _STLP_NO_LONG_DOUBLE
michael@0 236 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 237 { return qecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; }
michael@0 238 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 239 { return qfcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0; }
michael@0 240 # endif
michael@0 241 # define _STLP_NEED_CVT_BUFFER_SIZE
michael@0 242 # elif defined (__sun)
michael@0 243 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 244 { return econvert(x, n, pt, sign, buf); }
michael@0 245 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 246 { return fconvert(x, n, pt, sign, buf); }
michael@0 247 # ifndef _STLP_NO_LONG_DOUBLE
michael@0 248 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 249 { return qeconvert(&x, n, pt, sign, buf); }
michael@0 250 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 251 { return qfconvert(&x, n, pt, sign, buf); }
michael@0 252 # endif
michael@0 253 # elif defined (__DECCXX)
michael@0 254 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 255 { return (ecvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0); }
michael@0 256 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 257 { return (fcvt_r(x, n, pt, sign, buf, bsize) == 0 ? buf : 0); }
michael@0 258 # ifndef _STLP_NO_LONG_DOUBLE
michael@0 259 // fbp : no "long double" conversions !
michael@0 260 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 261 { return (ecvt_r((double)x, n, pt, sign, buf, bsize) == 0 ? buf : 0) ; }
michael@0 262 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf, size_t bsize)
michael@0 263 { return (fcvt_r((double)x, n, pt, sign, buf, bsize) == 0 ? buf : 0); }
michael@0 264 # endif
michael@0 265 # define _STLP_NEED_CVT_BUFFER_SIZE
michael@0 266 # elif defined (__hpux)
michael@0 267 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign)
michael@0 268 { return ecvt(x, n, pt, sign); }
michael@0 269 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign)
michael@0 270 { return fcvt(x, n, pt, sign); }
michael@0 271 # if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 272 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign)
michael@0 273 { return _ldecvt(*(long_double*)&x, n, pt, sign); }
michael@0 274 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign)
michael@0 275 { return _ldfcvt(*(long_double*)&x, n, pt, sign); }
michael@0 276 # endif
michael@0 277 # define _STLP_CVT_NEED_SYNCHRONIZATION
michael@0 278 # elif defined (__unix) && !defined (__APPLE__) && !defined (_CRAY) && \
michael@0 279 !defined (__ANDROID__)
michael@0 280 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 281 { return ecvt_r(x, n, pt, sign, buf); }
michael@0 282 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 283 { return fcvt_r(x, n, pt, sign, buf); }
michael@0 284 # if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 285 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 286 { return qecvt_r(x, n, pt, sign, buf); }
michael@0 287 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 288 { return qfcvt_r(x, n, pt, sign, buf); }
michael@0 289 # endif
michael@0 290 # elif defined (_STLP_MSVC_LIB) || defined (__MINGW32__) || defined (__BORLANDC__)
michael@0 291 # if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
michael@0 292 # define _STLP_APPEND(a, b) a##b
michael@0 293 # define _STLP_BUF_PARAMS , char* buf, size_t bsize
michael@0 294 # define _STLP_SECURE_FUN(F, X, N, PT, SIGN) _STLP_APPEND(F, _s)(buf, bsize, X, N, PT, SIGN); return buf
michael@0 295 # else
michael@0 296 # define _STLP_BUF_PARAMS
michael@0 297 # define _STLP_SECURE_FUN(F, X, N, PT, SIGN) return F(X, N, PT, SIGN)
michael@0 298 # define _STLP_CVT_NEED_SYNCHRONIZATION
michael@0 299 # endif
michael@0 300 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
michael@0 301 { _STLP_SECURE_FUN(_ecvt, x, n, pt, sign); }
michael@0 302 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
michael@0 303 { _STLP_SECURE_FUN(_fcvt, x, n, pt, sign); }
michael@0 304 # if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 305 # if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
michael@0 306 # define _STLP_PARAMS , buf, bsize
michael@0 307 # else
michael@0 308 # define _STLP_PARAMS
michael@0 309 # endif
michael@0 310 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
michael@0 311 { return _Stl_ecvtR(__STATIC_CAST(double, x), n, pt, sign _STLP_PARAMS); }
michael@0 312 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign _STLP_BUF_PARAMS)
michael@0 313 { return _Stl_fcvtR(__STATIC_CAST(double, x), n, pt, sign _STLP_PARAMS); }
michael@0 314 # undef _STLP_PARAMS
michael@0 315 # endif
michael@0 316 # undef _STLP_SECURE_FUN
michael@0 317 # undef _STLP_BUF_PARAMS
michael@0 318 # undef _STLP_APPEND
michael@0 319 # if defined (__BORLANDC__) /* || defined (__GNUC__) MinGW do not support 'L' modifier so emulation do not work */
michael@0 320 # define _STLP_EMULATE_LONG_DOUBLE_CVT
michael@0 321 # endif
michael@0 322 # elif defined (__ISCPP__)
michael@0 323 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 324 { return _fp_ecvt( x, n, pt, sign, buf); }
michael@0 325 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
michael@0 326 { return _fp_fcvt(x, n, pt, sign, buf); }
michael@0 327 # if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 328 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 329 { return _fp_ecvt( x, n, pt, sign, buf); }
michael@0 330 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf)
michael@0 331 { return _fp_fcvt(x, n, pt, sign, buf); }
michael@0 332 # endif
michael@0 333 # elif defined (_AIX) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \
michael@0 334 defined (__MRC__) || defined (__SC__) || defined (_CRAY) || \
michael@0 335 defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR) || \
michael@0 336 defined (__DMC__)
michael@0 337 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign)
michael@0 338 { return ecvt(x, n, pt, sign ); }
michael@0 339 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign)
michael@0 340 { return fcvt(x, n, pt, sign); }
michael@0 341 # if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 342 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign)
michael@0 343 { return ecvt(x, n, pt, sign ); }
michael@0 344 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign)
michael@0 345 { return fcvt(x, n, pt, sign); }
michael@0 346 # endif
michael@0 347 # define _STLP_CVT_NEED_SYNCHRONIZATION
michael@0 348 # else
michael@0 349 # error Missing _Stl_ecvtR and _Stl_fcvtR implementations.
michael@0 350 # endif
michael@0 351
michael@0 352 #if defined (_STLP_CVT_NEED_SYNCHRONIZATION)
michael@0 353 /* STLport synchronize access to *cvt functions but those methods might
michael@0 354 * be called from outside, in this case we will still have a race condition. */
michael@0 355 # if defined (_STLP_THREADS)
michael@0 356 static _STLP_STATIC_MUTEX& put_float_mutex() {
michael@0 357 static _STLP_STATIC_MUTEX __put_float_mutex _STLP_MUTEX_INITIALIZER;
michael@0 358 return __put_float_mutex;
michael@0 359 }
michael@0 360 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) {
michael@0 361 _STLP_auto_lock lock(put_float_mutex());
michael@0 362 strcpy(buf, _Stl_ecvtR(x, n, pt, sign)); return buf;
michael@0 363 }
michael@0 364 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) {
michael@0 365 _STLP_auto_lock lock(put_float_mutex());
michael@0 366 strcpy(buf, _Stl_fcvtR(x, n, pt, sign)); return buf;
michael@0 367 }
michael@0 368 # if !defined (_STLP_NO_LONG_DOUBLE) && !defined (_STLP_EMULATE_LONG_DOUBLE_CVT)
michael@0 369 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) {
michael@0 370 _STLP_auto_lock lock(put_float_mutex());
michael@0 371 strcpy(buf, _Stl_ecvtR(x, n, pt, sign)); return buf;
michael@0 372 }
michael@0 373 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) {
michael@0 374 _STLP_auto_lock lock(put_float_mutex());
michael@0 375 strcpy(buf, _Stl_fcvtR(x, n, pt, sign)); return buf;
michael@0 376 }
michael@0 377 # endif
michael@0 378 # else
michael@0 379 static inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char*)
michael@0 380 { return _Stl_ecvtR(x, n, pt, sign); }
michael@0 381 static inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char*)
michael@0 382 { return _Stl_fcvtR(x, n, pt, sign); }
michael@0 383 # if !defined (_STLP_NO_LONG_DOUBLE) && !defined (_STLP_EMULATE_LONG_DOUBLE_CVT)
michael@0 384 static inline char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char*)
michael@0 385 { return _Stl_ecvtR(x, n, pt, sign); }
michael@0 386 static inline char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char*)
michael@0 387 { return _Stl_fcvtR(x, n, pt, sign); }
michael@0 388 # endif
michael@0 389 # endif
michael@0 390 #endif
michael@0 391
michael@0 392 # if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) && !defined (_STLP_NEED_CVT_BUFFER_SIZE)
michael@0 393 # define _STLP_CVT_BUFFER(B) B
michael@0 394 # else
michael@0 395 # define _STLP_CVT_BUFFER(B) _STLP_ARRAY_AND_SIZE(B)
michael@0 396 # endif
michael@0 397
michael@0 398 # if defined (_STLP_EMULATE_LONG_DOUBLE_CVT)
michael@0 399 static void __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier);
michael@0 400
michael@0 401 // Emulation of ecvt/fcvt functions using sprintf:
michael@0 402 static char* _Stl_ecvtR(long double x, int n, int* pt, int* sign, char* buf) {
michael@0 403 // If long double value can be safely converted to double without losing precision
michael@0 404 // we use the ecvt function for double:
michael@0 405 double y = __STATIC_CAST(double, x);
michael@0 406 if (x == y)
michael@0 407 return _Stl_ecvtR(y, n, pt, sign, buf);
michael@0 408
michael@0 409 char fmtbuf[32];
michael@0 410 __fill_fmtbuf(fmtbuf, 0, 'L');
michael@0 411 sprintf(buf, fmtbuf, n, x < 0.0l ? -x : x);
michael@0 412 /* We are waiting for something having the form x.xxxe+yyyy */
michael@0 413 *pt = 0;
michael@0 414 *sign = 0;
michael@0 415 int i = -1;
michael@0 416 int offset = 0;
michael@0 417 while (buf[++i] != 0 && n != 0) {
michael@0 418 if (buf[i] >= '0' && buf[i] <= '9') {
michael@0 419 --n;
michael@0 420 if (offset != 0)
michael@0 421 buf[i - offset] = buf[i];
michael@0 422 }
michael@0 423 else {
michael@0 424 if (offset != 0) break;
michael@0 425 ++offset;
michael@0 426 *pt = i;
michael@0 427 }
michael@0 428 }
michael@0 429 if (offset != 0)
michael@0 430 buf[i - offset] = 0;
michael@0 431 // Extract exponent part in point position:
michael@0 432 int e = 0;
michael@0 433 while (buf[++i] != 0) {
michael@0 434 if (buf[i] >= '0' && buf[i] <= '9') {
michael@0 435 e = e * 10 + (buf[i] - '0');
michael@0 436 }
michael@0 437 }
michael@0 438 *pt += e;
michael@0 439 return buf;
michael@0 440 }
michael@0 441
michael@0 442 static char* _Stl_fcvtR(long double x, int n, int* pt, int* sign, char* buf) {
michael@0 443 // If long double value can be safely converted to double without losing precision
michael@0 444 // we use the fcvt function for double:
michael@0 445 double y = __STATIC_CAST(double, x);
michael@0 446 if (x == y)
michael@0 447 return _Stl_fcvtR(y, n, pt, sign, buf);
michael@0 448
michael@0 449 char fmtbuf[32];
michael@0 450 __fill_fmtbuf(fmtbuf, ios_base::fixed, 'L');
michael@0 451 sprintf(buf, fmtbuf, n, x < 0.0l ? -x : x);
michael@0 452 *pt = 0;
michael@0 453 *sign = 0;
michael@0 454 int i = -1;
michael@0 455 int offset = 0;
michael@0 456 while (buf[++i] != 0 && (offset == 0 || n != 0)) {
michael@0 457 if (buf[i] >= '0' && buf[i] <= '9') {
michael@0 458 if (offset != 0) {
michael@0 459 --n;
michael@0 460 buf[i - offset] = buf[i];
michael@0 461 }
michael@0 462 }
michael@0 463 else {
michael@0 464 ++offset;
michael@0 465 *pt = i;
michael@0 466 }
michael@0 467 }
michael@0 468 if (offset != 0)
michael@0 469 buf[i - offset] = 0;
michael@0 470 else
michael@0 471 *pt = i;
michael@0 472 return buf;
michael@0 473 }
michael@0 474 #endif
michael@0 475
michael@0 476 //----------------------------------------------------------------------
michael@0 477 // num_put
michael@0 478
michael@0 479 // __format_float formats a mantissa and exponent as returned by
michael@0 480 // one of the conversion functions (ecvt_r, fcvt_r, qecvt_r, qfcvt_r)
michael@0 481 // according to the specified precision and format flags. This is
michael@0 482 // based on doprnt but is much simpler since it is concerned only
michael@0 483 // with floating point input and does not consider all formats. It
michael@0 484 // also does not deal with blank padding, which is handled by
michael@0 485 // __copy_float_and_fill.
michael@0 486
michael@0 487 static size_t __format_float_scientific( __iostring& buf, const char *bp,
michael@0 488 int decpt, int sign, bool is_zero,
michael@0 489 ios_base::fmtflags flags,
michael@0 490 int precision) {
michael@0 491 // sign if required
michael@0 492 if (sign)
michael@0 493 buf += '-';
michael@0 494 else if (flags & ios_base::showpos)
michael@0 495 buf += '+';
michael@0 496
michael@0 497 // first digit of mantissa
michael@0 498 buf += *bp++;
michael@0 499
michael@0 500 // start of grouping position, grouping won't occur in scientific notation
michael@0 501 // as it is impossible to have something like 1234.0e04 but we return a correct
michael@0 502 // group position for coherency with __format_float_fixed.
michael@0 503 size_t __group_pos = buf.size();
michael@0 504
michael@0 505 // decimal point if required
michael@0 506 if (precision != 0 || flags & ios_base::showpoint) {
michael@0 507 buf += '.';
michael@0 508 }
michael@0 509
michael@0 510 // rest of mantissa
michael@0 511 while (*bp != 0 && precision--)
michael@0 512 buf += *bp++;
michael@0 513
michael@0 514 // trailing 0 if needed
michael@0 515 if (precision > 0)
michael@0 516 buf.append(precision, '0');
michael@0 517
michael@0 518 // exponent size = number of digits + exponent sign + exponent symbol + trailing zero
michael@0 519 char expbuf[MAXEDIGITS + 3];
michael@0 520 //We start filling at the buffer end
michael@0 521 char *suffix = expbuf + MAXEDIGITS + 2;
michael@0 522 *suffix = 0;
michael@0 523 if (!is_zero) {
michael@0 524 int nn = decpt - 1;
michael@0 525 if (nn < 0)
michael@0 526 nn = -nn;
michael@0 527 for (; nn > 9; nn /= 10)
michael@0 528 *--suffix = (char) todigit(nn % 10);
michael@0 529 *--suffix = (char) todigit(nn);
michael@0 530 }
michael@0 531
michael@0 532 // prepend leading zeros to exponent
michael@0 533 // C89 Standard says that it should be at least 2 digits, C99 Standard says that
michael@0 534 // we stop prepend zeros if more than 3 digits. To repect both STLport prepend zeros
michael@0 535 // until it is 2 digits.
michael@0 536 while (suffix > &expbuf[MAXEDIGITS])
michael@0 537 *--suffix = '0';
michael@0 538
michael@0 539 // put in the exponent sign
michael@0 540 *--suffix = (char) ((decpt > 0 || is_zero ) ? '+' : '-');
michael@0 541
michael@0 542 // put in the e
michael@0 543 *--suffix = flags & ios_base::uppercase ? 'E' : 'e';
michael@0 544
michael@0 545 // copy the suffix
michael@0 546 buf += suffix;
michael@0 547 return __group_pos;
michael@0 548 }
michael@0 549
michael@0 550 static size_t __format_float_fixed( __iostring &buf, const char *bp,
michael@0 551 int decpt, int sign,
michael@0 552 ios_base::fmtflags flags,
michael@0 553 int precision) {
michael@0 554 if ( sign && (decpt > -precision) && (*bp != 0) )
michael@0 555 buf += '-';
michael@0 556 else if ( flags & ios_base::showpos )
michael@0 557 buf += '+';
michael@0 558
michael@0 559 // digits before decimal point
michael@0 560 int nnn = decpt;
michael@0 561 do {
michael@0 562 buf += (nnn <= 0 || *bp == 0) ? '0' : *bp++;
michael@0 563 } while ( --nnn > 0 );
michael@0 564
michael@0 565 // start of grouping position
michael@0 566 size_t __group_pos = buf.size();
michael@0 567
michael@0 568 // decimal point if needed
michael@0 569 if ( flags & ios_base::showpoint || precision > 0 ) {
michael@0 570 buf += '.';
michael@0 571 }
michael@0 572
michael@0 573 // digits after decimal point if any
michael@0 574 while ( *bp != 0 && --precision >= 0 ) {
michael@0 575 buf += (++decpt <= 0) ? '0' : *bp++;
michael@0 576 }
michael@0 577
michael@0 578 // trailing zeros if needed
michael@0 579 if (precision > 0)
michael@0 580 buf.append(precision, '0');
michael@0 581
michael@0 582 return __group_pos;
michael@0 583 }
michael@0 584
michael@0 585 #if defined (_STLP_USE_SIGN_HELPER)
michael@0 586 template<class _FloatT>
michael@0 587 struct float_sign_helper {
michael@0 588 float_sign_helper(_FloatT __x)
michael@0 589 { _M_number._num = __x; }
michael@0 590
michael@0 591 bool is_negative() const {
michael@0 592 const unsigned short sign_mask(1 << (sizeof(unsigned short) * CHAR_BIT - 1));
michael@0 593 return (get_sign_word() & sign_mask) != 0;
michael@0 594 }
michael@0 595 private:
michael@0 596 union {
michael@0 597 unsigned short _Words[8];
michael@0 598 _FloatT _num;
michael@0 599 } _M_number;
michael@0 600
michael@0 601 unsigned short get_word_higher() const _STLP_NOTHROW
michael@0 602 { return _M_number._Words[0]; }
michael@0 603 unsigned short get_word_lower() const _STLP_NOTHROW
michael@0 604 { return _M_number._Words[(sizeof(_FloatT) >= 12 ? 10 : sizeof(_FloatT)) / sizeof(unsigned short) - 1]; }
michael@0 605 unsigned short get_sign_word() const _STLP_NOTHROW
michael@0 606 # if defined (_STLP_BIG_ENDIAN)
michael@0 607 { return get_word_higher(); }
michael@0 608 # else /* _STLP_LITTLE_ENDIAN */
michael@0 609 { return get_word_lower(); }
michael@0 610 # endif
michael@0 611 };
michael@0 612 #endif
michael@0 613
michael@0 614 template <class _FloatT>
michael@0 615 static size_t __format_nan_or_inf(__iostring& buf, _FloatT x, ios_base::fmtflags flags) {
michael@0 616 static const char* inf[2] = { "inf", "Inf" };
michael@0 617 static const char* nan[2] = { "nan", "NaN" };
michael@0 618 const char** inf_or_nan;
michael@0 619 #if !defined (_STLP_USE_SIGN_HELPER)
michael@0 620 if (_Stl_is_inf(x)) { // Infinity
michael@0 621 inf_or_nan = inf;
michael@0 622 if (_Stl_is_neg_inf(x))
michael@0 623 buf += '-';
michael@0 624 else if (flags & ios_base::showpos)
michael@0 625 buf += '+';
michael@0 626 } else { // NaN
michael@0 627 inf_or_nan = nan;
michael@0 628 if (_Stl_is_neg_nan(x))
michael@0 629 buf += '-';
michael@0 630 else if (flags & ios_base::showpos)
michael@0 631 buf += '+';
michael@0 632 }
michael@0 633 #else
michael@0 634 typedef numeric_limits<_FloatT> limits;
michael@0 635 if (x == limits::infinity() || x == -limits::infinity()) {
michael@0 636 inf_or_nan = inf;
michael@0 637 } else { // NaN
michael@0 638 inf_or_nan = nan;
michael@0 639 }
michael@0 640 float_sign_helper<_FloatT> helper(x);
michael@0 641 if (helper.is_negative())
michael@0 642 buf += '-';
michael@0 643 else if (flags & ios_base::showpos)
michael@0 644 buf += '+';
michael@0 645 #endif
michael@0 646 size_t ret = buf.size();
michael@0 647 buf += inf_or_nan[flags & ios_base::uppercase ? 1 : 0];
michael@0 648 return ret;
michael@0 649 }
michael@0 650
michael@0 651 static inline size_t __format_float(__iostring &buf, const char * bp,
michael@0 652 int decpt, int sign, bool is_zero,
michael@0 653 ios_base::fmtflags flags,
michael@0 654 int precision) {
michael@0 655 size_t __group_pos = 0;
michael@0 656 switch (flags & ios_base::floatfield) {
michael@0 657 case ios_base::scientific:
michael@0 658 __group_pos = __format_float_scientific( buf, bp, decpt, sign, is_zero,
michael@0 659 flags, precision);
michael@0 660 break;
michael@0 661 case ios_base::fixed:
michael@0 662 __group_pos = __format_float_fixed( buf, bp, decpt, sign,
michael@0 663 flags, precision);
michael@0 664 break;
michael@0 665 default: // g format
michael@0 666 // establish default precision
michael@0 667 if (flags & ios_base::showpoint || precision > 0) {
michael@0 668 if (precision == 0) precision = 1;
michael@0 669 } else
michael@0 670 precision = 6;
michael@0 671
michael@0 672 // reset exponent if value is zero
michael@0 673 if (is_zero)
michael@0 674 decpt = 1;
michael@0 675
michael@0 676 int kk = precision;
michael@0 677 if (!(flags & ios_base::showpoint)) {
michael@0 678 size_t n = strlen(bp);
michael@0 679 if (n < (size_t)kk)
michael@0 680 kk = (int)n;
michael@0 681 while (kk >= 1 && bp[kk-1] == '0')
michael@0 682 --kk;
michael@0 683 }
michael@0 684
michael@0 685 if (decpt < -3 || decpt > precision) {
michael@0 686 precision = kk - 1;
michael@0 687 __group_pos = __format_float_scientific( buf, bp, decpt, sign, is_zero,
michael@0 688 flags, precision);
michael@0 689 } else {
michael@0 690 precision = kk - decpt;
michael@0 691 __group_pos = __format_float_fixed( buf, bp, decpt, sign,
michael@0 692 flags, precision);
michael@0 693 }
michael@0 694 break;
michael@0 695 } /* switch */
michael@0 696 return __group_pos;
michael@0 697 }
michael@0 698
michael@0 699 #endif
michael@0 700
michael@0 701 #if defined (USE_SPRINTF_INSTEAD) || defined (_STLP_EMULATE_LONG_DOUBLE_CVT)
michael@0 702 struct GroupPos {
michael@0 703 bool operator () (char __c) const {
michael@0 704 return __c == '.' ||
michael@0 705 __c == 'e' || __c == 'E';
michael@0 706 }
michael@0 707 };
michael@0 708
michael@0 709 // Creates a format string for sprintf()
michael@0 710 static void __fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier) {
michael@0 711 fmtbuf[0] = '%';
michael@0 712 int i = 1;
michael@0 713
michael@0 714 if (flags & ios_base::showpos)
michael@0 715 fmtbuf[i++] = '+';
michael@0 716
michael@0 717 if (flags & ios_base::showpoint)
michael@0 718 fmtbuf[i++] = '#';
michael@0 719
michael@0 720 fmtbuf[i++] = '.';
michael@0 721 fmtbuf[i++] = '*';
michael@0 722
michael@0 723 if (long_modifier)
michael@0 724 fmtbuf[i++] = long_modifier;
michael@0 725
michael@0 726 switch (flags & ios_base::floatfield)
michael@0 727 {
michael@0 728 case ios_base::scientific:
michael@0 729 fmtbuf[i++] = (flags & ios_base::uppercase) ? 'E' : 'e';
michael@0 730 break;
michael@0 731 case ios_base::fixed:
michael@0 732 # if defined (__FreeBSD__)
michael@0 733 fmtbuf[i++] = 'f';
michael@0 734 # else
michael@0 735 fmtbuf[i++] = (flags & ios_base::uppercase) ? 'F' : 'f';
michael@0 736 # endif
michael@0 737 break;
michael@0 738 default:
michael@0 739 fmtbuf[i++] = (flags & ios_base::uppercase) ? 'G' : 'g';
michael@0 740 break;
michael@0 741 }
michael@0 742
michael@0 743 fmtbuf[i] = 0;
michael@0 744 }
michael@0 745
michael@0 746 #endif /* USE_SPRINTF_INSTEAD */
michael@0 747
michael@0 748 template <class _FloatT>
michael@0 749 static size_t __write_floatT(__iostring &buf, ios_base::fmtflags flags, int precision,
michael@0 750 _FloatT x
michael@0 751 #if defined (USE_SPRINTF_INSTEAD)
michael@0 752 , char modifier) {
michael@0 753 /* In theory, if we want 'arbitrary' precision, we should use 'arbitrary'
michael@0 754 * buffer size below, but really we limited by exponent part in double.
michael@0 755 * - ptr
michael@0 756 */
michael@0 757 typedef numeric_limits<_FloatT> limits;
michael@0 758 char static_buf[limits::max_exponent10 + 6]; // 6: -xxx.yyyE-zzz (sign, dot, E, exp sign, \0)
michael@0 759 char fmtbuf[32];
michael@0 760 __fill_fmtbuf(fmtbuf, flags, modifier);
michael@0 761 snprintf(_STLP_ARRAY_AND_SIZE(static_buf), fmtbuf, precision, x);
michael@0 762 buf = static_buf;
michael@0 763 return find_if(buf.begin(), buf.end(), GroupPos()) - buf.begin();
michael@0 764 #else
michael@0 765 ) {
michael@0 766 typedef numeric_limits<_FloatT> limits;
michael@0 767 //If numeric_limits support is correct we use the exposed values to detect NaN and infinity:
michael@0 768 if (limits::has_infinity && limits::has_quiet_NaN) {
michael@0 769 if (!(x == x) || // NaN check
michael@0 770 (x == limits::infinity() || x == -limits::infinity())) {
michael@0 771 return __format_nan_or_inf(buf, x, flags);
michael@0 772 }
michael@0 773 }
michael@0 774 // numeric_limits support is not good enough, we rely on platform dependent function
michael@0 775 // _Stl_is_nan_or_inf that do not support long double.
michael@0 776 else if (_Stl_is_nan_or_inf(x)) {
michael@0 777 return __format_nan_or_inf(buf, x, flags);
michael@0 778 }
michael@0 779 # if defined (__MINGW32__)
michael@0 780 //For the moment MinGW is limited to display at most numeric_limits<double>::max()
michael@0 781 if (x > numeric_limits<double>::max() ||
michael@0 782 x < -numeric_limits<double>::max()) {
michael@0 783 return __format_nan_or_inf(buf, x, flags);
michael@0 784 }
michael@0 785 # endif
michael@0 786
michael@0 787 /* Buffer size is max number of digits which is the addition of:
michael@0 788 * - max_exponent10: max number of digits in fixed mode
michael@0 789 * - digits10 + 2: max number of significant digits
michael@0 790 * - trailing '\0'
michael@0 791 */
michael@0 792 char cvtbuf[limits::max_exponent10 + limits::digits10 + 2 + 1];
michael@0 793 char *bp;
michael@0 794 int decpt, sign;
michael@0 795
michael@0 796 switch (flags & ios_base::floatfield) {
michael@0 797 case ios_base::fixed:
michael@0 798 {
michael@0 799 /* Here, number of digits represents digits _after_ decimal point.
michael@0 800 * In order to limit static buffer size we have to give 2 different values depending on x value.
michael@0 801 * For small values (abs(x) < 1) we need as many digits as requested by precision limited by the maximum number of digits
michael@0 802 * which is min_exponent10 + digits10 + 2
michael@0 803 * For bigger values we won't have more than limits::digits10 + 2 digits after decimal point. */
michael@0 804 int digits10 = (x > -1.0 && x < 1.0 ? -limits::min_exponent10 + limits::digits10 + 2
michael@0 805 : limits::digits10 + 2);
michael@0 806 bp = _Stl_fcvtR(x, (min) (precision, digits10), &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf) );
michael@0 807 }
michael@0 808 break;
michael@0 809 case ios_base::scientific:
michael@0 810 default:
michael@0 811 /* Here, number of digits is total number of digits which is limited to digits10 + 2. */
michael@0 812 {
michael@0 813 int digits10 = limits::digits10 + 2;
michael@0 814 bp = _Stl_ecvtR(x, (min) (precision, digits10), &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf) );
michael@0 815 }
michael@0 816 break;
michael@0 817 }
michael@0 818 return __format_float(buf, bp, decpt, sign, x == 0.0, flags, precision);
michael@0 819 #endif
michael@0 820 }
michael@0 821
michael@0 822 size_t _STLP_CALL
michael@0 823 __write_float(__iostring &buf, ios_base::fmtflags flags, int precision,
michael@0 824 double x) {
michael@0 825 return __write_floatT(buf, flags, precision, x
michael@0 826 #if defined (USE_SPRINTF_INSTEAD)
michael@0 827 , 0
michael@0 828 #endif
michael@0 829 );
michael@0 830 }
michael@0 831
michael@0 832 #if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 833 size_t _STLP_CALL
michael@0 834 __write_float(__iostring &buf, ios_base::fmtflags flags, int precision,
michael@0 835 long double x) {
michael@0 836 return __write_floatT(buf, flags, precision, x
michael@0 837 #if defined (USE_SPRINTF_INSTEAD)
michael@0 838 , 'L'
michael@0 839 #endif
michael@0 840 );
michael@0 841 }
michael@0 842 #endif
michael@0 843
michael@0 844 void _STLP_CALL __get_floor_digits(__iostring &out, _STLP_LONGEST_FLOAT_TYPE __x) {
michael@0 845 typedef numeric_limits<_STLP_LONGEST_FLOAT_TYPE> limits;
michael@0 846 #if defined (USE_SPRINTF_INSTEAD)
michael@0 847 char cvtbuf[limits::max_exponent10 + 6];
michael@0 848 # if !defined (_STLP_NO_LONG_DOUBLE)
michael@0 849 snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%Lf", __x); // check for 1234.56!
michael@0 850 # else
michael@0 851 snprintf(_STLP_ARRAY_AND_SIZE(cvtbuf), "%f", __x); // check for 1234.56!
michael@0 852 # endif
michael@0 853 char *p = strchr( cvtbuf, '.' );
michael@0 854 if ( p == 0 ) {
michael@0 855 out.append( cvtbuf );
michael@0 856 } else {
michael@0 857 out.append( cvtbuf, p );
michael@0 858 }
michael@0 859 #else
michael@0 860 char cvtbuf[limits::max_exponent10 + 1];
michael@0 861 char * bp;
michael@0 862 int decpt, sign;
michael@0 863 bp = _Stl_fcvtR(__x, 0, &decpt, &sign, _STLP_CVT_BUFFER(cvtbuf));
michael@0 864
michael@0 865 if (sign) {
michael@0 866 out += '-';
michael@0 867 }
michael@0 868 out.append(bp, bp + decpt);
michael@0 869 #endif
michael@0 870 }
michael@0 871
michael@0 872
michael@0 873 #if !defined (_STLP_NO_WCHAR_T)
michael@0 874 void _STLP_CALL __convert_float_buffer( __iostring const& str, __iowstring &out,
michael@0 875 const ctype<wchar_t>& ct, wchar_t dot, bool __check_dot) {
michael@0 876 string::const_iterator str_ite(str.begin()), str_end(str.end());
michael@0 877
michael@0 878 //First loop, check the dot char
michael@0 879 if (__check_dot) {
michael@0 880 while (str_ite != str_end) {
michael@0 881 if (*str_ite != '.') {
michael@0 882 out += ct.widen(*str_ite++);
michael@0 883 } else {
michael@0 884 out += dot;
michael@0 885 break;
michael@0 886 }
michael@0 887 }
michael@0 888 } else {
michael@0 889 if (str_ite != str_end) {
michael@0 890 out += ct.widen(*str_ite);
michael@0 891 }
michael@0 892 }
michael@0 893
michael@0 894 if (str_ite != str_end) {
michael@0 895 //Second loop, dot has been found, no check anymore
michael@0 896 while (++str_ite != str_end) {
michael@0 897 out += ct.widen(*str_ite);
michael@0 898 }
michael@0 899 }
michael@0 900 }
michael@0 901
michael@0 902 #endif
michael@0 903
michael@0 904 void _STLP_CALL
michael@0 905 __adjust_float_buffer(__iostring &str, char dot) {
michael@0 906 if ('.' != dot) {
michael@0 907 size_t __dot_pos = str.find('.');
michael@0 908 if (__dot_pos != string::npos) {
michael@0 909 str[__dot_pos] = dot;
michael@0 910 }
michael@0 911 }
michael@0 912 }
michael@0 913
michael@0 914 _STLP_MOVE_TO_STD_NAMESPACE
michael@0 915 _STLP_END_NAMESPACE
michael@0 916
michael@0 917 // Local Variables:
michael@0 918 // mode:C++
michael@0 919 // End:

mercurial