summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qlocale_tools.cpp
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2021-07-29 17:50:44 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2021-08-17 00:31:26 +0200
commite5e8e4f59ba4c3d59303220a57677360992eb553 (patch)
treee51970808bc3b1836f00367b37d71f1b492146bc /src/corelib/text/qlocale_tools.cpp
parent2696d5a71b16e4288f4b071f9291cec7f719455a (diff)
Make double-formatting code ready for QByteArray
Split off the actual logic in qdtoBasicLatin into a templated function, qdtoString, which supports both QByteArray and QString. Since it uses qullToBasicLatin_helper as part of its fallback path make the same change to it. Task-number: QTBUG-88484 Change-Id: Icac75ee74ba6a9ddc3aa8d4782a981ef50a88db4 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/corelib/text/qlocale_tools.cpp')
-rw-r--r--src/corelib/text/qlocale_tools.cpp75
1 files changed, 45 insertions, 30 deletions
diff --git a/src/corelib/text/qlocale_tools.cpp b/src/corelib/text/qlocale_tools.cpp
index 2826e8b10e..dc0460fa4e 100644
--- a/src/corelib/text/qlocale_tools.cpp
+++ b/src/corelib/text/qlocale_tools.cpp
@@ -462,22 +462,23 @@ qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)
return result;
}
-static Q_ALWAYS_INLINE void qulltoBasicLatin_helper(qulonglong number, int base, char16_t *&p)
+template <typename Char>
+static Q_ALWAYS_INLINE void qulltoString_helper(qulonglong number, int base, Char *&p)
{
// Performance-optimized code. Compiler can generate faster code when base is known.
switch (base) {
-#define BIG_BASE_LOOP(b) \
- do { \
- const int r = number % b; \
- *--p = (r < 10 ? u'0' : u'a' - 10) + r; \
- number /= b; \
+#define BIG_BASE_LOOP(b) \
+ do { \
+ const int r = number % b; \
+ *--p = Char((r < 10 ? '0' : 'a' - 10) + r); \
+ number /= b; \
} while (number)
#ifndef __OPTIMIZE_SIZE__
-#define SMALL_BASE_LOOP(b) \
- do { \
- *--p = u'0' + number % b; \
- number /= b; \
- } while (number)
+# define SMALL_BASE_LOOP(b) \
+ do { \
+ *--p = Char('0' + number % b); \
+ number /= b; \
+ } while (number)
case 2: SMALL_BASE_LOOP(2); break;
case 8: SMALL_BASE_LOOP(8); break;
@@ -502,7 +503,7 @@ QString qulltoBasicLatin(qulonglong number, int base, bool negative)
char16_t buff[maxlen];
char16_t *const end = buff + maxlen, *p = end;
- qulltoBasicLatin_helper(number, base, p);
+ qulltoString_helper<char16_t>(number, base, p);
if (negative)
*--p = u'-';
@@ -519,7 +520,7 @@ QString qulltoa(qulonglong number, int base, const QStringView zero)
char16_t *const end = buff + maxlen, *p = end;
if (base != 10 || zero == u"0") {
- qulltoBasicLatin_helper(number, base, p);
+ qulltoString_helper<char16_t>(number, base, p);
} else if (zero.size() && !zero.at(0).isSurrogate()) {
const char16_t zeroUcs2 = zero.at(0).unicode();
while (number != 0) {
@@ -627,7 +628,8 @@ static constexpr int digits(int number)
return i;
}
-QString qdtoBasicLatin(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
+template <typename T>
+static T dtoString(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
{
// Undocumented: aside from F.P.Shortest, precision < 0 is treated as
// default, 6 - same as printf().
@@ -690,10 +692,15 @@ QString qdtoBasicLatin(double d, QLocaleData::DoubleForm form, int precision, bo
Q_UNREACHABLE(); // Handled earlier
}
}
- QString result;
+
+ constexpr bool IsQString = std::is_same_v<T, QString>;
+ using Char = std::conditional_t<IsQString, char16_t, char>;
+
+ T result;
result.reserve(total);
+
if (negative && !isZero(d)) // We don't return "-0"
- result.append(u'-');
+ result.append(Char('-'));
if (!qIsFinite(d)) {
result.append(view);
if (uppercase)
@@ -704,57 +711,60 @@ QString qdtoBasicLatin(double d, QLocaleData::DoubleForm form, int precision, bo
result.append(view.first(1));
view = view.sliced(1);
if (!view.isEmpty() || (!succinct && precision > 0)) {
- result.append(u'.');
+ result.append(Char('.'));
result.append(view);
if (qsizetype pad = precision - view.size(); !succinct && pad > 0) {
for (int i = 0; i < pad; ++i)
- result.append(u'0');
+ result.append(Char('0'));
}
}
int exponent = decpt - 1;
- result.append(uppercase ? u'E' : u'e');
- result.append(exponent < 0 ? u'-' : u'+');
+ result.append(Char(uppercase ? 'E' : 'e'));
+ result.append(Char(exponent < 0 ? '-' : '+'));
exponent = std::abs(exponent);
Q_ASSUME(exponent <= D::max_exponent10 + D::max_digits10);
int exponentDigits = digits(exponent);
// C's printf guarantees a two-digit exponent, and so do we:
if (exponentDigits == 1)
- result.append(u'0');
+ result.append(Char('0'));
result.resize(result.size() + exponentDigits);
- auto location = reinterpret_cast<char16_t *>(result.end());
- qulltoBasicLatin_helper(exponent, 10, location);
+ auto location = reinterpret_cast<Char *>(result.end());
+ qulltoString_helper<Char>(exponent, 10, location);
break;
}
case QLocaleData::DFDecimal:
if (decpt < 0) {
- result.append(u"0.0");
+ if constexpr (IsQString)
+ result.append(u"0.0");
+ else
+ result.append("0.0");
while (++decpt < 0)
- result.append(u'0');
+ result.append(Char('0'));
result.append(view);
if (!succinct) {
auto numDecimals = result.size() - 2 - (negative ? 1 : 0);
for (qsizetype i = numDecimals; i < precision; ++i)
- result.append(u'0');
+ result.append(Char('0'));
}
} else {
if (decpt > view.size()) {
result.append(view);
const int sign = negative ? 1 : 0;
while (result.size() - sign < decpt)
- result.append(u'0');
+ result.append(Char('0'));
view = {};
} else if (decpt) {
result.append(view.first(decpt));
view = view.sliced(decpt);
} else {
- result.append(u'0');
+ result.append(Char('0'));
}
if (!view.isEmpty() || (!succinct && view.size() < precision)) {
- result.append(u'.');
+ result.append(Char('.'));
result.append(view);
if (!succinct) {
for (qsizetype i = view.size(); i < precision; ++i)
- result.append(u'0');
+ result.append(Char('0'));
}
}
}
@@ -768,4 +778,9 @@ QString qdtoBasicLatin(double d, QLocaleData::DoubleForm form, int precision, bo
return result;
}
+QString qdtoBasicLatin(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
+{
+ return dtoString<QString>(d, form, precision, uppercase);
+}
+
QT_END_NAMESPACE