Introduce Q{Json,Cbor}ValueConstRef
I screwed up when I wrote QCborValueRef by not having the ConstRef type. The code worked, but it wasn't const-correct, allowing you to write: const QCborArray &arr = something(); *arr.begin() = QCborArray(); This mistake was brought over to QJsonValue in Qt 6.0, so it has to be fixed for QJsonValue too. The actual fixes are in the next couple of commits. This change is believed to be binary-compatible: the Q{Json,Cbor}ValueRef classes continue to have the exact same size, except that they're now empty and have a new base class. They weren't trivial before this commit doesn't change that. [ChangeLog][Potentially Source-Incompatible Changes] The iterator classes for Qt's JSON and CBOR containers (array and map/object) had a const correctness issue which allowed a const_iterator to mutate the container being iterated on, even if that container was itself const. Qt 6.4 has a fix for this, but will cause compilation issues where QCborValueRef and QJsonValueRef were used where the correctness could be violated. To keep code compiling with both 6.3 and 6.4, either change to non-const iteration or replace the QxxxValueRef with a const QxxxValue reference. This change is binary-compatible. Change-Id: I5e52dc5b093c43a3b678fffd16b6063333765ae0 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
parent
9b8f064cd3
commit
04dc959d49
@ -288,6 +288,7 @@ inline QCborValue::QCborValue(QCborArray &&a)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
inline QCborArray QCborValueRef::toArray() const
|
inline QCborArray QCborValueRef::toArray() const
|
||||||
{
|
{
|
||||||
return concrete().toArray();
|
return concrete().toArray();
|
||||||
@ -297,6 +298,17 @@ inline QCborArray QCborValueRef::toArray(const QCborArray &a) const
|
|||||||
{
|
{
|
||||||
return concrete().toArray(a);
|
return concrete().toArray(a);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline QCborArray QCborValueConstRef::toArray() const
|
||||||
|
{
|
||||||
|
return concrete().toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QCborArray QCborValueConstRef::toArray(const QCborArray &a) const
|
||||||
|
{
|
||||||
|
return concrete().toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
Q_CORE_EXPORT size_t qHash(const QCborArray &array, size_t seed = 0);
|
Q_CORE_EXPORT size_t qHash(const QCborArray &array, size_t seed = 0);
|
||||||
|
|
||||||
|
@ -342,6 +342,7 @@ inline QCborValue::QCborValue(QCborMap &&m)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
inline QCborMap QCborValueRef::toMap() const
|
inline QCborMap QCborValueRef::toMap() const
|
||||||
{
|
{
|
||||||
return concrete().toMap();
|
return concrete().toMap();
|
||||||
@ -351,6 +352,17 @@ inline QCborMap QCborValueRef::toMap(const QCborMap &m) const
|
|||||||
{
|
{
|
||||||
return concrete().toMap(m);
|
return concrete().toMap(m);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline QCborMap QCborValueConstRef::toMap() const
|
||||||
|
{
|
||||||
|
return concrete().toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QCborMap QCborValueConstRef::toMap(const QCborMap &m) const
|
||||||
|
{
|
||||||
|
return concrete().toMap(m);
|
||||||
|
}
|
||||||
|
|
||||||
Q_CORE_EXPORT size_t qHash(const QCborMap &map, size_t seed = 0);
|
Q_CORE_EXPORT size_t qHash(const QCborMap &map, size_t seed = 0);
|
||||||
|
|
||||||
|
@ -2638,14 +2638,12 @@ Q_NEVER_INLINE void QCborValue::toCbor(QCborStreamWriter &writer, EncodingOption
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
void QCborValueRef::toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt)
|
void QCborValueRef::toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt)
|
||||||
{
|
{
|
||||||
concrete().toCbor(writer, opt);
|
concrete().toCbor(writer, opt);
|
||||||
}
|
}
|
||||||
void QCborValueRef::toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt) const
|
# endif
|
||||||
{
|
|
||||||
concrete().toCbor(writer, opt);
|
|
||||||
}
|
|
||||||
#endif // QT_CONFIG(cborstreamwriter)
|
#endif // QT_CONFIG(cborstreamwriter)
|
||||||
|
|
||||||
void QCborValueRef::assign(QCborValueRef that, const QCborValue &other)
|
void QCborValueRef::assign(QCborValueRef that, const QCborValue &other)
|
||||||
@ -2664,6 +2662,35 @@ void QCborValueRef::assign(QCborValueRef that, const QCborValueRef other)
|
|||||||
that = other.concrete();
|
that = other.concrete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QCborValue QCborValueConstRef::concrete(QCborValueConstRef self) noexcept
|
||||||
|
{
|
||||||
|
return self.d->valueAt(self.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
QCborValue::Type QCborValueConstRef::concreteType(QCborValueConstRef self) noexcept
|
||||||
|
{
|
||||||
|
return self.d->elements.at(self.i).type;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QCborValue QCborValueConstRef::operator[](const QString &key) const
|
||||||
|
{
|
||||||
|
const QCborValue item = d->valueAt(i);
|
||||||
|
return item[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
const QCborValue QCborValueConstRef::operator[](const QLatin1String key) const
|
||||||
|
{
|
||||||
|
const QCborValue item = d->valueAt(i);
|
||||||
|
return item[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
const QCborValue QCborValueConstRef::operator[](qint64 key) const
|
||||||
|
{
|
||||||
|
const QCborValue item = d->valueAt(i);
|
||||||
|
return item[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
QCborValue QCborValueRef::concrete(QCborValueRef self) noexcept
|
QCborValue QCborValueRef::concrete(QCborValueRef self) noexcept
|
||||||
{
|
{
|
||||||
return self.d->valueAt(self.i);
|
return self.d->valueAt(self.i);
|
||||||
@ -2690,8 +2717,7 @@ QCborValue::Type QCborValueRef::concreteType(QCborValueRef self) noexcept
|
|||||||
*/
|
*/
|
||||||
const QCborValue QCborValueRef::operator[](const QString &key) const
|
const QCborValue QCborValueRef::operator[](const QString &key) const
|
||||||
{
|
{
|
||||||
const QCborValue item = d->valueAt(i);
|
return QCborValueConstRef::operator[](key);
|
||||||
return item[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2712,8 +2738,7 @@ const QCborValue QCborValueRef::operator[](const QString &key) const
|
|||||||
*/
|
*/
|
||||||
const QCborValue QCborValueRef::operator[](QLatin1String key) const
|
const QCborValue QCborValueRef::operator[](QLatin1String key) const
|
||||||
{
|
{
|
||||||
const QCborValue item = d->valueAt(i);
|
return QCborValueConstRef::operator[](key);
|
||||||
return item[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2730,8 +2755,7 @@ const QCborValue QCborValueRef::operator[](QLatin1String key) const
|
|||||||
*/
|
*/
|
||||||
const QCborValue QCborValueRef::operator[](qint64 key) const
|
const QCborValue QCborValueRef::operator[](qint64 key) const
|
||||||
{
|
{
|
||||||
const QCborValue item = d->valueAt(i);
|
return QCborValueConstRef::operator[](key);
|
||||||
return item[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2922,7 +2946,7 @@ QCborValueRef QCborValueRef::operator[](qint64 key)
|
|||||||
Q_ASSERT(index < e.container->elements.size());
|
Q_ASSERT(index < e.container->elements.size());
|
||||||
return { e.container, index };
|
return { e.container, index };
|
||||||
}
|
}
|
||||||
|
#endif // < Qt 7
|
||||||
|
|
||||||
inline QCborArray::QCborArray(QCborContainerPrivate &dd) noexcept
|
inline QCborArray::QCborArray(QCborContainerPrivate &dd) noexcept
|
||||||
: d(&dd)
|
: d(&dd)
|
||||||
|
@ -330,11 +330,133 @@ private:
|
|||||||
};
|
};
|
||||||
Q_DECLARE_SHARED(QCborValue)
|
Q_DECLARE_SHARED(QCborValue)
|
||||||
|
|
||||||
class Q_CORE_EXPORT QCborValueRef
|
class QCborValueConstRef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
QCborValueConstRef(const QCborValueConstRef &) = default;
|
||||||
|
QCborValueConstRef &operator=(const QCborValueConstRef &) = delete;
|
||||||
operator QCborValue() const { return concrete(); }
|
operator QCborValue() const { return concrete(); }
|
||||||
|
|
||||||
|
QCborValue::Type type() const { return concreteType(*this); }
|
||||||
|
bool isInteger() const { return type() == QCborValue::Integer; }
|
||||||
|
bool isByteArray() const { return type() == QCborValue::ByteArray; }
|
||||||
|
bool isString() const { return type() == QCborValue::String; }
|
||||||
|
bool isArray() const { return type() == QCborValue::Array; }
|
||||||
|
bool isMap() const { return type() == QCborValue::Map; }
|
||||||
|
bool isTag() const { return concrete().isTag(); }
|
||||||
|
bool isFalse() const { return type() == QCborValue::False; }
|
||||||
|
bool isTrue() const { return type() == QCborValue::True; }
|
||||||
|
bool isBool() const { return isFalse() || isTrue(); }
|
||||||
|
bool isNull() const { return type() == QCborValue::Null; }
|
||||||
|
bool isUndefined() const { return type() == QCborValue::Undefined; }
|
||||||
|
bool isDouble() const { return type() == QCborValue::Double; }
|
||||||
|
bool isDateTime() const { return type() == QCborValue::DateTime; }
|
||||||
|
bool isUrl() const { return type() == QCborValue::Url; }
|
||||||
|
bool isRegularExpression() const { return type() == QCborValue::RegularExpression; }
|
||||||
|
bool isUuid() const { return type() == QCborValue::Uuid; }
|
||||||
|
bool isInvalid() const { return type() == QCborValue::Invalid; }
|
||||||
|
bool isContainer() const { return isMap() || isArray(); }
|
||||||
|
bool isSimpleType() const { return concrete().isSimpleType(); }
|
||||||
|
bool isSimpleType(QCborSimpleType st) const { return concrete().isSimpleType(st); }
|
||||||
|
|
||||||
|
QCborSimpleType toSimpleType(QCborSimpleType defaultValue = QCborSimpleType::Undefined) const
|
||||||
|
{
|
||||||
|
return concrete().toSimpleType(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
QCborTag tag(QCborTag defaultValue = QCborTag(-1)) const
|
||||||
|
{ return concrete().tag(defaultValue); }
|
||||||
|
QCborValue taggedValue(const QCborValue &defaultValue = QCborValue()) const
|
||||||
|
{ return concrete().taggedValue(defaultValue); }
|
||||||
|
|
||||||
|
qint64 toInteger(qint64 defaultValue = 0) const
|
||||||
|
{ return concrete().toInteger(defaultValue); }
|
||||||
|
bool toBool(bool defaultValue = false) const
|
||||||
|
{ return concrete().toBool(defaultValue); }
|
||||||
|
double toDouble(double defaultValue = 0) const
|
||||||
|
{ return concrete().toDouble(defaultValue); }
|
||||||
|
|
||||||
|
QByteArray toByteArray(const QByteArray &defaultValue = {}) const
|
||||||
|
{ return concrete().toByteArray(defaultValue); }
|
||||||
|
QString toString(const QString &defaultValue = {}) const
|
||||||
|
{ return concrete().toString(defaultValue); }
|
||||||
|
QDateTime toDateTime(const QDateTime &defaultValue = {}) const
|
||||||
|
{ return concrete().toDateTime(defaultValue); }
|
||||||
|
#ifndef QT_BOOTSTRAPPED
|
||||||
|
QUrl toUrl(const QUrl &defaultValue = {}) const
|
||||||
|
{ return concrete().toUrl(defaultValue); }
|
||||||
|
#endif
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const
|
||||||
|
{ return concrete().toRegularExpression(defaultValue); }
|
||||||
|
#endif
|
||||||
|
QUuid toUuid(const QUuid &defaultValue = {}) const
|
||||||
|
{ return concrete().toUuid(defaultValue); }
|
||||||
|
|
||||||
|
// only forward-declared, need split functions. Implemented in qcbor{array,map}.h
|
||||||
|
inline QCborArray toArray() const;
|
||||||
|
inline QCborArray toArray(const QCborArray &a) const;
|
||||||
|
inline QCborMap toMap() const;
|
||||||
|
inline QCborMap toMap(const QCborMap &m) const;
|
||||||
|
|
||||||
|
Q_CORE_EXPORT const QCborValue operator[](const QString &key) const;
|
||||||
|
Q_CORE_EXPORT const QCborValue operator[](QLatin1String key) const;
|
||||||
|
Q_CORE_EXPORT const QCborValue operator[](qint64 key) const;
|
||||||
|
|
||||||
|
int compare(const QCborValue &other) const
|
||||||
|
{ return concrete().compare(other); }
|
||||||
|
#if 0 && __has_include(<compare>)
|
||||||
|
std::strong_ordering operator<=>(const QCborValue &other) const
|
||||||
|
{
|
||||||
|
int c = compare(other);
|
||||||
|
if (c > 0) return std::strong_ordering::greater;
|
||||||
|
if (c == 0) return std::strong_ordering::equivalent;
|
||||||
|
return std::strong_ordering::less;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool operator==(const QCborValue &other) const
|
||||||
|
{ return compare(other) == 0; }
|
||||||
|
bool operator!=(const QCborValue &other) const
|
||||||
|
{ return !(*this == other); }
|
||||||
|
bool operator<(const QCborValue &other) const
|
||||||
|
{ return compare(other) < 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QVariant toVariant() const { return concrete().toVariant(); }
|
||||||
|
inline QJsonValue toJsonValue() const; // in qjsonvalue.h
|
||||||
|
|
||||||
|
#if QT_CONFIG(cborstreamwriter)
|
||||||
|
QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const
|
||||||
|
{ return concrete().toCbor(opt); }
|
||||||
|
void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const
|
||||||
|
{ return concrete().toCbor(writer, opt); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact) const
|
||||||
|
{ return concrete().toDiagnosticNotation(opt); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class QCborValue;
|
||||||
|
friend class QCborArray;
|
||||||
|
friend class QCborMap;
|
||||||
|
friend class QCborContainerPrivate;
|
||||||
|
|
||||||
|
QCborValue concrete() const noexcept { return concrete(*this); }
|
||||||
|
|
||||||
|
static Q_CORE_EXPORT QCborValue concrete(QCborValueConstRef that) noexcept;
|
||||||
|
static Q_CORE_EXPORT QCborValue::Type concreteType(QCborValueConstRef that) noexcept Q_DECL_PURE_FUNCTION;
|
||||||
|
|
||||||
|
constexpr QCborValueConstRef() : d(nullptr), i(0) {} // this will actually be invalid
|
||||||
|
constexpr QCborValueConstRef(QCborContainerPrivate *dd, qsizetype ii)
|
||||||
|
: d(dd), i(ii)
|
||||||
|
{}
|
||||||
|
QCborContainerPrivate *d;
|
||||||
|
qsizetype i;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QT6_ONLY(Q_CORE_EXPORT) QCborValueRef : public QCborValueConstRef
|
||||||
|
{
|
||||||
|
public:
|
||||||
QCborValueRef(const QCborValueRef &) noexcept = default;
|
QCborValueRef(const QCborValueRef &) noexcept = default;
|
||||||
QCborValueRef(QCborValueRef &&) noexcept = default;
|
QCborValueRef(QCborValueRef &&) noexcept = default;
|
||||||
QCborValueRef &operator=(const QCborValue &other)
|
QCborValueRef &operator=(const QCborValue &other)
|
||||||
@ -344,6 +466,15 @@ public:
|
|||||||
QCborValueRef &operator=(const QCborValueRef &other)
|
QCborValueRef &operator=(const QCborValueRef &other)
|
||||||
{ assign(*this, other); return *this; }
|
{ assign(*this, other); return *this; }
|
||||||
|
|
||||||
|
QT7_ONLY(Q_CORE_EXPORT) QCborValueRef operator[](qint64 key);
|
||||||
|
QT7_ONLY(Q_CORE_EXPORT) QCborValueRef operator[](QLatin1String key);
|
||||||
|
QT7_ONLY(Q_CORE_EXPORT) QCborValueRef operator[](const QString & key);
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
|
// retained for binary compatibility (due to the Q_CORE_EXPORT) because at
|
||||||
|
// least one compiler emits and exports all inlines in an exported class
|
||||||
|
|
||||||
|
operator QCborValue() const { return concrete(); }
|
||||||
QCborValue::Type type() const { return concreteType(); }
|
QCborValue::Type type() const { return concreteType(); }
|
||||||
bool isInteger() const { return type() == QCborValue::Integer; }
|
bool isInteger() const { return type() == QCborValue::Integer; }
|
||||||
bool isByteArray() const { return type() == QCborValue::ByteArray; }
|
bool isByteArray() const { return type() == QCborValue::ByteArray; }
|
||||||
@ -414,9 +545,6 @@ public:
|
|||||||
const QCborValue operator[](const QString &key) const;
|
const QCborValue operator[](const QString &key) const;
|
||||||
const QCborValue operator[](QLatin1String key) const;
|
const QCborValue operator[](QLatin1String key) const;
|
||||||
const QCborValue operator[](qint64 key) const;
|
const QCborValue operator[](qint64 key) const;
|
||||||
QCborValueRef operator[](qint64 key);
|
|
||||||
QCborValueRef operator[](QLatin1String key);
|
|
||||||
QCborValueRef operator[](const QString & key);
|
|
||||||
|
|
||||||
int compare(const QCborValue &other) const
|
int compare(const QCborValue &other) const
|
||||||
{ return concrete().compare(other); }
|
{ return concrete().compare(other); }
|
||||||
@ -440,32 +568,18 @@ public:
|
|||||||
QVariant toVariant() const { return concrete().toVariant(); }
|
QVariant toVariant() const { return concrete().toVariant(); }
|
||||||
QJsonValue toJsonValue() const;
|
QJsonValue toJsonValue() const;
|
||||||
|
|
||||||
// ### TEMPORARY
|
|
||||||
#if QT_CONFIG(cborstreamwriter)
|
#if QT_CONFIG(cborstreamwriter)
|
||||||
|
using QCborValueConstRef::toCbor;
|
||||||
QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation)
|
QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation)
|
||||||
{ return qAsConst(*this).toCbor(opt); }
|
{ return qAsConst(*this).toCbor(opt); }
|
||||||
QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const
|
|
||||||
{ return concrete().toCbor(opt); }
|
|
||||||
void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation);
|
void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation);
|
||||||
void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation) const;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using QCborValueConstRef::toDiagnosticNotation;
|
||||||
QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact)
|
QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact)
|
||||||
{ return qAsConst(*this).toDiagnosticNotation(opt); }
|
{ return qAsConst(*this).toDiagnosticNotation(opt); }
|
||||||
QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact) const
|
|
||||||
{ return concrete().toDiagnosticNotation(opt); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class QCborValue;
|
|
||||||
friend class QCborArray;
|
|
||||||
friend class QCborMap;
|
|
||||||
friend class QCborContainerPrivate;
|
|
||||||
friend class QCborValueRefPtr;
|
|
||||||
|
|
||||||
// static so we can pass this by value
|
|
||||||
static void assign(QCborValueRef that, const QCborValue &other);
|
|
||||||
static void assign(QCborValueRef that, QCborValue &&other);
|
|
||||||
static void assign(QCborValueRef that, const QCborValueRef other);
|
|
||||||
static QCborValue concrete(QCborValueRef that) noexcept;
|
static QCborValue concrete(QCborValueRef that) noexcept;
|
||||||
QCborValue concrete() const noexcept { return concrete(*this); }
|
QCborValue concrete() const noexcept { return concrete(*this); }
|
||||||
|
|
||||||
@ -473,13 +587,26 @@ private:
|
|||||||
QCborValue::Type concreteType() const noexcept { return concreteType(*this); }
|
QCborValue::Type concreteType() const noexcept { return concreteType(*this); }
|
||||||
|
|
||||||
// this will actually be invalid...
|
// this will actually be invalid...
|
||||||
constexpr QCborValueRef() : d(nullptr), i(0) {}
|
constexpr QCborValueRef() : QCborValueConstRef(nullptr, 0) {}
|
||||||
|
|
||||||
QCborValueRef(QCborContainerPrivate *dd, qsizetype ii)
|
QCborValueRef(QCborContainerPrivate *dd, qsizetype ii)
|
||||||
: d(dd), i(ii)
|
: QCborValueConstRef(dd, ii)
|
||||||
{}
|
{}
|
||||||
QCborContainerPrivate *d;
|
#else
|
||||||
qsizetype i;
|
private:
|
||||||
|
using QCborValueConstRef::QCborValueConstRef;
|
||||||
|
#endif // < Qt 7
|
||||||
|
|
||||||
|
friend class QCborValue;
|
||||||
|
friend class QCborArray;
|
||||||
|
friend class QCborMap;
|
||||||
|
friend class QCborContainerPrivate;
|
||||||
|
friend class QCborValueConstRef;
|
||||||
|
|
||||||
|
// static so we can pass this by value
|
||||||
|
QT7_ONLY(Q_CORE_EXPORT) static void assign(QCborValueRef that, const QCborValue &other);
|
||||||
|
QT7_ONLY(Q_CORE_EXPORT) static void assign(QCborValueRef that, QCborValue &&other);
|
||||||
|
QT7_ONLY(Q_CORE_EXPORT) static void assign(QCborValueRef that, const QCborValueRef other);
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_CORE_EXPORT size_t qHash(const QCborValue &value, size_t seed = 0);
|
Q_CORE_EXPORT size_t qHash(const QCborValue &value, size_t seed = 0);
|
||||||
|
@ -428,10 +428,12 @@ QJsonValue QCborValue::toJsonValue() const
|
|||||||
return QJsonPrivate::Value::fromTrustedCbor(simpleTypeString(type()));
|
return QJsonPrivate::Value::fromTrustedCbor(simpleTypeString(type()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
QJsonValue QCborValueRef::toJsonValue() const
|
QJsonValue QCborValueRef::toJsonValue() const
|
||||||
{
|
{
|
||||||
return qt_convertToJson(d, i);
|
return qt_convertToJson(d, i);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Recursively converts every \l QCborValue element in this array to JSON
|
Recursively converts every \l QCborValue element in this array to JSON
|
||||||
|
@ -283,6 +283,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class QJsonValue;
|
friend class QJsonValue;
|
||||||
friend class QJsonDocument;
|
friend class QJsonDocument;
|
||||||
|
friend class QJsonValueConstRef;
|
||||||
friend class QJsonValueRef;
|
friend class QJsonValueRef;
|
||||||
friend class QCborMap;
|
friend class QCborMap;
|
||||||
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
|
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
|
||||||
|
@ -934,27 +934,49 @@ QJsonValueRef &QJsonValueRef::operator =(const QJsonValueRef &ref)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant QJsonValueConstRef::toVariant() const
|
||||||
|
{
|
||||||
|
return concrete(*this).toVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonArray QJsonValueConstRef::toArray() const
|
||||||
|
{
|
||||||
|
return concrete(*this).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject QJsonValueConstRef::toObject() const
|
||||||
|
{
|
||||||
|
return concrete(*this).toObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonValue QJsonValueConstRef::concrete(QJsonValueConstRef self) noexcept
|
||||||
|
{
|
||||||
|
if (!self.is_object)
|
||||||
|
return self.a->at(self.index);
|
||||||
|
return self.o->valueAt(self.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
QVariant QJsonValueRef::toVariant() const
|
QVariant QJsonValueRef::toVariant() const
|
||||||
{
|
{
|
||||||
return toValue().toVariant();
|
return QJsonValueConstRef::toVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonArray QJsonValueRef::toArray() const
|
QJsonArray QJsonValueRef::toArray() const
|
||||||
{
|
{
|
||||||
return toValue().toArray();
|
return QJsonValueConstRef::toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject QJsonValueRef::toObject() const
|
QJsonObject QJsonValueRef::toObject() const
|
||||||
{
|
{
|
||||||
return toValue().toObject();
|
return QJsonValueConstRef::toObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonValue QJsonValueRef::toValue() const
|
QJsonValue QJsonValueRef::toValue() const
|
||||||
{
|
{
|
||||||
if (!is_object)
|
return concrete(*this);
|
||||||
return a->at(index);
|
|
||||||
return o->valueAt(index);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t qHash(const QJsonValue &value, size_t seed)
|
size_t qHash(const QJsonValue &value, size_t seed)
|
||||||
{
|
{
|
||||||
|
@ -150,20 +150,82 @@ private:
|
|||||||
static_assert(sizeof(QCborValue::Type) == sizeof(QJsonValue::Type));
|
static_assert(sizeof(QCborValue::Type) == sizeof(QJsonValue::Type));
|
||||||
};
|
};
|
||||||
|
|
||||||
class Q_CORE_EXPORT QJsonValueRef
|
Q_DECLARE_SHARED(QJsonValue)
|
||||||
|
|
||||||
|
class QJsonValueConstRef
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QJsonValueConstRef(const QJsonValueConstRef &) = default;
|
||||||
|
QJsonValueConstRef &operator=(const QJsonValueConstRef &) = delete;
|
||||||
|
inline operator QJsonValue() const { return concrete(*this); }
|
||||||
|
|
||||||
|
Q_CORE_EXPORT QVariant toVariant() const;
|
||||||
|
QJsonValue::Type type() const { return concrete(*this).type(); }
|
||||||
|
bool isNull() const { return type() == QJsonValue::Null; }
|
||||||
|
bool isBool() const { return type() == QJsonValue::Bool; }
|
||||||
|
bool isDouble() const { return type() == QJsonValue::Double; }
|
||||||
|
bool isString() const { return type() == QJsonValue::String; }
|
||||||
|
bool isArray() const { return type() == QJsonValue::Array; }
|
||||||
|
bool isObject() const { return type() == QJsonValue::Object; }
|
||||||
|
bool isUndefined() const { return type() == QJsonValue::Undefined; }
|
||||||
|
|
||||||
|
bool toBool(bool defaultValue = false) const
|
||||||
|
{ return concrete(*this).toBool(defaultValue); }
|
||||||
|
int toInt(int defaultValue = 0) const
|
||||||
|
{ return concrete(*this).toInt(defaultValue); }
|
||||||
|
qint64 toInteger(qint64 defaultValue = 0) const
|
||||||
|
{ return concrete(*this).toInteger(defaultValue); }
|
||||||
|
double toDouble(double defaultValue = 0) const
|
||||||
|
{ return concrete(*this).toDouble(defaultValue); }
|
||||||
|
QString toString(const QString &defaultValue = {}) const
|
||||||
|
{ return concrete(*this).toString(defaultValue); }
|
||||||
|
Q_CORE_EXPORT QJsonArray toArray() const;
|
||||||
|
Q_CORE_EXPORT QJsonObject toObject() const;
|
||||||
|
|
||||||
|
const QJsonValue operator[](QStringView key) const { return concrete(*this)[key]; }
|
||||||
|
const QJsonValue operator[](QLatin1String key) const { return concrete(*this)[key]; }
|
||||||
|
const QJsonValue operator[](qsizetype i) const { return concrete(*this)[i]; }
|
||||||
|
|
||||||
|
inline bool operator==(const QJsonValue &other) const { return concrete(*this) == other; }
|
||||||
|
inline bool operator!=(const QJsonValue &other) const { return concrete(*this) != other; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QJsonValueConstRef(QJsonArray *array, qsizetype idx)
|
||||||
|
: a(array), is_object(false), index(static_cast<quint64>(idx)) {}
|
||||||
|
QJsonValueConstRef(QJsonObject *object, qsizetype idx)
|
||||||
|
: o(object), is_object(true), index(static_cast<quint64>(idx)) {}
|
||||||
|
|
||||||
|
Q_CORE_EXPORT static QJsonValue concrete(QJsonValueConstRef self) noexcept;
|
||||||
|
|
||||||
|
union {
|
||||||
|
QJsonArray *a;
|
||||||
|
QJsonObject *o;
|
||||||
|
};
|
||||||
|
quint64 is_object : 1;
|
||||||
|
quint64 index : 63;
|
||||||
|
|
||||||
|
friend class QJsonArray;
|
||||||
|
friend class QJsonObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Q_CORE_EXPORT QJsonValueRef : public QJsonValueConstRef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QJsonValueRef(QJsonArray *array, qsizetype idx)
|
QJsonValueRef(QJsonArray *array, qsizetype idx)
|
||||||
: a(array), is_object(false), index(static_cast<quint64>(idx)) {}
|
: QJsonValueConstRef(array, idx) {}
|
||||||
QJsonValueRef(QJsonObject *object, qsizetype idx)
|
QJsonValueRef(QJsonObject *object, qsizetype idx)
|
||||||
: o(object), is_object(true), index(static_cast<quint64>(idx)) {}
|
: QJsonValueConstRef(object, idx) {}
|
||||||
|
|
||||||
QJsonValueRef(const QJsonValueRef &) = default;
|
QJsonValueRef(const QJsonValueRef &) = default;
|
||||||
|
|
||||||
inline operator QJsonValue() const { return toValue(); }
|
|
||||||
QJsonValueRef &operator = (const QJsonValue &val);
|
QJsonValueRef &operator = (const QJsonValue &val);
|
||||||
QJsonValueRef &operator = (const QJsonValueRef &val);
|
QJsonValueRef &operator = (const QJsonValueRef &val);
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||||
|
// retained for binary compatibility (due to the Q_CORE_EXPORT) because at
|
||||||
|
// least one compiler emits and exports all inlines in an exported class
|
||||||
|
|
||||||
|
operator QJsonValue() const { return toValue(); }
|
||||||
|
|
||||||
QVariant toVariant() const;
|
QVariant toVariant() const;
|
||||||
inline QJsonValue::Type type() const { return toValue().type(); }
|
inline QJsonValue::Type type() const { return toValue().type(); }
|
||||||
inline bool isNull() const { return type() == QJsonValue::Null; }
|
inline bool isNull() const { return type() == QJsonValue::Null; }
|
||||||
@ -191,19 +253,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonValue toValue() const;
|
QJsonValue toValue() const;
|
||||||
|
#endif // < Qt 7
|
||||||
union {
|
|
||||||
QJsonArray *a;
|
|
||||||
QJsonObject *o;
|
|
||||||
};
|
|
||||||
quint64 is_object : 1;
|
|
||||||
quint64 index : 63;
|
|
||||||
|
|
||||||
friend class QJsonArray;
|
|
||||||
friend class QJsonObject;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_SHARED(QJsonValue)
|
inline QJsonValue QCborValueConstRef::toJsonValue() const
|
||||||
|
{
|
||||||
|
return concrete().toJsonValue();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool operator==(const QJsonValueRef &lhs, const QJsonValueRef &rhs)
|
inline bool operator==(const QJsonValueRef &lhs, const QJsonValueRef &rhs)
|
||||||
{ return QJsonValue(lhs) == QJsonValue(rhs); }
|
{ return QJsonValue(lhs) == QJsonValue(rhs); }
|
||||||
|
@ -135,6 +135,8 @@ private slots:
|
|||||||
|
|
||||||
void cborValueRef_data();
|
void cborValueRef_data();
|
||||||
void cborValueRef();
|
void cborValueRef();
|
||||||
|
void cborValueConstRef_data() { cborValueRef_data(); }
|
||||||
|
void cborValueConstRef();
|
||||||
void cborValueRefMutatingArray_data() { cborValueRef_data(); }
|
void cborValueRefMutatingArray_data() { cborValueRef_data(); }
|
||||||
void cborValueRefMutatingArray();
|
void cborValueRefMutatingArray();
|
||||||
void cborValueRefMutatingMapIntKey_data() { cborValueRef_data(); }
|
void cborValueRefMutatingMapIntKey_data() { cborValueRef_data(); }
|
||||||
@ -2637,7 +2639,7 @@ void tst_QCborValue::cborValueRef_data()
|
|||||||
QTest::newRow("Tagged") << QCborValue::Tag << QCborValue(QCborKnownTags::Base64, QByteArray());
|
QTest::newRow("Tagged") << QCborValue::Tag << QCborValue(QCborKnownTags::Base64, QByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QCborValue::cborValueRef()
|
template <typename ValueRef> static void cborValueRef_template()
|
||||||
{
|
{
|
||||||
const QCborArray otherArray = {2};
|
const QCborArray otherArray = {2};
|
||||||
const QCborMap otherMap = { { 2, 21 } };
|
const QCborMap otherMap = { { 2, 21 } };
|
||||||
@ -2648,7 +2650,7 @@ void tst_QCborValue::cborValueRef()
|
|||||||
|
|
||||||
QFETCH(QCborValue, v);
|
QFETCH(QCborValue, v);
|
||||||
QCborArray a = { v };
|
QCborArray a = { v };
|
||||||
const QCborValueRef ref = a[0];
|
const ValueRef ref = a[0];
|
||||||
|
|
||||||
QCOMPARE(ref, v);
|
QCOMPARE(ref, v);
|
||||||
QVERIFY(ref.compare(v) == 0);
|
QVERIFY(ref.compare(v) == 0);
|
||||||
@ -2717,6 +2719,16 @@ void tst_QCborValue::cborValueRef()
|
|||||||
QCOMPARE(ref.toDiagnosticNotation(), v.toDiagnosticNotation());
|
QCOMPARE(ref.toDiagnosticNotation(), v.toDiagnosticNotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QCborValue::cborValueRef()
|
||||||
|
{
|
||||||
|
cborValueRef_template<QCborValueRef>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCborValue::cborValueConstRef()
|
||||||
|
{
|
||||||
|
cborValueRef_template<QCborValueConstRef>();
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QCborValue::cborValueRefMutatingArray()
|
void tst_QCborValue::cborValueRefMutatingArray()
|
||||||
{
|
{
|
||||||
// complements arrayMutation()
|
// complements arrayMutation()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user