1
1
#pragma once
2
2
3
3
#include " _awaker.h"
4
+ #if RESUMEF_USE_BOOST_ANY
5
+ #include < boost/any.hpp>
6
+ namespace resumef
7
+ {
8
+ using any_t = boost::any;
9
+ using boost::any_cast;
10
+ }
11
+ #else
4
12
#include < any>
13
+ namespace resumef
14
+ {
15
+ using any_t = std::any;
16
+ using std::any_cast;
17
+ }
18
+ #endif
5
19
6
20
// 纠结过when_any的返回值,是选用index + std::any,还是选用std::variant<>。最终选择了std::any。
7
21
// std::variant<>存在第一个元素不能默认构造的问题,需要使用std::monostate来占位,导致下标不是从0开始。
@@ -97,16 +111,34 @@ namespace resumef
97
111
98
112
inline future_vt operator ()() const
99
113
{
100
- if constexpr (std::is_same_v<future_type, future_vt>)
101
- {
102
- co_await _f;
103
- _val.get () = std::ignore;
104
- }
105
- else
106
- {
107
- _val.get () = co_await _f;
108
- }
114
+ _val.get () = co_await _f;
115
+ _e->signal ();
116
+ }
117
+ };
109
118
119
+ template <class _Ty >
120
+ struct when_all_functor <future_vt, _Ty>
121
+ {
122
+ using value_type = _Ty;
123
+ using future_type = future_vt;
124
+
125
+ when_impl_ptr _e;
126
+ mutable future_type _f;
127
+ mutable std::reference_wrapper<value_type> _val;
128
+
129
+ when_all_functor (const detail::when_impl_ptr & e, future_type f, value_type & v)
130
+ : _e(e)
131
+ , _f(std::move(f))
132
+ , _val(v)
133
+ {}
134
+ when_all_functor (when_all_functor &&) noexcept = default ;
135
+ when_all_functor & operator = (const when_all_functor &) = default ;
136
+ when_all_functor & operator = (when_all_functor &&) = default ;
137
+
138
+ inline future_vt operator ()() const
139
+ {
140
+ co_await _f;
141
+ _val.get () = std::ignore;
110
142
_e->signal ();
111
143
}
112
144
};
@@ -180,7 +212,7 @@ namespace resumef
180
212
return awaitable.get_future ();
181
213
}
182
214
183
- using when_any_pair = std::pair<intptr_t , std::any >;
215
+ using when_any_pair = std::pair<intptr_t , any_t >;
184
216
using when_any_result_ptr = std::shared_ptr<when_any_pair>;
185
217
186
218
template <class _Fty >
@@ -210,24 +242,53 @@ namespace resumef
210
242
{
211
243
if (_val->first < 0 )
212
244
{
213
- if constexpr (std::is_same_v<future_type, future_vt>)
245
+ auto tval = co_await _f;
246
+ if (_val->first < 0 )
214
247
{
215
- co_await _f;
216
- if (_val->first < 0 )
217
- {
218
- _val->first = _Idx;
219
- _e->signal ();
220
- }
248
+ _val->first = _Idx;
249
+ _val->second = std::move (tval);
250
+ _e->signal ();
221
251
}
222
- else
252
+ }
253
+ else
254
+ {
255
+ co_await _f;
256
+ }
257
+ }
258
+ };
259
+
260
+ template <>
261
+ struct when_any_functor <future_vt>
262
+ {
263
+ using value_type = when_any_pair;
264
+ using future_type = future_vt;
265
+
266
+ when_impl_ptr _e;
267
+ mutable future_type _f;
268
+ mutable when_any_result_ptr _val;
269
+ intptr_t _Idx;
270
+
271
+ when_any_functor (const when_impl_ptr & e, future_type f, const when_any_result_ptr & v, intptr_t idx)
272
+ : _e(e)
273
+ , _f(std::move(f))
274
+ , _val(v)
275
+ , _Idx(idx)
276
+ {
277
+ assert (idx >= 0 );
278
+ }
279
+ when_any_functor (when_any_functor &&) noexcept = default ;
280
+ when_any_functor & operator = (const when_any_functor &) = default ;
281
+ when_any_functor & operator = (when_any_functor &&) = default ;
282
+
283
+ inline future_vt operator ()() const
284
+ {
285
+ if (_val->first < 0 )
286
+ {
287
+ co_await _f;
288
+ if (_val->first < 0 )
223
289
{
224
- auto tval = co_await _f;
225
- if (_val->first < 0 )
226
- {
227
- _val->first = _Idx;
228
- _val->second = std::move (tval);
229
- _e->signal ();
230
- }
290
+ _val->first = _Idx;
291
+ _e->signal ();
231
292
}
232
293
}
233
294
else
@@ -340,7 +401,7 @@ namespace resumef
340
401
template <class ... _Fty>
341
402
auto when_any (scheduler & s, _Fty&&... f) -> future_t<detail::when_any_pair>
342
403
{
343
- auto vals = std::make_shared<detail::when_any_pair>(-1 , std::any {});
404
+ auto vals = std::make_shared<detail::when_any_pair>(-1 , any_t {});
344
405
345
406
return detail::when_any_count (sizeof ...(_Fty) ? 1 : 0 , vals, s, std::forward<_Fty>(f)...);
346
407
}
@@ -352,7 +413,7 @@ namespace resumef
352
413
template <class _Iter , typename _Fty = decltype (*std::declval<_Iter>())>
353
414
auto when_any (scheduler & s, _Iter begin, _Iter end) -> future_t<detail::when_any_pair>
354
415
{
355
- auto vals = std::make_shared<detail::when_any_pair>(-1 , std::any {});
416
+ auto vals = std::make_shared<detail::when_any_pair>(-1 , any_t {});
356
417
357
418
return detail::when_any_range ((begin != end) ? 1 : 0 , vals, s, begin, end);
358
419
}
0 commit comments