diff options
author | Marc Mutz <marc.mutz@qt.io> | 2023-01-12 11:33:30 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2023-01-13 21:07:18 +0100 |
commit | ce104cac500096734a94e6d132e342d07d7e8af0 (patch) | |
tree | 0d81acb3df72835bd3db739f7be735e62f197f23 /src | |
parent | 36619181fb0e507d4a092d74d7ad31c513ddaead (diff) |
QPermission: replace T data<T>() with std::optional<T> value<T>()
As discussed in API review, the default-constructed T() returned from
a mismatched data<T>() call is indistinguishable from a real T with
default state.
To make them distinguishable, return optional<T>. Call the new
function value<T>(), mimicking QVariant::value<T>(), and suggested in
API review, because data() is usually used to return raw pointers, not
values.
Remove the qWarning() on requestedType and actualType mismatch, as the
new function can be used in std::get_if/dynamic_cast-like if-then-else
chains, in which failure is part of the normal operation, and a
warning message misplaced:
if (auto loc = perm.value<QLocationPermission>())
~~~ use *loc ~~~
else if (auto con = perm.value<QContactsPermission>())
~~~ use *con ~~~
~~~ etc ~~~
Pick-to: 6.5
Change-Id: I799a58e930307323ebce8f9ac50a42455e9c017f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qpermissions.cpp | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qpermissions.h | 7 | ||||
-rw-r--r-- | src/corelib/kernel/qpermissions_android.cpp | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qpermissions_wasm.cpp | 2 | ||||
-rw-r--r-- | src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm | 6 |
5 files changed, 18 insertions, 21 deletions
diff --git a/src/corelib/kernel/qpermissions.cpp b/src/corelib/kernel/qpermissions.cpp index 3f97154921..e67b50c10b 100644 --- a/src/corelib/kernel/qpermissions.cpp +++ b/src/corelib/kernel/qpermissions.cpp @@ -211,8 +211,8 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg); { if (permission.status() != Qt::PermissionStatus:Granted) return; - auto locationPermission = permission.data<QLocationPermission>(); - if (locationPermission.accuracy() != QLocationPermission::Precise) + auto locationPermission = permission.value<QLocationPermission>(); + if (!locationPermission || locationPermission->accuracy() != QLocationPermission::Precise) return; updatePreciseLocation(); } @@ -243,13 +243,12 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg); */ /*! - \fn template <typename T, if_permission<T>> T QPermission::data() const + \fn template <typename T, if_permission<T>> std::optional<T> QPermission::value() const - Returns the \l{typed permission} of type \c T. + Returns the \l{typed permission} of type \c T, or \c{std::nullopt} if this + QPermission object doesn't contain one. - If the type doesn't match the type that was originally used to request the - permission, returns a default-constructed \c T. Use type() for dynamically - choosing which typed permission to request. + Use type() for dynamically choosing which typed permission to request. This function participates in overload resolution only if \c T is one of the \l{typed permission} classes: @@ -273,11 +272,8 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg); const void *QPermission::data(QMetaType requestedType) const { const auto actualType = type(); - if (requestedType != actualType) { - qCWarning(lcPermissions, "Cannot convert from %s to %s", - actualType.name(), requestedType.name()); + if (requestedType != actualType) return nullptr; - } return m_data.data(); } diff --git a/src/corelib/kernel/qpermissions.h b/src/corelib/kernel/qpermissions.h index 9c47df3eb1..7f56e9625e 100644 --- a/src/corelib/kernel/qpermissions.h +++ b/src/corelib/kernel/qpermissions.h @@ -16,6 +16,8 @@ #include <QtCore/qtypeinfo.h> #include <QtCore/qmetatype.h> +#include <optional> + #if !defined(Q_QDOC) QT_REQUIRE_CONFIG(permissions); #endif @@ -52,12 +54,11 @@ public: QMetaType type() const { return m_data.metaType(); } template <typename T, if_permission<T> = true> - T data() const + std::optional<T> value() const { if (auto p = data(QMetaType::fromType<T>())) return *static_cast<const T *>(p); - else - return T{}; + return std::nullopt; } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/corelib/kernel/qpermissions_android.cpp b/src/corelib/kernel/qpermissions_android.cpp index 9b3aa07db7..a0899ab673 100644 --- a/src/corelib/kernel/qpermissions_android.cpp +++ b/src/corelib/kernel/qpermissions_android.cpp @@ -53,7 +53,7 @@ static QStringList nativeStringsFromPermission(const QPermission &permission) { const auto id = permission.type().id(); if (id == qMetaTypeId<QLocationPermission>()) { - return nativeLocationPermission(permission.data<QLocationPermission>()); + return nativeLocationPermission(*permission.value<QLocationPermission>()); } else if (id == qMetaTypeId<QCameraPermission>()) { return { u"android.permission.CAMERA"_s }; } else if (id == qMetaTypeId<QMicrophonePermission>()) { @@ -63,12 +63,12 @@ static QStringList nativeStringsFromPermission(const QPermission &permission) return { u"android.permission.BLUETOOTH"_s }; } else if (id == qMetaTypeId<QContactsPermission>()) { const auto readContactsString = u"android.permission.READ_CONTACTS"_s; - if (!permission.data<QContactsPermission>().isReadWrite()) + if (!permission.value<QContactsPermission>()->isReadWrite()) return { readContactsString }; return { readContactsString, u"android.permission.WRITE_CONTACTS"_s }; } else if (id == qMetaTypeId<QCalendarPermission>()) { const auto readContactsString = u"android.permission.READ_CALENDAR"_s; - if (!permission.data<QCalendarPermission>().isReadWrite()) + if (!permission.value<QCalendarPermission>()->isReadWrite()) return { readContactsString }; return { readContactsString, u"android.permission.WRITE_CALENDAR"_s }; } diff --git a/src/corelib/kernel/qpermissions_wasm.cpp b/src/corelib/kernel/qpermissions_wasm.cpp index 60e2def853..175fc89dd0 100644 --- a/src/corelib/kernel/qpermissions_wasm.cpp +++ b/src/corelib/kernel/qpermissions_wasm.cpp @@ -216,7 +216,7 @@ namespace Q_ASSERT(!geolocation.isNull()); const auto &permission = geolocationRequestQueue->front().first; - const auto &locationPermission = permission.data<QLocationPermission>(); + const auto locationPermission = *permission.value<QLocationPermission>(); const bool highAccuracy = locationPermission.accuracy() == QLocationPermission::Precise; val options = val::object(); diff --git a/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm b/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm index cf27a9e837..39bae8cccb 100644 --- a/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm +++ b/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm @@ -55,7 +55,7 @@ struct PermissionRequest - (Qt::PermissionStatus)checkPermission:(QPermission)permission { - const auto locationPermission = permission.data<QLocationPermission>(); + const auto locationPermission = *permission.value<QLocationPermission>(); auto status = [self authorizationStatus:locationPermission]; if (status != Qt::PermissionStatus::Granted) @@ -118,7 +118,7 @@ struct PermissionRequest - (QStringList)usageDescriptionsFor:(QPermission)permission { QStringList usageDescriptions = { "NSLocationWhenInUseUsageDescription" }; - const auto locationPermission = permission.data<QLocationPermission>(); + const auto locationPermission = *permission.value<QLocationPermission>(); if (locationPermission.availability() == QLocationPermission::Always) usageDescriptions << "NSLocationAlwaysUsageDescription"; return usageDescriptions; @@ -150,7 +150,7 @@ struct PermissionRequest self.manager.delegate = self; } - const auto locationPermission = permission.data<QLocationPermission>(); + const auto locationPermission = *permission.value<QLocationPermission>(); switch (locationPermission.availability()) { case QLocationPermission::WhenInUse: // The documentation specifies that requestWhenInUseAuthorization can |