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 ++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) (limited to 'src/base') 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); }); } -- cgit v1.2.3