12#include "kasync_export.h"
23#include "continuations_p.h"
24#include "executor_p.h"
61template<
typename PrevOut,
typename Out,
typename ...
In>
66template<
typename Out,
typename ...
In>
72template<
typename Out,
typename ...
In>
73Job<
Out,
In ...> startImpl(Private::ContinuationHolder<Out, In ...> &&helper)
75 static_assert(
sizeof...(In) <= 1,
"Only one or zero input parameters are allowed.");
77 std::forward<Private::ContinuationHolder<Out, In...>>(helper),
nullptr, Private::ExecutionFlag::GoodCase));
96template<
typename Out = void,
typename ...
In,
typename F>
97auto start(F &&func) -> std::enable_if_t<!std::is_base_of<JobBase, decltype(func(std::declval<In>() ...))>::value,
98 Job<
decltype(func(std::declval<In>() ...)),
In...>>
100 static_assert(
sizeof...(In) <= 1,
"Only one or zero input parameters are allowed.");
101 return Private::startImpl<
Out,
In...>(Private::ContinuationHolder<
Out,
In ...>(SyncContinuation<
Out,
In ...>(std::forward<F>(func))));
105template<
typename Out = void,
typename ...
In,
typename F>
106auto start(F &&func) -> std::enable_if_t<std::is_base_of<JobBase, decltype(func(std::declval<In>() ...))>::value,
107 Job<
typename decltype(func(std::declval<In>() ...))::OutType,
In...>>
109 static_assert(
sizeof...(In) <= 1,
"Only one or zero input parameters are allowed.");
110 return Private::startImpl<
Out,
In...>(Private::ContinuationHolder<
Out,
In ...>(JobContinuation<
Out,
In...>(std::forward<F>(func))));
114template<
typename Out = void,
typename ...
In>
115auto start(AsyncContinuation<Out, In ...> &&func) -> Job<
Out,
In ...>
117 static_assert(
sizeof...(In) <= 1,
"Only one or zero input parameters are allowed.");
118 return Private::startImpl<
Out,
In...>(Private::ContinuationHolder<
Out,
In ...>(std::forward<AsyncContinuation<
Out,
In ...>>(func)));
121enum ControlFlowFlag {
133KASYNC_EXPORT Job<void> doWhile(
const Job<ControlFlowFlag> &body);
144KASYNC_EXPORT Job<void> doWhile(
const JobContinuation<ControlFlowFlag> &body);
153KASYNC_EXPORT Job<void> wait(
int delay);
163template<
typename Out =
void>
171template<
typename Out>
182template<
typename List,
typename ValueType =
typename List::value_type>
183Job<void, List>
forEach(KAsync::Job<void, ValueType> job);
194template<
typename List,
typename ValueType =
typename List::value_type>
195 Job<void, List>
forEach(JobContinuation<void, ValueType> &&);
206template<
typename List,
typename ValueType =
typename List::value_type>
207Job<void, List> serialForEach(KAsync::Job<void, ValueType> job);
218template<
typename List,
typename ValueType =
typename List::value_type>
219Job<void, List> serialForEach(JobContinuation<void, ValueType> &&);
224template<
template<
typename>
class Container>
225Job<void> waitForCompletion(Container<KAsync::Future<void>> &futures);
235template<
typename Out =
void>
246template<
typename Out =
void>
247Job<Out>
error(
const char *);
257template<
typename Out =
void>
258Job<Out>
error(
const Error &);
261class KASYNC_EXPORT JobBase
263 template<
typename Out,
typename ...
In>
267 explicit JobBase(
const Private::ExecutorBasePtr &executor)
268 : mExecutor(executor)
271 virtual ~JobBase() =
default;
274 Private::ExecutorBasePtr mExecutor;
320template<
typename Out,
typename ...
In>
321class [[nodiscard]] Job :
public JobBase
324 template<
typename OutOther,
typename ... InOther>
327 template<
typename OutOther,
typename ... InOther>
328 friend Job<OutOther, InOther ...> Private::startImpl(Private::ContinuationHolder<OutOther, InOther ...> &&);
330 template<
typename List,
typename ValueType>
331 friend Job<void, List>
forEach(KAsync::Job<void, ValueType> job);
333 template<
typename List,
typename ValueType>
334 friend Job<void, List> serialForEach(KAsync::Job<void, ValueType> job);
338 struct IncompleteType;
345 template<
typename OutOther,
typename ... InOther>
346 Job<OutOther,
In ...> then(
const Job<OutOther, InOther ...> &job)
const;
362 template<
typename OutOther = void,
typename ... InOther,
typename F>
363 auto then(F &&func)
const -> std::enable_if_t<std::is_base_of<JobBase, decltype(func(std::declval<Out>()))>::value,
364 Job<typename decltype(func(std::declval<Out>()))::OutType,
In...>>
366 using ResultJob =
decltype(func(std::declval<Out>()));
367 return thenImpl<typename ResultJob::OutType, Out>(
368 {JobContinuation<typename ResultJob::OutType, Out>(std::forward<F>(func))}, Private::ExecutionFlag::GoodCase);
372 template<
typename OutOther = void,
typename ... InOther,
typename F>
373 auto then(F &&func)
const -> std::enable_if_t<std::is_base_of<JobBase,
decltype(func())>::value,
374 Job<
typename decltype(func())::OutType,
In...>>
376 using ResultJob =
decltype(func());
377 return thenImpl<typename ResultJob::OutType>(
378 {JobContinuation<typename ResultJob::OutType>(std::forward<F>(func))}, Private::ExecutionFlag::GoodCase);
382 template<
typename OutOther = void,
typename ... InOther,
typename F>
383 auto then(F &&func)
const -> std::enable_if_t<std::is_base_of<JobBase,
decltype(func(KAsync::Error{}, std::declval<Out>()))>::value,
384 Job<
typename decltype(func(KAsync::Error{}, std::declval<Out>()))::OutType,
In...>>
386 using ResultJob =
decltype(func(KAsync::Error{}, std::declval<Out>()));
387 return thenImpl<typename ResultJob::OutType, Out>(
388 {JobErrorContinuation<typename ResultJob::OutType, Out>(std::forward<F>(func))}, Private::ExecutionFlag::Always);
392 template<
typename OutOther = void,
typename ... InOther,
typename F>
393 auto then(F &&func)
const -> std::enable_if_t<std::is_base_of<JobBase,
decltype(func(KAsync::Error{}))>::value,
394 Job<
typename decltype(func(KAsync::Error{}))::OutType,
In...>>
396 using ResultJob =
decltype(func(KAsync::Error{}));
397 return thenImpl<typename ResultJob::OutType>(
398 {JobErrorContinuation<typename ResultJob::OutType>(std::forward<F>(func))}, Private::ExecutionFlag::Always);
402 template<
typename OutOther = void,
typename ... InOther,
typename F>
403 auto then(F &&func)
const -> std::enable_if_t<!std::is_base_of<JobBase, decltype(func(std::declval<Out>()))>::value,
404 Job<decltype(func(std::declval<Out>())),
In...>>
406 using ResultType =
decltype(func(std::declval<Out>()));
407 return thenImpl<ResultType, Out>(
408 {SyncContinuation<ResultType, Out>(std::forward<F>(func))}, Private::ExecutionFlag::GoodCase);
412 template<
typename OutOther = void,
typename ... InOther,
typename F>
413 auto then(F &&func)
const -> std::enable_if_t<!std::is_base_of<JobBase,
decltype(func())>::value,
414 Job<
decltype(func()),
In...>>
416 using ResultType =
decltype(func());
417 return thenImpl<ResultType>(
418 {SyncContinuation<ResultType>(std::forward<F>(func))}, Private::ExecutionFlag::GoodCase);
422 template<
typename OutOther = void,
typename ... InOther,
typename F>
423 auto then(F &&func)
const -> std::enable_if_t<!std::is_base_of<JobBase,
decltype(func(KAsync::Error{}, std::declval<Out>()))>::value,
424 Job<
decltype(func(KAsync::Error{}, std::declval<Out>())),
In...>>
426 using ResultType =
decltype(func(KAsync::Error{}, std::declval<Out>()));
427 return thenImpl<ResultType, Out>(
428 {SyncErrorContinuation<ResultType, Out>(std::forward<F>(func))}, Private::ExecutionFlag::Always);
432 template<
typename OutOther = void,
typename ... InOther,
typename F>
433 auto then(F &&func)
const -> std::enable_if_t<!std::is_base_of<JobBase,
decltype(func(KAsync::Error{}))>::value,
434 Job<
decltype(func(KAsync::Error{})),
In...>>
436 using ResultType =
decltype(func(KAsync::Error{}));
437 return thenImpl<ResultType>(
438 {SyncErrorContinuation<ResultType>(std::forward<F>(func))}, Private::ExecutionFlag::Always);
442 template<
typename OutOther,
typename ... InOther>
443 Job<OutOther,
In ...> then(AsyncContinuation<OutOther, InOther ...> &&func)
const
445 return thenImpl<OutOther, InOther ...>({std::forward<AsyncContinuation<OutOther, InOther ...>>(func)},
446 Private::ExecutionFlag::GoodCase);
450 template<
typename OutOther,
typename ... InOther>
451 Job<OutOther,
In ...> then(AsyncErrorContinuation<OutOther, InOther ...> &&func)
const
453 return thenImpl<OutOther, InOther ...>({std::forward<AsyncErrorContinuation<OutOther, InOther ...>>(func)}, Private::ExecutionFlag::Always);
457 Job<
Out,
In ...> onError(SyncErrorContinuation<void> &&errorFunc)
const;
463 template<typename OutOther = void, typename ListType = Out, typename ValueType = typename ListType::value_type, std::enable_if_t<!std::is_void<ListType>::value,
int> = 0>
464 Job<void,
In ...> each(JobContinuation<void, ValueType> &&func)
const
466 eachInvariants<OutOther>();
467 return then<void,
In ...>(forEach<Out, ValueType>(std::forward<JobContinuation<void, ValueType>>(func)));
474 template<typename OutOther = void, typename ListType = Out, typename ValueType = typename ListType::value_type, std::enable_if_t<!std::is_void<ListType>::value,
int> = 0>
475 Job<void,
In ...> serialEach(JobContinuation<void, ValueType> &&func)
const
477 eachInvariants<OutOther>();
478 return then<void,
In ...>(serialForEach<Out, ValueType>(std::forward<JobContinuation<void, ValueType>>(func)));
490 template<
typename ... InOther>
491 operator std::conditional_t<std::is_void<OutType>::value, IncompleteType, Job<void>>();
501 Job<
Out,
In ...> &addToContext(
const T &value)
535 template<
typename FirstIn>
536 KAsync::Future<Out> exec(FirstIn in);
551 KAsync::Future<Out> exec();
553 explicit Job(JobContinuation<Out, In ...> &&func);
554 explicit Job(AsyncContinuation<Out, In ...> &&func);
558 explicit Job(Private::ExecutorBasePtr executor);
560 template<
typename OutOther,
typename ... InOther>
561 Job<OutOther,
In ...> thenImpl(Private::ContinuationHolder<OutOther, InOther ...> helper,
562 Private::ExecutionFlag execFlag = Private::ExecutionFlag::GoodCase)
const;
564 template<
typename InOther,
typename ... InOtherTail>
565 void thenInvariants()
const;
568 template<
typename ... InOther>
569 auto thenInvariants() const -> std::enable_if_t<(sizeof...(InOther) == 0)>;
571 template<typename OutOther>
572 void eachInvariants() const;
Q_SCRIPTABLE Q_NOREPLY void start()
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
void forEach(const typename Trait::template Vector< ItemType > &types, std::shared_ptr< Document< Trait > > doc, ItemFunctor< Trait > func, unsigned int maxNestingLevel=0)
QVariant fromValue(T &&value)