1//
2// async_result.hpp
3// ~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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>
20
21#include <boost/asio/detail/push_options.hpp>
22
23namespace boost {
24namespace asio {
25
26#if defined(BOOST_ASIO_HAS_CONCEPTS)
27
28namespace detail {
29
30template <typename T>
31struct is_completion_signature : false_type
32{
33};
34
35template <typename R, typename... Args>
36struct is_completion_signature<R(Args...)> : true_type
37{
38};
39
40template <typename R, typename... Args>
41struct is_completion_signature<R(Args...) &> : true_type
42{
43};
44
45template <typename R, typename... Args>
46struct is_completion_signature<R(Args...) &&> : true_type
47{
48};
49
50# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
51
52template <typename R, typename... Args>
53struct is_completion_signature<R(Args...) noexcept> : true_type
54{
55};
56
57template <typename R, typename... Args>
58struct is_completion_signature<R(Args...) & noexcept> : true_type
59{
60};
61
62template <typename R, typename... Args>
63struct is_completion_signature<R(Args...) && noexcept> : true_type
64{
65};
66
67# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
68
69template <typename... T>
70struct are_completion_signatures : false_type
71{
72};
73
74template <typename T0>
75struct are_completion_signatures<T0>
76 : is_completion_signature<T0>
77{
78};
79
80template <typename T0, typename... TN>
81struct are_completion_signatures<T0, TN...>
82 : integral_constant<bool, (
83 is_completion_signature<T0>::value
84 && are_completion_signatures<TN...>::value)>
85{
86};
87
88template <typename T, typename... Args>
89BOOST_ASIO_CONCEPT callable_with = requires(T&& t, Args&&... args)
90{
91 static_cast<T&&>(t)(static_cast<Args&&>(args)...);
92};
93
94template <typename T, typename... Signatures>
95struct is_completion_handler_for : false_type
96{
97};
98
99template <typename T, typename R, typename... Args>
100struct is_completion_handler_for<T, R(Args...)>
101 : integral_constant<bool, (callable_with<decay_t<T>, Args...>)>
102{
103};
104
105template <typename T, typename R, typename... Args>
106struct is_completion_handler_for<T, R(Args...) &>
107 : integral_constant<bool, (callable_with<decay_t<T>&, Args...>)>
108{
109};
110
111template <typename T, typename R, typename... Args>
112struct is_completion_handler_for<T, R(Args...) &&>
113 : integral_constant<bool, (callable_with<decay_t<T>&&, Args...>)>
114{
115};
116
117# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
118
119template <typename T, typename R, typename... Args>
120struct is_completion_handler_for<T, R(Args...) noexcept>
121 : integral_constant<bool, (callable_with<decay_t<T>, Args...>)>
122{
123};
124
125template <typename T, typename R, typename... Args>
126struct is_completion_handler_for<T, R(Args...) & noexcept>
127 : integral_constant<bool, (callable_with<decay_t<T>&, Args...>)>
128{
129};
130
131template <typename T, typename R, typename... Args>
132struct is_completion_handler_for<T, R(Args...) && noexcept>
133 : integral_constant<bool, (callable_with<decay_t<T>&&, Args...>)>
134{
135};
136
137# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
138
139template <typename T, typename Signature0, typename... SignatureN>
140struct is_completion_handler_for<T, Signature0, SignatureN...>
141 : integral_constant<bool, (
142 is_completion_handler_for<T, Signature0>::value
143 && is_completion_handler_for<T, SignatureN...>::value)>
144{
145};
146
147} // namespace detail
148
149template <typename T>
150BOOST_ASIO_CONCEPT completion_signature =
151 detail::is_completion_signature<T>::value;
152
153#define BOOST_ASIO_COMPLETION_SIGNATURE \
154 ::boost::asio::completion_signature
155
156template <typename T, typename... Signatures>
157BOOST_ASIO_CONCEPT completion_handler_for =
158 detail::are_completion_signatures<Signatures...>::value
159 && detail::is_completion_handler_for<T, Signatures...>::value;
160
161#define BOOST_ASIO_COMPLETION_HANDLER_FOR(sig) \
162 ::boost::asio::completion_handler_for<sig>
163#define BOOST_ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) \
164 ::boost::asio::completion_handler_for<sig0, sig1>
165#define BOOST_ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) \
166 ::boost::asio::completion_handler_for<sig0, sig1, sig2>
167
168#else // defined(BOOST_ASIO_HAS_CONCEPTS)
169
170#define BOOST_ASIO_COMPLETION_SIGNATURE typename
171#define BOOST_ASIO_COMPLETION_HANDLER_FOR(sig) typename
172#define BOOST_ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) typename
173#define BOOST_ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) typename
174
175#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
176
177namespace detail {
178
179template <typename T>
180struct is_lvalue_completion_signature : false_type
181{
182};
183
184template <typename R, typename... Args>
185struct is_lvalue_completion_signature<R(Args...) &> : true_type
186{
187};
188
189# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
190
191template <typename R, typename... Args>
192struct is_lvalue_completion_signature<R(Args...) & noexcept> : true_type
193{
194};
195
196# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
197
198template <typename... Signatures>
199struct are_any_lvalue_completion_signatures : false_type
200{
201};
202
203template <typename Sig0>
204struct are_any_lvalue_completion_signatures<Sig0>
205 : is_lvalue_completion_signature<Sig0>
206{
207};
208
209template <typename Sig0, typename... SigN>
210struct are_any_lvalue_completion_signatures<Sig0, SigN...>
211 : integral_constant<bool, (
212 is_lvalue_completion_signature<Sig0>::value
213 || are_any_lvalue_completion_signatures<SigN...>::value)>
214{
215};
216
217template <typename T>
218struct is_rvalue_completion_signature : false_type
219{
220};
221
222template <typename R, typename... Args>
223struct is_rvalue_completion_signature<R(Args...) &&> : true_type
224{
225};
226
227# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
228
229template <typename R, typename... Args>
230struct is_rvalue_completion_signature<R(Args...) && noexcept> : true_type
231{
232};
233
234# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
235
236template <typename... Signatures>
237struct are_any_rvalue_completion_signatures : false_type
238{
239};
240
241template <typename Sig0>
242struct are_any_rvalue_completion_signatures<Sig0>
243 : is_rvalue_completion_signature<Sig0>
244{
245};
246
247template <typename Sig0, typename... SigN>
248struct are_any_rvalue_completion_signatures<Sig0, SigN...>
249 : integral_constant<bool, (
250 is_rvalue_completion_signature<Sig0>::value
251 || are_any_rvalue_completion_signatures<SigN...>::value)>
252{
253};
254
255template <typename T>
256struct simple_completion_signature;
257
258template <typename R, typename... Args>
259struct simple_completion_signature<R(Args...)>
260{
261 typedef R type(Args...);
262};
263
264template <typename R, typename... Args>
265struct simple_completion_signature<R(Args...) &>
266{
267 typedef R type(Args...);
268};
269
270template <typename R, typename... Args>
271struct simple_completion_signature<R(Args...) &&>
272{
273 typedef R type(Args...);
274};
275
276# if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
277
278template <typename R, typename... Args>
279struct simple_completion_signature<R(Args...) noexcept>
280{
281 typedef R type(Args...);
282};
283
284template <typename R, typename... Args>
285struct simple_completion_signature<R(Args...) & noexcept>
286{
287 typedef R type(Args...);
288};
289
290template <typename R, typename... Args>
291struct simple_completion_signature<R(Args...) && noexcept>
292{
293 typedef R type(Args...);
294};
295
296# endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)
297
298template <typename CompletionToken,
299 BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
300class completion_handler_async_result
301{
302public:
303 typedef CompletionToken completion_handler_type;
304 typedef void return_type;
305
306 explicit completion_handler_async_result(completion_handler_type&)
307 {
308 }
309
310 return_type get()
311 {
312 }
313
314 template <typename Initiation,
315 BOOST_ASIO_COMPLETION_HANDLER_FOR(Signatures...) RawCompletionToken,
316 typename... Args>
317 static return_type initiate(Initiation&& initiation,
318 RawCompletionToken&& token, Args&&... args)
319 {
320 static_cast<Initiation&&>(initiation)(
321 static_cast<RawCompletionToken&&>(token),
322 static_cast<Args&&>(args)...);
323 }
324
325private:
326 completion_handler_async_result(
327 const completion_handler_async_result&) = delete;
328 completion_handler_async_result& operator=(
329 const completion_handler_async_result&) = delete;
330};
331
332} // namespace detail
333
334#if defined(GENERATING_DOCUMENTATION)
335
336/// An interface for customising the behaviour of an initiating function.
337/**
338 * The async_result traits class is used for determining:
339 *
340 * @li the concrete completion handler type to be called at the end of the
341 * asynchronous operation;
342 *
343 * @li the initiating function return type; and
344 *
345 * @li how the return value of the initiating function is obtained.
346 *
347 * The trait allows the handler and return types to be determined at the point
348 * where the specific completion handler signature is known.
349 *
350 * This template may be specialised for user-defined completion token types.
351 * The primary template assumes that the CompletionToken is the completion
352 * handler.
353 */
354template <typename CompletionToken,
355 BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
356class async_result
357{
358public:
359 /// The concrete completion handler type for the specific signature.
360 typedef CompletionToken completion_handler_type;
361
362 /// The return type of the initiating function.
363 typedef void return_type;
364
365 /// Construct an async result from a given handler.
366 /**
367 * When using a specalised async_result, the constructor has an opportunity
368 * to initialise some state associated with the completion handler, which is
369 * then returned from the initiating function.
370 */
371 explicit async_result(completion_handler_type& h);
372
373 /// Obtain the value to be returned from the initiating function.
374 return_type get();
375
376 /// Initiate the asynchronous operation that will produce the result, and
377 /// obtain the value to be returned from the initiating function.
378 template <typename Initiation, typename RawCompletionToken, typename... Args>
379 static return_type initiate(
380 Initiation&& initiation,
381 RawCompletionToken&& token,
382 Args&&... args);
383
384private:
385 async_result(const async_result&) = delete;
386 async_result& operator=(const async_result&) = delete;
387};
388
389#else // defined(GENERATING_DOCUMENTATION)
390
391template <typename CompletionToken,
392 BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
393class async_result :
394 public conditional_t<
395 detail::are_any_lvalue_completion_signatures<Signatures...>::value
396 || !detail::are_any_rvalue_completion_signatures<Signatures...>::value,
397 detail::completion_handler_async_result<CompletionToken, Signatures...>,
398 async_result<CompletionToken,
399 typename detail::simple_completion_signature<Signatures>::type...>
400 >
401{
402public:
403 typedef conditional_t<
404 detail::are_any_lvalue_completion_signatures<Signatures...>::value
405 || !detail::are_any_rvalue_completion_signatures<Signatures...>::value,
406 detail::completion_handler_async_result<CompletionToken, Signatures...>,
407 async_result<CompletionToken,
408 typename detail::simple_completion_signature<Signatures>::type...>
409 > base_type;
410
411 using base_type::base_type;
412
413private:
414 async_result(const async_result&) = delete;
415 async_result& operator=(const async_result&) = delete;
416};
417
418template <BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
419class async_result<void, Signatures...>
420{
421 // Empty.
422};
423
424#endif // defined(GENERATING_DOCUMENTATION)
425
426/// Helper template to deduce the handler type from a CompletionToken, capture
427/// a local copy of the handler, and then create an async_result for the
428/// handler.
429template <typename CompletionToken,
430 BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
431struct async_completion
432{
433 /// The real handler type to be used for the asynchronous operation.
434 typedef typename boost::asio::async_result<
435 decay_t<CompletionToken>, Signatures...>::completion_handler_type
436 completion_handler_type;
437
438 /// Constructor.
439 /**
440 * The constructor creates the concrete completion handler and makes the link
441 * between the handler and the asynchronous result.
442 */
443 explicit async_completion(CompletionToken& token)
444 : completion_handler(static_cast<conditional_t<
445 is_same<CompletionToken, completion_handler_type>::value,
446 completion_handler_type&, CompletionToken&&>>(token)),
447 result(completion_handler)
448 {
449 }
450
451 /// A copy of, or reference to, a real handler object.
452 conditional_t<
453 is_same<CompletionToken, completion_handler_type>::value,
454 completion_handler_type&, completion_handler_type> completion_handler;
455
456 /// The result of the asynchronous operation's initiating function.
457 async_result<decay_t<CompletionToken>, Signatures...> result;
458};
459
460namespace detail {
461
462struct async_result_memfns_base
463{
464 void initiate();
465};
466
467template <typename T>
468struct async_result_memfns_derived
469 : T, async_result_memfns_base
470{
471};
472
473template <typename T, T>
474struct async_result_memfns_check
475{
476};
477
478template <typename>
479char (&async_result_initiate_memfn_helper(...))[2];
480
481template <typename T>
482char async_result_initiate_memfn_helper(
483 async_result_memfns_check<
484 void (async_result_memfns_base::*)(),
485 &async_result_memfns_derived<T>::initiate>*);
486
487template <typename CompletionToken,
488 BOOST_ASIO_COMPLETION_SIGNATURE... Signatures>
489struct async_result_has_initiate_memfn
490 : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
491 async_result<decay_t<CompletionToken>, Signatures...>
492 >(0)) != 1>
493{
494};
495
496} // namespace detail
497
498#if defined(GENERATING_DOCUMENTATION)
499# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
500 void_or_deduced
501# define BOOST_ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \
502 void_or_deduced
503# define BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \
504 void_or_deduced
505#else
506# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
507 typename ::boost::asio::async_result< \
508 typename ::boost::asio::decay<ct>::type, sig>::return_type
509# define BOOST_ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \
510 typename ::boost::asio::async_result< \
511 typename ::boost::asio::decay<ct>::type, sig0, sig1>::return_type
512# define BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \
513 typename ::boost::asio::async_result< \
514 typename ::boost::asio::decay<ct>::type, sig0, sig1, sig2>::return_type
515#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
516 typename ::boost::asio::async_result< \
517 typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
518#define BOOST_ASIO_HANDLER_TYPE2(ct, sig0, sig1) \
519 typename ::boost::asio::async_result< \
520 typename ::boost::asio::decay<ct>::type, \
521 sig0, sig1>::completion_handler_type
522#define BOOST_ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \
523 typename ::boost::asio::async_result< \
524 typename ::boost::asio::decay<ct>::type, \
525 sig0, sig1, sig2>::completion_handler_type
526#endif
527
528#if defined(GENERATING_DOCUMENTATION)
529# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
530 auto
531# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
532 auto
533# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
534 auto
535#elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
536# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
537 auto
538# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
539 auto
540# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
541 auto
542#else
543# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
544 BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
545# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \
546 BOOST_ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)
547# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \
548 BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)
549#endif
550
551#if defined(GENERATING_DOCUMENTATION)
552# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
553 auto
554# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
555 auto
556# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
557 auto
558# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)
559#elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
560# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
561 auto
562# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
563 auto
564# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
565 auto
566# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)
567#else
568# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
569 auto
570# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
571 auto
572# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
573 auto
574# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr) -> decltype expr
575#endif
576
577#if defined(GENERATING_DOCUMENTATION)
578# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
579 void_or_deduced
580# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \
581 void_or_deduced
582# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \
583 void_or_deduced
584#else
585# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
586 decltype expr
587# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \
588 decltype expr
589# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \
590 decltype expr
591#endif
592
593#if defined(GENERATING_DOCUMENTATION)
594
595template <typename CompletionToken,
596 completion_signature... Signatures,
597 typename Initiation, typename... Args>
598void_or_deduced async_initiate(
599 Initiation&& initiation,
600 type_identity_t<CompletionToken>& token,
601 Args&&... args);
602
603#else // defined(GENERATING_DOCUMENTATION)
604
605template <typename CompletionToken,
606 BOOST_ASIO_COMPLETION_SIGNATURE... Signatures,
607 typename Initiation, typename... Args>
608inline auto async_initiate(Initiation&& initiation,
609 type_identity_t<CompletionToken>& token, Args&&... args)
610 -> constraint_t<
611 detail::async_result_has_initiate_memfn<
612 CompletionToken, Signatures...>::value,
613 decltype(
614 async_result<decay_t<CompletionToken>, Signatures...>::initiate(
615 static_cast<Initiation&&>(initiation),
616 static_cast<CompletionToken&&>(token),
617 static_cast<Args&&>(args)...))>
618{
619 return async_result<decay_t<CompletionToken>, Signatures...>::initiate(
620 static_cast<Initiation&&>(initiation),
621 static_cast<CompletionToken&&>(token),
622 static_cast<Args&&>(args)...);
623}
624
625template <typename CompletionToken,
626 BOOST_ASIO_COMPLETION_SIGNATURE... Signatures,
627 typename Initiation, typename... Args>
628inline constraint_t<
629 !detail::async_result_has_initiate_memfn<
630 CompletionToken, Signatures...>::value,
631 typename async_result<decay_t<CompletionToken>, Signatures...>::return_type>
632async_initiate(Initiation&& initiation,
633 type_identity_t<CompletionToken>& token, Args&&... args)
634{
635 async_completion<CompletionToken, Signatures...> completion(token);
636
637 static_cast<Initiation&&>(initiation)(
638 static_cast<
639 typename async_result<decay_t<CompletionToken>,
640 Signatures...>::completion_handler_type&&>(
641 completion.completion_handler),
642 static_cast<Args&&>(args)...);
643
644 return completion.result.get();
645}
646
647#endif // defined(GENERATING_DOCUMENTATION)
648
649#if defined(BOOST_ASIO_HAS_CONCEPTS)
650
651namespace detail {
652
653template <typename... Signatures>
654struct initiation_archetype
655{
656 template <completion_handler_for<Signatures...> CompletionHandler>
657 void operator()(CompletionHandler&&) const
658 {
659 }
660};
661
662} // namespace detail
663
664template <typename T, typename... Signatures>
665BOOST_ASIO_CONCEPT completion_token_for =
666 detail::are_completion_signatures<Signatures...>::value
667 &&
668 requires(T&& t)
669 {
670 async_initiate<T, Signatures...>(
671 detail::initiation_archetype<Signatures...>{}, t);
672 };
673
674#define BOOST_ASIO_COMPLETION_TOKEN_FOR(sig) \
675 ::boost::asio::completion_token_for<sig>
676#define BOOST_ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) \
677 ::boost::asio::completion_token_for<sig0, sig1>
678#define BOOST_ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) \
679 ::boost::asio::completion_token_for<sig0, sig1, sig2>
680
681#else // defined(BOOST_ASIO_HAS_CONCEPTS)
682
683#define BOOST_ASIO_COMPLETION_TOKEN_FOR(sig) typename
684#define BOOST_ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) typename
685#define BOOST_ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) typename
686
687#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
688
689namespace detail {
690
691struct async_operation_probe {};
692struct async_operation_probe_result {};
693
694template <typename Call, typename = void>
695struct is_async_operation_call : false_type
696{
697};
698
699template <typename Call>
700struct is_async_operation_call<Call,
701 void_t<
702 enable_if_t<
703 is_same<
704 result_of_t<Call>,
705 async_operation_probe_result
706 >::value
707 >
708 >
709 > : true_type
710{
711};
712
713} // namespace detail
714
715#if !defined(GENERATING_DOCUMENTATION)
716
717template <typename... Signatures>
718class async_result<detail::async_operation_probe, Signatures...>
719{
720public:
721 typedef detail::async_operation_probe_result return_type;
722
723 template <typename Initiation, typename... InitArgs>
724 static return_type initiate(Initiation&&,
725 detail::async_operation_probe, InitArgs&&...)
726 {
727 return return_type();
728 }
729};
730
731#endif // !defined(GENERATING_DOCUMENTATION)
732
733#if defined(GENERATING_DOCUMENTATION)
734
735/// The is_async_operation trait detects whether a type @c T and arguments
736/// @c Args... may be used to initiate an asynchronous operation.
737/**
738 * Class template @c is_async_operation is a trait is derived from @c true_type
739 * if the expression <tt>T(Args..., token)</tt> initiates an asynchronous
740 * operation, where @c token is an unspecified completion token type. Otherwise,
741 * @c is_async_operation is derived from @c false_type.
742 */
743template <typename T, typename... Args>
744struct is_async_operation : integral_constant<bool, automatically_determined>
745{
746};
747
748#else // defined(GENERATING_DOCUMENTATION)
749
750template <typename T, typename... Args>
751struct is_async_operation :
752 detail::is_async_operation_call<
753 T(Args..., detail::async_operation_probe)>
754{
755};
756
757#endif // defined(GENERATING_DOCUMENTATION)
758
759#if defined(BOOST_ASIO_HAS_CONCEPTS)
760
761template <typename T, typename... Args>
762BOOST_ASIO_CONCEPT async_operation = is_async_operation<T, Args...>::value;
763
764#define BOOST_ASIO_ASYNC_OPERATION(t) \
765 ::boost::asio::async_operation<t>
766#define BOOST_ASIO_ASYNC_OPERATION1(t, a0) \
767 ::boost::asio::async_operation<t, a0>
768#define BOOST_ASIO_ASYNC_OPERATION2(t, a0, a1) \
769 ::boost::asio::async_operation<t, a0, a1>
770#define BOOST_ASIO_ASYNC_OPERATION3(t, a0, a1, a2) \
771 ::boost::asio::async_operation<t, a0, a1, a2>
772
773#else // defined(BOOST_ASIO_HAS_CONCEPTS)
774
775#define BOOST_ASIO_ASYNC_OPERATION(t) typename
776#define BOOST_ASIO_ASYNC_OPERATION1(t, a0) typename
777#define BOOST_ASIO_ASYNC_OPERATION2(t, a0, a1) typename
778#define BOOST_ASIO_ASYNC_OPERATION3(t, a0, a1, a2) typename
779
780#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
781
782namespace detail {
783
784struct completion_signature_probe {};
785
786template <typename... T>
787struct completion_signature_probe_result
788{
789 template <template <typename...> class Op>
790 struct apply
791 {
792 typedef Op<T...> type;
793 };
794};
795
796template <typename T>
797struct completion_signature_probe_result<T>
798{
799 typedef T type;
800
801 template <template <typename...> class Op>
802 struct apply
803 {
804 typedef Op<T> type;
805 };
806};
807
808template <>
809struct completion_signature_probe_result<void>
810{
811 template <template <typename...> class Op>
812 struct apply
813 {
814 typedef Op<> type;
815 };
816};
817
818} // namespace detail
819
820#if !defined(GENERATING_DOCUMENTATION)
821
822template <typename... Signatures>
823class async_result<detail::completion_signature_probe, Signatures...>
824{
825public:
826 typedef detail::completion_signature_probe_result<Signatures...> return_type;
827
828 template <typename Initiation, typename... InitArgs>
829 static return_type initiate(Initiation&&,
830 detail::completion_signature_probe, InitArgs&&...)
831 {
832 return return_type();
833 }
834};
835
836template <typename Signature>
837class async_result<detail::completion_signature_probe, Signature>
838{
839public:
840 typedef detail::completion_signature_probe_result<Signature> return_type;
841
842 template <typename Initiation, typename... InitArgs>
843 static return_type initiate(Initiation&&,
844 detail::completion_signature_probe, InitArgs&&...)
845 {
846 return return_type();
847 }
848};
849
850#endif // !defined(GENERATING_DOCUMENTATION)
851
852#if defined(GENERATING_DOCUMENTATION)
853
854/// The completion_signature_of trait determines the completion signature
855/// of an asynchronous operation.
856/**
857 * Class template @c completion_signature_of is a trait with a member type
858 * alias @c type that denotes the completion signature of the asynchronous
859 * operation initiated by the expression <tt>T(Args..., token)</tt> operation,
860 * where @c token is an unspecified completion token type. If the asynchronous
861 * operation does not have exactly one completion signature, the instantion of
862 * the trait is well-formed but the member type alias @c type is omitted. If
863 * the expression <tt>T(Args..., token)</tt> is not an asynchronous operation
864 * then use of the trait is ill-formed.
865 */
866template <typename T, typename... Args>
867struct completion_signature_of
868{
869 typedef automatically_determined type;
870};
871
872#else // defined(GENERATING_DOCUMENTATION)
873
874template <typename T, typename... Args>
875struct completion_signature_of :
876 result_of_t<T(Args..., detail::completion_signature_probe)>
877{
878};
879
880#endif // defined(GENERATING_DOCUMENTATION)
881
882template <typename T, typename... Args>
883using completion_signature_of_t =
884 typename completion_signature_of<T, Args...>::type;
885
886namespace detail {
887
888template <typename T, typename = void>
889struct default_completion_token_impl
890{
891 typedef void type;
892};
893
894template <typename T>
895struct default_completion_token_impl<T,
896 void_t<typename T::default_completion_token_type>
897 >
898{
899 typedef typename T::default_completion_token_type type;
900};
901
902} // namespace detail
903
904#if defined(GENERATING_DOCUMENTATION)
905
906/// Traits type used to determine the default completion token type associated
907/// with a type (such as an executor).
908/**
909 * A program may specialise this traits type if the @c T template parameter in
910 * the specialisation is a user-defined type.
911 *
912 * Specialisations of this trait may provide a nested typedef @c type, which is
913 * a default-constructible completion token type.
914 */
915template <typename T>
916struct default_completion_token
917{
918 /// If @c T has a nested type @c default_completion_token_type,
919 /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type
920 /// is not defined.
921 typedef see_below type;
922};
923#else
924template <typename T>
925struct default_completion_token
926 : detail::default_completion_token_impl<T>
927{
928};
929#endif
930
931template <typename T>
932using default_completion_token_t = typename default_completion_token<T>::type;
933
934#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \
935 = typename ::boost::asio::default_completion_token<e>::type
936#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e) \
937 = typename ::boost::asio::default_completion_token<e>::type()
938
939} // namespace asio
940} // namespace boost
941
942#include <boost/asio/detail/pop_options.hpp>
943
944#endif // BOOST_ASIO_ASYNC_RESULT_HPP
945

source code of boost/libs/asio/include/boost/asio/async_result.hpp