summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-02-05 13:47:42 +0100
committerIvan Solovev <ivan.solovev@qt.io>2021-02-10 09:23:56 +0100
commit67f840a23295ad5d202005fc4913857d2da3edf5 (patch)
tree2b43604a22af683783f0e1a8befee6444b20b0f5
parent8efcfef59f6e18aba734dadfab82d13f26bc69c7 (diff)
downloadqtlocation-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.cpp63
-rw-r--r--src/positioning/qgeoareamonitorinfo.h27
-rw-r--r--tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp27
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 &parameters)
{
+ 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 &parameters);
+
+ 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;