10#include <private/qtools_p.h>
11#include <private/qnumeric_p.h>
24#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
30# define LLONG_MAX Q_INT64_C(0x7fffffffffffffff)
33# define LLONG_MIN (-LLONG_MAX - Q_INT64_C(1))
36# define ULLONG_MAX Q_UINT64_C(0xffffffffffffffff)
87#if !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
92 double_conversion::DoubleToStringConverter::DtoaMode
mode;
94 mode = double_conversion::DoubleToStringConverter::SHORTEST;
96 mode = double_conversion::DoubleToStringConverter::PRECISION;
98 mode = double_conversion::DoubleToStringConverter::FIXED;
103 const auto boundedBufferSize =
static_cast<int>((std::min)(
bufSize,
qsizetype(INT_MAX)));
104 double_conversion::DoubleToStringConverter::DoubleToAscii(
d,
mode,
precision,
buf,
116 precision = std::numeric_limits<double>::max_digits10;
132 const int formatLength = 7;
133 char format[formatLength];
134 format[formatLength - 1] =
'\0';
143 format[formatLength - 2] =
'f';
148 format[formatLength - 2] =
'e';
153 format[formatLength - 2] =
'g';
166 int firstSignificant = 0;
167 int decptInTarget =
length;
171 while (firstSignificant <
length) {
172 if (
target[firstSignificant] ==
'.')
173 decptInTarget = firstSignificant;
174 else if (
target[firstSignificant] !=
'0')
180 if (decptInTarget ==
length)
181 decptInTarget = std::find(
target.data() + firstSignificant,
target.data() +
length,
'.') -
198 decpt =
r.result + 1;
206 decpt = decptInTarget - firstSignificant;
211 decpt = decptInTarget - firstSignificant;
215 if (decptInTarget > firstSignificant) {
217 int lengthBeforeDecpt = decptInTarget - firstSignificant;
219 if (eSign > decptInTarget && lengthBeforeDecpt <
bufSize) {
221 memcpy(
buf + lengthBeforeDecpt,
target.data() + decptInTarget + 1,
222 qMin(eSign - decptInTarget - 1,
bufSize - lengthBeforeDecpt));
231 if (eSign > firstSignificant) {
262 if (
char c = *
num; numLen >= 3
263 && (
c ==
'-' ||
c ==
'+' ||
c ==
'I' ||
c ==
'i' ||
c ==
'N' ||
c ==
'n')) {
264 bool negative = (
c ==
'-');
265 bool hasSign = negative || (
c ==
'+');
273 auto lowered = [](
char c) {
287 if (
c ==
'i' &&
c2 ==
'n' && c3 ==
'f')
289 else if (
c ==
'n' &&
c2 ==
'a' && c3 ==
'n' && !hasSign)
297#if !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
298 int conv_flags = double_conversion::StringToDoubleConverter::NO_FLAGS;
300 conv_flags = double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK;
302 conv_flags = double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES
303 | double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES;
305 double_conversion::StringToDoubleConverter conv(conv_flags, 0.0,
qt_qnan(),
nullptr,
nullptr);
306 if (
int(numLen) != numLen) {
310 d = conv.StringToDouble(
num,
int(numLen), &processed);
319 return {
d, -processed };
324 constexpr auto maxDigitsForULongLong = 1 + std::numeric_limits<unsigned long long>::digits10;
326 char fmt[1 + maxDigitsForULongLong + 4 + 1];
327 qsnprintf(
fmt,
sizeof fmt,
"%s%llu%s",
"%",
static_cast<unsigned long long>(numLen),
"lf%n");
329 if (qDoubleSscanf(
num, QT_CLOCALE,
fmt, &
d, &processed) < 1)
341 for (
int i = 0;
i < processed; ++
i) {
343 if ((
c <
'0' ||
c >
'9') &&
c !=
'.' &&
c !=
'-' &&
c !=
'+' &&
c !=
'e' &&
c !=
'E') {
348 return {
d, -processed };
357 for (
int i = 0;
i < processed; ++
i) {
358 if (
num[
i] >=
'1' &&
num[
i] <=
'9') {
360 return {
d, -processed};
361 }
else if (
num[
i] ==
'e' ||
num[
i] ==
'E') {
366 return {
d, processed };
379 const char *x_or_b =
p + 1;
400 }
else if (
base == 0) {
416 return d >=
'a' &&
d <
'a' +
base - 10;
426 unsigned long long result = 0;
427 if (
p >= stop || *
p ==
'-')
430 if (!prefix.base || prefix.next >= stop)
433 const auto res = std::from_chars(prefix.next, stop,
result, prefix.base);
434 if (
res.ec != std::errc{})
447 const bool negate =
p < stop && *
p ==
'-';
448 if (negate || (
p < stop && *
p ==
'+'))
454 if (!prefix.base || prefix.next >= stop || !
isDigitForBase(*prefix.next, prefix.base))
458 auto res = std::from_chars(prefix.next, stop,
result, prefix.base);
459 if (negate &&
res.ec == std::errc::result_out_of_range) {
461 unsigned long long check = 0;
462 res = std::from_chars(prefix.next, stop, check, prefix.base);
463 if (
res.ec == std::errc{} && check + std::numeric_limits<long long>::min() == 0)
464 return { std::numeric_limits<long long>::min(),
res.ptr -
begin };
467 if (
res.ec != std::errc{})
472template <
typename Char>
477#define BIG_BASE_LOOP(b) \
479 const int r = number % b; \
480 *--p = Char((r < 10 ? '0' : 'a' - 10) + r); \
483#ifndef __OPTIMIZE_SIZE__
484# define SMALL_BASE_LOOP(b) \
486 *--p = Char('0' + number % b); \
494#undef SMALL_BASE_LOOP
508 const unsigned maxlen = 65;
509 static_assert(CHAR_BIT *
sizeof(
number) + 1 <= maxlen);
510 char16_t buff[maxlen];
511 char16_t *
const end = buff + maxlen, *
p =
end;
524 const unsigned maxlen = 128;
525 static_assert(CHAR_BIT *
sizeof(
number) <= maxlen);
526 char16_t buff[maxlen];
527 char16_t *
const end = buff + maxlen, *
p =
end;
531 }
else if (
zero.size() && !
zero.at(0).isSurrogate()) {
532 const char16_t zeroUcs2 =
zero.at(0).unicode();
538 }
else if (
zero.size() == 2 &&
zero.at(0).isHighSurrogate()) {
549 Q_UNREACHABLE_RETURN(
QString());
566 *se = s00 + (
r.used < 0 ? -
r.used :
r.used);
574 bool nonNullSign =
false;
575 int nonNullDecpt = 0;
579 constexpr qsizetype digits = std::numeric_limits<double>::max_digits10 + 1;
585 *
sign = nonNullSign ? 1 : 0;
587 *decpt = nonNullDecpt;
602 if (length <= decpt && length > 1)
604 else if (
length == 1 && decpt <= 0)
613 useDecimal = 1 - decpt <=
bias;
646 using D = std::numeric_limits<double>;
648 constexpr int MaxDigits = 1 +
qMax(D::max_exponent10, D::digits10 - D::min_exponent10);
662 bool negative =
false;
677 total += std::max(2,
digits(std::abs(decpt - 1)));
679 if (
int extraPrecision =
precision - (
length - 1); extraPrecision > 0 && !succinct)
680 total += extraPrecision;
703 constexpr bool IsQString = std::is_same_v<T, QString>;
704 using Char = std::conditional_t<IsQString, char16_t, char>;
724 for (
int i = 0;
i < pad; ++
i)
732 Q_ASSUME(
exponent <= D::max_exponent10 + D::max_digits10);
735 if (exponentDigits == 1)
744 if constexpr (IsQString)
752 auto numDecimals =
result.size() - 2 - (negative ? 1 : 0);
757 if (decpt >
view.size()) {
759 const int sign = negative ? 1 : 0;
static constexpr char32_t surrogateToUcs4(char16_t high, char16_t low) noexcept
Converts a UTF16 surrogate pair with the given high and low values to it's UCS-4-encoded code point.
static constexpr char16_t highSurrogate(char32_t ucs4) noexcept
Returns the high surrogate part of a UCS-4-encoded code point.
static constexpr char16_t lowSurrogate(char32_t ucs4) noexcept
Returns the low surrogate part of a UCS-4-encoded code point.
QVariant data(int key) const
Returns this item's custom data for the key key as a QVariant.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Combined button and popup list for selecting options.
constexpr bool isAsciiDigit(char32_t c) noexcept
Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt,...)
#define QT_CLOCALE_HOLDER
bool qIsFinite(qfloat16 f) noexcept
bool qIsNaN(qfloat16 f) noexcept
constexpr bool ascii_isspace(uchar c)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
static Q_DECL_CONST_FUNCTION bool qt_is_nan(double d)
constexpr static Q_DECL_CONST_FUNCTION double qt_qnan() noexcept
constexpr static Q_DECL_CONST_FUNCTION double qt_inf() noexcept
static Q_DECL_CONST_FUNCTION bool qt_is_inf(double d)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
GLenum GLint GLint * precision
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define QStringLiteral(str)
QVideoFrameFormat::PixelFormat fmt