Do not remove the trailing slash of URL if has it no path component
[TortoiseGit.git] / src / AsyncFramework / Future.h
blobb3f6a618fe3829b4670c0a137e6fce86f3d745f0
1 /***************************************************************************
2 * Copyright (C) 2009, 2012 by Stefan Fuhrmann *
3 * stefanfuhrmann@alice-dsl.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #pragma once
23 #include "JobBase.h"
25 namespace async
28 /**
29 * Execute a call to a funtion asynchronuously in the background.
30 * Return the result in \ref GetResult. The latter will wait for
31 * the call to finished, if necessary.
33 * Accepts a pointer to some free function or member function plus
34 * parameters and schedules it for execution it in the given job scheduler.
35 * If no scheduler is given, the default scheduler is used (see
36 * \ref CJobScheduler::GetDefault for details).
38 * Please note that the parameters must remain valid until the call
39 * actually got executed. Therefore, only pointer and value parameter
40 * are possible; reference parameters won't compile.
43 template<class R>
44 class CFuture
46 private:
48 class CFuture0 : public CJobBase
50 private:
52 R (*func)();
53 R& result;
55 protected:
57 virtual void InternalExecute() override
59 result = (*func)();
62 public:
64 CFuture0 (R (*func)(), R& result, CJobScheduler* scheduler)
65 : func (func)
66 , result (result)
68 Schedule (false, scheduler);
72 template<class C>
73 class CFutureMember0 : public CJobBase
75 private:
77 C* instance;
78 R (C::*func)();
79 R& result;
81 protected:
83 virtual void InternalExecute() override
85 result = (instance->*func)();
88 public:
90 CFutureMember0 (C* instance, R (C::*func)(), R& result, CJobScheduler* scheduler)
91 : instance (instance)
92 , func (func)
93 , result (result)
95 Schedule (false, scheduler);
99 template<class T1>
100 class CFuture1 : public CJobBase
102 private:
104 T1 parameter1;
105 R (*func)(T1);
106 R& result;
108 protected:
110 virtual void InternalExecute() override
112 result = (*func)(parameter1);
115 public:
117 CFuture1 (R (*func)(T1), R& result, T1 parameter1, CJobScheduler* scheduler)
118 : parameter1 (parameter1)
119 , func (func)
120 , result (result)
122 Schedule (false, scheduler);
126 template<class C, class T1>
127 class CFutureMember1 : public CJobBase
129 private:
131 C* instance;
132 T1 parameter1;
133 R (C::*func)(T1);
134 R& result;
136 protected:
138 virtual void InternalExecute() override
140 result = (instance->*func)(parameter1);
143 public:
145 CFutureMember1 (C* instance, R (C::*func)(T1), R& result, T1 parameter1, CJobScheduler* scheduler)
146 : instance (instance)
147 , parameter1 (parameter1)
148 , func (func)
149 , result (result)
151 Schedule (false, scheduler);
155 template<class T1, class T2>
156 class CFuture2 : public CJobBase
158 private:
160 T1 parameter1;
161 T2 parameter2;
162 R (*func)(T1, T2);
163 R& result;
165 protected:
167 virtual void InternalExecute() override
169 result = (*func)(parameter1, parameter2);
172 public:
174 CFuture2 (R (*func)(T1, T2), R& result, T1 parameter1, T2 parameter2, CJobScheduler* scheduler)
175 : parameter1 (parameter1)
176 , parameter2 (parameter2)
177 , func (func)
178 , result (result)
180 Schedule (false, scheduler);
184 template<class C, class T1, class T2>
185 class CFutureMember2 : public CJobBase
187 private:
189 C* instance;
190 T1 parameter1;
191 T2 parameter2;
192 R (C::*func)(T1, T2);
193 R& result;
195 protected:
197 virtual void InternalExecute() override
199 result = (instance->*func)(parameter1, parameter2);
202 public:
204 CFutureMember2 (C* instance, R (C::*func)(T1, T2), R& result, T1 parameter1, T2 parameter2, CJobScheduler* scheduler)
205 : instance (instance)
206 , parameter1 (parameter1)
207 , parameter2 (parameter2)
208 , func (func)
209 , result (result)
211 Schedule (false, scheduler);
215 template<class T1, class T2, class T3>
216 class CFuture3 : public CJobBase
218 private:
220 T1 parameter1;
221 T2 parameter2;
222 T3 parameter3;
223 R (*func)(T1, T2, T3);
224 R& result;
226 protected:
228 virtual void InternalExecute() override
230 result = (*func)(parameter1, parameter2, parameter3);
233 public:
235 CFuture3 (R (*func)(T1, T2, T3), R& result, T1 parameter1, T2 parameter2, T3 parameter3, CJobScheduler* scheduler)
236 : parameter1 (parameter1)
237 , parameter2 (parameter2)
238 , parameter3 (parameter3)
239 , func (func)
240 , result (result)
242 Schedule (false, scheduler);
246 template<class C, class T1, class T2, class T3>
247 class CFutureMember3 : public CJobBase
249 private:
251 C* instance;
252 T1 parameter1;
253 T2 parameter2;
254 T3 parameter3;
255 R (C::*func)(T1, T2, T3);
256 R& result;
258 protected:
260 virtual void InternalExecute() override
262 result = (instance->*func)(parameter1, parameter2, parameter3);
265 public:
267 CFutureMember3 (C* instance, R (C::*func)(T1, T2, T3), R& result, T1 parameter1, T2 parameter2, T3 parameter3, CJobScheduler* scheduler)
268 : instance (instance)
269 , parameter1 (parameter1)
270 , parameter2 (parameter2)
271 , parameter3 (parameter3)
272 , func (func)
273 , result (result)
275 Schedule (false, scheduler);
279 // result and actual "future"
281 R result;
282 CJobBase* job;
284 public:
286 // construct futures for all sorts of callable items
288 CFuture (R (*func)(), CJobScheduler* scheduler = NULL)
289 : job (NULL)
291 job = new CFuture0(func, result, scheduler);
294 template<class C>
295 CFuture (C* instance, R (C::*func)(), CJobScheduler* scheduler = NULL)
296 : job (NULL)
298 job = new CFutureMember0<C>(instance, func, result, scheduler);
301 template<class T1>
302 CFuture (R (*func)(T1), T1 parameter1, CJobScheduler* scheduler = NULL)
303 : job (NULL)
305 job = new CFuture1<T1>(func, result, parameter1, scheduler);
308 template<class C, class T1>
309 CFuture (C* instance, R (C::*func)(T1), T1 parameter1, CJobScheduler* scheduler = NULL)
310 : job (NULL)
312 job = new CFutureMember1<C, T1>(instance, func, result, parameter1, scheduler);
315 template<class T1, class T2>
316 CFuture (R (*func)(T1, T2), T1 parameter1, T2 parameter2, CJobScheduler* scheduler = NULL)
317 : job (NULL)
319 job = new CFuture2<T1, T2>
320 (func, result, parameter1, parameter2, scheduler);
323 template<class C, class T1, class T2>
324 CFuture (C* instance, R (C::*func)(T1, T2), T1 parameter1, T2 parameter2, CJobScheduler* scheduler = NULL)
325 : job (NULL)
327 job = new CFutureMember2<C, T1, T2>
328 (instance, func, result, parameter1, parameter2, scheduler);
331 template<class T1, class T2, class T3>
332 CFuture (R (*func)(T1, T2, T3), T1 parameter1, T2 parameter2, T3 parameter3, CJobScheduler* scheduler = NULL)
333 : job (NULL)
335 job = new CFuture3<T1, T2, T3>
336 (func, result, parameter1, parameter2, parameter3, scheduler);
339 template<class C, class T1, class T2, class T3>
340 CFuture (C* instance, R (C::*func)(T1, T2, T3), T1 parameter1, T2 parameter2, T3 parameter3, CJobScheduler* scheduler = NULL)
341 : job (NULL)
343 job = new CFutureMember3<C, T1, T2, T3>
344 (instance, func, result, parameter1, parameter2, parameter3, scheduler);
347 // cleanup
349 ~CFuture()
351 job->Delete (true);
354 // ensure the function has returned and pass the result back to the caller
356 const R& GetResult() const
358 job->WaitUntilDone();
359 return result;
362 bool IsDone() const
364 return job->GetStatus() == IJob::done;