From af3f0c1f5b36757867bf719dc27786e9f947024c Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Mon, 5 Jul 2021 16:59:09 +0200 Subject: More template magic for QFutures --- src/base/QXmppFutureUtils_p.h | 45 +++++++++++++++++++++++--------- src/client/QXmppClient.cpp | 2 +- src/client/QXmppDiscoveryManager.cpp | 4 +-- src/client/QXmppEntityTimeManager.cpp | 2 +- src/client/QXmppUploadRequestManager.cpp | 2 +- 5 files changed, 37 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/base/QXmppFutureUtils_p.h b/src/base/QXmppFutureUtils_p.h index d109f74b..9d188241 100644 --- a/src/base/QXmppFutureUtils_p.h +++ b/src/base/QXmppFutureUtils_p.h @@ -53,17 +53,31 @@ struct overloaded : Ts... { template overloaded(Ts...) -> overloaded; +template +A lambda_helper(Ret (F::*)(A, Rest...)); + +template +A lambda_helper(Ret (F::*)(A, Rest...) const); + +template +struct first_argument { + using type = decltype(lambda_helper(&F::operator())); +}; + +template +using first_argument_t = typename first_argument::type; + template QFuture makeReadyFuture(T &&value) { QFutureInterface interface(QFutureInterfaceBase::Started); - interface.reportResult(value); + interface.reportResult(std::move(value)); interface.reportFinished(); return interface.future(); } template -QFuture chain(QFuture &&source, QObject *context, Converter task) +auto chain(QFuture &&source, QObject *context, Converter task) -> QFuture { auto resultInterface = std::make_shared>(QFutureInterfaceBase::Started); @@ -77,9 +91,10 @@ QFuture chain(QFuture &&source, QObject *context, Converter task) return resultInterface->future(); } -template -Result parseIq(Input &&sendResult, Converter convert) +template +auto parseIq(Input &&sendResult, Converter convert) -> decltype(convert({})) { + using Result = decltype(convert({})); return std::visit(overloaded { [convert { std::move(convert) }](const QDomElement &element) -> Result { IqType iq; @@ -98,28 +113,32 @@ Result parseIq(Input &&sendResult, Converter convert) sendResult); } -template -Result parseIq(Input &&sendResult) +template +auto parseIq(Input &&sendResult) -> Result { - return parseIq(std::move(sendResult), [](IqType &&iq) { + return parseIq(std::move(sendResult), [](IqType &&iq) -> Result { // no conversion return iq; }); } -template -QFuture chainIq(QFuture &&input, QObject *context, Converter convert) +template +auto chainIq(QFuture &&input, QObject *context, Converter convert) -> QFuture { + using Result = decltype(convert({})); + using IqType = std::decay_t>; return chain(std::move(input), context, [convert { std::move(convert) }](Input &&input) -> Result { - return parseIq(std::move(input), convert); + return parseIq(std::move(input), convert); }); } -template -QFuture chainIq(QFuture &&input, QObject *context) +template +auto chainIq(QFuture &&input, QObject *context) -> QFuture { + // IQ type is first std::variant parameter + using IqType = std::decay_t(Result {}))>; return chain(std::move(input), context, [](Input &&sendResult) { - return parseIq(sendResult); + return parseIq(sendResult); }); } diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp index 74875275..0e37a4f9 100644 --- a/src/client/QXmppClient.cpp +++ b/src/client/QXmppClient.cpp @@ -387,7 +387,7 @@ QFuture QXmppClient::sendIq(const QXmppIq &iq) QFuture QXmppClient::sendGenericIq(const QXmppIq &iq) { using namespace QXmpp::Private; - return chainIq(sendIq(iq), this, [](const QXmppIq &) { + return chainIq(sendIq(iq), this, [](const QXmppIq &) -> EmptyResult { return QXmpp::Success(); }); } diff --git a/src/client/QXmppDiscoveryManager.cpp b/src/client/QXmppDiscoveryManager.cpp index 9e2198f0..517a49bb 100644 --- a/src/client/QXmppDiscoveryManager.cpp +++ b/src/client/QXmppDiscoveryManager.cpp @@ -144,7 +144,7 @@ QFuture QXmppDiscoveryManager::requestDiscoIn request.setQueryNode(node); } - return chainIq(client()->sendIq(request), this); + return chainIq(client()->sendIq(request), this); } /// @@ -167,7 +167,7 @@ QFuture QXmppDiscoveryManager::requestDiscoI request.setQueryNode(node); } - return chainIq(client()->sendIq(request), this, [](QXmppDiscoveryIq &&iq) { + return chainIq(client()->sendIq(request), this, [](QXmppDiscoveryIq &&iq) -> ItemsResult { return iq.items(); }); } diff --git a/src/client/QXmppEntityTimeManager.cpp b/src/client/QXmppEntityTimeManager.cpp index 251442ac..030e797b 100644 --- a/src/client/QXmppEntityTimeManager.cpp +++ b/src/client/QXmppEntityTimeManager.cpp @@ -78,7 +78,7 @@ auto QXmppEntityTimeManager::requestEntityTime(const QString &jid) -> QFuture(client()->sendIq(iq), this); + return chainIq(client()->sendIq(iq), this); } /// \cond diff --git a/src/client/QXmppUploadRequestManager.cpp b/src/client/QXmppUploadRequestManager.cpp index 27889ffb..439062b7 100644 --- a/src/client/QXmppUploadRequestManager.cpp +++ b/src/client/QXmppUploadRequestManager.cpp @@ -267,7 +267,7 @@ auto QXmppUploadRequestManager::requestSlot(const QString &fileName, iq.setSize(fileSize); iq.setContentType(mimeType); - return chainIq(client()->sendIq(iq), this); + return chainIq(client()->sendIq(iq), this); } /// Returns true if an HTTP File Upload service has been discovered. -- cgit v1.2.3