diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-09-08 12:42:52 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-09-23 19:30:10 +0200 |
commit | abd1b7f3068e7d4a41adf440d6f6163bfa9f531a (patch) | |
tree | 02cf059d4c3b9ec74a7901323515d479cacabdcf | |
parent | 720e2e0c92ca6635c5f05f318770a70cf653c1c7 (diff) |
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<void> works the same way
as QDBusPendingReply<>.
Change-Id: I8e822b2f97f0712746b917056ea8f3d5c219c7f6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/dbus/qdbuspendingreply.cpp | 36 | ||||
-rw-r--r-- | src/dbus/qdbuspendingreply.h | 153 |
2 files changed, 93 insertions, 96 deletions
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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply() + \fn template<typename... Types> QDBusPendingReply<Types...>::QDBusPendingReply() Creates an empty QDBusPendingReply object. Without assigning a QDBusPendingCall object to this reply, QDBusPendingReply cannot do @@ -103,7 +103,7 @@ */ /*! - \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply(const QDBusPendingReply &other) + \fn template<typename... Types> QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply(const QDBusPendingCall &call) + \fn template<typename... Types> QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply(const QDBusMessage &message) + \fn template<typename... Types> QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply &QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator=(const QDBusPendingReply &other) + \fn template<typename... Types> QDBusPendingReply &QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply &QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator=(const QDBusPendingCall &call) + \fn template<typename... Types> QDBusPendingReply &QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply &QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator=(const QDBusMessage &message) + \fn template<typename... Types> QDBusPendingReply &QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> int QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::count() const + \fn template<typename... Types> int QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QVariant QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::argumentAt(int index) const + \fn template<typename... Types> QVariant QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> T1 QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::value() const + \fn template<typename... Types> T1 QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator T1() const + \fn template<typename... Types> QDBusPendingReply<Types...>::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<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> void QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::waitForFinished() + \fn template<typename... Types> void QDBusPendingReply<Types...>::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<int Index, - typename T1, typename T2, typename T3, typename T4, - typename T5, typename T6, typename T7, typename T8> + template<int Index, typename T, typename... Types> struct Select { - typedef Select<Index - 1, T2, T3, T4, T5, T6, T7, T8, void> Next; + typedef Select<Index - 1, Types...> Next; typedef typename Next::Type Type; }; - template<typename T1, typename T2, typename T3, typename T4, - typename T5, typename T6, typename T7, typename T8> - struct Select<0, T1, T2, T3, T4, T5, T6, T7, T8> + template<typename T, typename... Types> + struct Select<0, T, Types...> { - typedef T1 Type; + typedef T Type; }; - template<typename T1> inline int metaTypeFor(T1 * = nullptr) - { return qMetaTypeId<T1>(); } + template<typename T> inline QMetaType metaTypeFor() + { return QMetaType::fromType<T>(); } // specialize for QVariant, allowing it to be used in place of QDBusVariant - template<> inline int metaTypeFor<QVariant>(QVariant *) - { return qMetaTypeId<QDBusVariant>(); } + template<> inline QMetaType metaTypeFor<QVariant>() + { return QMetaType::fromType<QDBusVariant>(); } +} - template<typename T1, typename T2, typename T3, typename T4, - typename T5, typename T6, typename T7, typename T8> - struct ForEach - { - typedef ForEach<T2, T3, T4, T5, T6, T7, T8, void> Next; - enum { Total = Next::Total + 1 }; - static inline void fillMetaTypes(int *p) - { - *p = metaTypeFor<T1>(nullptr); - Next::fillMetaTypes(++p); - } - }; - template<> - struct ForEach<void, void, void, void, void, void, void, void> - { - enum { Total = 0 }; - static inline void fillMetaTypes(int *) - { } - }; - struct TypeIsVoid {}; - template <typename T> struct NotVoid { typedef T Type; }; - template <> struct NotVoid<void> { typedef TypeIsVoid Type; }; -} // namespace QDBusPendingReplyTypes - -template<typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, - typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void> -class QDBusPendingReply: -#ifdef Q_CLANG_QDOC - public QDBusPendingCall -#else - public QDBusPendingReplyData -#endif +template<typename... Types> +class QDBusPendingReply : public QDBusPendingReplyBase { - typedef QDBusPendingReplyTypes::ForEach<T1, T2, T3, T4, T5, T6, T7, T8> ForEach; - template<int Index> struct Select : - QDBusPendingReplyTypes::Select<Index, T1, T2, T3, T4, T5, T6, T7, T8> - { - }; - + template<int Index> using Select = QDBusPendingReplyTypes::Select<Index, Types...>; public: - enum { Count = ForEach::Total }; + enum { Count = std::is_same_v<typename Select<0>::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<int Index> inline - const typename Select<Index>::Type argumentAt() const + typename Select<Index>::Type argumentAt() const { static_assert(Index >= 0 && Index < Count, "Index out of bounds"); typedef typename Select<Index>::Type ResultType; return qdbus_cast<ResultType>(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<T1>::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<int, Count> typeIds = { QDBusPendingReplyTypes::metaTypeFor<Types>().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 |