diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2021-11-27 10:29:35 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-02-15 17:00:05 -0800 |
commit | 705ea62f9e08730793adc7f6cec753c88e66ac4e (patch) | |
tree | a33dca0c92930c6a061ce228b2f8c0595b469f5f /src/corelib/serialization/qjsonobject.h | |
parent | a747ab0b72cac1bd9b666bdc27d2f40d900f7e9d (diff) |
QJsonValueConstRef: prepare for Qt 7
Instead of storing a pointer to the QJsonArray or QJsonObject (like the
Qt 4 & pre-5.15 versions did), do like QCborValueConstRef and store the
pointer to the QCborContainerPrivate.
Unlike QCborValueRef, we must keep the is_object bit because of API
behavior that assigning an Undefined to an object reference deletes it
from the container. I've chosen to use size_t instead of qsizetype for
this because then we don't lose any bits of the index. Therefore, the
index in the case of objects is stored as pair count (like before),
different from QCborValueRef which stores the actual index in the
QCborContainerPrivate.
It's the LSB (on little-endian architectures) so the calculation of
2 * index + 1 is the actual value stored in memory or in the
register. Unfortunately, right now, both Clang and GCC don't realize
this and generate unnecessary instructions. Clang:
0000000000000000 <QJsonValueConstRef::concreteType(QJsonValueConstRef)>:
0: mov %rsi,%rax
3: shr %rax
6: mov %rsi,%rcx
9: or $0x1,%rcx
d: test $0x1,%sil
11: cmove %rax,%rcx
[GCC code is identical, except it uses an AND instead of TEST]
That OR at offset 9 is a no-op because it sets a bit that is already set
in those conditions. At least they don't do unnecessary shifts.
Change-Id: I89446ea06b5742efb194fffd16bb7aadb6a9b341
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Diffstat (limited to 'src/corelib/serialization/qjsonobject.h')
-rw-r--r-- | src/corelib/serialization/qjsonobject.h | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index 1389f7b472..573d526dff 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -136,12 +136,11 @@ public: constexpr iterator(const iterator &other) = default; iterator &operator=(const iterator &other) { - item.o = other.item.o; - item.index = other.item.index; + item.rebind(other.item); return *this; } - inline QString key() const { return item.o->keyAt(item.index); } + inline QString key() const { return item.objectKey(); } inline QJsonValueRef value() const { return item; } inline QJsonValueRef operator*() const { return item; } inline const QJsonValueConstRef *operator->() const { return &item; } @@ -149,12 +148,12 @@ public: inline QJsonValueRef operator[](qsizetype j) const { return *(*this + j); } inline bool operator==(const iterator &other) const - { return item.o == other.item.o && item.index == other.item.index; } + { return item.d == other.item.d && item.index == other.item.index; } inline bool operator!=(const iterator &other) const { return !(*this == other); } bool operator<(const iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index < other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } bool operator<=(const iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index <= other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } bool operator>(const iterator& other) const { return !(*this <= other); } bool operator>=(const iterator& other) const { return !(*this < other); } @@ -170,12 +169,12 @@ public: public: inline bool operator==(const const_iterator &other) const - { return item.o == other.item.o && item.index == other.item.index; } + { return item.d == other.item.d && item.index == other.item.index; } inline bool operator!=(const const_iterator &other) const { return !(*this == other); } bool operator<(const const_iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index < other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } bool operator<=(const const_iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index <= other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } bool operator>(const const_iterator& other) const { return !(*this <= other); } bool operator>=(const const_iterator& other) const { return !(*this < other); } }; @@ -202,24 +201,23 @@ public: constexpr const_iterator(const const_iterator &other) = default; const_iterator &operator=(const const_iterator &other) { - item.o = other.item.o; - item.index = other.item.index; + item.rebind(other.item); return *this; } - inline QString key() const { return item.o->keyAt(item.index); } + inline QString key() const { return item.objectKey(); } inline QJsonValueConstRef value() const { return item; } inline const QJsonValueConstRef operator*() const { return item; } inline const QJsonValueConstRef *operator->() const { return &item; } inline QJsonValueConstRef operator[](qsizetype j) const { return *(*this + j); } inline bool operator==(const const_iterator &other) const - { return item.o == other.item.o && item.index == other.item.index; } + { return item.d == other.item.d && item.index == other.item.index; } inline bool operator!=(const const_iterator &other) const { return !(*this == other); } bool operator<(const const_iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index < other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } bool operator<=(const const_iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index <= other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } bool operator>(const const_iterator& other) const { return !(*this <= other); } bool operator>=(const const_iterator& other) const { return !(*this < other); } @@ -234,12 +232,12 @@ public: qsizetype operator-(const_iterator j) const { return item.index - j.item.index; } inline bool operator==(const iterator &other) const - { return item.o == other.item.o && item.index == other.item.index; } + { return item.d == other.item.d && item.index == other.item.index; } inline bool operator!=(const iterator &other) const { return !(*this == other); } bool operator<(const iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index < other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index < other.item.index; } bool operator<=(const iterator& other) const - { Q_ASSERT(item.o == other.item.o); return item.index <= other.item.index; } + { Q_ASSERT(item.d == other.item.d); return item.index <= other.item.index; } bool operator>(const iterator& other) const { return !(*this <= other); } bool operator>=(const iterator& other) const { return !(*this < other); } }; @@ -300,8 +298,8 @@ private: template <typename T> const_iterator constFindImpl(T key) const; template <typename T> iterator insertImpl(T key, const QJsonValue &value); - QString keyAt(qsizetype i) const; #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) + QString keyAt(qsizetype i) const; QJsonValue valueAt(qsizetype i) const; void setValueAt(qsizetype i, const QJsonValue &val); #endif @@ -313,6 +311,12 @@ private: Q_DECLARE_SHARED(QJsonObject) +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) +inline QJsonValueConstRef::QJsonValueConstRef(QJsonObject *o, qsizetype idx) + : d(o->o.data()), is_object(true), index(idx) +{} +#endif + Q_CORE_EXPORT size_t qHash(const QJsonObject &object, size_t seed = 0); #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) |