summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-09-10 18:36:27 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-09-14 12:41:00 +0200
commit721116de309f1933fad788fe4272c0d5c12b9909 (patch)
tree8cdd34d2f1c8cffbb31b05e448fbb7494082ad6b
parentcdb9ffd7e1e075a5fafb1477e2e87bef0b3fa49d (diff)
Add QVariantRef, QVariantPointer, QVariantConstPointer
Change-Id: Ia329265826ab2f76e77ac14bb8d8e415a1b41dd6 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/corelib/kernel/qvariant.cpp109
-rw-r--r--src/corelib/kernel/qvariant.h49
2 files changed, 158 insertions, 0 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index bfeee901da..d0a548bc74 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2958,4 +2958,113 @@ QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::opera
return const_iterator(impl, new QAtomicInt(0));
}
+/*!
+ \class QVariantRef
+ \since 6.0
+ \inmodule QtCore
+ \brief The QVariantRef acts as a non-const reference to a QVariant.
+
+ As the generic iterators don't actually instantiate a QVariant on each
+ step, they cannot return a reference to one from operator*(). QVariantRef
+ provides the same functionality as an actual reference to a QVariant would,
+ but is backed by a pointer given as template parameter. The template is
+ implemented for pointers of type QSequentialIterator and
+ QAssociativeIterator.
+*/
+
+/*!
+ \fn QVariantRef::QVariantRef(const Pointer *pointer)
+
+ Creates a QVariantRef from an \a pointer.
+ */
+
+/*!
+ \fn QVariantRef &QVariantRef::operator=(const QVariantRef &value)
+
+ Assigns a new \a value to the value pointed to by the pointer this
+ QVariantRef refers to.
+ */
+
+/*!
+ \fn QVariantRef &QVariantRef::operator=(QVariantRef &&value)
+
+ Assigns a new \a value to the value pointed to by the pointer this
+ QVariantRef refers to.
+*/
+
+/*!
+ \fn void swap(QVariantRef a, QVariantRef b)
+
+ Swaps the values pointed to by the pointers the QVariantRefs
+ \a a and \a b refer to.
+*/
+
+/*!
+ \class QVariantConstPointer
+ \since 6.0
+ \inmodule QtCore
+ \brief Emulated const pointer to QVariant based on a pointer
+
+ QVariantConstPointer wraps a QVariant and returns it from its operator*().
+ This makes it suitable as replacement for an actual const pointer. We cannot
+ return an actual const pointer from generic iterators as the iterators don't
+ hold an actual QVariant.
+*/
+
+/*!
+ Constructs a QVariantConstPointer from a \a variant.
+ */
+QVariantConstPointer::QVariantConstPointer(QVariant variant)
+ : m_variant(std::move(variant))
+{
+}
+
+/*!
+ Dereferences the QVariantConstPointer to retrieve its internal QVariant.
+ */
+QVariant QVariantConstPointer::operator*() const
+{
+ return m_variant;
+}
+
+/*!
+ Returns a const pointer to the QVariant, conforming to the
+ conventions for operator->().
+ */
+const QVariant *QVariantConstPointer::operator->() const
+{
+ return &m_variant;
+}
+
+/*!
+ \class QVariantPointer
+ \since 6.0
+ \inmodule QtCore
+ \brief Emulated pointer to QVariant based on a pointer
+
+ QVariantConstPointer wraps a pointer and returns QVariantRef to it from its
+ operator*(). This makes it suitable as replacement for an actual pointer. We
+ cannot return an actual pointer from generic iterators as the iterators don't
+ hold an actual QVariant.
+*/
+
+/*!
+ \fn QVariantPointer::QVariantPointer(const Pointer *pointer)
+
+ Constructs a QVariantPointer from the given \a pointer.
+ */
+
+/*!
+ \fn QVariantRef QVariantPointer::operator*() const
+
+ Dereferences the QVariantPointer to a QVariantRef.
+ */
+
+/*!
+ \fn Pointer QVariantPointer::operator->() const
+
+ Dereferences and returns the pointer. The pointer is expected to also
+ implement operator->().
+ */
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index ad766c9a8e..796dd80fd7 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -662,6 +662,55 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant::Type);
#endif
+template<typename Pointer>
+class Q_CORE_EXPORT QVariantRef
+{
+private:
+ const Pointer *m_pointer = nullptr;
+
+public:
+ explicit QVariantRef(const Pointer *reference) : m_pointer(reference) {}
+ QVariantRef(const QVariantRef &) = default;
+ QVariantRef(QVariantRef &&) = default;
+ ~QVariantRef() = default;
+
+ operator QVariant() const;
+ QVariantRef &operator=(const QVariant &value);
+ QVariantRef &operator=(const QVariantRef &value) { return operator=(QVariant(value)); }
+ QVariantRef &operator=(QVariantRef &&value) { return operator=(QVariant(value)); }
+
+ friend void swap(QVariantRef a, QVariantRef b)
+ {
+ QVariant tmp = a;
+ a = b;
+ b = std::move(tmp);
+ }
+};
+
+class Q_CORE_EXPORT QVariantConstPointer
+{
+private:
+ QVariant m_variant;
+
+public:
+ explicit QVariantConstPointer(QVariant variant);
+
+ QVariant operator*() const;
+ const QVariant *operator->() const;
+};
+
+template<typename Pointer>
+class Q_CORE_EXPORT QVariantPointer
+{
+private:
+ const Pointer *m_pointer = nullptr;
+
+public:
+ explicit QVariantPointer(const Pointer *pointer) : m_pointer(pointer) {}
+ QVariantRef<Pointer> operator*() const { return QVariantRef<Pointer>(m_pointer); }
+ Pointer operator->() const { return *m_pointer; }
+};
+
QT_END_NAMESPACE
#endif // QVARIANT_H