From 1d946c166cc7a4a2556e8bfaab7dc66695b555e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Mon, 30 Mar 2015 15:47:45 +0200 Subject: Async: allow consumer continuation without arguments It is now possible to chain a job that takes no arguments after a job that returns void. Unfortunatelly it is not yet possible to disregard return value of a previous job. --- async/src/async.h | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'async/src') diff --git a/async/src/async.h b/async/src/async.h index 8296fbc..2be1260 100644 --- a/async/src/async.h +++ b/async/src/async.h @@ -150,7 +150,10 @@ class SyncThenExecutor : public Executor::type, public: SyncThenExecutor(SyncThenTask then, ErrorHandler errorHandler, const ExecutorBasePtr &parent); void previousFutureReady(); + private: + void run(std::false_type); // !std::is_void + void run(std::true_type); // std::is_void SyncThenTask mFunc; }; @@ -170,6 +173,8 @@ public: SyncEachExecutor(SyncEachTask each, ErrorHandler errorHandler, const ExecutorBasePtr &parent); void previousFutureReady(); private: + void run(Async::Future *future, const typename PrevOut::value_type &arg, std::false_type); // !std::is_void + void run(Async::Future *future, const typename PrevOut::value_type &arg, std::true_type); // std::is_void SyncEachTask mFunc; }; @@ -386,8 +391,8 @@ private: { static_assert(detail::isIterable::value, "The 'Each' task can only be connected to a job that returns a list or an array."); - static_assert(detail::isIterable::value, - "The result type of 'Each' task must be a list or an array."); + static_assert(std::is_void::value || detail::isIterable::value, + "The result type of 'Each' task must be void, a list or an array."); } template @@ -603,9 +608,21 @@ void SyncThenExecutor::previousFutureReady() assert(this->mPrevFuture->isFinished()); } + run(std::is_void()); + this->mResult->setFinished(); +} + +template +void SyncThenExecutor::run(std::false_type) +{ Out result = this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ...); static_cast*>(this->mResult)->setValue(result); - this->mResult->setFinished(); +} + +template +void SyncThenExecutor::run(std::true_type) +{ + this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ...); } template @@ -626,11 +643,23 @@ void SyncEachExecutor::previousFutureReady() } for (auto arg : this->mPrevFuture->value()) { - out->setValue(out->value() + this->mFunc(arg)); + run(out, arg, std::is_void()); } out->setFinished(); } +template +void SyncEachExecutor::run(Async::Future *out, const typename PrevOut::value_type &arg, std::false_type) +{ + out->setValue(out->value() + this->mFunc(arg)); +} + +template +void SyncEachExecutor::run(Async::Future * /* unushed */, const typename PrevOut::value_type &arg, std::true_type) +{ + this->mFunc(arg); +} + template SyncReduceExecutor::SyncReduceExecutor(SyncReduceTask reduce, ErrorHandler errorHandler, const ExecutorBasePtr &parent) : SyncThenExecutor(reduce, errorHandler, parent) -- cgit v1.2.3