00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00047 #ifndef FASTFORMAT_INCL_FASTFORMAT_INSERTERS_HPP_REAL
00048 #define FASTFORMAT_INCL_FASTFORMAT_INSERTERS_HPP_REAL
00049
00050
00051
00052
00053
00054 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00055 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_REAL_MAJOR 1
00056 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_REAL_MINOR 1
00057 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_REAL_REVISION 3
00058 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_REAL_EDIT 4
00059 #endif
00060
00061
00062
00063
00064
00065 #include <fastformat/fastformat.h>
00066 #include <fastformat/quality/contract.h>
00067 #include <fastformat/util/string/snprintf.h>
00068
00069 #include <stlsoft/conversion/integer_to_string.hpp>
00070 #include <stlsoft/string/shim_string.hpp>
00071 #include <stlsoft/util/limit_traits.h>
00072
00073 #include <stdlib.h>
00074
00075
00076
00077
00078
00079 #if !defined(FASTFORMAT_NO_NAMESPACE)
00080 namespace fastformat
00081 {
00082 namespace inserters
00083 {
00084 #endif
00085
00086
00087
00088
00089
00090 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00091 namespace real_impl
00092 {
00093
00094 inline int default_width_sentinel_()
00095 {
00096 return stlsoft::limit_traits<int>::minimum();
00097 }
00098
00099 inline int default_precision_sentinel_()
00100 {
00101 return -1;
00102 }
00103
00104 inline stlsoft::basic_shim_string<ff_char_t, 64> real_helper_2(
00105 double const& value
00106 , ff_char_t const* fmt
00107 )
00108 {
00109 typedef stlsoft::basic_shim_string<ff_char_t, 64> result_t;
00110
00111 enum { maxRepeats = 4 };
00112
00113 #if _STLSOFT_VER < 0x010a0000 && \
00114 defined(_STLSOFT_1_10_VER) && \
00115 _STLSOFT_1_10_VER < 0x010a0109
00116
00117
00118
00119 # error This class cannot work with STLSoft 1.10 versions between 1.10.1 alpha 1 and 1.10.1 alpha 9. Please download the latest version of STLSoft 1.10 alpha
00120
00121 #elif _STLSOFT_VER >= 0x010a0000 || \
00122 defined(_STLSOFT_1_10_VER)
00123
00124
00125
00126
00127
00128 result_t result(64);
00129
00130 # ifndef STLSOFT_CF_THROW_BAD_ALLOC
00131 if(!result.empty())
00132 # endif
00133 {
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 { for(int i = 0;; )
00144 {
00145 int n = fastformat_util_snprintf(result.data(), result.size() - 1, fmt, value);
00146
00147 if(n > int(result.size()))
00148 {
00149
00150
00151
00152
00153
00154
00155 if(!result.resize(n))
00156 {
00157 result.truncate(0);
00158 break;
00159 }
00160 }
00161 else if(n < 0)
00162 {
00163 if(maxRepeats == ++i)
00164 {
00165 result.truncate(0);
00166 break;
00167 }
00168 else
00169 {
00170
00171
00172
00173 if(!result.resize(1u + result.size() * 2))
00174 {
00175 result.truncate(0);
00176 break;
00177 }
00178 }
00179 }
00180 else
00181 {
00182
00183
00184
00185
00186 result.truncate(size_t(n));
00187
00188 break;
00189 }
00190 }}
00191 }
00192
00193 return result;
00194
00195 #else
00196
00197
00198
00199
00200
00201
00202
00203 result_t result(64);
00204 result_t::buffer_type& buffer = result.get_buffer();
00205
00206 # ifndef STLSOFT_CF_THROW_BAD_ALLOC
00207 if(!buffer.empty())
00208 # endif
00209 {
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 { for(int i = 0;; )
00220 {
00221 int n = fastformat_util_snprintf(&buffer[0], buffer.size() - 1, fmt, value);
00222
00223 if(n > int(buffer.size() - 1))
00224 {
00225
00226
00227
00228
00229
00230
00231 if(!buffer.resize(size_t(n) + 1u))
00232 {
00233 buffer.resize(1u);
00234 break;
00235 }
00236 }
00237 else if(n < 0)
00238 {
00239 if(maxRepeats == ++i)
00240 {
00241 break;
00242 }
00243 else
00244 {
00245
00246
00247
00248 if(!buffer.resize(1u + buffer.size() * 2))
00249 {
00250 buffer.resize(1u);
00251 break;
00252 }
00253 }
00254 }
00255 else
00256 {
00257
00258
00259
00260
00261 buffer[size_t(n)] = '\0';
00262
00263 buffer.resize(size_t(n) + 1u);
00264
00265 break;
00266 }
00267 }}
00268 }
00269
00270 return result;
00271 #endif
00272 }
00273
00274 inline stlsoft::basic_shim_string<ff_char_t, 64> real_helper_4(
00275 double const& value
00276 , int minimumWidth
00277 , int precision
00278 , ff_char_t const* specifier
00279 )
00280 {
00281 ff_char_t type = 'f';
00282 ff_char_t fmt_[] = FASTFORMAT_LITERAL_STRING("%-01234567890123456789.01234567890123456789f");
00283 ff_char_t* fmt = fmt_;
00284
00285 if(NULL != specifier)
00286 {
00287 type = *specifier;
00288 }
00289
00290 if( default_width_sentinel_() == minimumWidth &&
00291 precision < 0)
00292 {
00293 fmt[1] = type;
00294 fmt[2] = '\0';
00295 }
00296 else
00297 {
00298 if(default_width_sentinel_() == minimumWidth)
00299 {
00300 minimumWidth = 0;
00301 }
00302 if(precision < 0)
00303 {
00304 precision = 0;
00305 }
00306
00307
00308
00309
00310 #if 0
00311
00312 int n = fastformat_util_snprintf(&fmt[0], STLSOFT_NUM_ELEMENTS(fmt_) - 1, FASTFORMAT_LITERAL_STRING("%%%d.%d%c"), minimumWidth, precision, type);
00313
00314 FASTFORMAT_CONTRACT_ENFORCE_ASSUMPTION((n > 0) && (n < int(STLSOFT_NUM_ELEMENTS(fmt_)) - 1));
00315
00316 fmt[n] = '\0';
00317
00318 #else
00319
00320 const size_t fmtDim = STLSOFT_NUM_ELEMENTS(fmt_) - 1;
00321 ff_char_t* end = &fmt[fmtDim];
00322 size_t n1;
00323 size_t n2;
00324
00325 stlsoft::integer_to_string(end - 21, 21, precision, n1);
00326 *--end = type;
00327 end -= n1;
00328 stlsoft::integer_to_string(end - 21, 21, minimumWidth, n2);
00329 *--end = '.';
00330 end -= n2;
00331 *--end = '%';
00332 fmt = end;
00333
00334 #endif
00335 }
00336
00337 return real_helper_2(value, fmt);
00338 }
00339
00340 }
00341 #endif
00342
00343
00344
00345
00346
00353 inline stlsoft::basic_shim_string<ff_char_t, 64> real(
00354 double const& value
00355 )
00356 {
00357 return real_impl::real_helper_4(value, real_impl::default_width_sentinel_(), real_impl::default_precision_sentinel_(), NULL);
00358 }
00359
00372 inline stlsoft::basic_shim_string<ff_char_t, 64> real(
00373 double const& value
00374 , int minimumWidth
00375 , int decimalPlaces
00376 )
00377 {
00378 FASTFORMAT_CONTRACT_ENFORCE_PRECONDITION_PARAMS_APPL_LAYER(abs(minimumWidth) < 512, "maximum value for width exceeded");
00379 FASTFORMAT_CONTRACT_ENFORCE_PRECONDITION_PARAMS_APPL_LAYER(abs(minimumWidth) < 1 || decimalPlaces <= abs(minimumWidth), "decimal places must not exceed width");
00380
00381 return real_impl::real_helper_4(value, minimumWidth, decimalPlaces, NULL);
00382 }
00383
00398 inline stlsoft::basic_shim_string<ff_char_t, 64> real(
00399 double const& value
00400 , int minimumWidth
00401 , int decimalPlaces
00402 , ff_char_t type
00403 )
00404 {
00405 FASTFORMAT_CONTRACT_ENFORCE_PRECONDITION_PARAMS_APPL_LAYER(abs(minimumWidth) < 512, "maximum value for width exceeded");
00406 FASTFORMAT_CONTRACT_ENFORCE_PRECONDITION_PARAMS_APPL_LAYER(abs(minimumWidth) < 1 || decimalPlaces <= abs(minimumWidth), "decimal places must not exceed width");
00407 FASTFORMAT_CONTRACT_ENFORCE_PRECONDITION_PARAMS_APPL_LAYER(('f' == type) || ('e' == type) || ('E' == type) || ('g' == type) || ('G' == type), "type parameter must be one of 'f', 'e', 'E', 'g' or 'G'");
00408
00409 return real_impl::real_helper_4(value, minimumWidth, decimalPlaces, &type);
00410 }
00411
00412
00413
00414
00415
00416 #if !defined(FASTFORMAT_NO_NAMESPACE)
00417 }
00418 using ::fastformat::inserters::real;
00419 }
00420 #endif
00421
00422
00423
00424
00425
00426 #ifdef STLSOFT_CF_PRAGMA_ONCE_SUPPORT
00427 # pragma once
00428 #endif
00429
00430
00431
00432 #endif
00433
00434