diff options
| author | Linus Jahn <lnj@kaidan.im> | 2021-07-05 16:59:09 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2021-07-05 18:07:28 +0200 |
| commit | af3f0c1f5b36757867bf719dc27786e9f947024c (patch) | |
| tree | abfefdd6e7b1f9173fc9a7f36d822d044c45e46a /src | |
| parent | f79990e13fffd36a5d2aa4153ef06b48c0eeebe4 (diff) | |
| download | qxmpp-af3f0c1f5b36757867bf719dc27786e9f947024c.tar.gz | |
More template magic for QFutures
Diffstat (limited to 'src')
| -rw-r--r-- | src/base/QXmppFutureUtils_p.h | 45 | ||||
| -rw-r--r-- | src/client/QXmppClient.cpp | 2 | ||||
| -rw-r--r-- | src/client/QXmppDiscoveryManager.cpp | 4 | ||||
| -rw-r--r-- | src/client/QXmppEntityTimeManager.cpp | 2 | ||||
| -rw-r--r-- | src/client/QXmppUploadRequestManager.cpp | 2 |
5 files changed, 37 insertions, 18 deletions
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<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; +template<typename F, typename Ret, typename A, typename... Rest> +A lambda_helper(Ret (F::*)(A, Rest...)); + +template<typename F, typename Ret, typename A, typename... Rest> +A lambda_helper(Ret (F::*)(A, Rest...) const); + +template<typename F> +struct first_argument { + using type = decltype(lambda_helper(&F::operator())); +}; + +template<typename F> +using first_argument_t = typename first_argument<F>::type; + template<typename T> QFuture<T> makeReadyFuture(T &&value) { QFutureInterface<T> interface(QFutureInterfaceBase::Started); - interface.reportResult(value); + interface.reportResult(std::move(value)); interface.reportFinished(); return interface.future(); } template<typename Result, typename Input, typename Converter> -QFuture<Result> chain(QFuture<Input> &&source, QObject *context, Converter task) +auto chain(QFuture<Input> &&source, QObject *context, Converter task) -> QFuture<Result> { auto resultInterface = std::make_shared<QFutureInterface<Result>>(QFutureInterfaceBase::Started); @@ -77,9 +91,10 @@ QFuture<Result> chain(QFuture<Input> &&source, QObject *context, Converter task) return resultInterface->future(); } -template<typename Result, typename IqType, typename Input, typename Converter> -Result parseIq(Input &&sendResult, Converter convert) +template<typename IqType, typename Input, typename Converter> +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<typename Result, typename IqType, typename Input> -Result parseIq(Input &&sendResult) +template<typename IqType, typename Result, typename Input> +auto parseIq(Input &&sendResult) -> Result { - return parseIq<Result, IqType>(std::move(sendResult), [](IqType &&iq) { + return parseIq<IqType>(std::move(sendResult), [](IqType &&iq) -> Result { // no conversion return iq; }); } -template<typename Result, typename IqType, typename Input, typename Converter> -QFuture<Result> chainIq(QFuture<Input> &&input, QObject *context, Converter convert) +template<typename Input, typename Converter> +auto chainIq(QFuture<Input> &&input, QObject *context, Converter convert) -> QFuture<decltype(convert({}))> { + using Result = decltype(convert({})); + using IqType = std::decay_t<first_argument_t<Converter>>; return chain<Result>(std::move(input), context, [convert { std::move(convert) }](Input &&input) -> Result { - return parseIq<Result, IqType>(std::move(input), convert); + return parseIq<IqType>(std::move(input), convert); }); } -template<typename Result, typename IqType, typename Input> -QFuture<Result> chainIq(QFuture<Input> &&input, QObject *context) +template<typename Result, typename Input> +auto chainIq(QFuture<Input> &&input, QObject *context) -> QFuture<Result> { + // IQ type is first std::variant parameter + using IqType = std::decay_t<decltype(std::get<0>(Result {}))>; return chain<Result>(std::move(input), context, [](Input &&sendResult) { - return parseIq<Result, IqType>(sendResult); + return parseIq<IqType, Result>(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::IqResult> QXmppClient::sendIq(const QXmppIq &iq) QFuture<QXmppClient::EmptyResult> QXmppClient::sendGenericIq(const QXmppIq &iq) { using namespace QXmpp::Private; - return chainIq<EmptyResult, QXmppIq>(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::InfoResult> QXmppDiscoveryManager::requestDiscoIn request.setQueryNode(node); } - return chainIq<InfoResult, QXmppDiscoveryIq>(client()->sendIq(request), this); + return chainIq<InfoResult>(client()->sendIq(request), this); } /// @@ -167,7 +167,7 @@ QFuture<QXmppDiscoveryManager::ItemsResult> QXmppDiscoveryManager::requestDiscoI request.setQueryNode(node); } - return chainIq<ItemsResult, QXmppDiscoveryIq>(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<En iq.setType(QXmppIq::Get); iq.setTo(jid); - return chainIq<EntityTimeResult, QXmppEntityTimeIq>(client()->sendIq(iq), this); + return chainIq<EntityTimeResult>(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<SlotResult, QXmppHttpUploadSlotIq>(client()->sendIq(iq), this); + return chainIq<SlotResult>(client()->sendIq(iq), this); } /// Returns true if an HTTP File Upload service has been discovered. |
