diff options
Diffstat (limited to 'async/src')
-rw-r--r-- | async/src/async.h | 35 | ||||
-rw-r--r-- | async/src/async_impl.h | 15 |
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 | ||
23 | namespace Async { | 24 | namespace 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 | ||
49 | template<typename T> | ||
50 | inline typename std::enable_if<!std::is_void<T>::value, void>::type | ||
51 | copyFutureValue(const Async::Future<T> &in, Async::Future<T> &out) | ||
52 | { | ||
53 | out.setValue(in.value()); | ||
54 | } | ||
55 | |||
56 | template<typename T> | ||
57 | inline typename std::enable_if<std::is_void<T>::value, void>::type | ||
58 | copyFutureValue(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 |