diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2021-02-05 13:47:42 +0100 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2021-02-10 09:23:56 +0100 |
commit | 67f840a23295ad5d202005fc4913857d2da3edf5 (patch) | |
tree | 2b43604a22af683783f0e1a8befee6444b20b0f5 | |
parent | 8efcfef59f6e18aba734dadfab82d13f26bc69c7 (diff) | |
download | qtlocation-67f840a23295ad5d202005fc4913857d2da3edf5.tar.gz |
QtPositioning: refactor QGeoAreaMonitorInfo
The following changes were implemented for the class:
- Use QExplicitlySharedDataPointer for private d-ptr instead of
QSharedDataPointer, so that we can have more control over the sharing
behavior.
- Implement move-constructor and move-assignment operator.
The moved-from object is left in partially-formed state. Such
behavior is documented.
- Use Q_DECLARE_SHARED to declare the typeinfo as Q_RELOCATABLE_TYPE
and provide a free swap() overload.
- Provide a qHash() overload.
- Provide a QTest::toString() overload.
Task-number: QTBUG-90491
Change-Id: I8d89dff15d92e6643cf405700db73dc636d38b77
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r-- | src/positioning/qgeoareamonitorinfo.cpp | 63 | ||||
-rw-r--r-- | src/positioning/qgeoareamonitorinfo.h | 27 | ||||
-rw-r--r-- | tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp | 27 |
3 files changed, 112 insertions, 5 deletions
diff --git a/src/positioning/qgeoareamonitorinfo.cpp b/src/positioning/qgeoareamonitorinfo.cpp index 5d39dee2..fd0f3283 100644 --- a/src/positioning/qgeoareamonitorinfo.cpp +++ b/src/positioning/qgeoareamonitorinfo.cpp @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE \inmodule QtPositioning \since 5.2 \ingroup QtPositioning-positioning + \ingroup shared \brief The QGeoAreaMonitorInfo class describes the parameters of an area or region to be monitored for proximity. @@ -128,12 +129,25 @@ QGeoAreaMonitorInfo::QGeoAreaMonitorInfo(const QGeoAreaMonitorInfo &other) } /*! + \fn QGeoAreaMonitorInfo::QGeoAreaMonitorInfo(QGeoAreaMonitorInfo &&other) noexcept + \since 6.2 + + Constructs a QGeoAreaMonitorInfo object by moving from \a other. + + Note that a moved-from QGeoAreaMonitorInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! Destructor */ QGeoAreaMonitorInfo::~QGeoAreaMonitorInfo() { } +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QGeoAreaMonitorInfoPrivate) + /*! Assigns \a other to this QGeoAreaMonitorInfo object and returns a reference to this QGeoAreaMonitorInfo object. @@ -145,6 +159,18 @@ QGeoAreaMonitorInfo &QGeoAreaMonitorInfo::operator=(const QGeoAreaMonitorInfo &o } /*! + \fn QGeoAreaMonitorInfo &QGeoAreaMonitorInfo::operator=(QGeoAreaMonitorInfo &&other) noexcept + \since 6.2 + + Move-assigns \a other to this QGeoAreaMonitorInfo object and returns a + reference to this QGeoAreaMonitorInfo object. + + Note that a moved-from QGeoAreaMonitorInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! Returns true if all of this object's values are the same as those of \a other. */ @@ -181,8 +207,10 @@ QString QGeoAreaMonitorInfo::name() const */ void QGeoAreaMonitorInfo::setName(const QString &name) { - if (d->name != name) + if (d->name != name) { + d.detach(); d->name = name; + } } /*! @@ -223,6 +251,7 @@ QGeoShape QGeoAreaMonitorInfo::area() const */ void QGeoAreaMonitorInfo::setArea(const QGeoShape &newShape) { + d.detach(); d->shape = newShape; } @@ -249,6 +278,7 @@ QDateTime QGeoAreaMonitorInfo::expiration() const */ void QGeoAreaMonitorInfo::setExpiration(const QDateTime &expiry) { + d.detach(); d->expiry = expiry; } @@ -281,6 +311,7 @@ bool QGeoAreaMonitorInfo::isPersistent() const */ void QGeoAreaMonitorInfo::setPersistent(bool isPersistent) { + d.detach(); d->persistent = isPersistent; } @@ -302,9 +333,21 @@ QVariantMap QGeoAreaMonitorInfo::notificationParameters() const */ void QGeoAreaMonitorInfo::setNotificationParameters(const QVariantMap ¶meters) { + d.detach(); d->notificationParameters = parameters; } +/*! + \internal +*/ +void QGeoAreaMonitorInfo::detach() +{ + if (d) + d.detach(); + else + d = new QGeoAreaMonitorInfoPrivate; +} + #ifndef QT_NO_DATASTREAM /*! @@ -376,4 +419,22 @@ QDebug operator<<(QDebug dbg, const QGeoAreaMonitorInfo &monitor) #endif +size_t qHash(const QGeoAreaMonitorInfo &key, size_t seed) noexcept +{ + return qHashMulti(seed, key.d->uid); +} + +namespace QTest +{ + +char *toString(const QGeoAreaMonitorInfo &info) +{ + QString result; + QDebug dbg(&result); + dbg << info; + return qstrdup(qPrintable(result)); +} + +} // namespace QTest + QT_END_NAMESPACE diff --git a/src/positioning/qgeoareamonitorinfo.h b/src/positioning/qgeoareamonitorinfo.h index ae65d2c7..1374ebdf 100644 --- a/src/positioning/qgeoareamonitorinfo.h +++ b/src/positioning/qgeoareamonitorinfo.h @@ -42,7 +42,8 @@ #include <QtPositioning/QGeoCoordinate> #include <QtPositioning/QGeoShape> -#include <QtCore/QSharedDataPointer> +#include <QtCore/QExplicitlySharedDataPointer> +#include <QtCore/QMetaType> #include <QtCore/QVariantMap> QT_BEGIN_NAMESPACE @@ -55,15 +56,27 @@ Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &, const QGeoAreaMonito Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &, QGeoAreaMonitorInfo &); #endif +Q_POSITIONING_EXPORT size_t qHash(const QGeoAreaMonitorInfo &key, size_t seed = 0) noexcept; +namespace QTest +{ +Q_POSITIONING_EXPORT char *toString(const QGeoAreaMonitorInfo &info); +} // namespace QTest + class QGeoAreaMonitorInfoPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QGeoAreaMonitorInfoPrivate, Q_POSITIONING_EXPORT) + class Q_POSITIONING_EXPORT QGeoAreaMonitorInfo { public: explicit QGeoAreaMonitorInfo(const QString &name = QString()); QGeoAreaMonitorInfo(const QGeoAreaMonitorInfo &other); + QGeoAreaMonitorInfo(QGeoAreaMonitorInfo &&other) noexcept = default; ~QGeoAreaMonitorInfo(); QGeoAreaMonitorInfo &operator=(const QGeoAreaMonitorInfo &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QGeoAreaMonitorInfo) + + void swap(QGeoAreaMonitorInfo &other) noexcept { d.swap(other.d); } bool operator==(const QGeoAreaMonitorInfo &other) const; bool operator!=(const QGeoAreaMonitorInfo &other) const; @@ -85,19 +98,29 @@ public: QVariantMap notificationParameters() const; void setNotificationParameters(const QVariantMap ¶meters); + + void detach(); + private: - QSharedDataPointer<QGeoAreaMonitorInfoPrivate> d; + QExplicitlySharedDataPointer<QGeoAreaMonitorInfoPrivate> d; + friend class QGeoAreaMonitorInfoPrivate; #ifndef QT_NO_DATASTREAM friend Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &, const QGeoAreaMonitorInfo &); friend Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &, QGeoAreaMonitorInfo &); #endif + friend Q_POSITIONING_EXPORT size_t qHash(const QGeoAreaMonitorInfo &key, size_t seed) noexcept; + friend Q_POSITIONING_EXPORT char *QTest::toString(const QGeoAreaMonitorInfo& info); }; +Q_DECLARE_SHARED(QGeoAreaMonitorInfo) + #ifndef QT_NO_DEBUG_STREAM Q_POSITIONING_EXPORT QDebug operator<<(QDebug, const QGeoAreaMonitorInfo &); #endif QT_END_NAMESPACE +Q_DECLARE_METATYPE(QGeoAreaMonitorInfo) + #endif // QGEOAREAMONITORINFO_H diff --git a/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp b/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp index 914b35bd..16fe2149 100644 --- a/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp +++ b/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp @@ -52,8 +52,6 @@ QT_USE_NAMESPACE #define UPDATE_INTERVAL 200 -Q_DECLARE_METATYPE(QGeoAreaMonitorInfo) - QString tst_qgeoareamonitorinfo_debug; void tst_qgeoareamonitorinfo_messageHandler(QtMsgType type, @@ -237,6 +235,31 @@ private slots: delete obj; } + void tst_monitor_move_semantics() + { + QGeoAreaMonitorInfo info1("test"); + info1.setArea(QGeoCircle(QGeoCoordinate(1.0, 1.0), 100)); + info1.setExpiration(QDateTime::currentDateTimeUtc()); + QGeoAreaMonitorInfo infoCopy(info1); + + QGeoAreaMonitorInfo info2(std::move(info1)); + QCOMPARE(info2, infoCopy); + + QGeoAreaMonitorInfo info3; + info3.setName("name"); + info3.setArea(QGeoRectangle(QGeoCoordinate(1, 2), QGeoCoordinate(2, 1))); + info3.setPersistent(true); + infoCopy = info3; + + // check that (move)assigning to the moved-from object is ok + info1 = std::move(info3); + QCOMPARE(info1, infoCopy); + + // The moved-from object info3 will go out of scope and will be + // destroyed here, so we also implicitly check that moved-from object's + // destructor is called without any issues. + } + void tst_monitorValid() { QGeoAreaMonitorInfo mon; |