JSON: add some QStringView overloads

[ChangeLog][QtCore][JSON] Added overloads of functions taking key
strings as QStringView; in QJsonObject, QJsonValue and QJsonDocument.

Change-Id: I78b40aba8200003acfae257ff06f5f15737005e7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru>
This commit is contained in:
Mat Sutcliffe 2019-07-12 20:22:49 +01:00
parent a4e9fa03ca
commit 7f8e3aab2d
9 changed files with 198 additions and 37 deletions

View File

@ -175,7 +175,7 @@ void Base::removeItems(int pos, int numItems)
length -= numItems;
}
int Object::indexOf(const QString &key, bool *exists) const
int Object::indexOf(QStringView key, bool *exists) const
{
int min = 0;
int n = length;
@ -257,7 +257,7 @@ bool Array::isValid(int maxSize) const
}
bool Entry::operator ==(const QString &key) const
bool Entry::operator ==(QStringView key) const
{
if (value.latinKey)
return (shallowLatin1Key() == key);
@ -270,7 +270,7 @@ bool Entry::operator==(QLatin1String key) const
if (value.latinKey)
return shallowLatin1Key() == key;
else
return shallowKey() == key;
return shallowKey() == QString(key); // ### conversion to QString
}
bool Entry::operator ==(const Entry &other) const

View File

@ -153,14 +153,14 @@ typedef qle_uint offset;
// round the size up to the next 4 byte boundary
inline int alignedSize(int size) { return (size + 3) & ~3; }
static inline bool useCompressed(const QString &s)
static inline bool useCompressed(QStringView s)
{
if (s.length() >= 0x8000)
return false;
return QtPrivate::isLatin1(s);
}
static inline int qStringSize(const QString &string, bool compress)
static inline int qStringSize(QStringView string, bool compress)
{
int l = 2 + string.length();
if (!compress)
@ -214,37 +214,31 @@ public:
return maxSize >= 0 && uint(d->length) <= maxSize / sizeof(ushort);
}
inline String &operator=(const QString &str)
inline String &operator=(QStringView str)
{
d->length = str.length();
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
const ushort *uc = (const ushort *)str.unicode();
for (int i = 0; i < str.length(); ++i)
d->utf16[i] = uc[i];
#else
memcpy(d->utf16, str.unicode(), str.length()*sizeof(ushort));
#endif
qToLittleEndian<quint16>(str.utf16(), str.length(), d->utf16);
if (str.length() & 1)
d->utf16[str.length()] = 0;
return *this;
}
inline bool operator ==(const QString &str) const {
inline bool operator ==(QStringView str) const {
int slen = str.length();
int l = d->length;
if (slen != l)
return false;
const ushort *s = (const ushort *)str.constData();
const ushort *s = (const ushort *)str.utf16();
const qle_ushort *a = d->utf16;
const ushort *b = s;
while (l-- && *a == *b)
a++,b++;
return (l == -1);
}
inline bool operator !=(const QString &str) const {
inline bool operator !=(QStringView str) const {
return !operator ==(str);
}
inline bool operator >=(const QString &str) const {
inline bool operator >=(QStringView str) const {
// ###
return toString() >= str;
}
@ -292,11 +286,11 @@ public:
return byteSize() <= maxSize;
}
inline Latin1String &operator=(const QString &str)
inline Latin1String &operator=(QStringView str)
{
int len = d->length = str.length();
uchar *l = (uchar *)d->latin1;
const ushort *uc = (const ushort *)str.unicode();
const ushort *uc = (const ushort *)str.utf16();
qt_to_latin1_unchecked(l, uc, len);
for ( ; (quintptr)(l+len) & 0x3; ++len)
@ -351,11 +345,11 @@ public:
{ \
return lhs.toQLatin1String() op rhs; \
} \
inline bool operator op(const QString &lhs, Latin1String rhs) noexcept \
inline bool operator op(QStringView lhs, Latin1String rhs) noexcept \
{ \
return lhs op rhs.toQLatin1String(); \
} \
inline bool operator op(Latin1String lhs, const QString &rhs) noexcept \
inline bool operator op(Latin1String lhs, QStringView rhs) noexcept \
{ \
return lhs.toQLatin1String() op rhs; \
} \
@ -419,7 +413,7 @@ inline bool String::operator<(const Latin1String &str) const
}
static inline void copyString(char *dest, const QString &str, bool compress)
static inline void copyString(char *dest, QStringView str, bool compress)
{
if (compress) {
Latin1String string(dest);
@ -469,7 +463,7 @@ public:
Entry *entryAt(int i) const {
return reinterpret_cast<Entry *>(((char *)this) + table()[i]);
}
int indexOf(const QString &key, bool *exists) const;
int indexOf(QStringView key, bool *exists) const;
int indexOf(QLatin1String key, bool *exists) const;
bool isValid(int maxSize) const;
@ -577,9 +571,9 @@ public:
return shallowKey().isValid(maxSize);
}
bool operator ==(const QString &key) const;
inline bool operator !=(const QString &key) const { return !operator ==(key); }
inline bool operator >=(const QString &key) const;
bool operator ==(QStringView key) const;
inline bool operator !=(QStringView key) const { return !operator ==(key); }
inline bool operator >=(QStringView key) const;
bool operator==(QLatin1String key) const;
inline bool operator!=(QLatin1String key) const { return !operator ==(key); }
@ -589,7 +583,7 @@ public:
bool operator >=(const Entry &other) const;
};
inline bool Entry::operator >=(const QString &key) const
inline bool Entry::operator >=(QStringView key) const
{
if (value.latinKey)
return (shallowLatin1Key() >= key);
@ -602,10 +596,10 @@ inline bool Entry::operator >=(QLatin1String key) const
if (value.latinKey)
return shallowLatin1Key() >= key;
else
return shallowKey() >= key;
return shallowKey() >= QString(key); // ### conversion to QString
}
inline bool operator <(const QString &key, const Entry &e)
inline bool operator <(QStringView key, const Entry &e)
{ return e >= key; }
inline bool operator<(QLatin1String key, const Entry &e)

View File

@ -544,6 +544,7 @@ void QJsonDocument::setArray(const QJsonArray &array)
d->ref.ref();
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns a QJsonValue representing the value for the key \a key.
@ -557,6 +558,16 @@ void QJsonDocument::setArray(const QJsonArray &array)
\sa QJsonValue, QJsonValue::isUndefined(), QJsonObject
*/
const QJsonValue QJsonDocument::operator[](const QString &key) const
{
return (*this)[QStringView(key)];
}
#endif
/*!
\overload
\since 5.14
*/
const QJsonValue QJsonDocument::operator[](QStringView key) const
{
if (!isObject())
return QJsonValue(QJsonValue::Undefined);

View File

@ -146,7 +146,10 @@ public:
void setObject(const QJsonObject &object);
void setArray(const QJsonArray &array);
#if QT_STRINGVIEW_LEVEL < 2
const QJsonValue operator[](const QString &key) const;
#endif
const QJsonValue operator[](QStringView key) const;
const QJsonValue operator[](QLatin1String key) const;
const QJsonValue operator[](int i) const;

View File

@ -377,6 +377,7 @@ bool QJsonObject::isEmpty() const
return !o->length;
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns a QJsonValue representing the value for the key \a key.
@ -385,6 +386,16 @@ bool QJsonObject::isEmpty() const
\sa QJsonValue, QJsonValue::isUndefined()
*/
QJsonValue QJsonObject::value(const QString &key) const
{
return value(QStringView(key));
}
#endif
/*!
\overload
\since 5.14
*/
QJsonValue QJsonObject::value(QStringView key) const
{
if (!d)
return QJsonValue(QJsonValue::Undefined);
@ -412,6 +423,7 @@ QJsonValue QJsonObject::value(QLatin1String key) const
return QJsonValue(d, o, o->entryAt(i)->value);
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns a QJsonValue representing the value for the key \a key.
@ -423,8 +435,16 @@ QJsonValue QJsonObject::value(QLatin1String key) const
*/
QJsonValue QJsonObject::operator [](const QString &key) const
{
return value(key);
return (*this)[QStringView(key)];
}
#endif
/*!
\fn QJsonValue QJsonObject::operator [](QStringView key) const
\overload
\since 5.14
*/
/*!
\fn QJsonValue QJsonObject::operator [](QLatin1String key) const
@ -433,6 +453,7 @@ QJsonValue QJsonObject::operator [](const QString &key) const
\since 5.7
*/
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns a reference to the value for \a key.
@ -445,6 +466,16 @@ QJsonValue QJsonObject::operator [](const QString &key) const
\sa value()
*/
QJsonValueRef QJsonObject::operator [](const QString &key)
{
return (*this)[QStringView(key)];
}
#endif
/*!
\overload
\since 5.14
*/
QJsonValueRef QJsonObject::operator [](QStringView key)
{
bool keyExists = false;
int index = o ? o->indexOf(key, &keyExists) : 0;
@ -465,6 +496,7 @@ QJsonValueRef QJsonObject::operator [](QLatin1String key)
return operator[](QString(key));
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Inserts a new item with the key \a key and a value of \a value.
@ -479,6 +511,16 @@ QJsonValueRef QJsonObject::operator [](QLatin1String key)
\sa remove(), take(), QJsonObject::iterator, end()
*/
QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value)
{
return insert(QStringView(key), value);
}
#endif
/*!
\overload
\since 5.14
*/
QJsonObject::iterator QJsonObject::insert(QStringView key, const QJsonValue &value)
{
if (value.t == QJsonValue::Undefined) {
remove(key);
@ -492,7 +534,7 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &
/*!
\internal
*/
QJsonObject::iterator QJsonObject::insertAt(int pos, const QString &key, const QJsonValue &value, bool keyExists)
QJsonObject::iterator QJsonObject::insertAt(int pos, QStringView key, const QJsonValue &value, bool keyExists)
{
QJsonValue val = value;
@ -530,12 +572,23 @@ QJsonObject::iterator QJsonObject::insertAt(int pos, const QString &key, const Q
return iterator(this, pos);
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Removes \a key from the object.
\sa insert(), take()
*/
void QJsonObject::remove(const QString &key)
{
remove(QStringView(key));
}
#endif
/*!
\overload
\since 5.14
*/
void QJsonObject::remove(QStringView key)
{
if (!d)
return;
@ -548,6 +601,7 @@ void QJsonObject::remove(const QString &key)
removeAt(index);
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Removes \a key from the object.
@ -558,6 +612,16 @@ void QJsonObject::remove(const QString &key)
\sa insert(), remove(), QJsonValue
*/
QJsonValue QJsonObject::take(const QString &key)
{
return take(QStringView(key));
}
#endif
/*!
\overload
\since 5.14
*/
QJsonValue QJsonObject::take(QStringView key)
{
if (!o)
return QJsonValue(QJsonValue::Undefined);
@ -573,12 +637,23 @@ QJsonValue QJsonObject::take(const QString &key)
return v;
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns \c true if the object contains key \a key.
\sa insert(), remove(), take()
*/
bool QJsonObject::contains(const QString &key) const
{
return contains(QStringView(key));
}
#endif
/*!
\overload
\since 5.14
*/
bool QJsonObject::contains(QStringView key) const
{
if (!o)
return false;
@ -656,6 +731,7 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it)
return it;
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns an iterator pointing to the item with key \a key in the
map.
@ -664,6 +740,16 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it)
returns end().
*/
QJsonObject::iterator QJsonObject::find(const QString &key)
{
return find(QStringView(key));
}
#endif
/*!
\overload
\since 5.14
*/
QJsonObject::iterator QJsonObject::find(QStringView key)
{
bool keyExists = false;
int index = o ? o->indexOf(key, &keyExists) : 0;
@ -687,10 +773,18 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key)
return iterator(this, index);
}
#if QT_STRINGVIEW_LEVEL < 2
/*! \fn QJsonObject::const_iterator QJsonObject::find(const QString &key) const
\overload
*/
#endif
/*! \fn QJsonObject::const_iterator QJsonObject::find(QStringView key) const
\overload
\since 5.14
*/
/*! \fn QJsonObject::const_iterator QJsonObject::find(QLatin1String key) const
@ -698,6 +792,7 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key)
\since 5.7
*/
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns a const iterator pointing to the item with key \a key in the
map.
@ -706,6 +801,16 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key)
returns constEnd().
*/
QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
{
return constFind(QStringView(key));
}
#endif
/*!
\overload
\since 5.14
*/
QJsonObject::const_iterator QJsonObject::constFind(QStringView key) const
{
bool keyExists = false;
int index = o ? o->indexOf(key, &keyExists) : 0;

View File

@ -100,16 +100,26 @@ public:
inline int length() const { return size(); }
bool isEmpty() const;
#if QT_STRINGVIEW_LEVEL < 2
QJsonValue value(const QString &key) const;
QJsonValue value(QLatin1String key) const;
QJsonValue operator[] (const QString &key) const;
QJsonValue operator[] (QLatin1String key) const { return value(key); }
QJsonValueRef operator[] (const QString &key);
#endif
QJsonValue value(QStringView key) const;
QJsonValue value(QLatin1String key) const;
QJsonValue operator[] (QStringView key) const { return value(key); }
QJsonValue operator[] (QLatin1String key) const { return value(key); }
QJsonValueRef operator[] (QStringView key);
QJsonValueRef operator[] (QLatin1String key);
#if QT_STRINGVIEW_LEVEL < 2
void remove(const QString &key);
QJsonValue take(const QString &key);
bool contains(const QString &key) const;
#endif
void remove(QStringView key);
QJsonValue take(QStringView key);
bool contains(QStringView key) const;
bool contains(QLatin1String key) const;
bool operator==(const QJsonObject &other) const;
@ -218,13 +228,19 @@ public:
// more Qt
typedef iterator Iterator;
typedef const_iterator ConstIterator;
#if QT_STRINGVIEW_LEVEL < 2
iterator find(const QString &key);
iterator find(QLatin1String key);
const_iterator find(const QString &key) const { return constFind(key); }
const_iterator find(QLatin1String key) const { return constFind(key); }
const_iterator constFind(const QString &key) const;
const_iterator constFind(QLatin1String key) const;
iterator insert(const QString &key, const QJsonValue &value);
#endif
iterator find(QStringView key);
iterator find(QLatin1String key);
const_iterator find(QStringView key) const { return constFind(key); }
const_iterator find(QLatin1String key) const { return constFind(key); }
const_iterator constFind(QStringView key) const;
const_iterator constFind(QLatin1String key) const;
iterator insert(QStringView key, const QJsonValue &value);
// STL compatibility
typedef QJsonValue mapped_type;
@ -253,7 +269,7 @@ private:
QJsonValue valueAt(int i) const;
void setValueAt(int i, const QJsonValue &val);
void removeAt(int i);
iterator insertAt(int i, const QString &key, const QJsonValue &val, bool exists);
iterator insertAt(int i, QStringView key, const QJsonValue &val, bool exists);
QJsonPrivate::Data *d;
QJsonPrivate::Object *o;

View File

@ -694,6 +694,7 @@ QJsonObject QJsonValue::toObject() const
return toObject(QJsonObject());
}
#if QT_STRINGVIEW_LEVEL < 2
/*!
Returns a QJsonValue representing the value for the key \a key.
@ -707,6 +708,16 @@ QJsonObject QJsonValue::toObject() const
\sa QJsonValue, QJsonValue::isUndefined(), QJsonObject
*/
const QJsonValue QJsonValue::operator[](const QString &key) const
{
return (*this)[QStringView(key)];
}
#endif
/*!
\overload
\since 5.14
*/
const QJsonValue QJsonValue::operator[](QStringView key) const
{
if (!isObject())
return QJsonValue(QJsonValue::Undefined);

View File

@ -137,7 +137,10 @@ public:
QJsonObject toObject() const;
QJsonObject toObject(const QJsonObject &defaultValue) const;
#if QT_STRINGVIEW_LEVEL < 2
const QJsonValue operator[](const QString &key) const;
#endif
const QJsonValue operator[](QStringView key) const;
const QJsonValue operator[](QLatin1String key) const;
const QJsonValue operator[](int i) const;

View File

@ -436,6 +436,7 @@ void tst_QtJson::testObjectSimple()
object.insert("boolean", true);
QCOMPARE(object.value("boolean").toBool(), true);
QCOMPARE(object.value(QLatin1String("boolean")).toBool(), true);
QJsonObject object2 = object;
QStringList keys = object.keys();
QVERIFY2(keys.contains("number"), "key number not found");
@ -461,6 +462,23 @@ void tst_QtJson::testObjectSimple()
object.insert("string", QString::fromLatin1("foo"));
QVERIFY2(object.value(QLatin1String("string")).toString() != before, "value should have been updated");
// same tests again but with QStringView keys
object2.insert(QStringView(u"value"), value);
QCOMPARE(object2.value("value"), value);
size = object2.size();
object2.remove(QStringView(u"boolean"));
QCOMPARE(object2.size(), size - 1);
QVERIFY2(!object2.contains(QStringView(u"boolean")), "key boolean should have been removed");
taken = object2.take(QStringView(u"value"));
QCOMPARE(taken, value);
QVERIFY2(!object2.contains("value"), "key value should have been removed");
before = object2.value("string").toString();
object2.insert(QStringView(u"string"), QString::fromLatin1("foo"));
QVERIFY2(object2.value(QStringView(u"string")).toString() != before, "value should have been updated");
size = object.size();
QJsonObject subobject;
subobject.insert("number", 42);