]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // async_result.hpp | |
3 | // ~~~~~~~~~~~~~~~~ | |
4 | // | |
92f5a8d4 | 5 | // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 FG |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | ||
11 | #ifndef BOOST_ASIO_ASYNC_RESULT_HPP | |
12 | #define BOOST_ASIO_ASYNC_RESULT_HPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <boost/asio/detail/config.hpp> | |
19 | #include <boost/asio/detail/type_traits.hpp> | |
92f5a8d4 | 20 | #include <boost/asio/detail/variadic_templates.hpp> |
b32b8144 FG |
21 | |
22 | #include <boost/asio/detail/push_options.hpp> | |
23 | ||
24 | namespace boost { | |
25 | namespace asio { | |
26 | ||
92f5a8d4 TL |
27 | #if defined(BOOST_ASIO_HAS_CONCEPTS) \ |
28 | && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \ | |
29 | && defined(BOOST_ASIO_HAS_DECLTYPE) | |
30 | ||
31 | namespace detail { | |
32 | ||
33 | template <typename T> | |
34 | struct is_completion_signature : false_type | |
35 | { | |
36 | }; | |
37 | ||
38 | template <typename R, typename... Args> | |
39 | struct is_completion_signature<R(Args...)> : true_type | |
40 | { | |
41 | }; | |
42 | ||
43 | template <typename T, typename... Args> | |
44 | BOOST_ASIO_CONCEPT callable_with = requires(T t, Args&&... args) | |
45 | { | |
46 | t(static_cast<Args&&>(args)...); | |
47 | }; | |
48 | ||
49 | template <typename T, typename Signature> | |
50 | struct is_completion_handler_for : false_type | |
51 | { | |
52 | }; | |
53 | ||
54 | template <typename T, typename R, typename... Args> | |
55 | struct is_completion_handler_for<T, R(Args...)> | |
56 | : integral_constant<bool, (callable_with<T, Args...>)> | |
57 | { | |
58 | }; | |
59 | ||
60 | } // namespace detail | |
61 | ||
62 | template <typename T> | |
63 | BOOST_ASIO_CONCEPT completion_signature = | |
64 | detail::is_completion_signature<T>::value; | |
65 | ||
66 | #define BOOST_ASIO_COMPLETION_SIGNATURE \ | |
67 | ::boost::asio::completion_signature | |
68 | ||
69 | template <typename T, completion_signature Signature> | |
70 | BOOST_ASIO_CONCEPT completion_handler_for = | |
71 | detail::is_completion_handler_for<T, Signature>::value; | |
72 | ||
73 | #define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) \ | |
74 | ::boost::asio::completion_handler_for<s> | |
75 | ||
76 | #else // defined(BOOST_ASIO_HAS_CONCEPTS) | |
77 | // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
78 | // && defined(BOOST_ASIO_HAS_DECLTYPE) | |
79 | ||
80 | #define BOOST_ASIO_COMPLETION_SIGNATURE typename | |
81 | #define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) typename | |
82 | ||
83 | #endif // defined(BOOST_ASIO_HAS_CONCEPTS) | |
84 | // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
85 | // && defined(BOOST_ASIO_HAS_DECLTYPE) | |
86 | ||
b32b8144 FG |
87 | /// An interface for customising the behaviour of an initiating function. |
88 | /** | |
89 | * The async_result traits class is used for determining: | |
90 | * | |
91 | * @li the concrete completion handler type to be called at the end of the | |
92 | * asynchronous operation; | |
93 | * | |
94 | * @li the initiating function return type; and | |
95 | * | |
96 | * @li how the return value of the initiating function is obtained. | |
97 | * | |
98 | * The trait allows the handler and return types to be determined at the point | |
99 | * where the specific completion handler signature is known. | |
100 | * | |
101 | * This template may be specialised for user-defined completion token types. | |
102 | * The primary template assumes that the CompletionToken is the completion | |
103 | * handler. | |
104 | */ | |
92f5a8d4 | 105 | template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature> |
b32b8144 FG |
106 | class async_result |
107 | { | |
108 | public: | |
b32b8144 FG |
109 | /// The concrete completion handler type for the specific signature. |
110 | typedef CompletionToken completion_handler_type; | |
111 | ||
112 | /// The return type of the initiating function. | |
113 | typedef void return_type; | |
b32b8144 FG |
114 | |
115 | /// Construct an async result from a given handler. | |
116 | /** | |
117 | * When using a specalised async_result, the constructor has an opportunity | |
118 | * to initialise some state associated with the completion handler, which is | |
119 | * then returned from the initiating function. | |
120 | */ | |
121 | explicit async_result(completion_handler_type& h) | |
b32b8144 FG |
122 | { |
123 | (void)h; | |
124 | } | |
125 | ||
126 | /// Obtain the value to be returned from the initiating function. | |
127 | return_type get() | |
128 | { | |
b32b8144 FG |
129 | } |
130 | ||
92f5a8d4 | 131 | #if defined(GENERATING_DOCUMENTATION) |
b32b8144 | 132 | |
92f5a8d4 TL |
133 | /// Initiate the asynchronous operation that will produce the result, and |
134 | /// obtain the value to be returned from the initiating function. | |
135 | template <typename Initiation, typename RawCompletionToken, typename... Args> | |
136 | static return_type initiate( | |
137 | BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
138 | BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, | |
139 | BOOST_ASIO_MOVE_ARG(Args)... args); | |
b32b8144 | 140 | |
92f5a8d4 | 141 | #elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) |
b32b8144 | 142 | |
92f5a8d4 TL |
143 | template <typename Initiation, |
144 | BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken, | |
145 | typename... Args> | |
146 | static return_type initiate( | |
147 | BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
148 | BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, | |
149 | BOOST_ASIO_MOVE_ARG(Args)... args) | |
b32b8144 | 150 | { |
92f5a8d4 TL |
151 | BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( |
152 | BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), | |
153 | BOOST_ASIO_MOVE_CAST(Args)(args)...); | |
b32b8144 FG |
154 | } |
155 | ||
92f5a8d4 TL |
156 | #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) |
157 | ||
158 | template <typename Initiation, | |
159 | BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken> | |
160 | static return_type initiate( | |
161 | BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
162 | BOOST_ASIO_MOVE_ARG(RawCompletionToken) token) | |
b32b8144 | 163 | { |
92f5a8d4 TL |
164 | BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( |
165 | BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token)); | |
b32b8144 | 166 | } |
92f5a8d4 TL |
167 | |
168 | #define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \ | |
169 | template <typename Initiation, \ | |
170 | BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken, \ | |
171 | BOOST_ASIO_VARIADIC_TPARAMS(n)> \ | |
172 | static return_type initiate( \ | |
173 | BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ | |
174 | BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \ | |
175 | BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ | |
176 | { \ | |
177 | BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \ | |
178 | BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), \ | |
179 | BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ | |
180 | } \ | |
181 | /**/ | |
182 | BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF) | |
183 | #undef BOOST_ASIO_PRIVATE_INITIATE_DEF | |
184 | ||
185 | #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
186 | ||
187 | private: | |
188 | async_result(const async_result&) BOOST_ASIO_DELETED; | |
189 | async_result& operator=(const async_result&) BOOST_ASIO_DELETED; | |
190 | }; | |
191 | ||
192 | #if !defined(GENERATING_DOCUMENTATION) | |
193 | ||
194 | template <BOOST_ASIO_COMPLETION_SIGNATURE Signature> | |
195 | class async_result<void, Signature> | |
196 | { | |
197 | // Empty. | |
b32b8144 FG |
198 | }; |
199 | ||
92f5a8d4 | 200 | #endif // !defined(GENERATING_DOCUMENTATION) |
b32b8144 FG |
201 | |
202 | /// Helper template to deduce the handler type from a CompletionToken, capture | |
203 | /// a local copy of the handler, and then create an async_result for the | |
204 | /// handler. | |
92f5a8d4 | 205 | template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature> |
b32b8144 FG |
206 | struct async_completion |
207 | { | |
208 | /// The real handler type to be used for the asynchronous operation. | |
209 | typedef typename boost::asio::async_result< | |
210 | typename decay<CompletionToken>::type, | |
211 | Signature>::completion_handler_type completion_handler_type; | |
212 | ||
213 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
214 | /// Constructor. | |
215 | /** | |
216 | * The constructor creates the concrete completion handler and makes the link | |
217 | * between the handler and the asynchronous result. | |
218 | */ | |
219 | explicit async_completion(CompletionToken& token) | |
220 | : completion_handler(static_cast<typename conditional< | |
221 | is_same<CompletionToken, completion_handler_type>::value, | |
222 | completion_handler_type&, CompletionToken&&>::type>(token)), | |
223 | result(completion_handler) | |
224 | { | |
225 | } | |
226 | #else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
227 | explicit async_completion(typename decay<CompletionToken>::type& token) | |
228 | : completion_handler(token), | |
229 | result(completion_handler) | |
230 | { | |
231 | } | |
232 | ||
233 | explicit async_completion(const typename decay<CompletionToken>::type& token) | |
234 | : completion_handler(token), | |
235 | result(completion_handler) | |
236 | { | |
237 | } | |
238 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
239 | ||
240 | /// A copy of, or reference to, a real handler object. | |
241 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
242 | typename conditional< | |
243 | is_same<CompletionToken, completion_handler_type>::value, | |
244 | completion_handler_type&, completion_handler_type>::type completion_handler; | |
245 | #else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
246 | completion_handler_type completion_handler; | |
247 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
248 | ||
249 | /// The result of the asynchronous operation's initiating function. | |
250 | async_result<typename decay<CompletionToken>::type, Signature> result; | |
251 | }; | |
252 | ||
253 | namespace detail { | |
254 | ||
255 | template <typename CompletionToken, typename Signature> | |
256 | struct async_result_helper | |
257 | : async_result<typename decay<CompletionToken>::type, Signature> | |
258 | { | |
259 | }; | |
260 | ||
92f5a8d4 TL |
261 | struct async_result_memfns_base |
262 | { | |
263 | void initiate(); | |
264 | }; | |
b32b8144 | 265 | |
92f5a8d4 TL |
266 | template <typename T> |
267 | struct async_result_memfns_derived | |
268 | : T, async_result_memfns_base | |
269 | { | |
270 | }; | |
271 | ||
272 | template <typename T, T> | |
273 | struct async_result_memfns_check | |
274 | { | |
275 | }; | |
276 | ||
277 | template <typename> | |
278 | char (&async_result_initiate_memfn_helper(...))[2]; | |
279 | ||
280 | template <typename T> | |
281 | char async_result_initiate_memfn_helper( | |
282 | async_result_memfns_check< | |
283 | void (async_result_memfns_base::*)(), | |
284 | &async_result_memfns_derived<T>::initiate>*); | |
285 | ||
286 | template <typename CompletionToken, typename Signature> | |
287 | struct async_result_has_initiate_memfn | |
288 | : integral_constant<bool, sizeof(async_result_initiate_memfn_helper< | |
289 | async_result<typename decay<CompletionToken>::type, Signature> | |
290 | >(0)) != 1> | |
291 | { | |
292 | }; | |
293 | ||
294 | } // namespace detail | |
b32b8144 FG |
295 | |
296 | #if defined(GENERATING_DOCUMENTATION) | |
297 | # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ | |
298 | void_or_deduced | |
299 | #elif defined(_MSC_VER) && (_MSC_VER < 1500) | |
300 | # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ | |
301 | typename ::boost::asio::detail::async_result_helper< \ | |
302 | ct, sig>::return_type | |
303 | #define BOOST_ASIO_HANDLER_TYPE(ct, sig) \ | |
304 | typename ::boost::asio::detail::async_result_helper< \ | |
305 | ct, sig>::completion_handler_type | |
306 | #else | |
307 | # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ | |
308 | typename ::boost::asio::async_result< \ | |
309 | typename ::boost::asio::decay<ct>::type, sig>::return_type | |
310 | #define BOOST_ASIO_HANDLER_TYPE(ct, sig) \ | |
311 | typename ::boost::asio::async_result< \ | |
312 | typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type | |
313 | #endif | |
314 | ||
92f5a8d4 TL |
315 | #if defined(GENERATION_DOCUMENTATION) |
316 | # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \ | |
317 | auto | |
318 | #elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION) | |
319 | # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \ | |
320 | auto | |
321 | #else | |
322 | # define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \ | |
323 | BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) | |
324 | #endif | |
325 | ||
326 | #if defined(GENERATION_DOCUMENTATION) | |
327 | # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \ | |
328 | void_or_deduced | |
329 | #elif defined(BOOST_ASIO_HAS_DECLTYPE) | |
330 | # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \ | |
331 | decltype expr | |
332 | #else | |
333 | # define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \ | |
334 | BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) | |
335 | #endif | |
336 | ||
337 | #if defined(GENERATING_DOCUMENTATION) | |
338 | ||
339 | template <typename CompletionToken, | |
340 | completion_signature Signature, | |
341 | typename Initiation, typename... Args> | |
342 | void_or_deduced async_initiate( | |
343 | BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
344 | BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken), | |
345 | BOOST_ASIO_MOVE_ARG(Args)... args); | |
346 | ||
347 | #elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
348 | ||
349 | template <typename CompletionToken, | |
350 | BOOST_ASIO_COMPLETION_SIGNATURE Signature, | |
351 | typename Initiation, typename... Args> | |
352 | inline typename enable_if< | |
353 | detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, | |
354 | BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, | |
355 | (async_result<typename decay<CompletionToken>::type, | |
356 | Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(), | |
357 | declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(), | |
358 | declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))>::type | |
359 | async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
360 | BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, | |
361 | BOOST_ASIO_MOVE_ARG(Args)... args) | |
362 | { | |
363 | return async_result<typename decay<CompletionToken>::type, | |
364 | Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), | |
365 | BOOST_ASIO_MOVE_CAST(CompletionToken)(token), | |
366 | BOOST_ASIO_MOVE_CAST(Args)(args)...); | |
367 | } | |
368 | ||
369 | template <typename CompletionToken, | |
370 | BOOST_ASIO_COMPLETION_SIGNATURE Signature, | |
371 | typename Initiation, typename... Args> | |
372 | inline typename enable_if< | |
373 | !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, | |
374 | BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type | |
375 | async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
376 | BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, | |
377 | BOOST_ASIO_MOVE_ARG(Args)... args) | |
378 | { | |
379 | async_completion<CompletionToken, Signature> completion(token); | |
380 | ||
381 | BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( | |
382 | BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, | |
383 | Signature))(completion.completion_handler), | |
384 | BOOST_ASIO_MOVE_CAST(Args)(args)...); | |
385 | ||
386 | return completion.result.get(); | |
387 | } | |
388 | ||
389 | #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
390 | ||
391 | template <typename CompletionToken, | |
392 | BOOST_ASIO_COMPLETION_SIGNATURE Signature, | |
393 | typename Initiation> | |
394 | inline typename enable_if< | |
395 | detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, | |
396 | BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, | |
397 | (async_result<typename decay<CompletionToken>::type, | |
398 | Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(), | |
399 | declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>())))>::type | |
400 | async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
401 | BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) | |
402 | { | |
403 | return async_result<typename decay<CompletionToken>::type, | |
404 | Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), | |
405 | BOOST_ASIO_MOVE_CAST(CompletionToken)(token)); | |
406 | } | |
407 | ||
408 | template <typename CompletionToken, | |
409 | BOOST_ASIO_COMPLETION_SIGNATURE Signature, | |
410 | typename Initiation> | |
411 | inline typename enable_if< | |
412 | !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, | |
413 | BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type | |
414 | async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, | |
415 | BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) | |
416 | { | |
417 | async_completion<CompletionToken, Signature> completion(token); | |
418 | ||
419 | BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( | |
420 | BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, | |
421 | Signature))(completion.completion_handler)); | |
422 | ||
423 | return completion.result.get(); | |
424 | } | |
425 | ||
426 | #define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \ | |
427 | template <typename CompletionToken, \ | |
428 | BOOST_ASIO_COMPLETION_SIGNATURE Signature, \ | |
429 | typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ | |
430 | inline typename enable_if< \ | |
431 | detail::async_result_has_initiate_memfn< \ | |
432 | CompletionToken, Signature>::value, \ | |
433 | BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, \ | |
434 | (async_result<typename decay<CompletionToken>::type, \ | |
435 | Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(), \ | |
436 | declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(), \ | |
437 | BOOST_ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \ | |
438 | async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ | |
439 | BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ | |
440 | BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ | |
441 | { \ | |
442 | return async_result<typename decay<CompletionToken>::type, \ | |
443 | Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \ | |
444 | BOOST_ASIO_MOVE_CAST(CompletionToken)(token), \ | |
445 | BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ | |
446 | } \ | |
447 | \ | |
448 | template <typename CompletionToken, \ | |
449 | BOOST_ASIO_COMPLETION_SIGNATURE Signature, \ | |
450 | typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ | |
451 | inline typename enable_if< \ | |
452 | !detail::async_result_has_initiate_memfn< \ | |
453 | CompletionToken, Signature>::value, \ | |
454 | BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \ | |
455 | async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ | |
456 | BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ | |
457 | BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ | |
458 | { \ | |
459 | async_completion<CompletionToken, Signature> completion(token); \ | |
460 | \ | |
461 | BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \ | |
462 | BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, \ | |
463 | Signature))(completion.completion_handler), \ | |
464 | BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ | |
465 | \ | |
466 | return completion.result.get(); \ | |
467 | } \ | |
468 | /**/ | |
469 | BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF) | |
470 | #undef BOOST_ASIO_PRIVATE_INITIATE_DEF | |
471 | ||
472 | #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
473 | ||
474 | #if defined(BOOST_ASIO_HAS_CONCEPTS) \ | |
475 | && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \ | |
476 | && defined(BOOST_ASIO_HAS_DECLTYPE) | |
477 | ||
478 | namespace detail { | |
479 | ||
480 | template <typename Signature> | |
481 | struct initiation_archetype | |
482 | { | |
483 | template <completion_handler_for<Signature> CompletionHandler> | |
484 | void operator()(CompletionHandler&&) const | |
485 | { | |
486 | } | |
487 | }; | |
488 | ||
489 | } // namespace detail | |
490 | ||
491 | template <typename T, completion_signature Signature> | |
492 | BOOST_ASIO_CONCEPT completion_token_for = requires(T&& t) | |
493 | { | |
494 | async_initiate<T, Signature>(detail::initiation_archetype<Signature>{}, t); | |
495 | }; | |
496 | ||
497 | #define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) \ | |
498 | ::boost::asio::completion_token_for<s> | |
499 | ||
500 | #else // defined(BOOST_ASIO_HAS_CONCEPTS) | |
501 | // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
502 | // && defined(BOOST_ASIO_HAS_DECLTYPE) | |
503 | ||
504 | #define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) typename | |
505 | ||
506 | #endif // defined(BOOST_ASIO_HAS_CONCEPTS) | |
507 | // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) | |
508 | // && defined(BOOST_ASIO_HAS_DECLTYPE) | |
509 | ||
510 | namespace detail { | |
511 | ||
512 | template <typename> | |
513 | struct default_completion_token_check | |
514 | { | |
515 | typedef void type; | |
516 | }; | |
517 | ||
518 | template <typename T, typename = void> | |
519 | struct default_completion_token_impl | |
520 | { | |
521 | typedef void type; | |
522 | }; | |
523 | ||
524 | template <typename T> | |
525 | struct default_completion_token_impl<T, | |
526 | typename default_completion_token_check< | |
527 | typename T::default_completion_token_type>::type> | |
528 | { | |
529 | typedef typename T::default_completion_token_type type; | |
530 | }; | |
531 | ||
532 | } // namespace detail | |
533 | ||
534 | #if defined(GENERATING_DOCUMENTATION) | |
535 | ||
536 | /// Traits type used to determine the default completion token type associated | |
537 | /// with a type (such as an executor). | |
538 | /** | |
539 | * A program may specialise this traits type if the @c T template parameter in | |
540 | * the specialisation is a user-defined type. | |
541 | * | |
542 | * Specialisations of this trait may provide a nested typedef @c type, which is | |
543 | * a default-constructible completion token type. | |
544 | */ | |
545 | template <typename T> | |
546 | struct default_completion_token | |
547 | { | |
548 | /// If @c T has a nested type @c default_completion_token_type, | |
549 | /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type | |
550 | /// is not defined. | |
551 | typedef see_below type; | |
552 | }; | |
553 | #else | |
554 | template <typename T> | |
555 | struct default_completion_token | |
556 | : detail::default_completion_token_impl<T> | |
557 | { | |
558 | }; | |
559 | #endif | |
560 | ||
561 | #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) | |
562 | ||
563 | template <typename T> | |
564 | using default_completion_token_t = typename default_completion_token<T>::type; | |
565 | ||
566 | #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) | |
567 | ||
568 | #if defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) | |
569 | ||
570 | #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \ | |
571 | = typename ::boost::asio::default_completion_token<e>::type | |
572 | #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e) \ | |
573 | = typename ::boost::asio::default_completion_token<e>::type() | |
574 | ||
575 | #else // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) | |
576 | ||
577 | #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) | |
578 | #define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e) | |
579 | ||
580 | #endif // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS) | |
581 | ||
582 | } // namespace asio | |
583 | } // namespace boost | |
584 | ||
585 | #include <boost/asio/detail/pop_options.hpp> | |
586 | ||
b32b8144 | 587 | #endif // BOOST_ASIO_ASYNC_RESULT_HPP |