diff options
Diffstat (limited to 'async/src/async.h')
-rw-r--r-- | async/src/async.h | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/async/src/async.h b/async/src/async.h index 239927d..182e57c 100644 --- a/async/src/async.h +++ b/async/src/async.h | |||
@@ -39,13 +39,20 @@ class JobBase; | |||
39 | template<typename Out, typename ... In> | 39 | template<typename Out, typename ... In> |
40 | class Job; | 40 | class Job; |
41 | 41 | ||
42 | template<typename Out, typename ... In, typename F> | 42 | template<typename Out, typename ... In> |
43 | Job<Out, In ...> start(F func); | 43 | using ThenTask = typename detail::identity<std::function<void(In ..., Async::Future<Out>&)>>::type; |
44 | template<typename Out, typename In> | ||
45 | using EachTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; | ||
46 | template<typename Out, typename In> | ||
47 | using ReduceTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; | ||
48 | |||
49 | template<typename Out, typename ... In> | ||
50 | Job<Out, In ...> start(ThenTask<Out, In ...> func); | ||
44 | 51 | ||
45 | namespace Private | 52 | namespace Private |
46 | { | 53 | { |
47 | template<typename Out, typename ... In> | 54 | template<typename Out, typename ... In> |
48 | Async::Future<Out>* doExec(Job<Out, In ...> *job, const In & ... args); | 55 | void doExec(Job<Out, In ...> *job, Async::Future<Out> &out, const In & ... args); |
49 | } | 56 | } |
50 | 57 | ||
51 | class JobBase | 58 | class JobBase |
@@ -56,7 +63,8 @@ class JobBase | |||
56 | protected: | 63 | protected: |
57 | enum JobType { | 64 | enum JobType { |
58 | Then, | 65 | Then, |
59 | Each | 66 | Each, |
67 | Reduce | ||
60 | }; | 68 | }; |
61 | 69 | ||
62 | public: | 70 | public: |
@@ -75,8 +83,8 @@ class Job : public JobBase | |||
75 | template<typename Out_, typename ... In_> | 83 | template<typename Out_, typename ... In_> |
76 | friend class Job; | 84 | friend class Job; |
77 | 85 | ||
78 | template<typename Out_, typename ... In_, typename F_> | 86 | template<typename Out_, typename ... In_> |
79 | friend Job<Out_, In_ ...> start(F_ func); | 87 | friend Job<Out_, In_ ...> start(Async::ThenTask<Out_, In_ ...> func); |
80 | 88 | ||
81 | typedef Out OutType; | 89 | typedef Out OutType; |
82 | typedef typename std::tuple_element<0, std::tuple<In ..., void>>::type InType; | 90 | typedef typename std::tuple_element<0, std::tuple<In ..., void>>::type InType; |
@@ -87,16 +95,28 @@ public: | |||
87 | delete reinterpret_cast<Async::Future<Out>*>(mResult); | 95 | delete reinterpret_cast<Async::Future<Out>*>(mResult); |
88 | } | 96 | } |
89 | 97 | ||
90 | template<typename Out_, typename ... In_, typename F> | 98 | template<typename Out_, typename ... In_> |
91 | Job<Out_, In_ ...> then(F func) | 99 | Job<Out_, In_ ...> then(ThenTask<Out_, In_ ...> func) |
92 | { | 100 | { |
93 | return Job<Out_, In_ ...>::create(func, JobBase::Then, this); | 101 | return Job<Out_, In_ ...>::create(func, JobBase::Then, this); |
94 | } | 102 | } |
95 | 103 | ||
96 | template<typename Out_, typename ... In_, typename F> | 104 | template<typename Out_, typename In_> |
97 | Job<Out_, In_ ...> each(F func) | 105 | Job<Out_, In_> each(EachTask<Out_, In_> func) |
98 | { | 106 | { |
99 | return Job<Out_, In_ ...>::create(func, JobBase::Each, this); | 107 | static_assert(detail::isIterable<OutType>::value, |
108 | "The 'Each' task can only be connected to a job that returns a list or array."); | ||
109 | static_assert(detail::isIterable<Out_>::value, | ||
110 | "The result type of 'Each' task must be a list or an array."); | ||
111 | return Job<Out_, In_>::create(func, JobBase::Each, this); | ||
112 | } | ||
113 | |||
114 | template<typename Out_, typename In_> | ||
115 | Job<Out_, In_> reduce(ReduceTask<Out_, In_> func) | ||
116 | { | ||
117 | static_assert(Async::detail::isIterable<OutType>::value, | ||
118 | "The result type of 'Reduce' task must be a list or an array."); | ||
119 | return Job<Out_, In_>::create(func, JobBase::Reduce, this); | ||
100 | } | 120 | } |
101 | 121 | ||
102 | Async::Future<Out> result() const | 122 | Async::Future<Out> result() const |
@@ -116,7 +136,7 @@ private: | |||
116 | static Job<Out, In ... > create(F func, JobBase::JobType jobType, JobBase *parent = nullptr); | 136 | static Job<Out, In ... > create(F func, JobBase::JobType jobType, JobBase *parent = nullptr); |
117 | 137 | ||
118 | public: | 138 | public: |
119 | std::function<Async::Future<Out>(In ...)> mFunc; | 139 | std::function<void(In ..., Async::Future<Out>&)> mFunc; |
120 | }; | 140 | }; |
121 | 141 | ||
122 | 142 | ||
@@ -126,16 +146,16 @@ public: | |||
126 | 146 | ||
127 | // ********** Out of line definitions **************** | 147 | // ********** Out of line definitions **************** |
128 | 148 | ||
129 | template<typename Out, typename ... In, typename F> | 149 | template<typename Out, typename ... In> |
130 | Async::Job<Out, In ...> Async::start(F func) | 150 | Async::Job<Out, In ...> Async::start(ThenTask<Out, In ...> func) |
131 | { | 151 | { |
132 | return Job<Out, In ...>::create(func, JobBase::Then); | 152 | return Job<Out, In ...>::create(func, JobBase::Then); |
133 | } | 153 | } |
134 | 154 | ||
135 | template<typename Out, typename ... In> | 155 | template<typename Out, typename ... In> |
136 | Async::Future<Out>* Async::Private::doExec(Job<Out, In ...> *job, const In & ... args) | 156 | void Async::Private::doExec(Job<Out, In ...> *job, Async::Future<Out> &out, const In & ... args) |
137 | { | 157 | { |
138 | return new Async::Future<Out>(job->mFunc(args ...)); | 158 | job->mFunc(args ..., out); |
139 | }; | 159 | }; |
140 | 160 | ||
141 | template<typename Out, typename ... In> | 161 | template<typename Out, typename ... In> |
@@ -148,10 +168,10 @@ void Async::Job<Out, In ...>::exec() | |||
148 | assert(in->isFinished()); | 168 | assert(in->isFinished()); |
149 | } | 169 | } |
150 | 170 | ||
151 | Job<Out, In ...> *job = dynamic_cast<Job<Out, In ...>*>(this); | 171 | auto out = new Async::Future<Out>(); |
152 | Async::Future<Out> *out = Private::doExec<Out, In ...>(this, in ? in->value() : In() ...); | 172 | Private::doExec<Out, In ...>(this, *out, in ? in->value() : In() ...); |
153 | out->waitForFinished(); | 173 | out->waitForFinished(); |
154 | job->mResult = reinterpret_cast<void*>(out); | 174 | mResult = reinterpret_cast<void*>(out); |
155 | } | 175 | } |
156 | 176 | ||
157 | template<typename Out, typename ... In> | 177 | template<typename Out, typename ... In> |