• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2021 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MINDSPORE_CORE_MINDRT_INCLUDE_ASYNC_DEFER_H
18 #define MINDSPORE_CORE_MINDRT_INCLUDE_ASYNC_DEFER_H
19 
20 #include <functional>
21 
22 #include "async/async.h"
23 #include "async/option.h"
24 
25 namespace mindspore {
26 
27 template <typename F>
28 class Deferred : public std::function<F> {
29  public:
~Deferred()30   virtual ~Deferred() {}
31 
32  private:
33   template <typename G>
34   friend class internal::DeferredHelper;
35 
36   template <typename T>
37   friend Deferred<void()> Defer(const AID &aid, void (T::*method)());
38 
39   template <typename R, typename T>
40   friend Deferred<Future<R>()> Defer(const AID &aid, Future<R> (T::*method)());
41 
42   template <typename R, typename T>
43   friend Deferred<Future<R>()> Defer(const AID &aid, R (T::*method)());
44 
Deferred(const std::function<F> & f)45   Deferred(const std::function<F> &f) : std::function<F>(f) {}
46 };
47 
48 namespace internal {
49 
50 template <typename F>
51 class DeferredHelper {
52  public:
DeferredHelper(const AID & id,F && function)53   DeferredHelper(const AID &id, F &&function) : aid(id), f(std::forward<F>(function)) {}
54 
DeferredHelper(F && function)55   DeferredHelper(F &&function) : f(std::forward<F>(function)) {}
56 
~DeferredHelper()57   ~DeferredHelper() {}
58 
59   operator Deferred<void()>() && {
60     if (aid.IsNone()) {
61       return std::function<void()>(std::forward<F>(f));
62     }
63 
64     Option<AID> optionAid = aid;
65     F &&function = std::forward<F>(f);
66 
67     return std::function<void()>([=]() { Async(optionAid.Get(), function); });
68   }
69 
70   operator std::function<void()>() && {
71     if (aid.IsNone()) {
72       return std::function<void()>(std::forward<F>(f));
73     }
74 
75     Option<AID> optionAid = aid;
76     F &&function = std::forward<F>(f);
77 
78     return std::function<void()>([=]() { Async(optionAid.Get(), function); });
79   }
80 
81   template <typename R>
82   operator Deferred<R()>() && {
83     if (aid.IsNone()) {
84       return std::function<R()>(std::forward<F>(f));
85     }
86 
87     Option<AID> optionAid = aid;
88     F &&function = std::forward<F>(f);
89 
90     return std::function<R()>([=]() { return Async(optionAid.Get(), function); });
91   }
92 
93   template <typename R>
94   operator std::function<R()>() && {
95     if (aid.IsNone()) {
96       return std::function<R()>(std::forward<F>(f));
97     }
98 
99     Option<AID> optionAid = aid;
100     F &&function = std::forward<F>(f);
101 
102     return std::function<R()>([=]() { return Async(optionAid.Get(), function); });
103   }
104 
105   template <typename Arg>
106   operator Deferred<void(Arg)>() && {
107     if (aid.IsNone()) {
108       return std::function<void(Arg)>(std::forward<F>(f));
109     }
110 
111     Option<AID> optionAid = aid;
112     F &&function = std::forward<F>(f);
113 
114     return std::function<void(Arg)>([=](Arg arg) {
115       std::function<void()> handler([=]() { function(arg); });
116       Async(optionAid.Get(), handler);
117     });
118   }
119 
120   template <typename Arg>
121   operator std::function<void(Arg)>() && {
122     if (aid.IsNone()) {
123       return std::function<void(Arg)>(std::forward<F>(f));
124     }
125 
126     Option<AID> optionAid = aid;
127     F &&function = std::forward<F>(f);
128 
129     return std::function<void(Arg)>([=](Arg arg) {
130       std::function<void()> handler([=]() { function(arg); });
131       Async(optionAid.Get(), handler);
132     });
133   }
134 
135   template <typename... Args>
136   operator Deferred<void(Args...)>() && {
137     if (aid.IsNone()) {
138       return std::function<void(Args...)>(std::forward<F>(f));
139     }
140 
141     Option<AID> optionAid = aid;
142     F &&function = std::forward<F>(f);
143 
144     return std::function<void(Args...)>([=](Args... args) {
145       auto tuple = std::make_tuple(std::forward<Args>(args)...);
146       std::function<void()> handler([=]() { Apply(function, tuple); });
147       Async(optionAid.Get(), handler);
148     });
149   }
150 
151   template <typename... Args>
152   operator std::function<void(Args...)>() && {
153     if (aid.IsNone()) {
154       return std::function<void(Args...)>(std::forward<F>(f));
155     }
156 
157     Option<AID> optionAid = aid;
158     F &&function = std::forward<F>(f);
159 
160     return std::function<void(Args...)>([=](Args... args) {
161       auto tuple = std::make_tuple(std::forward<Args>(args)...);
162       std::function<void()> handler([=]() { Apply(function, tuple); });
163       Async(optionAid.Get(), handler);
164     });
165   }
166 
167   template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type = 0, typename Arg>
168   operator Deferred<R(Arg)>() && {
169     if (aid.IsNone()) {
170       return std::function<R(Arg)>(std::forward<F>(f));
171     }
172 
173     Option<AID> optionAid = aid;
174     F &&function = std::forward<F>(f);
175 
176     return std::function<R(Arg)>([=](Arg arg) {
177       std::function<R()> handler([=]() { return function(arg); });
178       return Async(optionAid.Get(), handler);
179     });
180   }
181 
182   template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type = 0, typename Arg>
183   operator std::function<R(Arg)>() && {
184     if (aid.IsNone()) {
185       return std::function<R(Arg)>(std::forward<F>(f));
186     }
187 
188     Option<AID> optionAid = aid;
189     F &&function = std::forward<F>(f);
190 
191     return std::function<R(Arg)>([=](Arg arg) {
192       std::function<R()> handler([=]() { return function(arg); });
193       return Async(optionAid.Get(), handler);
194     });
195   }
196 
197   template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type = 0, typename... Args>
198   operator Deferred<R(Args...)>() && {
199     if (aid.IsNone()) {
200       return std::function<R(Args...)>(std::forward<F>(f));
201     }
202 
203     Option<AID> optionAid = aid;
204     F &&function = std::forward<F>(f);
205 
206     return std::function<R(Args...)>([=](Args... args) {
207       auto tuple = std::make_tuple(std::forward<Args>(args)...);
208       std::function<R()> handler([=]() { return Apply(function, tuple); });
209       return Async(optionAid.Get(), handler);
210     });
211   }
212 
213   template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type = 0, typename... Args>
214   operator std::function<R(Args...)>() && {
215     if (aid.IsNone()) {
216       return std::function<R(Args...)>(std::forward<F>(f));
217     }
218 
219     Option<AID> optionAid = aid;
220     F &&function = std::forward<F>(f);
221 
222     return std::function<R(Args...)>([=](Args... args) {
223       auto tuple = std::make_tuple(std::forward<Args>(args)...);
224       std::function<R()> handler([=]() { return Apply(function, tuple); });
225       return Async(optionAid.Get(), handler);
226     });
227   }
228 
229  private:
230   template <typename G>
231   friend DeferredHelper<G> Defer(const AID &aid, G &&g);
232 
233   Option<AID> aid;
234   F f;
235 };
236 
237 }  // namespace internal
238 
239 template <typename F>
Defer(const AID & aid,F && f)240 internal::DeferredHelper<F> Defer(const AID &aid, F &&f) {
241   return internal::DeferredHelper<F>(aid, std::forward<F>(f));
242 }
243 
244 template <typename T>
Defer(const AID & aid,void (T::* method)())245 Deferred<void()> Defer(const AID &aid, void (T::*method)()) {
246   return Deferred<void()>([=]() { Async(aid, method); });
247 }
248 
249 template <typename R, typename T>
Defer(const AID & aid,Future<R> (T::* method)())250 Deferred<Future<R>()> Defer(const AID &aid, Future<R> (T::*method)()) {
251   return Deferred<Future<R>()>([=]() { return Async(aid, method); });
252 }
253 
254 template <typename R, typename T>
Defer(const AID & aid,R (T::* method)())255 Deferred<Future<R>()> Defer(const AID &aid, R (T::*method)()) {
256   return Deferred<Future<R>()>([=]() { return Async(aid, method); });
257 }
258 
259 template <typename T, typename... Args0, typename... Args1>
260 auto Defer(T *t, void (T::*method)(Args0...), Args1 &&... args)
261   -> internal::DeferredHelper<decltype(std::bind(&std::function<void(Args0...)>::operator(),
262                                                  std::function<void(Args0...)>(), std::forward<Args1>(args)...))> {
263   std::function<void(Args0...)> f([=](Args0... args0) {
264     if (t != nullptr) {
265       (t->*method)(args0...);
266     }
267   });
268 
269   return std::bind(&std::function<void(Args0...)>::operator(), std::move(f), std::forward<Args1>(args)...);
270 }
271 
272 template <typename T, typename... Args0, typename... Args1>
273 auto Defer(std::shared_ptr<T> t, void (T::*method)(Args0...), Args1 &&... args)
274   -> internal::DeferredHelper<decltype(std::bind(&std::function<void(Args0...)>::operator(),
275                                                  std::function<void(Args0...)>(), std::forward<Args1>(args)...))> {
276   std::function<void(Args0...)> f([=](Args0... args0) {
277     if (t != nullptr) {
278       (t.get()->*method)(args0...);
279     }
280   });
281 
282   return std::bind(&std::function<void(Args0...)>::operator(), std::move(f), std::forward<Args1>(args)...);
283 }
284 
285 template <typename T, typename... Args0, typename... Args1>
286 auto Defer(const AID &aid, void (T::*method)(Args0...), Args1 &&... args)
287   -> internal::DeferredHelper<decltype(std::bind(&std::function<void(Args0...)>::operator(),
288                                                  std::function<void(Args0...)>(), std::forward<Args1>(args)...))> {
289   std::function<void(Args0...)> f([=](Args0... args0) { Async(aid, method, args0...); });
290 
291   return std::bind(&std::function<void(Args0...)>::operator(), std::move(f), std::forward<Args1>(args)...);
292 }
293 
294 template <typename R, typename T, typename... Args0, typename... Args1>
295 auto Defer(const AID &aid, Future<R> (T::*method)(Args0...), Args1 &&... args)
296   -> internal::DeferredHelper<decltype(std::bind(&std::function<Future<R>(Args0...)>::operator(),
297                                                  std::function<Future<R>(Args0...)>(), std::forward<Args1>(args)...))> {
298   std::function<Future<R>(Args0...)> f([=](Args0... args0) { return Async(aid, method, args0...); });
299 
300   return std::bind(&std::function<Future<R>(Args0...)>::operator(), std::move(f), std::forward<Args1>(args)...);
301 }
302 
303 template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type = 0,
304           typename std::enable_if<!internal::IsFuture<R>::value, int>::type = 0, typename T, typename... Args0,
305           typename... Args1>
306 auto Defer(const AID &aid, R (T::*method)(Args0...), Args1 &&... args)
307   -> internal::DeferredHelper<decltype(std::bind(&std::function<Future<R>(Args0...)>::operator(),
308                                                  std::function<Future<R>(Args0...)>(), std::forward<Args1>(args)...))> {
309   std::function<Future<R>(Args0...)> f([=](Args0... args0) { return Async(aid, method, args0...); });
310 
311   return std::bind(&std::function<Future<R>(Args0...)>::operator(), std::move(f), std::forward<Args1>(args)...);
312 }
313 
314 }  // namespace mindspore
315 
316 #endif
317