Coverage Report

Created: 2024-02-17 06:25

/src/poco/Foundation/include/Poco/NumericString.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// NumericString.h
3
//
4
// Library: Foundation
5
// Package: Core
6
// Module:  NumericString
7
//
8
// Numeric string utility functions.
9
//
10
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11
// and Contributors.
12
//
13
// SPDX-License-Identifier: BSL-1.0
14
//
15
16
17
#ifndef Foundation_NumericString_INCLUDED
18
#define Foundation_NumericString_INCLUDED
19
20
21
#include "Poco/Foundation.h"
22
#include "Poco/Buffer.h"
23
#include "Poco/FPEnvironment.h"
24
#ifdef min
25
  #undef min
26
#endif
27
#ifdef max
28
  #undef max
29
#endif
30
#include <limits>
31
#include <cmath>
32
#include <cctype>
33
#if !defined(POCO_NO_LOCALE)
34
  #include <locale>
35
#endif
36
#include <type_traits>
37
#if defined(POCO_NOINTMAX)
38
typedef Poco::UInt64 uintmax_t;
39
typedef Poco::Int64 intmax_t;
40
#endif
41
#if !defined (INTMAX_MAX)
42
#define INTMAX_MAX std::numeric_limits<intmax_t>::max()
43
#endif
44
#ifdef POCO_COMPILER_MSVC
45
#pragma warning(push)
46
#pragma warning(disable : 4146)
47
#endif // POCO_COMPILER_MSVC
48
49
// binary numbers are supported, thus 64 (bits) + 1 (string terminating zero) + 2 (hex prefix)
50
0
#define POCO_MAX_INT_STRING_LEN (67)
51
// value from strtod.cc (double_conversion::kMaxSignificantDecimalDigits)
52
0
#define POCO_MAX_FLT_STRING_LEN 780
53
54
0
#define POCO_FLT_INF "inf"
55
0
#define POCO_FLT_NAN "nan"
56
0
#define POCO_FLT_EXP 'e'
57
58
59
namespace Poco {
60
61
62
namespace Impl {
63
64
  template<bool SIGNED, typename T>
65
  class IsNegativeImpl;
66
67
  template<typename T>
68
  class IsNegativeImpl<true, T>
69
  {
70
  public:
71
    bool operator()(T x) { return x < 0; }
72
  };
73
74
  template<typename T>
75
  class IsNegativeImpl<false, T>
76
  {
77
  public:
78
    bool operator()(T) { return false; }
79
  };
80
81
}
82
83
84
template<typename T>
85
inline bool isNegative(T x)
86
{
87
  using namespace Impl;
88
  return IsNegativeImpl<std::numeric_limits<T>::is_signed, T>()(x);
89
}
90
91
92
template<typename To, typename From>
93
inline bool isIntOverflow(From val)
94
{
95
  poco_assert_dbg (std::numeric_limits<From>::is_integer);
96
  poco_assert_dbg (std::numeric_limits<To>::is_integer);
97
  bool ret;
98
  if (std::numeric_limits<To>::is_signed)
99
  {
100
    ret = (!std::numeric_limits<From>::is_signed &&
101
        (uintmax_t)val > (uintmax_t)INTMAX_MAX) ||
102
        (intmax_t)val  < (intmax_t)std::numeric_limits<To>::min() ||
103
        (intmax_t)val  > (intmax_t)std::numeric_limits<To>::max();
104
  }
105
  else
106
  {
107
    ret = isNegative(val) ||
108
        (uintmax_t)val > (uintmax_t)std::numeric_limits<To>::max();
109
  }
110
  return ret;
111
}
112
113
114
template<typename R, typename F, typename S>
115
bool safeMultiply(R& result, F f, S s)
116
2.19M
{
117
2.19M
  if ((f == 0) || (s==0))
118
2.13M
  {
119
2.13M
    result = 0;
120
2.13M
    return true;
121
2.13M
  }
122
123
56.8k
  if (f > 0)
124
56.8k
  {
125
56.8k
    if (s > 0)
126
56.8k
    {
127
56.8k
      if (f > (std::numeric_limits<R>::max() / s))
128
0
        return false;
129
56.8k
    }
130
0
    else
131
0
    {
132
0
      if (s < (std::numeric_limits<R>::min() / f))
133
0
        return false;
134
0
    }
135
56.8k
  }
136
0
  else
137
0
  {
138
0
    if (s > 0)
139
0
    {
140
0
      if (f < (std::numeric_limits<R>::min() / s))
141
0
        return false;
142
0
    }
143
0
    else
144
0
    {
145
0
      if (s < (std::numeric_limits<R>::max() / f))
146
0
        return false;
147
0
    }
148
0
  }
149
56.8k
  result = f * s;
150
56.8k
  return true;
151
56.8k
}
152
153
154
template <typename F, typename T>
155
inline T& isSafeIntCast(F from)
156
  /// Returns true if it is safe to cast
157
  /// integer from F to T.
158
{
159
  if (!isIntOverflow<T, F>(from)) return true;
160
  return false;
161
}
162
163
164
template <typename F, typename T>
165
inline T& safeIntCast(F from, T& to)
166
  /// Returns cast value if it is safe
167
  /// to cast integer from F to T,
168
  /// otherwise throws BadCastException.
169
{
170
  if (!isIntOverflow<T, F>(from))
171
  {
172
    to = static_cast<T>(from);
173
    return to;
174
  }
175
  throw BadCastException("safeIntCast: Integer overflow");
176
}
177
178
inline char decimalSeparator()
179
  /// Returns decimal separator from global locale or
180
  /// default '.' for platforms where locale is unavailable.
181
0
{
182
0
#if !defined(POCO_NO_LOCALE)
183
0
  return std::use_facet<std::numpunct<char>>(std::locale()).decimal_point();
184
0
#else
185
0
  return '.';
186
0
#endif
187
0
}
188
189
190
inline char thousandSeparator()
191
  /// Returns thousand separator from global locale or
192
  /// default ',' for platforms where locale is unavailable.
193
0
{
194
0
#if !defined(POCO_NO_LOCALE)
195
0
  return std::use_facet<std::numpunct<char>>(std::locale()).thousands_sep();
196
0
#else
197
0
  return ',';
198
0
#endif
199
0
}
200
201
202
//
203
// String to Number Conversions
204
//
205
206
template <typename I>
207
bool strToInt(const char* pStr, I& outResult, short base, char thSep = ',')
208
  /// Converts zero-terminated character array to integer number;
209
  /// Thousand separators are recognized for base10 and current locale;
210
  /// they are silently skipped and not verified for correct positioning.
211
  /// It is not allowed to convert a negative number to anything except
212
  /// 10-base signed integer.
213
  /// For hexadecimal numbers, the case of the digits is not relevant.
214
  ///
215
  /// Function returns true if successful. If parsing was unsuccessful,
216
  /// the return value is false with the result value undetermined.
217
2.13M
{
218
2.13M
  poco_assert_dbg (base == 2 || base == 8 || base == 10 || base == 16);
219
220
2.13M
  if (!pStr) return false;
221
2.13M
  while (std::isspace(*pStr)) ++pStr;
222
2.13M
  if ((*pStr == '\0') || ((*pStr == '-') && ((base != 10) || (std::is_unsigned<I>::value))))
223
1
    return false;
224
225
2.13M
  bool negative = false;
226
2.13M
  if ((base == 10) && (*pStr == '-'))
227
325
  {
228
325
    if (!std::numeric_limits<I>::is_signed) return false;
229
325
    negative = true;
230
325
    ++pStr;
231
325
  }
232
2.13M
  else if (*pStr == '+') ++pStr;
233
234
  // numbers are parsed as unsigned, for negative numbers the sign is applied after parsing
235
  // overflow is checked in every parse step
236
2.13M
  uintmax_t limitCheck = std::numeric_limits<I>::max();
237
2.13M
  if (negative) ++limitCheck;
238
2.13M
  uintmax_t result = 0;
239
2.13M
  unsigned char add = 0;
240
4.32M
  for (; *pStr != '\0'; ++pStr)
241
2.19M
  {
242
2.19M
    if (*pStr == thSep)
243
0
    {
244
0
      if (base == 10) continue;
245
0
      throw Poco::SyntaxException("strToInt: thousand separators only allowed for base 10");
246
0
    }
247
2.19M
    if (result > (limitCheck / base)) return false;
248
2.19M
    if (!safeMultiply(result, result, base)) return false;
249
2.19M
    switch (*pStr)
250
2.19M
    {
251
1.94M
    case '0': case '1': case '2': case '3':
252
2.07M
    case '4': case '5': case '6': case '7':
253
2.07M
      add = (*pStr - '0');
254
2.07M
      break;
255
256
118k
    case '8': case '9':
257
118k
      if ((base == 10) || (base == 0x10)) add = (*pStr - '0');
258
0
      else return false;
259
118k
      break;
260
261
118k
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
262
0
      if (base != 0x10) return false;
263
0
      add = (*pStr - 'a') + 10;
264
0
      break;
265
266
0
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
267
0
      if (base != 0x10) return false;
268
0
      add = (*pStr - 'A') + 10;
269
0
      break;
270
271
0
    default:
272
0
      return false;
273
2.19M
    }
274
2.19M
    if ((limitCheck - static_cast<uintmax_t>(result)) < add) return false;
275
2.19M
    result += add;
276
2.19M
  }
277
278
2.13M
  if (negative && (base == 10))
279
324
    outResult = static_cast<I>(-result);
280
2.13M
  else
281
2.13M
    outResult = static_cast<I>(result);
282
283
2.13M
  return true;
284
2.13M
}
Unexecuted instantiation: bool Poco::strToInt<int>(char const*, int&, short, char)
Unexecuted instantiation: bool Poco::strToInt<unsigned int>(char const*, unsigned int&, short, char)
bool Poco::strToInt<long>(char const*, long&, short, char)
Line
Count
Source
217
2.13M
{
218
2.13M
  poco_assert_dbg (base == 2 || base == 8 || base == 10 || base == 16);
219
220
2.13M
  if (!pStr) return false;
221
2.13M
  while (std::isspace(*pStr)) ++pStr;
222
2.13M
  if ((*pStr == '\0') || ((*pStr == '-') && ((base != 10) || (std::is_unsigned<I>::value))))
223
0
    return false;
224
225
2.13M
  bool negative = false;
226
2.13M
  if ((base == 10) && (*pStr == '-'))
227
325
  {
228
325
    if (!std::numeric_limits<I>::is_signed) return false;
229
325
    negative = true;
230
325
    ++pStr;
231
325
  }
232
2.13M
  else if (*pStr == '+') ++pStr;
233
234
  // numbers are parsed as unsigned, for negative numbers the sign is applied after parsing
235
  // overflow is checked in every parse step
236
2.13M
  uintmax_t limitCheck = std::numeric_limits<I>::max();
237
2.13M
  if (negative) ++limitCheck;
238
2.13M
  uintmax_t result = 0;
239
2.13M
  unsigned char add = 0;
240
4.31M
  for (; *pStr != '\0'; ++pStr)
241
2.17M
  {
242
2.17M
    if (*pStr == thSep)
243
0
    {
244
0
      if (base == 10) continue;
245
0
      throw Poco::SyntaxException("strToInt: thousand separators only allowed for base 10");
246
0
    }
247
2.17M
    if (result > (limitCheck / base)) return false;
248
2.17M
    if (!safeMultiply(result, result, base)) return false;
249
2.17M
    switch (*pStr)
250
2.17M
    {
251
1.93M
    case '0': case '1': case '2': case '3':
252
2.06M
    case '4': case '5': case '6': case '7':
253
2.06M
      add = (*pStr - '0');
254
2.06M
      break;
255
256
115k
    case '8': case '9':
257
115k
      if ((base == 10) || (base == 0x10)) add = (*pStr - '0');
258
0
      else return false;
259
115k
      break;
260
261
115k
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
262
0
      if (base != 0x10) return false;
263
0
      add = (*pStr - 'a') + 10;
264
0
      break;
265
266
0
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
267
0
      if (base != 0x10) return false;
268
0
      add = (*pStr - 'A') + 10;
269
0
      break;
270
271
0
    default:
272
0
      return false;
273
2.17M
    }
274
2.17M
    if ((limitCheck - static_cast<uintmax_t>(result)) < add) return false;
275
2.17M
    result += add;
276
2.17M
  }
277
278
2.13M
  if (negative && (base == 10))
279
324
    outResult = static_cast<I>(-result);
280
2.13M
  else
281
2.13M
    outResult = static_cast<I>(result);
282
283
2.13M
  return true;
284
2.13M
}
bool Poco::strToInt<unsigned long>(char const*, unsigned long&, short, char)
Line
Count
Source
217
891
{
218
891
  poco_assert_dbg (base == 2 || base == 8 || base == 10 || base == 16);
219
220
891
  if (!pStr) return false;
221
891
  while (std::isspace(*pStr)) ++pStr;
222
891
  if ((*pStr == '\0') || ((*pStr == '-') && ((base != 10) || (std::is_unsigned<I>::value))))
223
1
    return false;
224
225
890
  bool negative = false;
226
890
  if ((base == 10) && (*pStr == '-'))
227
0
  {
228
0
    if (!std::numeric_limits<I>::is_signed) return false;
229
0
    negative = true;
230
0
    ++pStr;
231
0
  }
232
890
  else if (*pStr == '+') ++pStr;
233
234
  // numbers are parsed as unsigned, for negative numbers the sign is applied after parsing
235
  // overflow is checked in every parse step
236
890
  uintmax_t limitCheck = std::numeric_limits<I>::max();
237
890
  if (negative) ++limitCheck;
238
890
  uintmax_t result = 0;
239
890
  unsigned char add = 0;
240
17.9k
  for (; *pStr != '\0'; ++pStr)
241
17.1k
  {
242
17.1k
    if (*pStr == thSep)
243
0
    {
244
0
      if (base == 10) continue;
245
0
      throw Poco::SyntaxException("strToInt: thousand separators only allowed for base 10");
246
0
    }
247
17.1k
    if (result > (limitCheck / base)) return false;
248
17.1k
    if (!safeMultiply(result, result, base)) return false;
249
17.1k
    switch (*pStr)
250
17.1k
    {
251
6.44k
    case '0': case '1': case '2': case '3':
252
14.2k
    case '4': case '5': case '6': case '7':
253
14.2k
      add = (*pStr - '0');
254
14.2k
      break;
255
256
2.88k
    case '8': case '9':
257
2.88k
      if ((base == 10) || (base == 0x10)) add = (*pStr - '0');
258
0
      else return false;
259
2.88k
      break;
260
261
2.88k
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
262
0
      if (base != 0x10) return false;
263
0
      add = (*pStr - 'a') + 10;
264
0
      break;
265
266
0
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
267
0
      if (base != 0x10) return false;
268
0
      add = (*pStr - 'A') + 10;
269
0
      break;
270
271
0
    default:
272
0
      return false;
273
17.1k
    }
274
17.1k
    if ((limitCheck - static_cast<uintmax_t>(result)) < add) return false;
275
17.1k
    result += add;
276
17.1k
  }
277
278
839
  if (negative && (base == 10))
279
0
    outResult = static_cast<I>(-result);
280
839
  else
281
839
    outResult = static_cast<I>(result);
282
283
839
  return true;
284
890
}
285
286
287
template <typename I>
288
bool strToInt(const std::string& str, I& result, short base, char thSep = ',')
289
  /// Converts string to integer number;
290
  /// This is a wrapper function, for details see see the
291
  /// bool strToInt(const char*, I&, short, char) implementation.
292
{
293
  return strToInt(str.c_str(), result, base, thSep);
294
}
295
296
297
//
298
// Number to String Conversions
299
//
300
301
namespace Impl {
302
303
  class Ptr
304
    /// Utility char pointer wrapper class.
305
    /// Class ensures increment/decrement remain within boundaries.
306
  {
307
  public:
308
    Ptr(char* ptr, std::size_t offset): _beg(ptr), _cur(ptr), _end(ptr + offset)
309
0
    {
310
0
    }
311
312
    char*& operator ++ () // prefix
313
0
    {
314
0
      checkBounds(_cur + 1);
315
0
      return ++_cur;
316
0
    }
317
318
    char* operator ++ (int) // postfix
319
0
    {
320
0
      checkBounds(_cur + 1);
321
0
      char* tmp = _cur++;
322
0
      return tmp;
323
0
    }
324
325
    char*& operator -- () // prefix
326
0
    {
327
0
      checkBounds(_cur - 1);
328
0
      return --_cur;
329
0
    }
330
331
    char* operator -- (int) // postfix
332
0
    {
333
0
      checkBounds(_cur - 1);
334
0
      char* tmp = _cur--;
335
0
      return tmp;
336
0
    }
337
338
    char*& operator += (int incr)
339
0
    {
340
0
      checkBounds(_cur + incr);
341
0
      return _cur += incr;
342
0
    }
343
344
    char*& operator -= (int decr)
345
0
    {
346
0
      checkBounds(_cur - decr);
347
0
      return _cur -= decr;
348
0
    }
349
350
    operator char* () const
351
0
    {
352
0
      return _cur;
353
0
    }
354
355
    std::size_t span() const
356
0
    {
357
0
      return _end - _beg;
358
0
    }
359
360
  private:
361
    void checkBounds(char* ptr)
362
0
    {
363
0
      if (ptr > _end) throw RangeException();
364
0
    }
365
366
    const char* _beg;
367
    char*       _cur;
368
    const char* _end;
369
};
370
371
template <typename T>
372
using EnableSigned = typename std::enable_if< std::is_signed<T>::value >::type*;
373
374
template <typename T>
375
using EnableUnsigned = typename std::enable_if< std::is_unsigned<T>::value >::type*;
376
377
} // namespace Impl
378
379
380
template <typename T, Impl::EnableSigned<T> = nullptr>
381
bool intToStr(T value,
382
  unsigned short base,
383
  char* result,
384
  std::size_t& size,
385
  bool prefix = false,
386
  int width = -1,
387
  char fill = ' ',
388
  char thSep = 0,
389
  bool lowercase = false)
390
  /// Converts signed integer to string. Standard numeric bases from binary to hexadecimal
391
  /// are supported.
392
  /// If width is non-zero, it pads the return value with fill character to the specified width.
393
  /// When padding is zero character ('0'), it is prepended to the number itself; all other
394
  /// paddings are prepended to the formatted result with minus sign or base prefix included
395
  /// If prefix is true and base is octal or hexadecimal, respective prefix ('0' for octal,
396
  /// "0x" for hexadecimal) is prepended. For all other bases, prefix argument is ignored.
397
  /// Formatted string has at least [width] total length.
398
0
{
399
0
  poco_assert_dbg (((value < 0) && (base == 10)) || (value >= 0));
400
401
0
  if (base < 2 || base > 0x10)
402
0
  {
403
0
    *result = '\0';
404
0
    return false;
405
0
  }
406
407
0
  Impl::Ptr ptr(result, size);
408
0
  int thCount = 0;
409
0
  T tmpVal;
410
0
  do
411
0
  {
412
0
    tmpVal = value;
413
0
    value /= base;
414
0
    *ptr++ = (lowercase ? "fedcba9876543210123456789abcdef" : "FEDCBA9876543210123456789ABCDEF")[15 + (tmpVal - value * base)];
415
0
    if (thSep && (base == 10) && (++thCount == 3))
416
0
    {
417
0
      *ptr++ = thSep;
418
0
      thCount = 0;
419
0
    }
420
0
  } while (value);
421
422
0
  if ('0' == fill)
423
0
  {
424
0
    if (tmpVal < 0) --width;
425
0
    if (prefix && base == 010) --width;
426
0
    if (prefix && base == 0x10) width -= 2;
427
0
    while ((ptr - result) < width) *ptr++ = fill;
428
0
  }
429
430
0
  if (prefix && base == 010) *ptr++ = '0';
431
0
  else if (prefix && base == 0x10)
432
0
  {
433
0
    *ptr++ = 'x';
434
0
    *ptr++ = '0';
435
0
  }
436
437
0
  if (tmpVal < 0) *ptr++ = '-';
438
439
0
  if ('0' != fill)
440
0
  {
441
0
    while ((ptr - result) < width) *ptr++ = fill;
442
0
  }
443
444
0
  size = ptr - result;
445
0
  poco_assert_dbg (size <= ptr.span());
446
0
  poco_assert_dbg ((-1 == width) || (size >= size_t(width)));
447
0
  *ptr-- = '\0';
448
449
0
  char* ptrr = result;
450
0
  char tmp;
451
0
  while(ptrr < ptr)
452
0
  {
453
0
     tmp    = *ptr;
454
0
    *ptr--  = *ptrr;
455
0
    *ptrr++ = tmp;
456
0
  }
457
458
0
  return true;
459
0
}
Unexecuted instantiation: bool Poco::intToStr<int, (void*)0>(int, unsigned short, char*, unsigned long&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<long, (void*)0>(long, unsigned short, char*, unsigned long&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<long long, (void*)0>(long long, unsigned short, char*, unsigned long&, bool, int, char, char, bool)
460
461
462
template <typename T, Impl::EnableUnsigned<T> = nullptr>
463
bool intToStr(T value,
464
  unsigned short base,
465
  char* result,
466
  std::size_t& size,
467
  bool prefix = false,
468
  int width = -1,
469
  char fill = ' ',
470
  char thSep = 0,
471
  bool lowercase = false)
472
  /// Converts unsigned integer to string. Numeric bases from binary to hexadecimal are supported.
473
  /// If width is non-zero, it pads the return value with fill character to the specified width.
474
  /// When padding is zero character ('0'), it is prepended to the number itself; all other
475
  /// paddings are prepended to the formatted result with minus sign or base prefix included
476
  /// If prefix is true and base is octal or hexadecimal, respective prefix ('0' for octal,
477
  /// "0x" for hexadecimal) is prepended. For all other bases, prefix argument is ignored.
478
  /// Formatted string has at least [width] total length.
479
0
{
480
0
  if (base < 2 || base > 0x10)
481
0
  {
482
0
    *result = '\0';
483
0
    return false;
484
0
  }
485
486
0
  Impl::Ptr ptr(result, size);
487
0
  int thCount = 0;
488
0
  T tmpVal;
489
0
  do
490
0
  {
491
0
    tmpVal = value;
492
0
    value /= base;
493
0
    *ptr++ = (lowercase ? "fedcba9876543210123456789abcdef" : "FEDCBA9876543210123456789ABCDEF")[15 + (tmpVal - value * base)];
494
0
    if (thSep && (base == 10) && (++thCount == 3))
495
0
    {
496
0
      *ptr++ = thSep;
497
0
      thCount = 0;
498
0
    }
499
0
  } while (value);
500
501
0
  if ('0' == fill)
502
0
  {
503
0
    if (prefix && base == 010) --width;
504
0
    if (prefix && base == 0x10) width -= 2;
505
0
    while ((ptr - result) < width) *ptr++ = fill;
506
0
  }
507
508
0
  if (prefix && base == 010) *ptr++ = '0';
509
0
  else if (prefix && base == 0x10)
510
0
  {
511
0
    *ptr++ = 'x';
512
0
    *ptr++ = '0';
513
0
  }
514
515
0
  if ('0' != fill)
516
0
  {
517
0
    while ((ptr - result) < width) *ptr++ = fill;
518
0
  }
519
520
0
  size = ptr - result;
521
0
  poco_assert_dbg (size <= ptr.span());
522
0
  poco_assert_dbg ((-1 == width) || (size >= size_t(width)));
523
0
  *ptr-- = '\0';
524
525
0
  char* ptrr = result;
526
0
  char tmp;
527
0
  while(ptrr < ptr)
528
0
  {
529
0
    tmp     = *ptr;
530
0
    *ptr--  = *ptrr;
531
0
    *ptrr++ = tmp;
532
0
  }
533
534
0
  return true;
535
0
}
Unexecuted instantiation: bool Poco::intToStr<unsigned int, (void*)0>(unsigned int, unsigned short, char*, unsigned long&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<unsigned long, (void*)0>(unsigned long, unsigned short, char*, unsigned long&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<unsigned long long, (void*)0>(unsigned long long, unsigned short, char*, unsigned long&, bool, int, char, char, bool)
536
537
538
template <typename T>
539
[[deprecated("use intToStr instead")]]
540
bool uIntToStr(T value,
541
  unsigned short base,
542
  char* result,
543
  std::size_t& size,
544
  bool prefix = false,
545
  int width = -1,
546
  char fill = ' ',
547
  char thSep = 0,
548
  bool lowercase = false)
549
  /// Converts unsigned integer to string. Numeric bases from binary to hexadecimal are supported.
550
  /// If width is non-zero, it pads the return value with fill character to the specified width.
551
  /// When padding is zero character ('0'), it is prepended to the number itself; all other
552
  /// paddings are prepended to the formatted result with minus sign or base prefix included
553
  /// If prefix is true and base is octal or hexadecimal, respective prefix ('0' for octal,
554
  /// "0x" for hexadecimal) is prepended. For all other bases, prefix argument is ignored.
555
  /// Formatted string has at least [width] total length.
556
  ///
557
  /// This function is deprecated; use intToStr instead.
558
{
559
  return intToStr(value, base, result, size, prefix, width, fill, thSep, lowercase);
560
}
561
562
563
template <typename T>
564
bool intToStr (T number,
565
  unsigned short base,
566
  std::string& result,
567
  bool prefix = false,
568
  int width = -1,
569
  char fill = ' ',
570
  char thSep = 0,
571
  bool lowercase = false)
572
  /// Converts integer to string; This is a wrapper function, for details see the
573
  /// bool intToStr(T, unsigned short, char*, int, int, char, char) implementation.
574
0
{
575
0
  char res[POCO_MAX_INT_STRING_LEN] = {0};
576
0
  std::size_t size = POCO_MAX_INT_STRING_LEN;
577
0
  bool ret = intToStr(number, base, res, size, prefix, width, fill, thSep, lowercase);
578
0
  result.assign(res, size);
579
0
  return ret;
580
0
}
Unexecuted instantiation: bool Poco::intToStr<int>(int, unsigned short, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<unsigned int>(unsigned int, unsigned short, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<long>(long, unsigned short, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<unsigned long>(unsigned long, unsigned short, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<long long>(long long, unsigned short, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool, int, char, char, bool)
Unexecuted instantiation: bool Poco::intToStr<unsigned long long>(unsigned long long, unsigned short, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool, int, char, char, bool)
581
582
583
template <typename T>
584
[[deprecated("use intToStr instead")]]
585
bool uIntToStr (T number,
586
  unsigned short base,
587
  std::string& result,
588
  bool prefix = false,
589
  int width = -1,
590
  char fill = ' ',
591
  char thSep = 0,
592
  bool lowercase = false)
593
  /// Converts unsigned integer to string; This is a wrapper function, for details see the
594
  /// bool uIntToStr(T, unsigned short, char*, int, int, char, char) implementation.
595
  ///
596
  /// This function is deprecated; use intToStr instead.
597
{
598
  return intToStr(number, base, result, prefix, width, fill, thSep, lowercase);
599
}
600
601
602
//
603
// Wrappers for double-conversion library (http://code.google.com/p/double-conversion/).
604
//
605
// Library is the implementation of the algorithm described in Florian Loitsch's paper:
606
// http://florian.loitsch.com/publications/dtoa-pldi2010.pdf
607
//
608
609
610
Foundation_API void floatToStr(char* buffer,
611
  int bufferSize,
612
  float value,
613
  int lowDec = -std::numeric_limits<float>::digits10,
614
  int highDec = std::numeric_limits<float>::digits10);
615
  /// Converts a float value to string. Converted string must be shorter than bufferSize.
616
  /// Conversion is done by computing the shortest string of digits that correctly represents
617
  /// the input number. Depending on lowDec and highDec values, the function returns
618
  /// decimal or exponential representation.
619
620
Foundation_API void floatToFixedStr(char* buffer,
621
  int bufferSize,
622
  float value,
623
  int precision);
624
  /// Converts a float value to string. Converted string must be shorter than bufferSize.
625
  /// Computes a decimal representation with a fixed number of digits after the
626
    /// decimal point.
627
628
629
Foundation_API std::string& floatToStr(std::string& str,
630
  float value,
631
  int precision = -1,
632
  int width = 0,
633
  char thSep = 0,
634
  char decSep = 0);
635
  /// Converts a float value, assigns it to the supplied string and returns the reference.
636
  /// This function calls floatToStr(char*, int, float, int, int) and formats the result according to
637
  /// precision (total number of digits after the decimal point, -1 means ignore precision argument)
638
  /// and width (total length of formatted string).
639
640
641
Foundation_API std::string& floatToFixedStr(std::string& str,
642
  float value,
643
  int precision,
644
  int width = 0,
645
  char thSep = 0,
646
  char decSep = 0);
647
  /// Converts a float value, assigns it to the supplied string and returns the reference.
648
  /// This function calls floatToFixedStr(char*, int, float, int) and formats the result according to
649
  /// precision (total number of digits after the decimal point) and width (total length of formatted string).
650
651
652
Foundation_API void doubleToStr(char* buffer,
653
  int bufferSize,
654
  double value,
655
  int lowDec = -std::numeric_limits<double>::digits10,
656
  int highDec = std::numeric_limits<double>::digits10);
657
  /// Converts a double value to string. Converted string must be shorter than bufferSize.
658
  /// Conversion is done by computing the shortest string of digits that correctly represents
659
  /// the input number. Depending on lowDec and highDec values, the function returns
660
  /// decimal or exponential representation.
661
662
663
Foundation_API void doubleToFixedStr(char* buffer,
664
  int bufferSize,
665
  double value,
666
  int precision);
667
  /// Converts a double value to string. Converted string must be shorter than bufferSize.
668
  /// Computes a decimal representation with a fixed number of digits after the
669
    /// decimal point.
670
671
672
Foundation_API std::string& doubleToStr(std::string& str,
673
  double value,
674
  int precision = -1,
675
  int width = 0,
676
  char thSep = 0,
677
  char decSep = 0);
678
  /// Converts a double value, assigns it to the supplied string and returns the reference.
679
  /// This function calls doubleToStr(char*, int, double, int, int) and formats the result according to
680
  /// precision (total number of digits after the decimal point, -1 means ignore precision argument)
681
  /// and width (total length of formatted string).
682
683
684
Foundation_API std::string& doubleToFixedStr(std::string& str,
685
  double value,
686
  int precision = -1,
687
  int width = 0,
688
  char thSep = 0,
689
  char decSep = 0);
690
  /// Converts a double value, assigns it to the supplied string and returns the reference.
691
  /// This function calls doubleToFixedStr(char*, int, double, int) and formats the result according to
692
  /// precision (total number of digits after the decimal point) and width (total length of formatted string).
693
694
695
Foundation_API float strToFloat(const char* str,
696
  const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN);
697
  /// Converts the string of characters into single-precision floating point number.
698
  /// Function uses double_conversion::DoubleToStringConverter to do the conversion.
699
700
701
Foundation_API bool strToFloat(const std::string&, float& result,
702
  char decSep = '.', char thSep = ',',
703
  const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN);
704
  /// Converts the string of characters into single-precision floating point number.
705
  /// The conversion result is assigned to the result parameter.
706
  /// If decimal separator and/or thousand separator are different from defaults, they should be
707
  /// supplied to ensure proper conversion.
708
  ///
709
  /// Returns true if successful, false otherwise.
710
711
712
Foundation_API double strToDouble(const char* str,
713
  const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN);
714
  /// Converts the string of characters into double-precision floating point number.
715
716
717
Foundation_API bool strToDouble(const std::string& str, double& result,
718
  char decSep = '.', char thSep = ',',
719
  const char* inf = POCO_FLT_INF, const char* nan = POCO_FLT_NAN);
720
  /// Converts the string of characters into double-precision floating point number.
721
  /// The conversion result is assigned to the result parameter.
722
  /// If decimal separator and/or thousand separator are different from defaults, they should be
723
  /// supplied to ensure proper conversion.
724
  ///
725
  /// Returns true if successful, false otherwise.
726
727
728
} // namespace Poco
729
730
731
#ifdef POCO_COMPILER_MSVC
732
#pragma warning(pop)
733
#endif // POCO_COMPILER_MSVC
734
735
736
#endif // Foundation_NumericString_INCLUDED