From 5b8b8e4e0471ea904388b3b9c8efd597f9daebea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Thu, 11 Dec 2014 18:53:38 +0100 Subject: Async: move some more code out-of-line --- async/src/.async.h.kate-swp | Bin 0 -> 238 bytes async/src/async.cpp | 14 +++- async/src/async.h | 196 ++++++++++++++++++++++++-------------------- 3 files changed, 121 insertions(+), 89 deletions(-) create mode 100644 async/src/.async.h.kate-swp (limited to 'async/src') diff --git a/async/src/.async.h.kate-swp b/async/src/.async.h.kate-swp new file mode 100644 index 0000000..82f3ca1 Binary files /dev/null and b/async/src/.async.h.kate-swp differ diff --git a/async/src/async.cpp b/async/src/async.cpp index 16da384..0b8d7f3 100644 --- a/async/src/async.cpp +++ b/async/src/async.cpp @@ -28,7 +28,19 @@ using namespace Async; -JobBase::JobBase(ExecutorBase *executor) +Private::ExecutorBase::ExecutorBase(ExecutorBase* parent) + : mPrev(parent) + , mResult(0) +{ +} + +Private::ExecutorBase::~ExecutorBase() +{ + delete mResult; +} + + +JobBase::JobBase(Private::ExecutorBase *executor) : mExecutor(executor) { } diff --git a/async/src/async.h b/async/src/async.h index 52d0570..66e455c 100644 --- a/async/src/async.h +++ b/async/src/async.h @@ -51,39 +51,30 @@ using EachTask = typename detail::identity using ReduceTask = typename detail::identity&)>>::type; -template -Job start(ThenTask func); +namespace Private +{ template struct PreviousOut { using type = typename std::tuple_element<0, std::tuple>::type; }; - class ExecutorBase { template friend class Executor; public: - virtual ~ExecutorBase() - { - delete mResult; - } - + virtual ~ExecutorBase(); virtual void exec() = 0; - FutureBase* result() const + inline FutureBase* result() const { return mResult; } protected: - ExecutorBase(ExecutorBase *parent) - : mPrev(parent) - , mResult(0) - { - } + ExecutorBase(ExecutorBase *parent); ExecutorBase *mPrev; FutureBase *mResult; @@ -95,20 +86,9 @@ class Executor : public ExecutorBase protected: Executor(ExecutorBase *parent) : ExecutorBase(parent) - { - } - - Async::Future* chainup() - { - if (mPrev) { - mPrev->exec(); - auto future = static_cast*>(mPrev->result()); - assert(future->isFinished()); - return future; - } else { - return 0; - } - } + {} + virtual ~Executor() {} + inline Async::Future* chainup(); std::function &)> mFunc; }; @@ -117,72 +97,28 @@ template class ThenExecutor: public Executor::type, Out, In ...> { public: - ThenExecutor(ThenTask then, ExecutorBase *parent = nullptr) - : Executor::type, Out, In ...>(parent) - { - this->mFunc = then; - } - - void exec() - { - auto in = this->chainup(); - (void)in; // supress 'unused variable' warning when In is void - - auto out = new Async::Future(); - this->mFunc(in ? in->value() : In() ..., *out); - out->waitForFinished(); - this->mResult = out; - } + ThenExecutor(ThenTask then, ExecutorBase *parent = nullptr); + void exec(); }; template class EachExecutor : public Executor { public: - EachExecutor(EachTask each, ExecutorBase *parent) - : Executor(parent) - { - this->mFunc = each; - } - - void exec() - { - auto in = this->chainup(); - - auto *out = new Async::Future(); - for (auto arg : in->value()) { - Async::Future future; - this->mFunc(arg, future); - future.waitForFinished(); - out->setValue(out->value() + future.value()); - } - out->setFinished(); - - this->mResult = out; - } + EachExecutor(EachTask each, ExecutorBase *parent); + void exec(); }; template class ReduceExecutor : public Executor { public: - ReduceExecutor(ReduceTask reduce, ExecutorBase *parent) - : Executor(parent) - { - this->mFunc = reduce; - } - - void exec() - { - auto in = this->chainup(); - - auto out = new Async::Future(); - this->mFunc(in->value(), *out); - out->waitForFinished(); - this->mResult = out; - } + ReduceExecutor(ReduceTask reduce, ExecutorBase *parent); + void exec(); }; +} // namespace Private + class JobBase { @@ -190,13 +126,13 @@ class JobBase friend class Job; public: - JobBase(ExecutorBase *executor); + JobBase(Private::ExecutorBase *executor); ~JobBase(); void exec(); protected: - ExecutorBase *mExecutor; + Private::ExecutorBase *mExecutor; }; template @@ -212,7 +148,7 @@ public: template Job then(ThenTask func) { - return Job(new ThenExecutor(func, mExecutor)); + return Job(new Private::ThenExecutor(func, mExecutor)); } template @@ -222,7 +158,7 @@ public: "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."); - return Job(new EachExecutor(func, mExecutor)); + return Job(new Private::EachExecutor(func, mExecutor)); } template @@ -232,7 +168,7 @@ public: "The 'Result' task can only be connected to a job that returns a list or an array"); static_assert(std::is_same::value, "The return type of previous task must be compatible with input type of this task"); - return Job(new ReduceExecutor(func, mExecutor)); + return Job(new Private::ReduceExecutor(func, mExecutor)); } Async::Future result() const @@ -241,7 +177,7 @@ public: } private: - Job(ExecutorBase *executor) + Job(Private::ExecutorBase *executor) : JobBase(executor) { } @@ -252,12 +188,96 @@ private: // ********** Out of line definitions **************** +namespace Async { + template -Async::Job Async::start(ThenTask func) +Job start(ThenTask func) { - return Job(new ThenExecutor(func)); + return Job(new Private::ThenExecutor(func)); } +namespace Private { + +template +Future* Executor::chainup() +{ + if (mPrev) { + mPrev->exec(); + auto future = static_cast*>(mPrev->result()); + assert(future->isFinished()); + return future; + } else { + return 0; + } +} + +template +ThenExecutor::ThenExecutor(ThenTask then, ExecutorBase* parent) + : Executor::type, Out, In ...>(parent) +{ + this->mFunc = then; +} + +template +void ThenExecutor::exec() +{ + auto in = this->chainup(); + (void)in; // supress 'unused variable' warning when In is void + + auto out = new Async::Future(); + this->mFunc(in ? in->value() : In() ..., *out); + out->waitForFinished(); + this->mResult = out; +} + +template +EachExecutor::EachExecutor(EachTask each, ExecutorBase* parent) + : Executor(parent) +{ + this->mFunc = each; +} + +template +void EachExecutor::exec() +{ + auto in = this->chainup(); + + auto *out = new Async::Future(); + for (auto arg : in->value()) { + Async::Future future; + this->mFunc(arg, future); + future.waitForFinished(); + out->setValue(out->value() + future.value()); + } + out->setFinished(); + + this->mResult = out; +} + +template +ReduceExecutor::ReduceExecutor(ReduceTask reduce, ExecutorBase* parent) + : Executor(parent) +{ + this->mFunc = reduce; +} + +template +void ReduceExecutor::exec() +{ + auto in = this->chainup(); + + auto out = new Async::Future(); + this->mFunc(in->value(), *out); + out->waitForFinished(); + this->mResult = out; +} + +} // namespace Private + +} // namespace Async + + + #endif // ASYNC_H -- cgit v1.2.3