summaryrefslogtreecommitdiffstats
path: root/async/src/async.h
diff options
context:
space:
mode:
authorDan Vrátil <dvratil@redhat.com>2014-12-11 11:07:04 +0100
committerDan Vrátil <dvratil@redhat.com>2014-12-11 11:07:20 +0100
commit67d47d893bc582fbd06da8bd93a1c416fa314ca6 (patch)
treea30004b1c974baef1a700f6647eae2cf43e9f06b /async/src/async.h
parent0fc8477dec805f943e829a662a9e42337ce628ab (diff)
downloadsink-67d47d893bc582fbd06da8bd93a1c416fa314ca6.tar.gz
sink-67d47d893bc582fbd06da8bd93a1c416fa314ca6.zip
Prototype of Async library
Diffstat (limited to 'async/src/async.h')
-rw-r--r--async/src/async.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/async/src/async.h b/async/src/async.h
new file mode 100644
index 0000000..790dfe9
--- /dev/null
+++ b/async/src/async.h
@@ -0,0 +1,158 @@
1/*
2 * Copyright 2014 Daniel Vrátil <dvratil@redhat.com>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License or (at your option) version 3 or any later version
8 * accepted by the membership of KDE e.V. (or its successor approved
9 * by the membership of KDE e.V.), which shall act as a proxy
10 * defined in Section 14 of version 3 of the license.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef ASYNC_H
23#define ASYNC_H
24
25#include <functional>
26#include <list>
27#include <type_traits>
28#include <iostream>
29#include <cassert>
30
31#include "future.h"
32#include "async_impl.h"
33
34
35namespace Async {
36
37template<typename Out, typename ... In>
38class Job;
39
40template<typename Out, typename ... In>
41Job<Out, In ...> start(const std::function<Async::Future<Out>(In ...)> &func);
42
43
44class JobBase
45{
46public:
47 JobBase(JobBase *prev = nullptr)
48 : mPrev(prev)
49 , mResult(0)
50 {}
51
52 virtual void exec() = 0;
53
54public:
55 JobBase *mPrev;
56 void *mResult;
57};
58
59namespace Private {
60
61 template<typename Out, typename In>
62 typename std::enable_if<!std::is_void<In>::value, void>::type
63 doExec(JobBase *prev, JobBase *jobBase);
64
65 template<typename Out, typename ... In>
66 typename std::enable_if<sizeof...(In) == 0, void>::type
67 doExec(JobBase *prev, JobBase *jobBase, int * /* disambiguate */ = 0);
68}
69
70template<typename Out, typename ... In>
71class Job : public JobBase
72{
73 template<typename Out_, typename ... In_>
74 friend class Job;
75
76 template<typename Out_, typename ... In_, typename F_>
77 friend Job<Out_, In_ ...> start(F_ func);
78
79public:
80 ~Job()
81 {
82 // Can't delete in JobBase, since we don't know the type
83 // and deleting void* is undefined
84 delete reinterpret_cast<Async::Future<Out>*>(mResult);
85 }
86
87 template<typename Out_, typename ... In_, typename F>
88 Job<Out_, In_ ...> then(F func)
89 {
90 Job<Out_, In_ ...> job(this);
91 job.mFunc = func;
92 return job;
93 }
94
95 Async::Future<Out> result() const
96 {
97 return *reinterpret_cast<Async::Future<Out>*>(mResult);
98 }
99
100
101 void exec()
102 {
103 Async::Private::doExec<Out, In ...>(mPrev, this);
104 }
105
106private:
107 Job(JobBase *parent = nullptr)
108 : JobBase(parent)
109 {}
110
111public:
112 std::function<Async::Future<Out>(In ...)> mFunc;
113};
114
115template<typename Out, typename ... In, typename F>
116Job<Out, In ...> start(F func)
117{
118 Job<Out, In ...> job;
119 job.mFunc = std::function<Async::Future<Out>(In ...)>(func);
120 return job;
121}
122
123} // namespace Async
124
125template<typename Out, typename In>
126typename std::enable_if<!std::is_void<In>::value, void>::type
127Async::Private::doExec(JobBase *prev, JobBase *jobBase)
128{
129 prev->exec();
130 Async::Future<In> *in = reinterpret_cast<Async::Future<In>*>(prev->mResult);
131 assert(in->isFinished());
132
133 Job<Out, In> *job = dynamic_cast<Job<Out, In>*>(jobBase);
134 Async::Future<Out> *out = new Async::Future<Out>(job->mFunc(in->value()));
135 out->waitForFinished();
136 job->mResult = reinterpret_cast<void*>(out);
137};
138
139template<typename Out, typename ... In>
140typename std::enable_if<sizeof...(In) == 0, void>::type
141Async::Private::doExec(JobBase *prev, JobBase *jobBase, int * /* disambiguation */ = 0)
142{
143 if (prev) {
144 prev->exec();
145 Async::Future<void> *in = reinterpret_cast<Async::Future<void>*>(prev->mResult);
146 assert(in->isFinished());
147 }
148
149 Job<Out> *job = dynamic_cast<Job<Out>*>(jobBase);
150 Async::Future<Out> *out = new Async::Future<Out>(job->mFunc());
151 out->waitForFinished();
152 job->mResult = reinterpret_cast<void*>(out);
153};
154
155
156#endif // ASYNC_H
157
158