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_INTEGER
00048 #define FASTFORMAT_INCL_FASTFORMAT_INSERTERS_HPP_INTEGER
00049
00050
00051
00052
00053
00054 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00055 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_INTEGER_MAJOR 1
00056 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_INTEGER_MINOR 0
00057 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_INTEGER_REVISION 1
00058 # define FASTFORMAT_VER_FASTFORMAT_INSERTERS_HPP_INTEGER_EDIT 1
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/meta/is_integral_type.hpp>
00071 #include <stlsoft/string/shim_string.hpp>
00072 #include <stlsoft/util/limit_traits.h>
00073 #include <stlsoft/util/integral_printf_traits.hpp>
00074
00075 #include <stdlib.h>
00076
00077
00078
00079
00080
00081 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00082 _MSC_VER < 1300
00083
00084
00085
00086
00087 # define FASTFORMAT_INSERTER_INTEGER_NO_USE_SHIM_STRING_
00088 # include <stlsoft/string/simple_string.hpp>
00089 #endif
00090
00091
00092
00093
00094
00095 #if !defined(FASTFORMAT_NO_NAMESPACE)
00096 namespace fastformat
00097 {
00098 namespace inserters
00099 {
00100 #endif
00101
00102
00103
00104
00105
00106 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00107 namespace integer_impl
00108 {
00109
00110 # ifdef FASTFORMAT_INSERTER_INTEGER_NO_USE_SHIM_STRING_
00111 typedef stlsoft::basic_simple_string<ff_char_t> ff_to_i_r_t_;
00112 # else
00113 typedef stlsoft::basic_shim_string<ff_char_t, 20> ff_to_i_r_t_;
00114 # endif
00115
00116 inline int default_width_sentinel_()
00117 {
00118 return stlsoft::limit_traits<int>::minimum();
00119 }
00120
00121 inline int default_precision_sentinel_()
00122 {
00123 return -1;
00124 }
00125
00126 template <typename I>
00127 inline ff_to_i_r_t_ integer_helper_2(
00128 I const& value
00129 , ff_char_t const* fmt
00130 )
00131 {
00132 STLSOFT_STATIC_ASSERT(stlsoft::is_integral_type<I>::value);
00133
00134 typedef ff_to_i_r_t_ result_t;
00135
00136 enum { maxRepeats = 3 };
00137
00138 #ifdef FASTFORMAT_INSERTER_INTEGER_NO_USE_SHIM_STRING_
00139
00140 result_t result(20u, '~');
00141
00142 { for(int i = 0;; )
00143 {
00144 int n = fastformat_util_snprintf(&result[0], result.size(), fmt, value);
00145
00146 if(n > int(result.size()))
00147 {
00148
00149
00150
00151
00152
00153
00154 result.resize(n);
00155 }
00156 else if(n < 0)
00157 {
00158 if(maxRepeats == ++i)
00159 {
00160 result.clear();
00161 break;
00162 }
00163 else
00164 {
00165
00166
00167
00168 result.resize(1u + result.size() * 3);
00169 }
00170 }
00171 else
00172 {
00173
00174
00175
00176
00177 result.resize(size_t(n));
00178
00179 break;
00180 }
00181 }}
00182
00183 return result;
00184
00185 #else
00186
00187
00188 # if _STLSOFT_VER < 0x010a0000 && \
00189 defined(_STLSOFT_1_10_VER) && \
00190 _STLSOFT_1_10_VER < 0x010a0109
00191
00192
00193
00194 # 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
00195
00196 # elif _STLSOFT_VER >= 0x010a0000 || \
00197 defined(_STLSOFT_1_10_VER)
00198
00199
00200
00201
00202
00203 result_t result(64);
00204
00205 # ifndef STLSOFT_CF_THROW_BAD_ALLOC
00206 if(!result.empty())
00207 # endif
00208 {
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 { for(int i = 0;; )
00219 {
00220 int n = fastformat_util_snprintf(result.data(), result.size() - 1, fmt, value);
00221
00222 if(n > int(result.size()))
00223 {
00224
00225
00226
00227
00228
00229
00230 if(!result.resize(n))
00231 {
00232 result.truncate(0);
00233 break;
00234 }
00235 }
00236 else if(n < 0)
00237 {
00238 if(maxRepeats == ++i)
00239 {
00240 result.truncate(0);
00241 break;
00242 }
00243 else
00244 {
00245
00246
00247
00248 if(!result.resize(1u + result.size() * 3))
00249 {
00250 result.truncate(0);
00251 break;
00252 }
00253 }
00254 }
00255 else
00256 {
00257
00258
00259
00260
00261 result.truncate(size_t(n));
00262
00263 break;
00264 }
00265 }}
00266 }
00267
00268 return result;
00269
00270 # else
00271
00272
00273
00274
00275
00276
00277
00278 result_t result(64);
00279 result_t::buffer_type& buffer = result.get_buffer();
00280
00281 # ifndef STLSOFT_CF_THROW_BAD_ALLOC
00282 if(!buffer.empty())
00283 # endif
00284 {
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 { for(int i = 0;; )
00295 {
00296 int n = fastformat_util_snprintf(&buffer[0], buffer.size() - 1, fmt, value);
00297
00298 if(n > int(buffer.size() - 1))
00299 {
00300
00301
00302
00303
00304
00305
00306 if(!buffer.resize(size_t(n) + 1u))
00307 {
00308 buffer.resize(1u);
00309 break;
00310 }
00311 }
00312 else if(n < 0)
00313 {
00314 if(maxRepeats == ++i)
00315 {
00316 break;
00317 }
00318 else
00319 {
00320
00321
00322
00323 if(!buffer.resize(1u + buffer.size() * 3))
00324 {
00325 buffer.resize(1u);
00326 break;
00327 }
00328 }
00329 }
00330 else
00331 {
00332
00333
00334
00335
00336 buffer[size_t(n)] = '\0';
00337
00338 buffer.resize(size_t(n) + 1u);
00339
00340 break;
00341 }
00342 }}
00343 }
00344
00345 return result;
00346 # endif
00347 #endif
00348 }
00349
00350 template <typename I>
00351 inline ff_to_i_r_t_ integer_helper_3(
00352 I const& value
00353 , int minimumWidth
00354 , int precision
00355 )
00356 {
00357 STLSOFT_STATIC_ASSERT(stlsoft::is_integral_type<I>::value);
00358
00359 if( default_width_sentinel_() == minimumWidth &&
00360 precision < 0)
00361 {
00362 ff_char_t sz[21];
00363 size_t n;
00364 ff_char_t const* s = stlsoft::integer_to_string(&sz[0], STLSOFT_NUM_ELEMENTS(sz), value, n);
00365
00366 return ff_to_i_r_t_(s, n);
00367 }
00368 else
00369 {
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 ff_char_t fmt_[101];
00386 ff_char_t* fmt = fmt_;
00387 #ifdef FASTFORMAT_USE_WIDE_STRINGS
00388 wchar-t const* type = stlsoft::integral_printf_traits<I>::format_w() + 1;
00389 #else
00390 char const* type = stlsoft::integral_printf_traits<I>::format_a() + 1;
00391 #endif
00392 size_t typeLen = stlsoft::c_str_len(type);
00393
00394 if(default_width_sentinel_() == minimumWidth)
00395 {
00396 minimumWidth = 0;
00397 }
00398 if(precision < 0)
00399 {
00400 precision = (0 == value) ? 1 : 0;
00401 }
00402
00403 const size_t fmtDim = STLSOFT_NUM_ELEMENTS(fmt_) - 1;
00404 ff_char_t* end = &fmt[fmtDim];
00405 size_t n1;
00406 size_t n2;
00407
00408
00409
00410
00411
00412 stlsoft::integer_to_string(end - (21 + typeLen), 21, precision, n1);
00413
00414
00415 ::memcpy(end - (typeLen + 1), type, sizeof(ff_char_t) * typeLen);
00416
00417
00418 *--end = '\0';
00419
00420 end -= typeLen;
00421 end -= n1;
00422
00423
00424 stlsoft::integer_to_string(end - 21, 21, minimumWidth, n2);
00425
00426
00427 *--end = '.';
00428
00429 end -= n2;
00430
00431
00432 *--end = '%';
00433 fmt = end;
00434
00435 return integer_helper_2(value, fmt);
00436 }
00437 }
00438
00439 }
00440 #endif
00441
00442
00443
00444
00445
00460 template <typename I>
00461 inline integer_impl::ff_to_i_r_t_ integer(
00462 I const& value
00463 , int minimumWidth
00464 , int precision
00465 )
00466 {
00467 STLSOFT_STATIC_ASSERT(stlsoft::is_integral_type<I>::value);
00468
00469 FASTFORMAT_CONTRACT_ENFORCE_PRECONDITION_PARAMS_APPL_LAYER(abs(minimumWidth) < 512, "maximum value for width exceeded");
00470 FASTFORMAT_CONTRACT_ENFORCE_PRECONDITION_PARAMS_APPL_LAYER(abs(minimumWidth) < 1 || precision <= abs(minimumWidth), "decimal places must not exceed width");
00471
00472 return integer_impl::integer_helper_3(value, minimumWidth, precision);
00473 }
00474
00475
00476
00477
00478
00479 #if !defined(FASTFORMAT_NO_NAMESPACE)
00480 }
00481 using ::fastformat::inserters::integer;
00482 }
00483 #endif
00484
00485
00486
00487
00488
00489 #ifdef STLSOFT_CF_PRAGMA_ONCE_SUPPORT
00490 # pragma once
00491 #endif
00492
00493
00494
00495 #endif
00496
00497