os/ossrv/stdcpp/src/num_put_float.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
 * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
sl@0
     3
 *
sl@0
     4
 * Copyright (c) 1999
sl@0
     5
 * Silicon Graphics Computer Systems, Inc.
sl@0
     6
 *
sl@0
     7
 * Copyright (c) 1999 
sl@0
     8
 * Boris Fomitchev
sl@0
     9
 *
sl@0
    10
 * This material is provided "as is", with absolutely no warranty expressed
sl@0
    11
 * or implied. Any use is at your own risk.
sl@0
    12
 *
sl@0
    13
 * Permission to use or copy this software for any purpose is hereby granted 
sl@0
    14
 * without fee, provided the above notices are retained on all copies.
sl@0
    15
 * Permission to modify the code and to distribute modified code is granted,
sl@0
    16
 * provided the above notices are retained, and a notice that the code was
sl@0
    17
 * modified is included with the above copyright notice.
sl@0
    18
 *
sl@0
    19
 */
sl@0
    20
sl@0
    21
# include "stlport_prefix.h"
sl@0
    22
sl@0
    23
# ifdef __DECCXX
sl@0
    24
#define NDIG 400
sl@0
    25
# else
sl@0
    26
#define NDIG 82
sl@0
    27
# endif
sl@0
    28
sl@0
    29
# ifdef _STLP_NO_LONG_DOUBLE
sl@0
    30
#  define MAXECVT 17
sl@0
    31
#  define MAXFCVT 18
sl@0
    32
typedef double max_double_type;
sl@0
    33
# else
sl@0
    34
#  define MAXECVT 35
sl@0
    35
#  define MAXFCVT 36
sl@0
    36
typedef long double max_double_type;
sl@0
    37
# endif
sl@0
    38
sl@0
    39
#define MAXFSIG MAXECVT
sl@0
    40
#define MAXESIZ 5
sl@0
    41
sl@0
    42
#define todigit(x) ((x)+'0')
sl@0
    43
sl@0
    44
# include <stl/_config.h>
sl@0
    45
sl@0
    46
# ifdef _STLP_UNIX
sl@0
    47
sl@0
    48
# if defined (__sun) 
sl@0
    49
#  include <floatingpoint.h>
sl@0
    50
# endif
sl@0
    51
sl@0
    52
//# if !(defined(_STLP_USE_GLIBC) || defined(__FreeBSD__) || defined(__NetBSD__) || defined (_AIX) || defined(__MVS__) || defined (__OS400__) || defined (__QNXNTO__) || defined (__APPLE__) || defined (__DJGPP))
sl@0
    53
# if defined (__sun) || defined (__digital__) || defined (__sgi) || defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
sl@0
    54
// DEC, SGI & Solaris need this
sl@0
    55
#  include <values.h>
sl@0
    56
#  include <nan.h>
sl@0
    57
# endif
sl@0
    58
sl@0
    59
# if defined (__QNXNTO__) || ( defined(__GNUC__) && defined(__APPLE__) )
sl@0
    60
#  define USE_SPRINTF_INSTEAD
sl@0
    61
# endif
sl@0
    62
sl@0
    63
#  if defined( _AIX ) // JFA 3-Aug-2000
sl@0
    64
#    include <math.h>
sl@0
    65
#    include <float.h>
sl@0
    66
#  endif
sl@0
    67
sl@0
    68
# endif
sl@0
    69
sl@0
    70
# include <cstdlib>
sl@0
    71
sl@0
    72
//#if defined(_CRAY)
sl@0
    73
//# include <stdlib.h>
sl@0
    74
//#endif
sl@0
    75
sl@0
    76
#if defined (_MSC_VER) || defined (__MINGW32__) || defined (__BORLANDC__) || defined (__DJGPP)  || defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
sl@0
    77
# include <float.h>
sl@0
    78
#endif
sl@0
    79
sl@0
    80
#if defined(__MRC__) || defined(__SC__)	|| defined(_CRAY)	//*TY 02/24/2000 - added support for MPW
sl@0
    81
# include <fp.h>
sl@0
    82
#endif
sl@0
    83
sl@0
    84
#include <cmath>
sl@0
    85
sl@0
    86
#if defined( __MSL__ )
sl@0
    87
# include <cstdlib>	// for atoi
sl@0
    88
# include <cstdio>	// for snprintf
sl@0
    89
# include <algorithm>
sl@0
    90
# include <cassert>
sl@0
    91
#endif
sl@0
    92
sl@0
    93
#if defined (__ISCPP__)
sl@0
    94
# include <cfloat>
sl@0
    95
#endif
sl@0
    96
sl@0
    97
sl@0
    98
# include "num_put.h"
sl@0
    99
# include <algorithm>
sl@0
   100
sl@0
   101
sl@0
   102
#if defined(__hpux) && !defined(_INCLUDE_HPUX_SOURCE)
sl@0
   103
     extern "C" double erf(double);
sl@0
   104
     extern "C" double erfc(double);
sl@0
   105
     extern "C" double gamma(double);                             /* obsolescent */
sl@0
   106
     extern "C" double hypot(double, double);
sl@0
   107
     extern "C" int    isnan(double);
sl@0
   108
     extern "C" double j0(double);
sl@0
   109
     extern "C" double j1(double);
sl@0
   110
     extern "C" double jn(int, double);
sl@0
   111
     extern "C" double lgamma(double);
sl@0
   112
     extern "C" double y0(double);
sl@0
   113
     extern "C" double y1(double);
sl@0
   114
     extern "C" double yn(int, double);
sl@0
   115
sl@0
   116
#  define HUGE_VALF     _SINFINITY
sl@0
   117
#  define INFINITY      _SINFINITY
sl@0
   118
#  define NAN           _SQNAN
sl@0
   119
sl@0
   120
#  define isnan(x)              _ISNAN(x)
sl@0
   121
#  define isinf(x)              _ISINF(x)
sl@0
   122
#  define signbit(x)            _SIGNBIT(x)
sl@0
   123
#  define isfinite(x)           _ISFINITE(x)
sl@0
   124
#  define isnormal(x)           _ISNORMAL(x)
sl@0
   125
#  define fpclassify(x)         _FPCLASSIFY(x)
sl@0
   126
#  define isunordered(x,y)      _ISUNORDERED(x,y)
sl@0
   127
#  define isgreater(x,y)        _ISGREATER(x,y)
sl@0
   128
#  define isgreaterequal(x,y)   _ISGREATEREQUAL(x,y)
sl@0
   129
#  define isless(x,y)           _ISLESS(x,y)
sl@0
   130
#  define islessequal(x,y)      _ISLESSEQUAL(x,y)
sl@0
   131
#  define islessgreater(x,y)    _ISLESSGREATER(x,y)
sl@0
   132
sl@0
   133
#  define FP_NORMAL     0
sl@0
   134
#  define FP_ZERO       1
sl@0
   135
#  define FP_INFINITE   2
sl@0
   136
#  define FP_SUBNORMAL  3
sl@0
   137
#  define FP_NAN        4
sl@0
   138
sl@0
   139
#  define DECIMAL_DIG   17
sl@0
   140
sl@0
   141
#  define _IS64(x) (sizeof(x)==sizeof(double))
sl@0
   142
#  define _IS32(x) (sizeof(x)==sizeof(float))
sl@0
   143
sl@0
   144
extern "C" {
sl@0
   145
     extern double copysign(double, double);
sl@0
   146
     extern const float _SINFINITY;
sl@0
   147
     extern const float _SQNAN;
sl@0
   148
#    ifdef _PA_RISC
sl@0
   149
#      define _ISNAN(x)          (_IS32(x)?_Isnanf(x):(isnan)(x))
sl@0
   150
#      define _ISINF(x)          (_IS32(x)?_Isinff(x):_Isinf(x))
sl@0
   151
#      define _SIGNBIT(x)        (_IS32(x)?_Signbitf(x):_Signbit(x))
sl@0
   152
#      define _ISFINITE(x)       (_IS32(x)?_Isfinitef(x):_Isfinite(x))
sl@0
   153
#      define _ISNORMAL(x)       (_IS32(x)?_Isnormalf(x):_Isnormal(x))
sl@0
   154
#      define _FPCLASSIFY(x)     (_IS32(x)?_Fpclassifyf(x)>>1:_Fpclassify(x)>>1)
sl@0
   155
#      define _ISUNORDERED(x,y)  (_IS32(x)&&_IS32(y)?_Isunorderedf(x,y):_Isunordered(x,y))
sl@0
   156
       extern int _Signbit(double);
sl@0
   157
       extern int _Signbitf(float);
sl@0
   158
       extern int _Isnanf(float);
sl@0
   159
       extern int _Isfinite(double);
sl@0
   160
       extern int _Isfinitef(float);
sl@0
   161
       extern int _Isinf(double);
sl@0
   162
       extern int _Isinff(float);
sl@0
   163
       extern int _Isnormal(double);
sl@0
   164
       extern int _Isnormalf(float);
sl@0
   165
       extern int _Isunordered(double, double);
sl@0
   166
       extern int _Isunorderedf(float, float);
sl@0
   167
       extern int _Fpclassify(double);
sl@0
   168
       extern int _Fpclassifyf(float);
sl@0
   169
#    else
sl@0
   170
#      include "math_ia64_internal.h"
sl@0
   171
#      define _FPCLASSIFY(x)     (_IS32(x)?_Fpclassf(x):_Fpclass(x))
sl@0
   172
       extern int _Fpclass(double);
sl@0
   173
       extern int _Fpclassf(float);
sl@0
   174
#    endif
sl@0
   175
}
sl@0
   176
sl@0
   177
#ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED
sl@0
   178
extern "C" char *fcvt(double, int, int *, int *);
sl@0
   179
extern "C" char *ecvt(double, int, int *, int *);
sl@0
   180
#endif
sl@0
   181
#ifndef _INCLUDE_HPUX_SOURCE
sl@0
   182
#  ifndef _LONG_DOUBLE
sl@0
   183
#    define _LONG_DOUBLE
sl@0
   184
     typedef struct {
sl@0
   185
       uint32_t word1, word2, word3, word4;
sl@0
   186
     } long_double;
sl@0
   187
#  endif /* _LONG_DOUBLE */
sl@0
   188
extern "C" char *_ldecvt(long_double, int, int *, int *);
sl@0
   189
extern "C" char *_ldfcvt(long_double, int, int *, int *);
sl@0
   190
sl@0
   191
#endif
sl@0
   192
sl@0
   193
#endif /* __hpux */
sl@0
   194
sl@0
   195
_STLP_BEGIN_NAMESPACE
sl@0
   196
sl@0
   197
#if defined (__MWERKS__) || defined(__BEOS__)
sl@0
   198
#  define USE_SPRINTF_INSTEAD
sl@0
   199
#endif
sl@0
   200
sl@0
   201
# if defined (_AIX)
sl@0
   202
// Some OS'es only provide non-reentrant primitives, so we have to use additional synchronization here
sl@0
   203
# ifdef _REENTRANT
sl@0
   204
static _STLP_STATIC_MUTEX __put_float_mutex _STLP_MUTEX_INITIALIZER;
sl@0
   205
# define LOCK_CVT _STLP_auto_lock lock(__put_float_mutex);
sl@0
   206
# define RETURN_CVT(ecvt, x, n, pt, sign, buf) strcpy(buf, ecvt(x, n, pt, sign)); return buf;
sl@0
   207
# else
sl@0
   208
# define LOCK_CVT
sl@0
   209
# define RETURN_CVT(ecvt, x, n, pt, sign, buf) return ecvt(x, n, pt, sign);
sl@0
   210
# endif
sl@0
   211
# endif
sl@0
   212
sl@0
   213
// Tests for infinity and NaN differ on different OSs.  We encapsulate
sl@0
   214
// these differences here.
sl@0
   215
sl@0
   216
#ifdef USE_SPRINTF_INSTEAD
sl@0
   217
sl@0
   218
#elif defined (__hpux) || defined (__DJGPP) || ( defined(_STLP_USE_GLIBC) && ! defined (__MSL__) )
sl@0
   219
#  if defined (isfinite) 
sl@0
   220
inline bool _Stl_is_nan_or_inf(double x) { return !isfinite(x); }
sl@0
   221
#  else
sl@0
   222
inline bool _Stl_is_nan_or_inf(double x) { return !finite(x); }
sl@0
   223
#  endif
sl@0
   224
inline bool _Stl_is_neg_nan(double x)    { return isnan(x) && ( copysign(1., x) < 0 ); }
sl@0
   225
inline bool _Stl_is_inf(double x)        { return isinf(x); }
sl@0
   226
// inline bool _Stl_is_neg_inf(double x)    { return isinf(x) < 0; }  
sl@0
   227
inline bool _Stl_is_neg_inf(double x)    { return isinf(x) && x < 0; }
sl@0
   228
#elif defined(__unix) && !defined(__FreeBSD__)  && !defined(__NetBSD__) \
sl@0
   229
      && !defined(__APPLE__)  && !defined(__DJGPP) && !defined(__osf__) \
sl@0
   230
      && !defined(_CRAY)
sl@0
   231
inline bool _Stl_is_nan_or_inf(double x) { return IsNANorINF(x); }
sl@0
   232
inline bool _Stl_is_inf(double x)        { return IsNANorINF(x) && IsINF(x); }
sl@0
   233
inline bool _Stl_is_neg_inf(double x)    { return (IsINF(x)) && (x < 0.0); }
sl@0
   234
inline bool _Stl_is_neg_nan(double x)    { return IsNegNAN(x); }
sl@0
   235
# elif defined (__BORLANDC__) && ( __BORLANDC__ < 0x540 )
sl@0
   236
inline bool _Stl_is_nan_or_inf(double x) {  return !_finite(x); }
sl@0
   237
inline bool _Stl_is_inf(double x)        {  return _Stl_is_nan_or_inf(x) && ! _isnan(x);}
sl@0
   238
inline bool _Stl_is_neg_inf(double x)    {  return _Stl_is_inf(x) && x < 0 ; }
sl@0
   239
inline bool _Stl_is_neg_nan(double x)    { return _isnan(x) && x < 0 ; } 
sl@0
   240
#elif defined (_MSC_VER) || (defined (__MINGW32__) && !defined (__SYMBIAN32__)) || defined (__BORLANDC__) 
sl@0
   241
inline bool _Stl_is_nan_or_inf(double x) { return !_finite(x); }
sl@0
   242
inline bool _Stl_is_inf(double x)        { 
sl@0
   243
  int fclass = _fpclass(x); 
sl@0
   244
  return fclass == _FPCLASS_NINF || fclass == _FPCLASS_PINF; 
sl@0
   245
}
sl@0
   246
inline bool _Stl_is_neg_inf(double x)    { return _fpclass(x) == _FPCLASS_NINF; }
sl@0
   247
inline bool _Stl_is_neg_nan(double x)    { return _isnan(x) && _copysign(1., x) < 0 ; } 
sl@0
   248
#elif defined(__MRC__) || defined(__SC__)		//*TY 02/24/2000 - added support for MPW
sl@0
   249
bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !isfinite(x); }
sl@0
   250
bool _Stl_is_inf(double x)        { return !isfinite(x); }
sl@0
   251
bool _Stl_is_neg_inf(double x)    { return !isfinite(x) && signbit(x); }
sl@0
   252
bool _Stl_is_neg_nan(double x)    { return isnan(x) && signbit(x); }
sl@0
   253
#elif /* defined (__FreeBSD__) */ ( defined (__GNUC__) && defined (__APPLE__) )
sl@0
   254
inline bool _Stl_is_nan_or_inf(double x) { return !finite(x); }
sl@0
   255
inline bool _Stl_is_inf(double x)        {   return _Stl_is_nan_or_inf(x) && ! isnan(x); }
sl@0
   256
inline bool _Stl_is_neg_inf(double x)    {   return _Stl_is_inf(x) && x < 0 ; }
sl@0
   257
inline bool _Stl_is_neg_nan(double x)    { return isnan(x) && copysign(1., x) < 0 ; } 
sl@0
   258
#elif defined( _AIX ) // JFA 11-Aug-2000
sl@0
   259
bool _Stl_is_nan_or_inf(double x) { return isnan(x) || !finite(x); }
sl@0
   260
bool _Stl_is_inf(double x)        { return !finite(x); }
sl@0
   261
// bool _Stl_is_neg_inf(double x)    { return _class(x) == FP_MINUS_INF; }
sl@0
   262
bool _Stl_is_neg_inf(double x)    { return _Stl_is_inf(x) && ( copysign(1., x) < 0 );  }
sl@0
   263
bool _Stl_is_neg_nan(double x)    { return isnan(x) && ( copysign(1., x) < 0 );  }
sl@0
   264
#elif defined (__ISCPP__)
sl@0
   265
inline bool _Stl_is_nan_or_inf  (double x) { return _fp_isINF(x) || _fp_isNAN(x); }
sl@0
   266
inline bool _Stl_is_inf         (double x) { return _fp_isINF(x); }
sl@0
   267
inline bool _Stl_is_neg_inf     (double x) { return _fp_isINF(x) && x < 0; }
sl@0
   268
inline bool _Stl_is_neg_nan     (double x) { return _fp_isNAN(x) && x < 0; }
sl@0
   269
#elif defined(_CRAY)
sl@0
   270
 #if defined(_CRAYIEEE)
sl@0
   271
inline bool _Stl_is_nan_or_inf(double x) { return isnan(x) || isinf(x); }
sl@0
   272
inline bool _Stl_is_inf(double x)        { return isinf(x); }
sl@0
   273
inline bool _Stl_is_neg_inf(double x)    { return isinf(x) && signbit(x); }
sl@0
   274
inline bool _Stl_is_neg_nan(double x)    { return isnan(x) && signbit(x); }
sl@0
   275
 #else
sl@0
   276
inline bool _Stl_is_nan_or_inf(double x) { return false; }
sl@0
   277
inline bool _Stl_is_inf(double x)        { return false; }
sl@0
   278
inline bool _Stl_is_neg_inf(double x)    { return false; }
sl@0
   279
inline bool _Stl_is_neg_nan(double x)    { return false; }
sl@0
   280
 #endif
sl@0
   281
#elif ! defined (USE_SPRINTF_INSTEAD)
sl@0
   282
# define USE_SPRINTF_INSTEAD
sl@0
   283
#endif
sl@0
   284
sl@0
   285
sl@0
   286
# ifndef  USE_SPRINTF_INSTEAD
sl@0
   287
// Reentrant versions of floating-point conversion functions.  The argument
sl@0
   288
// lists look slightly different on different operating systems, so we're
sl@0
   289
// encapsulating the differences here.
sl@0
   290
sl@0
   291
#if defined (__CYGWIN__) || defined(__DJGPP)
sl@0
   292
  inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   293
    { return ecvtbuf(x, n, pt, sign, buf); }
sl@0
   294
  inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   295
    { return fcvtbuf(x, n, pt, sign, buf); }
sl@0
   296
# ifndef _STLP_NO_LONG_DOUBLE
sl@0
   297
  inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   298
    { return ecvtbuf(x, n, pt, sign, buf); }
sl@0
   299
  inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   300
    { return fcvtbuf(x, n, pt, sign, buf); }
sl@0
   301
# endif
sl@0
   302
#elif defined (_STLP_USE_GLIBC)
sl@0
   303
  inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   304
    { return buf + ecvt_r(x, n, pt, sign, buf, NDIG+2); }
sl@0
   305
  inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   306
    { return buf + fcvt_r(x, n, pt, sign, buf, NDIG+2); }
sl@0
   307
#  ifndef _STLP_NO_LONG_DOUBLE
sl@0
   308
  inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   309
    { return buf + qecvt_r(x, n, pt, sign, buf, NDIG+2); }
sl@0
   310
  inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   311
    { return buf + qfcvt_r(x, n, pt, sign, buf, NDIG+2); }
sl@0
   312
#  endif
sl@0
   313
#elif defined (_STLP_SCO_OPENSERVER) || defined (__NCR_SVR)
sl@0
   314
  inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   315
    { return ecvt(x, n, pt, sign); }
sl@0
   316
  inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   317
    { return fcvt(x, n, pt, sign); }
sl@0
   318
#  ifndef _STLP_NO_LONG_DOUBLE
sl@0
   319
  inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   320
    { return ecvtl(x, n, pt, sign); }
sl@0
   321
  inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   322
    { return fcvtl(x, n, pt, sign); }
sl@0
   323
#  endif
sl@0
   324
#elif defined (__sun)
sl@0
   325
  inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   326
    { return econvert(x, n, pt, sign, buf); }
sl@0
   327
  inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   328
    { return fconvert(x, n, pt, sign, buf); }
sl@0
   329
#  ifndef _STLP_NO_LONG_DOUBLE
sl@0
   330
  inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   331
    { return qeconvert(&x, n, pt, sign, buf); }
sl@0
   332
  inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   333
    { return qfconvert(&x, n, pt, sign, buf); }
sl@0
   334
#  endif
sl@0
   335
#elif defined (__DECCXX) 
sl@0
   336
  inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   337
    { return (ecvt_r(x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
sl@0
   338
  inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   339
    { return (fcvt_r(x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
sl@0
   340
#  ifndef _STLP_NO_LONG_DOUBLE
sl@0
   341
// fbp : no "long double" conversions !
sl@0
   342
  inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   343
    { return (ecvt_r((double)x, n, pt, sign, buf, NDIG)==0 ? buf : 0) ; }
sl@0
   344
  inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   345
    { return (fcvt_r((double)x, n, pt, sign, buf, NDIG)==0 ? buf : 0); }
sl@0
   346
#  endif
sl@0
   347
#elif defined (__hpux)
sl@0
   348
   inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   349
     { return ecvt(x, n, pt, sign); }
sl@0
   350
   inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   351
     { return fcvt(x, n, pt, sign); }
sl@0
   352
# ifndef _STLP_NO_LONG_DOUBLE
sl@0
   353
sl@0
   354
#  if defined( _REENTRANT ) && (defined(_PTHREADS_DRAFT4) || defined(PTHREAD_THREADS_MAX))
sl@0
   355
   inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   356
     { return (_ldecvt_r(*(long_double*)&x, n, pt, sign, buf, NDIG+2)==0 ? buf : 0); }
sl@0
   357
   inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   358
     { return (_ldfcvt_r(*(long_double*)&x, n, pt, sign, buf, NDIG+2)==0 ? buf : 0); }
sl@0
   359
#  else
sl@0
   360
   inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   361
     { return _ldecvt(*(long_double*)&x, n, pt, sign); }
sl@0
   362
   inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   363
     { return _ldfcvt(*(long_double*)&x, n, pt, sign); }
sl@0
   364
#  endif
sl@0
   365
# endif
sl@0
   366
#elif defined (_AIX)
sl@0
   367
  inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   368
    { LOCK_CVT RETURN_CVT(ecvt, x, n, pt, sign, buf) }
sl@0
   369
  inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   370
    { LOCK_CVT RETURN_CVT(fcvt, x, n, pt, sign, buf) }
sl@0
   371
# ifndef _STLP_NO_LONG_DOUBLE
sl@0
   372
  inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   373
    { LOCK_CVT RETURN_CVT(ecvt, x, n, pt, sign, buf) }
sl@0
   374
  inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   375
    { LOCK_CVT RETURN_CVT(fcvt, x, n, pt, sign, buf) }
sl@0
   376
# endif
sl@0
   377
#elif defined (__unix)  && !defined(__FreeBSD__)  && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_CRAY)
sl@0
   378
  inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   379
    { return ecvt_r(x, n, pt, sign, buf); }
sl@0
   380
  inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   381
    { return fcvt_r(x, n, pt, sign, buf); }
sl@0
   382
# ifndef _STLP_NO_LONG_DOUBLE
sl@0
   383
  inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   384
    { return qecvt_r(x, n, pt, sign, buf); }
sl@0
   385
  inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   386
    { return qfcvt_r(x, n, pt, sign, buf); }
sl@0
   387
#  endif
sl@0
   388
#elif defined (_MSC_VER) || defined (__MINGW32__) || defined (__BORLANDC__)
sl@0
   389
// those guys claim _cvt functions being reentrant.
sl@0
   390
inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) {  return _ecvt(x, n, pt, sign); }
sl@0
   391
inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf) { return _fcvt(x, n, pt, sign); }
sl@0
   392
# ifndef _STLP_NO_LONG_DOUBLE
sl@0
   393
inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf) { return _ecvt((double)x, n, pt, sign); }
sl@0
   394
inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf) { return _fcvt((double)x, n, pt, sign); }
sl@0
   395
# endif
sl@0
   396
#elif defined (__ISCPP__)
sl@0
   397
inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   398
{ return _fp_ecvt( x, n, pt, sign, buf); }
sl@0
   399
sl@0
   400
inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* buf)
sl@0
   401
{ return _fp_fcvt(x, n, pt, sign, buf); }
sl@0
   402
sl@0
   403
# ifndef _STLP_NO_LONG_DOUBLE
sl@0
   404
inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   405
{ return _fp_ecvt( x, n, pt, sign, buf); }
sl@0
   406
sl@0
   407
inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* buf)
sl@0
   408
{ return _fp_fcvt(x, n, pt, sign, buf); }
sl@0
   409
# endif
sl@0
   410
#elif defined (__MRC__) || defined(__SC__) || defined(_CRAY)
sl@0
   411
inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* )
sl@0
   412
{ return ecvt( x, n, pt, sign ); }
sl@0
   413
inline char* _Stl_fcvtR(double x, int n, int* pt, int* sign, char* )
sl@0
   414
{ return fcvt(x, n, pt, sign); }
sl@0
   415
#ifndef _STLP_NO_LONG_DOUBLE
sl@0
   416
inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* )
sl@0
   417
{ return ecvt( x, n, pt, sign ); }
sl@0
   418
inline char* _Stl_qfcvtR(long double x, int n, int* pt, int* sign, char* )
sl@0
   419
{ return fcvt(x, n, pt, sign); }
sl@0
   420
#endif
sl@0
   421
#endif
sl@0
   422
sl@0
   423
sl@0
   424
//----------------------------------------------------------------------
sl@0
   425
// num_put
sl@0
   426
sl@0
   427
// Helper functions for _M_do_put_float
sl@0
   428
sl@0
   429
// __format_float formats a mantissa and exponent as returned by
sl@0
   430
// one of the conversion functions (ecvt_r, fcvt_r, qecvt_r, qfcvt_r)
sl@0
   431
// according to the specified precision and format flags.  This is
sl@0
   432
// based on doprnt but is much simpler since it is concerned only
sl@0
   433
// with floating point input and does not consider all formats.  It
sl@0
   434
// also does not deal with blank padding, which is handled by
sl@0
   435
// __copy_float_and_fill. 
sl@0
   436
sl@0
   437
void __format_float_scientific(char * buf, const char * bp, 
sl@0
   438
			       int decpt, int sign, bool is_zero,
sl@0
   439
			       ios_base::fmtflags flags,
sl@0
   440
			       int precision, bool /* islong */)
sl@0
   441
{
sl@0
   442
  char * suffix;
sl@0
   443
  char expbuf[MAXESIZ + 2];
sl@0
   444
  // sign if required
sl@0
   445
  if (sign)
sl@0
   446
    *buf++ = '-';
sl@0
   447
  else if (flags & ios_base::showpos)
sl@0
   448
    *buf++ = '+';
sl@0
   449
  
sl@0
   450
  // first digit of mantissa
sl@0
   451
  *buf++ = *bp++;
sl@0
   452
sl@0
   453
  // decimal point if required
sl@0
   454
  if (precision != 0 || flags & ios_base::showpoint)
sl@0
   455
    *buf++ = '.';
sl@0
   456
  // rest of mantissa
sl@0
   457
  int rz = precision;
sl@0
   458
  while (rz-- > 0 && *bp != 0)
sl@0
   459
    *buf++ = *bp++;
sl@0
   460
sl@0
   461
  // exponent
sl@0
   462
  *(suffix = &expbuf[MAXESIZ]) = 0;
sl@0
   463
  if (!is_zero) {
sl@0
   464
    int nn = decpt - 1;
sl@0
   465
    if (nn < 0)
sl@0
   466
      nn = -nn;
sl@0
   467
    for (; nn > 9; nn /= 10)
sl@0
   468
      *--suffix = (char) todigit(nn % 10);
sl@0
   469
    *--suffix = (char) todigit(nn);
sl@0
   470
  }
sl@0
   471
  	
sl@0
   472
  // prepend leading zeros to exponent
sl@0
   473
  while (suffix > &expbuf[MAXESIZ - 2])
sl@0
   474
    *--suffix = '0';
sl@0
   475
  
sl@0
   476
  // put in the exponent sign
sl@0
   477
  *--suffix = (char) ((decpt > 0 || is_zero ) ? '+' : '-');
sl@0
   478
  
sl@0
   479
  // put in the e
sl@0
   480
  *--suffix = flags & ios_base::uppercase ? 'E' : 'e';
sl@0
   481
sl@0
   482
  // copy the suffix
sl@0
   483
  strcpy(buf, suffix);
sl@0
   484
}
sl@0
   485
sl@0
   486
static inline 
sl@0
   487
void __flush_static_buf(string &buf, 
sl@0
   488
                        char *sbeginbuf, char *sendbuf, char *&scurpos) {
sl@0
   489
  if (scurpos == sendbuf) {
sl@0
   490
    buf.append(sbeginbuf, sendbuf);
sl@0
   491
    scurpos = sbeginbuf;
sl@0
   492
  }
sl@0
   493
}
sl@0
   494
  
sl@0
   495
void __format_float_fixed(string &buf, const char * bp,
sl@0
   496
			  int decpt, int sign, bool /* x */,
sl@0
   497
			  ios_base::fmtflags flags,
sl@0
   498
			  int precision, bool islong )
sl@0
   499
{
sl@0
   500
  char static_buf[128];
sl@0
   501
  char *sbuf = static_buf;
sl@0
   502
  char *sendbuf = static_buf + sizeof(static_buf);
sl@0
   503
sl@0
   504
  if (sign && decpt > -precision && *bp != 0)
sl@0
   505
    *sbuf++ = '-';
sl@0
   506
  else if (flags & ios_base::showpos)
sl@0
   507
    *sbuf++ = '+';
sl@0
   508
  
sl@0
   509
  int rzero   = 0;
sl@0
   510
  int nn      = decpt;
sl@0
   511
  int k       = 0;
sl@0
   512
  int maxfsig = islong ? 2*MAXFSIG : MAXFSIG;
sl@0
   513
sl@0
   514
  do {
sl@0
   515
    *sbuf++ = (char) ((nn <= 0 || *bp == 0 || k >= maxfsig) ?
sl@0
   516
      '0' : (k++, *bp++));
sl@0
   517
    __flush_static_buf(buf, static_buf, sendbuf, sbuf);
sl@0
   518
  } while (--nn > 0);
sl@0
   519
sl@0
   520
  // decimal point if needed
sl@0
   521
  if (flags & ios_base::showpoint || precision > 0) {
sl@0
   522
    *sbuf++ = '.';
sl@0
   523
    __flush_static_buf(buf, static_buf, sendbuf, sbuf);
sl@0
   524
  }
sl@0
   525
sl@0
   526
  // digits after decimal point if any
sl@0
   527
  nn = (min) (precision, MAXFCVT);
sl@0
   528
  if (precision > nn)
sl@0
   529
    rzero = precision - nn;
sl@0
   530
  while (--nn >= 0) {
sl@0
   531
    *sbuf++ = (++decpt <= 0 || *bp == '\0' || k >= maxfsig)
sl@0
   532
      		? '0' : (k++, *bp++);
sl@0
   533
    __flush_static_buf(buf, static_buf, sendbuf, sbuf);
sl@0
   534
  }
sl@0
   535
sl@0
   536
  // trailing zeros if needed
sl@0
   537
  while (rzero-- > 0) {
sl@0
   538
    *sbuf++ = '0';
sl@0
   539
    __flush_static_buf(buf, static_buf, sendbuf, sbuf);
sl@0
   540
  }
sl@0
   541
  buf.append(static_buf, sbuf);
sl@0
   542
}
sl@0
   543
sl@0
   544
sl@0
   545
void __format_nan_or_inf(char * buf, double x,
sl@0
   546
			 ios_base::fmtflags flags)
sl@0
   547
{
sl@0
   548
  static const char* inf[2] = { "inf", "Inf" };
sl@0
   549
  static const char* nan[2] = { "nan", "NaN" };
sl@0
   550
  const char** inf_or_nan = 0;
sl@0
   551
  if (_Stl_is_inf((double)x)) {            // Infinity
sl@0
   552
    inf_or_nan = inf;
sl@0
   553
    if (_Stl_is_neg_inf((double)x))
sl@0
   554
      *buf++ = '-';
sl@0
   555
    else if (flags & ios_base::showpos)
sl@0
   556
      *buf++ = '+';
sl@0
   557
  }
sl@0
   558
  else {                      // NaN
sl@0
   559
    inf_or_nan = nan;
sl@0
   560
    if (_Stl_is_neg_nan((double)x))
sl@0
   561
      *buf++ = '-';
sl@0
   562
    else if (flags & ios_base::showpos)
sl@0
   563
      *buf++ = '+';
sl@0
   564
  }
sl@0
   565
  strcpy(buf, flags & ios_base::uppercase ? inf_or_nan[1] : inf_or_nan[0]);  
sl@0
   566
}
sl@0
   567
sl@0
   568
template <class max_double_type>
sl@0
   569
static inline 
sl@0
   570
void __format_float(string &buf, const char * bp,
sl@0
   571
                    int decpt, int sign, max_double_type x,
sl@0
   572
                    ios_base::fmtflags flags,
sl@0
   573
                    int precision, bool islong)
sl@0
   574
{
sl@0
   575
  char static_buf[128];
sl@0
   576
  // Output of infinities and NANs does not depend on the format flags
sl@0
   577
  if (_Stl_is_nan_or_inf((double)x)) {       // Infinity or NaN
sl@0
   578
    __format_nan_or_inf(static_buf, x, flags);
sl@0
   579
    buf = static_buf;
sl@0
   580
  } 
sl@0
   581
  else {                        // representable number
sl@0
   582
    switch (flags & ios_base::floatfield) {
sl@0
   583
    case ios_base::scientific:
sl@0
   584
      __format_float_scientific(static_buf, bp, decpt, sign, x == 0.0, flags,
sl@0
   585
                                precision, islong);
sl@0
   586
      buf = static_buf;
sl@0
   587
      break;
sl@0
   588
      
sl@0
   589
    case ios_base::fixed:
sl@0
   590
      __format_float_fixed(buf, bp, decpt, sign, true, flags,
sl@0
   591
                           precision, islong);
sl@0
   592
      break;
sl@0
   593
      
sl@0
   594
    default: // g format
sl@0
   595
      // establish default precision
sl@0
   596
      if (flags & ios_base::showpoint || precision > 0) {
sl@0
   597
        if (precision == 0) precision = 1;
sl@0
   598
      }
sl@0
   599
      else
sl@0
   600
        precision = 6;
sl@0
   601
      
sl@0
   602
      // reset exponent if value is zero
sl@0
   603
      if (x == 0)
sl@0
   604
        decpt = 1;
sl@0
   605
      
sl@0
   606
      int kk = precision;
sl@0
   607
      if (!(flags & ios_base::showpoint)) {
sl@0
   608
        size_t n = strlen(bp);
sl@0
   609
        if (n < kk)
sl@0
   610
          kk = (int)n;
sl@0
   611
        while (kk >= 1 && bp[kk-1] == '0')
sl@0
   612
          --kk;
sl@0
   613
      }
sl@0
   614
      
sl@0
   615
      if (decpt < -3 || decpt > precision) {
sl@0
   616
        precision = kk - 1;
sl@0
   617
        __format_float_scientific(static_buf, bp, decpt, sign, x == 0,
sl@0
   618
                                  flags, precision, islong);
sl@0
   619
        buf = static_buf;
sl@0
   620
      }
sl@0
   621
      else {
sl@0
   622
        precision = kk - decpt;
sl@0
   623
        __format_float_fixed(buf, bp, decpt, sign, true,
sl@0
   624
                             flags, precision, islong);
sl@0
   625
      }
sl@0
   626
      break;
sl@0
   627
    } /* switch */
sl@0
   628
  } /* else */
sl@0
   629
}
sl@0
   630
sl@0
   631
# else
sl@0
   632
// Creates a format string for sprintf()
sl@0
   633
static int fill_fmtbuf(char* fmtbuf, ios_base::fmtflags flags, char long_modifier)
sl@0
   634
{
sl@0
   635
  fmtbuf[0] = '%';
sl@0
   636
  int i = 1;
sl@0
   637
sl@0
   638
  if (flags & ios_base::showpos)
sl@0
   639
    fmtbuf[i++] = '+';
sl@0
   640
sl@0
   641
  if (flags & ios_base::showpoint)
sl@0
   642
    fmtbuf[i++] = '#';
sl@0
   643
sl@0
   644
  fmtbuf[i++] = '.';
sl@0
   645
  fmtbuf[i++] = '*';
sl@0
   646
  
sl@0
   647
  if (long_modifier)
sl@0
   648
    fmtbuf[i++] = long_modifier;
sl@0
   649
sl@0
   650
  switch (flags & ios_base::floatfield)
sl@0
   651
    {
sl@0
   652
    case ios_base::scientific:
sl@0
   653
      fmtbuf[i++] = (flags & ios_base::uppercase) ?  'E' : 'e';      
sl@0
   654
      break;
sl@0
   655
    case ios_base::fixed:
sl@0
   656
#if defined (__FreeBSD__)
sl@0
   657
      fmtbuf[i++] = 'f';
sl@0
   658
#else
sl@0
   659
      fmtbuf[i++] = (flags & ios_base::uppercase) ? 'F' : 'f'; 
sl@0
   660
#endif
sl@0
   661
      break;
sl@0
   662
    default:
sl@0
   663
      fmtbuf[i++] = (flags & ios_base::uppercase) ?  'G' : 'g';      
sl@0
   664
      break;
sl@0
   665
    }
sl@0
   666
sl@0
   667
  fmtbuf[i] = 0;
sl@0
   668
  return i;
sl@0
   669
}
sl@0
   670
# endif  /* USE_SPRINTF_INSTEAD */
sl@0
   671
sl@0
   672
sl@0
   673
_STLP_EXP_DECLSPEC void  _STLP_CALL
sl@0
   674
__write_float(string &buf, ios_base::fmtflags flags, int precision,
sl@0
   675
              double x)
sl@0
   676
{
sl@0
   677
# ifdef USE_SPRINTF_INSTEAD
sl@0
   678
  char static_buf[256+10];//+2 - 10/1/07
sl@0
   679
  char fmtbuf[32];
sl@0
   680
  fill_fmtbuf(fmtbuf, flags, 0);
sl@0
   681
  sprintf(static_buf, fmtbuf, precision, x);    
sl@0
   682
  // we should be able to return static_buf + sprintf(), but we do not trust'em...
sl@0
   683
  buf = static_buf;
sl@0
   684
# else
sl@0
   685
  char cvtbuf[NDIG+2];
sl@0
   686
  char * bp;
sl@0
   687
  int decpt, sign;
sl@0
   688
sl@0
   689
  switch (flags & ios_base::floatfield) {
sl@0
   690
  case ios_base::fixed:
sl@0
   691
    bp = _Stl_fcvtR(x, (min) (precision, MAXFCVT), &decpt, &sign, cvtbuf);
sl@0
   692
    break;
sl@0
   693
  case ios_base::scientific :
sl@0
   694
    bp = _Stl_ecvtR(x, (min) (precision + 1, MAXECVT), &decpt, &sign, cvtbuf);
sl@0
   695
    break;
sl@0
   696
  default :
sl@0
   697
    bp = _Stl_ecvtR(x, (min) (precision, MAXECVT), &decpt, &sign, cvtbuf);
sl@0
   698
    break;
sl@0
   699
  }
sl@0
   700
  __format_float(buf, bp, decpt, sign, x, flags, precision, false);
sl@0
   701
# endif
sl@0
   702
sl@0
   703
}
sl@0
   704
sl@0
   705
# ifndef _STLP_NO_LONG_DOUBLE
sl@0
   706
_STLP_EXP_DECLSPEC void _STLP_CALL
sl@0
   707
__write_float(string &buf, ios_base::fmtflags flags, int precision,
sl@0
   708
              long double x)
sl@0
   709
{
sl@0
   710
# ifdef USE_SPRINTF_INSTEAD
sl@0
   711
  char static_buf[128];
sl@0
   712
  char fmtbuf[64];
sl@0
   713
  int i = fill_fmtbuf(fmtbuf, flags, 'L');
sl@0
   714
  sprintf(static_buf, fmtbuf, precision, x);    
sl@0
   715
  // we should be able to return buf + sprintf(), but we do not trust'em...
sl@0
   716
  buf = static_buf;
sl@0
   717
# else
sl@0
   718
  char cvtbuf[NDIG+2];
sl@0
   719
  char * bp;
sl@0
   720
  int decpt, sign;
sl@0
   721
sl@0
   722
  switch (flags & ios_base::floatfield) {
sl@0
   723
  case ios_base::fixed:
sl@0
   724
    bp = _Stl_qfcvtR(x, (min) (precision, MAXFCVT), &decpt, &sign, cvtbuf);
sl@0
   725
    break;
sl@0
   726
  case ios_base::scientific :
sl@0
   727
    bp = _Stl_qecvtR(x, (min) (precision + 1, MAXECVT),     &decpt, &sign, cvtbuf);
sl@0
   728
    break;
sl@0
   729
  default :
sl@0
   730
    bp = _Stl_qecvtR(x, (min) (precision, MAXECVT), &decpt, &sign, cvtbuf);
sl@0
   731
    break;
sl@0
   732
  }
sl@0
   733
  __format_float(buf, bp, decpt, sign, x, flags, precision, true);
sl@0
   734
# endif
sl@0
   735
}
sl@0
   736
# endif
sl@0
   737
sl@0
   738
sl@0
   739
# ifndef _STLP_NO_WCHAR_T
sl@0
   740
sl@0
   741
_STLP_EXP_DECLSPEC wchar_t* _STLP_CALL
sl@0
   742
__convert_float_buffer(const char* first, const char* last, wchar_t* out,
sl@0
   743
                       const ctype<wchar_t>& ct, wchar_t dot)
sl@0
   744
{
sl@0
   745
  ct.widen(first, last, out);
sl@0
   746
  if (ct.widen('.') != dot)
sl@0
   747
    replace(out, out + (last - first), ct.widen('.'), dot);
sl@0
   748
  return out + (last - first);
sl@0
   749
}
sl@0
   750
sl@0
   751
# endif
sl@0
   752
sl@0
   753
_STLP_EXP_DECLSPEC void _STLP_CALL
sl@0
   754
__adjust_float_buffer(char* first, char* last, char dot)
sl@0
   755
{
sl@0
   756
  if ('.' != dot)
sl@0
   757
    replace(first, last, '.', dot);
sl@0
   758
}
sl@0
   759
sl@0
   760
_STLP_END_NAMESPACE
sl@0
   761
sl@0
   762
// Local Variables:
sl@0
   763
// mode:C++
sl@0
   764
// End: