From abd1b7f3068e7d4a41adf440d6f6163bfa9f531a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 8 Sep 2020 12:42:52 +0200 Subject: Cleanup QDBusPendingReply Remove the limitation of max 8 arguments and clean up the template code. This required a bit of special work to ensure QDBusPendingReply works the same way as QDBusPendingReply<>. Change-Id: I8e822b2f97f0712746b917056ea8f3d5c219c7f6 Reviewed-by: Thiago Macieira --- src/dbus/qdbuspendingreply.cpp | 36 +++++----- src/dbus/qdbuspendingreply.h | 153 ++++++++++++++++++++--------------------- 2 files changed, 93 insertions(+), 96 deletions(-) (limited to 'src/dbus') diff --git a/src/dbus/qdbuspendingreply.cpp b/src/dbus/qdbuspendingreply.cpp index df37d92211..f83b3d27a2 100644 --- a/src/dbus/qdbuspendingreply.cpp +++ b/src/dbus/qdbuspendingreply.cpp @@ -95,7 +95,7 @@ */ /*! - \fn template QDBusPendingReply::QDBusPendingReply() + \fn template QDBusPendingReply::QDBusPendingReply() Creates an empty QDBusPendingReply object. Without assigning a QDBusPendingCall object to this reply, QDBusPendingReply cannot do @@ -103,7 +103,7 @@ */ /*! - \fn template QDBusPendingReply::QDBusPendingReply(const QDBusPendingReply &other) + \fn template QDBusPendingReply::QDBusPendingReply(const QDBusPendingReply &other) Creates a copy of the \a other QDBusPendingReply object. Just like QDBusPendingCall and QDBusPendingCallWatcher, this QDBusPendingReply @@ -112,7 +112,7 @@ */ /*! - \fn template QDBusPendingReply::QDBusPendingReply(const QDBusPendingCall &call) + \fn template QDBusPendingReply::QDBusPendingReply(const QDBusPendingCall &call) Creates a QDBusPendingReply object that will take its contents from the \a call pending asynchronous call. This QDBusPendingReply object @@ -120,7 +120,7 @@ */ /*! - \fn template QDBusPendingReply::QDBusPendingReply(const QDBusMessage &message) + \fn template QDBusPendingReply::QDBusPendingReply(const QDBusMessage &message) Creates a QDBusPendingReply object that will take its contents from the message \a message. In this case, this object will be already @@ -130,7 +130,7 @@ */ /*! - \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingReply &other) + \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingReply &other) Makes a copy of \a other and drops the reference to the current pending call. If the current reference is to an unfinished pending @@ -140,7 +140,7 @@ */ /*! - \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingCall &call) + \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingCall &call) Makes this object take its contents from the \a call pending call and drops the reference to the current pending call. If the @@ -150,7 +150,7 @@ */ /*! - \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusMessage &message) + \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusMessage &message) Makes this object take its contents from the \a message message and drops the reference to the current pending call. If the @@ -172,7 +172,7 @@ */ /*! - \fn template int QDBusPendingReply::count() const + \fn template int QDBusPendingReply::count() const Return the number of arguments the reply is supposed to have. This number matches the number of non-void template parameters in this @@ -184,7 +184,7 @@ */ /*! - \fn template QVariant QDBusPendingReply::argumentAt(int index) const + \fn template QVariant QDBusPendingReply::argumentAt(int index) const Returns the argument at position \a index in the reply's contents. If the reply doesn't have that many elements, this @@ -199,7 +199,7 @@ */ /*! - \fn template T1 QDBusPendingReply::value() const + \fn template T1 QDBusPendingReply::value() const Returns the first argument in this reply, cast to type \c T1 (the first template parameter of this class). This is equivalent to @@ -217,7 +217,7 @@ */ /*! - \fn template QDBusPendingReply::operator T1() const + \fn template QDBusPendingReply::operator T1() const Returns the first argument in this reply, cast to type \c T1 (the first template parameter of this class). This is equivalent to @@ -235,7 +235,7 @@ */ /*! - \fn template void QDBusPendingReply::waitForFinished() + \fn template void QDBusPendingReply::waitForFinished() Suspends the execution of the calling thread until the reply is received and processed. After this function returns, isFinished() @@ -245,27 +245,27 @@ \sa QDBusPendingCallWatcher::waitForFinished() */ -QDBusPendingReplyData::QDBusPendingReplyData() +QDBusPendingReplyBase::QDBusPendingReplyBase() : QDBusPendingCall(nullptr) // initialize base class empty { } -QDBusPendingReplyData::~QDBusPendingReplyData() +QDBusPendingReplyBase::~QDBusPendingReplyBase() { } -void QDBusPendingReplyData::assign(const QDBusPendingCall &other) +void QDBusPendingReplyBase::assign(const QDBusPendingCall &other) { QDBusPendingCall::operator=(other); } -void QDBusPendingReplyData::assign(const QDBusMessage &message) +void QDBusPendingReplyBase::assign(const QDBusMessage &message) { d = new QDBusPendingCallPrivate(QDBusMessage(), nullptr); // drops the reference to the old one d->replyMessage = message; } -QVariant QDBusPendingReplyData::argumentAt(int index) const +QVariant QDBusPendingReplyBase::argumentAt(int index) const { if (!d) return QVariant(); @@ -275,7 +275,7 @@ QVariant QDBusPendingReplyData::argumentAt(int index) const return d->replyMessage.arguments().value(index); } -void QDBusPendingReplyData::setMetaTypes(int count, const int *types) +void QDBusPendingReplyBase::setMetaTypes(int count, const int *types) { Q_ASSERT(d); const auto locker = qt_scoped_lock(d->mutex); diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h index 62e955a82b..18c02508a0 100644 --- a/src/dbus/qdbuspendingreply.h +++ b/src/dbus/qdbuspendingreply.h @@ -49,11 +49,11 @@ QT_BEGIN_NAMESPACE -class Q_DBUS_EXPORT QDBusPendingReplyData: public QDBusPendingCall +class Q_DBUS_EXPORT QDBusPendingReplyBase : public QDBusPendingCall { protected: - QDBusPendingReplyData(); - ~QDBusPendingReplyData(); + QDBusPendingReplyBase(); + ~QDBusPendingReplyBase(); void assign(const QDBusPendingCall &call); void assign(const QDBusMessage &message); @@ -62,79 +62,45 @@ protected: }; namespace QDBusPendingReplyTypes { - template + template struct Select { - typedef Select Next; + typedef Select Next; typedef typename Next::Type Type; }; - template - struct Select<0, T1, T2, T3, T4, T5, T6, T7, T8> + template + struct Select<0, T, Types...> { - typedef T1 Type; + typedef T Type; }; - template inline int metaTypeFor(T1 * = nullptr) - { return qMetaTypeId(); } + template inline QMetaType metaTypeFor() + { return QMetaType::fromType(); } // specialize for QVariant, allowing it to be used in place of QDBusVariant - template<> inline int metaTypeFor(QVariant *) - { return qMetaTypeId(); } + template<> inline QMetaType metaTypeFor() + { return QMetaType::fromType(); } +} - template - struct ForEach - { - typedef ForEach Next; - enum { Total = Next::Total + 1 }; - static inline void fillMetaTypes(int *p) - { - *p = metaTypeFor(nullptr); - Next::fillMetaTypes(++p); - } - }; - template<> - struct ForEach - { - enum { Total = 0 }; - static inline void fillMetaTypes(int *) - { } - }; - struct TypeIsVoid {}; - template struct NotVoid { typedef T Type; }; - template <> struct NotVoid { typedef TypeIsVoid Type; }; -} // namespace QDBusPendingReplyTypes - -template -class QDBusPendingReply: -#ifdef Q_CLANG_QDOC - public QDBusPendingCall -#else - public QDBusPendingReplyData -#endif +template +class QDBusPendingReply : public QDBusPendingReplyBase { - typedef QDBusPendingReplyTypes::ForEach ForEach; - template struct Select : - QDBusPendingReplyTypes::Select - { - }; - + template using Select = QDBusPendingReplyTypes::Select; public: - enum { Count = ForEach::Total }; + enum { Count = std::is_same_v::Type, void> ? 0 : sizeof...(Types) }; - inline QDBusPendingReply() - { } + inline constexpr int count() const { return Count; } + + + inline QDBusPendingReply() = default; inline QDBusPendingReply(const QDBusPendingReply &other) - : QDBusPendingReplyData(other) + : QDBusPendingReplyBase(other) { } inline /*implicit*/ QDBusPendingReply(const QDBusPendingCall &call) // required by qdbusxml2cpp-generated code { *this = call; } inline /*implicit*/ QDBusPendingReply(const QDBusMessage &message) { *this = message; } + inline QDBusPendingReply &operator=(const QDBusPendingReply &other) { assign(other); return *this; } inline QDBusPendingReply &operator=(const QDBusPendingCall &call) @@ -142,23 +108,14 @@ public: inline QDBusPendingReply &operator=(const QDBusMessage &message) { assign(message); return *this; } - inline int count() const { return Count; } - -#if defined(Q_CLANG_QDOC) - QVariant argumentAt(int index) const; -#else - using QDBusPendingReplyData::argumentAt; -#endif - -#ifndef Q_CLANG_QDOC + using QDBusPendingReplyBase::argumentAt; template inline - const typename Select::Type argumentAt() const + typename Select::Type argumentAt() const { static_assert(Index >= 0 && Index < Count, "Index out of bounds"); typedef typename Select::Type ResultType; return qdbus_cast(argumentAt(Index)); } -#endif #if defined(Q_CLANG_QDOC) bool isFinished() const; @@ -168,43 +125,83 @@ public: bool isError() const; QDBusError error() const; QDBusMessage reply() const; +#endif - inline T1 value() const; - inline operator T1() const; -#else inline typename Select<0>::Type value() const { return argumentAt<0>(); } - inline operator typename QDBusPendingReplyTypes::NotVoid::Type() const + inline operator typename Select<0>::Type() const { return argumentAt<0>(); } -#endif private: inline void calculateMetaTypes() { if (!d) return; - int typeIds[Count > 0 ? Count : 1]; // use at least one since zero-sized arrays aren't valid - ForEach::fillMetaTypes(typeIds); - setMetaTypes(Count, typeIds); + if constexpr (Count == 0) { + setMetaTypes(0, nullptr); + } else { + std::array typeIds = { QDBusPendingReplyTypes::metaTypeFor().id()... }; + setMetaTypes(Count, typeIds.data()); + } } inline void assign(const QDBusPendingCall &call) { - QDBusPendingReplyData::assign(call); + QDBusPendingReplyBase::assign(call); calculateMetaTypes(); } inline void assign(const QDBusMessage &message) { - QDBusPendingReplyData::assign(message); + QDBusPendingReplyBase::assign(message); calculateMetaTypes(); } }; +template<> +class QDBusPendingReply<> : public QDBusPendingReplyBase +{ +public: + enum { Count = 0 }; + inline int count() const { return Count; } + + inline QDBusPendingReply() = default; + inline QDBusPendingReply(const QDBusPendingReply &other) + : QDBusPendingReplyBase(other) + { } + inline /*implicit*/ QDBusPendingReply(const QDBusPendingCall &call) // required by qdbusxml2cpp-generated code + { *this = call; } + inline /*implicit*/ QDBusPendingReply(const QDBusMessage &message) + { *this = message; } + + inline QDBusPendingReply &operator=(const QDBusPendingReply &other) + { assign(other); return *this; } + inline QDBusPendingReply &operator=(const QDBusPendingCall &call) + { assign(call); return *this; } + inline QDBusPendingReply &operator=(const QDBusMessage &message) + { assign(message); return *this; } + +private: + inline void assign(const QDBusPendingCall &call) + { + QDBusPendingReplyBase::assign(call); + if (d) + setMetaTypes(0, nullptr); + } + + inline void assign(const QDBusMessage &message) + { + QDBusPendingReplyBase::assign(message); + if (d) + setMetaTypes(0, nullptr); + } + +}; + QT_END_NAMESPACE #endif // QT_NO_DBUS -- cgit v1.2.3