summaryrefslogtreecommitdiffstats
path: root/async/src
diff options
context:
space:
mode:
Diffstat (limited to 'async/src')
-rw-r--r--async/src/async.h35
-rw-r--r--async/src/async_impl.h15
2 files changed, 50 insertions, 0 deletions
diff --git a/async/src/async.h b/async/src/async.h
index 386722a..d21caf8 100644
--- a/async/src/async.h
+++ b/async/src/async.h
@@ -291,6 +291,12 @@ public:
291 new Private::SyncThenExecutor<OutOther, InOther ...>(func, errorFunc, mExecutor))); 291 new Private::SyncThenExecutor<OutOther, InOther ...>(func, errorFunc, mExecutor)));
292 } 292 }
293 293
294 template<typename OutOther, typename ... InOther>
295 Job<OutOther, InOther ...> then(Job<OutOther, InOther ...> otherJob, ErrorHandler errorFunc = ErrorHandler())
296 {
297 return then<OutOther, InOther ...>(nestedJobWrapper<OutOther, InOther ...>(otherJob), errorFunc);
298 }
299
294 template<typename OutOther, typename InOther> 300 template<typename OutOther, typename InOther>
295 Job<OutOther, InOther> each(EachTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) 301 Job<OutOther, InOther> each(EachTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler())
296 { 302 {
@@ -308,6 +314,13 @@ public:
308 } 314 }
309 315
310 template<typename OutOther, typename InOther> 316 template<typename OutOther, typename InOther>
317 Job<OutOther, InOther> each(Job<OutOther, InOther> otherJob, ErrorHandler errorFunc = ErrorHandler())
318 {
319 eachInvariants<OutOther>();
320 return each<OutOther, InOther>(nestedJobWrapper<OutOther, InOther>(otherJob), errorFunc);
321 }
322
323 template<typename OutOther, typename InOther>
311 Job<OutOther, InOther> reduce(ReduceTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) 324 Job<OutOther, InOther> reduce(ReduceTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler())
312 { 325 {
313 reduceInvariants<InOther>(); 326 reduceInvariants<InOther>();
@@ -323,6 +336,12 @@ public:
323 new Private::SyncReduceExecutor<OutOther, InOther>(func, errorFunc, mExecutor))); 336 new Private::SyncReduceExecutor<OutOther, InOther>(func, errorFunc, mExecutor)));
324 } 337 }
325 338
339 template<typename OutOther, typename InOther>
340 Job<OutOther, InOther> reduce(Job<OutOther, InOther> otherJob, ErrorHandler errorFunc = ErrorHandler())
341 {
342 return reduce<OutOther, InOther>(nestedJobWrapper<OutOther, InOther>(otherJob), errorFunc);
343 }
344
326 template<typename FirstIn> 345 template<typename FirstIn>
327 Async::Future<Out> exec(FirstIn in) 346 Async::Future<Out> exec(FirstIn in)
328 { 347 {
@@ -377,6 +396,22 @@ private:
377 static_assert(std::is_same<typename Out::value_type, typename InOther::value_type>::value, 396 static_assert(std::is_same<typename Out::value_type, typename InOther::value_type>::value,
378 "The return type of previous task must be compatible with input type of this task"); 397 "The return type of previous task must be compatible with input type of this task");
379 } 398 }
399
400 template<typename OutOther, typename ... InOther>
401 inline std::function<void(InOther ..., Async::Future<OutOther>&)> nestedJobWrapper(Job<OutOther, InOther ...> otherJob) {
402 return [otherJob](InOther ... in, Async::Future<OutOther> &future) {
403 // copy by value is const
404 auto job = otherJob;
405 FutureWatcher<OutOther> *watcher = new FutureWatcher<OutOther>();
406 QObject::connect(watcher, &FutureWatcherBase::futureReady,
407 [watcher, &future]() {
408 Async::detail::copyFutureValue(watcher->future(), future);
409 future.setFinished();
410 watcher->deleteLater();
411 });
412 watcher->setFuture(job.exec(in ...));
413 };
414 }
380}; 415};
381 416
382} // namespace Async 417} // namespace Async
diff --git a/async/src/async_impl.h b/async/src/async_impl.h
index 58f6ced..eccbc9b 100644
--- a/async/src/async_impl.h
+++ b/async/src/async_impl.h
@@ -19,6 +19,7 @@
19#define ASYNC_IMPL_H 19#define ASYNC_IMPL_H
20 20
21#include "async.h" 21#include "async.h"
22#include <type_traits>
22 23
23namespace Async { 24namespace Async {
24 25
@@ -45,6 +46,20 @@ struct prevOut {
45 using type = typename std::tuple_element<0, std::tuple<T ..., void>>::type; 46 using type = typename std::tuple_element<0, std::tuple<T ..., void>>::type;
46}; 47};
47 48
49template<typename T>
50inline typename std::enable_if<!std::is_void<T>::value, void>::type
51copyFutureValue(const Async::Future<T> &in, Async::Future<T> &out)
52{
53 out.setValue(in.value());
54}
55
56template<typename T>
57inline typename std::enable_if<std::is_void<T>::value, void>::type
58copyFutureValue(const Async::Future<T> &in, Async::Future<T> &out)
59{
60 // noop
61}
62
48} // namespace Detail 63} // namespace Detail
49 64
50} // namespace Async 65} // namespace Async