9#include "qxmpp_export.h"
21namespace QXmpp::Private {
25class QXMPP_EXPORT TaskPrivate
28 TaskPrivate(
void (*freeResult)(
void *));
31 bool isFinished()
const;
32 void setFinished(
bool);
33 bool isContextAlive();
34 void setContext(QObject *);
36 void setResult(
void *);
37 void resetResult() { setResult(
nullptr); }
38 const std::function<void(TaskPrivate &,
void *)> continuation()
const;
39 void setContinuation(std::function<
void(TaskPrivate &,
void *)> &&);
40 void invokeContinuation(
void *result);
43 std::shared_ptr<TaskData> d;
99 template<
typename Continuation>
101 void then(QObject *context, Continuation continuation)
103 if constexpr (!std::is_void_v<T>) {
104 static_assert(std::is_invocable_v<Continuation, T &&>,
"Function needs to be invocable with T &&.");
106 static_assert(std::is_invocable_v<Continuation>,
"Function needs to be invocable without arguments.");
108 using namespace QXmpp::Private;
110 if (d.isFinished()) {
111 if constexpr (std::is_void_v<T>) {
116 continuation(std::move(*
reinterpret_cast<T *
>(d.result())));
121 d.setContext(context);
122 d.setContinuation([f = std::forward<Continuation>(continuation)](TaskPrivate &d,
void *
result)
mutable {
123 if (d.isContextAlive()) {
124 if constexpr (std::is_void_v<T>) {
127 f(std::move(*reinterpret_cast<T *>(result)));
132 d.setContinuation({});
143 [[nodiscard]]
bool isFinished()
const {
return d.isFinished(); }
149 template<
typename U = T, std::enable_if_t<(!std::is_
void_v<U>)> * =
nullptr>
153 return d.result() !=
nullptr;
164 template<
typename U = T, std::enable_if_t<(!std::is_
void_v<U>)> * =
nullptr>
165 [[nodiscard]]
const U &result() const
168 Q_ASSERT(isFinished());
169 Q_ASSERT(hasResult());
170 return *
reinterpret_cast<U *
>(d.result());
181 template<
typename U = T, std::enable_if_t<(!std::is_
void_v<U>)> * =
nullptr>
182 [[nodiscard]] U takeResult()
185 Q_ASSERT(isFinished());
186 Q_ASSERT(hasResult());
187 U result = std::move(*
reinterpret_cast<U *
>(d.result()));
197 QFutureInterface<T> interface;
199 if constexpr (std::is_same_v<T, void>) {
200 then(context, [interface]()
mutable {
201 interface.reportFinished();
204 then(context, [interface](T &&val)
mutable {
205 interface.reportResult(val);
206 interface.reportFinished();
210 return interface.future();
216 explicit QXmppTask(QXmpp::Private::TaskPrivate data)
221 QXmpp::Private::TaskPrivate d;
Create and update QXmppTask objects to communicate results of asynchronous operations.
Definition QXmppPromise.h:23
Definition QXmppTask.h:62
void then(QObject *context, Continuation continuation)
Definition QXmppTask.h:101
QFuture< T > toFuture(QObject *context)
Definition QXmppTask.h:195
bool hasResult() const
Definition QXmppTask.h:151
const T & result() const
Definition QXmppTask.h:162
bool isFinished() const
Definition QXmppTask.h:143
T takeResult()
Definition QXmppTask.h:179