diff --git a/src/corelib/kernel/qpermissions.cpp b/src/corelib/kernel/qpermissions.cpp index 0b6b2604e1a..12224636ff3 100644 --- a/src/corelib/kernel/qpermissions.cpp +++ b/src/corelib/kernel/qpermissions.cpp @@ -281,14 +281,17 @@ const void *QPermission::data(QMetaType requestedType) const return m_data.data(); } - - -#define QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(ClassName) \ - ClassName::ClassName() : d(new ClassName##Private) {} \ +#define QT_PERMISSION_IMPL_COMMON(ClassName) \ + /* Class##Private is unused until we need it: */ \ + static_assert(sizeof(ClassName) == sizeof(void*), \ + "You have added too many members to " #ClassName "::ShortData. " \ + "Decrease their size or switch to using a d-pointer."); \ ClassName::ClassName(const ClassName &other) noexcept = default; \ - ClassName::ClassName(ClassName &&other) noexcept = default; \ - ClassName::~ClassName() noexcept = default; \ - ClassName &ClassName::operator=(const ClassName &other) noexcept = default; + ClassName::~ClassName() = default; \ + ClassName &ClassName::operator=(const ClassName &other) noexcept = default; \ + ClassName::ClassName() \ + /* impl supplied by caller */ + /*! \class QCameraPermission @@ -309,8 +312,10 @@ const void *QPermission::data(QMetaType requestedType) const \include permissions.qdocinc permission-metadata */ -class QCameraPermissionPrivate : public QSharedData {}; -QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QCameraPermission) + +QT_PERMISSION_IMPL_COMMON(QCameraPermission) + : u{} // stateless, atm +{} /*! \class QMicrophonePermission @@ -331,8 +336,10 @@ QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QCameraPermission) \include permissions.qdocinc permission-metadata */ -class QMicrophonePermissionPrivate : public QSharedData {}; -QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QMicrophonePermission) + +QT_PERMISSION_IMPL_COMMON(QMicrophonePermission) + : u{} // stateless, atm +{} /*! \class QBluetoothPermission @@ -353,8 +360,10 @@ QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QMicrophonePermission) \include permissions.qdocinc permission-metadata */ -class QBluetoothPermissionPrivate : public QSharedData {}; -QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QBluetoothPermission) + +QT_PERMISSION_IMPL_COMMON(QBluetoothPermission) + : u{} // stateless, atm +{} /*! \class QLocationPermission @@ -389,17 +398,10 @@ QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QBluetoothPermission) \include permissions.qdocinc permission-metadata */ -class QLocationPermissionPrivate : public QSharedData -{ -public: - using Accuracy = QLocationPermission::Accuracy; - Accuracy accuracy = Accuracy::Approximate; - using Availability = QLocationPermission::Availability; - Availability availability = Availability::WhenInUse; -}; - -QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QLocationPermission) +QT_PERMISSION_IMPL_COMMON(QLocationPermission) + : u{ShortData{Accuracy::Approximate, Availability::WhenInUse, {}}} +{} /*! \enum QLocationPermission::Accuracy @@ -426,8 +428,7 @@ QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QLocationPermission) */ void QLocationPermission::setAccuracy(Accuracy accuracy) { - d.detach(); - d->accuracy = accuracy; + u.data.accuracy = accuracy; } /*! @@ -435,7 +436,7 @@ void QLocationPermission::setAccuracy(Accuracy accuracy) */ QLocationPermission::Accuracy QLocationPermission::accuracy() const { - return d->accuracy; + return u.data.accuracy; } /*! @@ -443,8 +444,7 @@ QLocationPermission::Accuracy QLocationPermission::accuracy() const */ void QLocationPermission::setAvailability(Availability availability) { - d.detach(); - d->availability = availability; + u.data.availability = availability; } /*! @@ -452,7 +452,7 @@ void QLocationPermission::setAvailability(Availability availability) */ QLocationPermission::Availability QLocationPermission::availability() const { - return d->availability; + return u.data.availability; } /*! @@ -478,13 +478,10 @@ QLocationPermission::Availability QLocationPermission::availability() const \include permissions.qdocinc permission-metadata */ -class QContactsPermissionPrivate : public QSharedData -{ -public: - bool isReadWrite = false; -}; -QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QContactsPermission) +QT_PERMISSION_IMPL_COMMON(QContactsPermission) + : u{ShortData{false, {}}} +{} /*! Sets whether the request is for read-write (\a enable == \c true) or @@ -492,8 +489,7 @@ QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QContactsPermission) */ void QContactsPermission::setReadWrite(bool enable) { - d.detach(); - d->isReadWrite = enable; + u.data.readWrite = enable; } /*! @@ -502,7 +498,7 @@ void QContactsPermission::setReadWrite(bool enable) */ bool QContactsPermission::isReadWrite() const { - return d->isReadWrite; + return u.data.readWrite; } /*! @@ -528,13 +524,10 @@ bool QContactsPermission::isReadWrite() const \include permissions.qdocinc permission-metadata */ -class QCalendarPermissionPrivate : public QSharedData -{ -public: - bool isReadWrite = false; -}; -QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QCalendarPermission) +QT_PERMISSION_IMPL_COMMON(QCalendarPermission) + : u{ShortData{false, {}}} +{} /*! Sets whether the request is for read-write (\a enable == \c true) or @@ -542,8 +535,7 @@ QT_DEFINE_PERMISSION_SPECIAL_FUNCTIONS(QCalendarPermission) */ void QCalendarPermission::setReadWrite(bool enable) { - d.detach(); - d->isReadWrite = enable; + u.data.readWrite = enable; } /*! @@ -552,7 +544,7 @@ void QCalendarPermission::setReadWrite(bool enable) */ bool QCalendarPermission::isReadWrite() const { - return d->isReadWrite; + return u.data.readWrite; } /*! @@ -576,6 +568,8 @@ QDebug operator<<(QDebug debug, const QPermission &permission) } #endif +#undef QT_PERMISSION_IMPL_COMMON + QT_END_NAMESPACE #include "moc_qpermissions.cpp" diff --git a/src/corelib/kernel/qpermissions.h b/src/corelib/kernel/qpermissions.h index 9c47df3eb17..eb440c498ae 100644 --- a/src/corelib/kernel/qpermissions.h +++ b/src/corelib/kernel/qpermissions.h @@ -77,21 +77,28 @@ private: Q_GADGET_EXPORT(Q_CORE_EXPORT) \ using QtPermissionHelper = void; \ friend class QPermission; \ + union U { \ + U() : d(nullptr) {} \ + U(ShortData _data) : data(_data) {} \ + U(ClassName##Private *_d) : d(_d) {} \ + ShortData data; \ + ClassName##Private *d; \ + } u; \ public: \ Q_CORE_EXPORT ClassName(); \ Q_CORE_EXPORT ClassName(const ClassName &other) noexcept; \ - Q_CORE_EXPORT ClassName(ClassName &&other) noexcept; \ - Q_CORE_EXPORT ~ClassName() noexcept; \ + ClassName(ClassName &&other) noexcept \ + : u{other.u} { other.u.d = nullptr; } \ + Q_CORE_EXPORT ~ClassName(); \ Q_CORE_EXPORT ClassName &operator=(const ClassName &other) noexcept; \ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(ClassName) \ - void swap(ClassName &other) noexcept { d.swap(other.d); } \ + void swap(ClassName &other) noexcept { std::swap(u, other.u); } \ private: \ - QtPrivate::QExplicitlySharedDataPointerV2 d; + /*end*/ class QLocationPermissionPrivate; class QLocationPermission { - QT_PERMISSION(QLocationPermission) public: enum Accuracy : quint8 { Approximate, @@ -110,26 +117,46 @@ public: Q_CORE_EXPORT void setAvailability(Availability availability); Q_CORE_EXPORT Availability availability() const; + +private: + struct ShortData { + Accuracy accuracy; + Availability availability; + char reserved[sizeof(void*) - sizeof(accuracy) - sizeof(availability)]; + }; + QT_PERMISSION(QLocationPermission) }; Q_DECLARE_SHARED(QLocationPermission) class QCalendarPermissionPrivate; class QCalendarPermission { - QT_PERMISSION(QCalendarPermission) public: Q_CORE_EXPORT void setReadWrite(bool enable); Q_CORE_EXPORT bool isReadWrite() const; + +private: + struct ShortData { + bool readWrite; + char reserved[sizeof(void*) - sizeof(readWrite)]; + }; + QT_PERMISSION(QCalendarPermission) }; Q_DECLARE_SHARED(QCalendarPermission) class QContactsPermissionPrivate; class QContactsPermission { - QT_PERMISSION(QContactsPermission) public: Q_CORE_EXPORT void setReadWrite(bool enable); Q_CORE_EXPORT bool isReadWrite() const; + +private: + struct ShortData { + bool readWrite; + char reserved[sizeof(void*) - sizeof(readWrite)]; + }; + QT_PERMISSION(QContactsPermission) }; Q_DECLARE_SHARED(QContactsPermission) @@ -137,6 +164,7 @@ Q_DECLARE_SHARED(QContactsPermission) class ClassName##Private; \ class ClassName \ { \ + struct ShortData { char reserved[sizeof(void*)]; }; \ QT_PERMISSION(ClassName) \ }; \ Q_DECLARE_SHARED(ClassName)