QCbor/JsonValue: add toStringView()
This is like toString(), but returns a view on the underlying string data (which may be US-ASCII (= L1), UTF-8, or UTF-16, so the return value is QASV). Use it around the code a bit. Benchmark results on my machine (with -perf -iterations 1000): PASS : BenchmarkQtJson::iteratorKey() RESULT : BenchmarkQtJson::iteratorKey(): 78,268.426 nsecs per iteration (total: 78,268,427, iterations: 1000) 349,458.080 CPU cycles per iteration, 4,46 GHz (total: 349,458,080, iterations: 1000) 780,327.957 instructions per iteration, 2,233 instr/cycle (total: 780,327,957, iterations: 1000) 173,511.019 branch instructions per iteration, 2,22 G/sec (total: 173,511,020, iterations: 1000) PASS : BenchmarkQtJson::iteratorKeyValueView() RESULT : BenchmarkQtJson::iteratorKeyValueView(): 58,424.756 nsecs per iteration (total: 58,424,756, iterations: 1000) 267,176.603 CPU cycles per iteration, 4,57 GHz (total: 267,176,604, iterations: 1000) 614,805.388 instructions per iteration, 2,301 instr/cycle (total: 614,805,389, iterations: 1000) 140,681.105 branch instructions per iteration, 2,41 G/sec (total: 140,681,106, iterations: 1000) PASS : BenchmarkQtJson::iteratorKeyView() RESULT : BenchmarkQtJson::iteratorKeyView(): 44,060.925 nsecs per iteration (total: 44,060,925, iterations: 1000) 196,344.233 CPU cycles per iteration, 4,46 GHz (total: 196,344,233, iterations: 1000) 426,631.322 instructions per iteration, 2,173 instr/cycle (total: 426,631,323, iterations: 1000) 93,703.100 branch instructions per iteration, 2,13 G/sec (total: 93,703,101, iterations: 1000) PASS : BenchmarkQtJson::iteratorKeyViewValueView() RESULT : BenchmarkQtJson::iteratorKeyViewValueView(): 29,205.569 nsecs per iteration (total: 29,205,570, iterations: 1000) 131,089.040 CPU cycles per iteration, 4,49 GHz (total: 131,089,041, iterations: 1000) 258,529.469 instructions per iteration, 1,972 instr/cycle (total: 258,529,469, iterations: 1000) 60,875.631 branch instructions per iteration, 2,08 G/sec (total: 60,875,631, iterations: 1000) [ChangeLog][QtCore][QCborValue/QJsonValue] Add toStringView() method. Fixes: QTBUG-133688 Change-Id: I4200035e995426f1cce46a73a429921a0cd56c85 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
3e1dffd5dd
commit
3070efb64a
@ -2195,7 +2195,7 @@ QByteArray QCborValue::toByteArray(const QByteArray &defaultValue) const
|
||||
Note that this function performs no conversion from other types to
|
||||
QString.
|
||||
|
||||
\sa isString(), isByteArray(), toByteArray()
|
||||
\sa toStringView(), isString(), isByteArray(), toByteArray()
|
||||
*/
|
||||
QString QCborValue::toString(const QString &defaultValue) const
|
||||
{
|
||||
@ -2206,6 +2206,33 @@ QString QCborValue::toString(const QString &defaultValue) const
|
||||
return container->stringAt(n);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.10
|
||||
|
||||
Returns the string value stored in this QCborValue, if it is of the string
|
||||
type. Otherwise, it returns \a defaultValue. Since QCborValue stores
|
||||
strings in either US-ASCII, UTF-8 or UTF-16, the returned QAnyStringView
|
||||
may be in any of these encodings.
|
||||
|
||||
This function does not allocate memory. The return value is valid until the
|
||||
next call to a non-const member function on this object. If this object goes
|
||||
out of scope, the return value is valid until the next call to a non-const
|
||||
member function on the parent CBOR object (map or array).
|
||||
|
||||
Note that this function performs no conversion from other types to
|
||||
QString.
|
||||
|
||||
\sa toString(), isString(), isByteArray(), toByteArray()
|
||||
*/
|
||||
QAnyStringView QCborValue::toStringView(QAnyStringView defaultValue) const
|
||||
{
|
||||
if (!container || !isString())
|
||||
return defaultValue;
|
||||
|
||||
Q_ASSERT(n >= 0);
|
||||
return container->anyStringViewAt(n);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(datestring)
|
||||
/*!
|
||||
Returns the date/time value stored in this QCborValue, if it is of the
|
||||
@ -2901,6 +2928,14 @@ QString QCborValueConstRef::concreteString(QCborValueConstRef self, const QStrin
|
||||
return self.d->stringAt(self.i);
|
||||
}
|
||||
|
||||
QAnyStringView QCborValueConstRef::concreteStringView(QCborValueConstRef self, QAnyStringView defaultValue)
|
||||
{
|
||||
QtCbor::Element e = self.d->elements.at(self.i);
|
||||
if (e.type != QCborValue::String)
|
||||
return defaultValue;
|
||||
return self.d->anyStringViewAt(self.i);
|
||||
}
|
||||
|
||||
bool
|
||||
QCborValueConstRef::comparesEqual_helper(QCborValueConstRef lhs, QCborValueConstRef rhs) noexcept
|
||||
{
|
||||
|
@ -198,6 +198,7 @@ public:
|
||||
|
||||
QByteArray toByteArray(const QByteArray &defaultValue = {}) const;
|
||||
QString toString(const QString &defaultValue = {}) const;
|
||||
QAnyStringView toStringView(QAnyStringView defaultValue = {}) const;
|
||||
#if QT_CONFIG(datestring)
|
||||
QDateTime toDateTime(const QDateTime &defaultValue = {}) const;
|
||||
#endif
|
||||
@ -350,6 +351,8 @@ public:
|
||||
{ return concrete().toByteArray(defaultValue); }
|
||||
QString toString(const QString &defaultValue = {}) const
|
||||
{ return concrete().toString(defaultValue); }
|
||||
QAnyStringView toStringView(QAnyStringView defaultValue = {}) const
|
||||
{ return concreteStringView(*this, defaultValue); }
|
||||
#if QT_CONFIG(datestring)
|
||||
QDateTime toDateTime(const QDateTime &defaultValue = {}) const
|
||||
{ return concrete().toDateTime(defaultValue); }
|
||||
@ -442,6 +445,8 @@ protected:
|
||||
concreteByteArray(QCborValueConstRef that, const QByteArray &defaultValue);
|
||||
static Q_CORE_EXPORT QString
|
||||
concreteString(QCborValueConstRef that, const QString &defaultValue);
|
||||
static Q_CORE_EXPORT QAnyStringView
|
||||
concreteStringView(QCborValueConstRef that, QAnyStringView defaultValue);
|
||||
|
||||
constexpr QCborValueConstRef() : d(nullptr), i(0) {} // this will actually be invalid
|
||||
constexpr QCborValueConstRef(QCborContainerPrivate *dd, qsizetype ii)
|
||||
|
@ -744,12 +744,34 @@ double QJsonValue::toDouble(double defaultValue) const
|
||||
Converts the value to a QString and returns it.
|
||||
|
||||
If type() is not String, the \a defaultValue will be returned.
|
||||
|
||||
\sa toStringView()
|
||||
*/
|
||||
QString QJsonValue::toString(const QString &defaultValue) const
|
||||
{
|
||||
return value.toString(defaultValue);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.10
|
||||
|
||||
Returns the string value stored in this QJsonValue, if it is of the
|
||||
\l{String}{string} type. Otherwise, it returns \a defaultValue. Since
|
||||
QJsonValue stores strings in either US-ASCII, UTF-8 or UTF-16, the returned
|
||||
QAnyStringView may be in any of these encodings.
|
||||
|
||||
This function does not allocate memory. The return value is valid until the
|
||||
next call to a non-const member function on this object. If this object goes
|
||||
out of scope, the return value is valid until the next call to a non-const
|
||||
member function on the parent JSON object or array.
|
||||
|
||||
\sa toString()
|
||||
*/
|
||||
QAnyStringView QJsonValue::toStringView(QAnyStringView defaultValue) const
|
||||
{
|
||||
return value.toStringView(defaultValue);
|
||||
}
|
||||
|
||||
/*!
|
||||
Converts the value to a QString and returns it.
|
||||
|
||||
@ -1066,6 +1088,15 @@ QString QJsonValueConstRef::concreteString(QJsonValueConstRef self, const QStrin
|
||||
return d->stringAt(index);
|
||||
}
|
||||
|
||||
QAnyStringView QJsonValueConstRef::concreteStringView(QJsonValueConstRef self, QAnyStringView defaultValue)
|
||||
{
|
||||
const QCborContainerPrivate *d = QJsonPrivate::Value::container(self);
|
||||
const qsizetype index = QJsonPrivate::Value::indexHelper(self);
|
||||
if (d->elements.at(index).type != QCborValue::String)
|
||||
return defaultValue;
|
||||
return d->anyStringViewAt(index);
|
||||
}
|
||||
|
||||
QJsonValue QJsonValueConstRef::concrete(QJsonValueConstRef self) noexcept
|
||||
{
|
||||
const QCborContainerPrivate *d = QJsonPrivate::Value::container(self);
|
||||
|
@ -100,6 +100,7 @@ public:
|
||||
double toDouble(double defaultValue = 0) const;
|
||||
QString toString() const;
|
||||
QString toString(const QString &defaultValue) const;
|
||||
QAnyStringView toStringView(QAnyStringView defaultValue = {}) const;
|
||||
QJsonArray toArray() const;
|
||||
QJsonArray toArray(const QJsonArray &defaultValue) const;
|
||||
QJsonObject toObject() const;
|
||||
@ -165,6 +166,8 @@ public:
|
||||
{ return concreteDouble(*this, defaultValue); }
|
||||
QString toString(const QString &defaultValue = {}) const
|
||||
{ return concreteString(*this, defaultValue); }
|
||||
QAnyStringView toStringView(QAnyStringView defaultValue = {}) const
|
||||
{ return concreteStringView(*this, defaultValue); }
|
||||
Q_CORE_EXPORT QJsonArray toArray() const;
|
||||
Q_CORE_EXPORT QJsonObject toObject() const;
|
||||
|
||||
@ -195,6 +198,7 @@ protected:
|
||||
Q_CORE_EXPORT static double
|
||||
concreteDouble(QJsonValueConstRef self, double defaultValue) noexcept Q_DECL_PURE_FUNCTION;
|
||||
Q_CORE_EXPORT static QString concreteString(QJsonValueConstRef self, const QString &defaultValue);
|
||||
Q_CORE_EXPORT static QAnyStringView concreteStringView(QJsonValueConstRef self, QAnyStringView defaultValue);
|
||||
Q_CORE_EXPORT static QJsonValue concrete(QJsonValueConstRef self) noexcept;
|
||||
|
||||
// for iterators
|
||||
@ -287,6 +291,8 @@ public:
|
||||
inline qint64 toInteger(qint64 defaultValue = 0) const { return QJsonValueConstRef::toInteger(defaultValue); }
|
||||
inline double toDouble(double defaultValue = 0) const { return QJsonValueConstRef::toDouble(defaultValue); }
|
||||
inline QString toString(const QString &defaultValue = {}) const { return QJsonValueConstRef::toString(defaultValue); }
|
||||
QAnyStringView toStringView(QAnyStringView defaultValue = {}) const
|
||||
{ return QJsonValueConstRef::toStringView(defaultValue); }
|
||||
QJsonArray toArray() const;
|
||||
QJsonObject toObject() const;
|
||||
|
||||
|
@ -176,8 +176,8 @@ VersionTerm VersionTerm::fromJson(const QJsonValue &v)
|
||||
if (!v.isObject())
|
||||
return result;
|
||||
const QJsonObject o = v.toObject();
|
||||
result.number = QVersionNumber::fromString(o.value("value"_L1).toString());
|
||||
const QString opS = o.value("op"_L1).toString();
|
||||
result.number = QVersionNumber::fromString(o.value("value"_L1).toStringView());
|
||||
const auto opS = o.value("op"_L1).toStringView();
|
||||
for (size_t i = 0; i < sizeof(operators) / sizeof(operators[0]); ++i) {
|
||||
if (opS == QLatin1StringView(operators[i])) {
|
||||
result.op = static_cast<Operator>(i);
|
||||
|
@ -1044,14 +1044,15 @@ void QKmsScreenConfig::loadConfig()
|
||||
m_devicePath = object.value("device"_L1).toString();
|
||||
m_separateScreens = object.value("separateScreens"_L1).toBool(m_separateScreens);
|
||||
|
||||
const QString vdOriString = object.value("virtualDesktopLayout"_L1).toString();
|
||||
const auto vdOriString = object.value("virtualDesktopLayout"_L1).toStringView();
|
||||
if (!vdOriString.isEmpty()) {
|
||||
if (vdOriString == "horizontal"_L1)
|
||||
m_virtualDesktopLayout = VirtualDesktopLayoutHorizontal;
|
||||
else if (vdOriString == "vertical"_L1)
|
||||
m_virtualDesktopLayout = VirtualDesktopLayoutVertical;
|
||||
else
|
||||
qCWarning(qLcKmsDebug) << "Unknown virtualDesktopOrientation value" << vdOriString;
|
||||
qCWarning(qLcKmsDebug, "Unknown virtualDesktopOrientation value %ls",
|
||||
qUtf16Printable(vdOriString.toString()));
|
||||
}
|
||||
|
||||
const QJsonArray outputs = object.value("outputs"_L1).toArray();
|
||||
|
@ -342,6 +342,7 @@ static void basicTypeCheck(QCborValue::Type type, const QCborValue &v, const QVa
|
||||
QVERIFY(validexpr)
|
||||
CMP(v.toByteArray(), QByteArray, v.toByteArray().isNull());
|
||||
CMP(v.toString(), QString, v.toString().isNull());
|
||||
CMP(v.toStringView(), QString, v.toStringView().isNull());
|
||||
CMP(v.toDateTime(), QDateTime, !v.toDateTime().isValid());
|
||||
CMP(v.toUrl(), QUrl, !v.toUrl().isValid());
|
||||
CMP(v.toRegularExpression(), QRegularExpression, v.toRegularExpression().pattern().isNull());
|
||||
@ -886,6 +887,7 @@ void tst_QCborValue::mapSimpleInitializerList()
|
||||
QCborValue v = m.value(2);
|
||||
QVERIFY(v.isString());
|
||||
QCOMPARE(v.toString(), "Hello");
|
||||
QCOMPARE(v.toStringView(), u8"Hello");
|
||||
QCOMPARE(vmap[2], v);
|
||||
}
|
||||
{
|
||||
@ -893,6 +895,7 @@ void tst_QCborValue::mapSimpleInitializerList()
|
||||
QCborValue v = m.value(3);
|
||||
QVERIFY(v.isString());
|
||||
QCOMPARE(v.toString(), "World");
|
||||
QCOMPARE(v.toStringView(), "World"_L1);
|
||||
QCOMPARE(vmap[3], v);
|
||||
}
|
||||
{
|
||||
@ -934,6 +937,7 @@ void tst_QCborValue::mapSimpleInitializerList()
|
||||
QCOMPARE((it + 1).key(), QCborValue(2));
|
||||
QVERIFY((it + 1)->isString());
|
||||
QCOMPARE((it + 1)->toString(), "Hello");
|
||||
QCOMPARE((it + 1)->toStringView(), u8"Hello");
|
||||
it += 2;
|
||||
QCOMPARE(it.key(), QCborValue("Hello"));
|
||||
QVERIFY(it->isInteger());
|
||||
@ -941,6 +945,7 @@ void tst_QCborValue::mapSimpleInitializerList()
|
||||
QCOMPARE(it.key(), QCborValue(3));
|
||||
QVERIFY(it->isString());
|
||||
QCOMPARE(it.value().toString(), "World");
|
||||
QCOMPARE(it.value().toStringView(), "World"_L1);
|
||||
--end;
|
||||
QCOMPARE(end.key(), QCborValue("World"));
|
||||
QCOMPARE(end.value(), QCborValue(3));
|
||||
@ -1462,6 +1467,7 @@ void tst_QCborValue::arrayStringElements()
|
||||
|
||||
QCborValueRef r1 = a[0];
|
||||
QCOMPARE(r1.toString(), "Hello");
|
||||
QCOMPARE(r1.toStringView(), u8"Hello");
|
||||
QCOMPARE(r1.operator QCborValue(), QCborValue("Hello"));
|
||||
QT_TEST_EQUALITY_OPS(r1, QCborValue("Hello"), true);
|
||||
|
||||
@ -1476,10 +1482,11 @@ void tst_QCborValue::arrayStringElements()
|
||||
|
||||
v2 = a.at(1);
|
||||
QCOMPARE(v2.toString(), "World");
|
||||
QCOMPARE(v2.toStringView(), u8"World");
|
||||
QT_TEST_EQUALITY_OPS(v2, QCborValue("World"), true);
|
||||
|
||||
QCOMPARE(a.takeAt(1).toString(), "World");
|
||||
QCOMPARE(a.takeAt(0).toString(), "Hello");
|
||||
QCOMPARE(a.takeAt(0).toStringView(), "Hello"_L1);
|
||||
QVERIFY(a.isEmpty());
|
||||
}
|
||||
|
||||
@ -1492,6 +1499,7 @@ void tst_QCborValue::mapStringValues()
|
||||
|
||||
QCborValueRef r1 = m[0];
|
||||
QCOMPARE(r1.toString(), "Hello");
|
||||
QCOMPARE(r1.toStringView(), "Hello"_L1);
|
||||
QCOMPARE(r1.operator QCborValue(), QCborValue("Hello"));
|
||||
QT_TEST_EQUALITY_OPS(r1, QCborValue("Hello"), true);
|
||||
|
||||
@ -1506,10 +1514,11 @@ void tst_QCborValue::mapStringValues()
|
||||
|
||||
v2 = (m.begin() + 1).value();
|
||||
QCOMPARE(v2.toString(), "World");
|
||||
QCOMPARE(v2.toStringView(), "World"_L1);
|
||||
QCOMPARE(v2, QCborValue("World"));
|
||||
|
||||
QCOMPARE(m.extract(m.begin() + 1).toString(), "World");
|
||||
QCOMPARE(m.take(0).toString(), "Hello");
|
||||
QCOMPARE(m.take(0).toStringView(), u8"Hello");
|
||||
QVERIFY(m.isEmpty());
|
||||
}
|
||||
|
||||
@ -1530,6 +1539,7 @@ void tst_QCborValue::mapStringKeys()
|
||||
QVERIFY(m2.value(QCborValue(QByteArray("foo"))).isUndefined());
|
||||
QVERIFY(m.value(QCborValue(QLatin1String("foo"))).isUndefined());
|
||||
QCOMPARE(m.value(QCborValue(QByteArray("foo"))).toString(), "bar");
|
||||
QCOMPARE(m.value(QCborValue(QByteArray("foo"))).toStringView(), "bar");
|
||||
|
||||
m.insert(u"World"_s, QCborValue(3)); // replaces
|
||||
QCOMPARE(m.size(), 3);
|
||||
@ -1796,7 +1806,7 @@ void tst_QCborValue::mapComplexKeys()
|
||||
|
||||
// basics_data() strings are Latin1
|
||||
QByteArray latin1 = v.toString().toLatin1();
|
||||
Q_ASSERT(v.toString() == QString::fromLatin1(latin1));
|
||||
Q_ASSERT(v.toStringView() == QString::fromLatin1(latin1));
|
||||
QCOMPARE(m[QLatin1String(latin1)].toInteger(), 42);
|
||||
}
|
||||
|
||||
@ -3007,6 +3017,7 @@ template <typename ValueRef> static void cborValueRef_template()
|
||||
QCOMPARE(ref.toDouble(47), v.toDouble(47));
|
||||
QCOMPARE(ref.toByteArray("other"), v.toByteArray("other"));
|
||||
QCOMPARE(ref.toString("other"), v.toString("other"));
|
||||
QCOMPARE(ref.toStringView("other"_L1), v.toStringView("other"));
|
||||
QCOMPARE(ref.toArray(otherArray), v.toArray(otherArray));
|
||||
QCOMPARE(ref.toMap(otherMap), v.toMap(otherMap));
|
||||
QCOMPARE(ref.toDateTime(otherDateTime), v.toDateTime(otherDateTime));
|
||||
|
@ -38,6 +38,17 @@ private Q_SLOTS:
|
||||
[](auto it) { return it->toString(); });
|
||||
}
|
||||
|
||||
void iteratorKeyValueView()
|
||||
{
|
||||
iteratorKeyImpl([](auto it) { return it.key(); },
|
||||
[](auto it) { return it->toStringView(); });
|
||||
}
|
||||
void iteratorKeyViewValueView()
|
||||
{
|
||||
iteratorKeyImpl([](auto it) { return it.keyView(); },
|
||||
[](auto it) { return it->toStringView(); });
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename KeyFunc, typename ValueFunc>
|
||||
void iteratorKeyImpl(KeyFunc key, ValueFunc val);
|
||||
|
Loading…
x
Reference in New Issue
Block a user