1 //
2 // impl/compose.hpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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_IMPL_COMPOSE_HPP
12 #define BOOST_ASIO_IMPL_COMPOSE_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/associated_executor.hpp>
20 #include <boost/asio/detail/handler_alloc_helpers.hpp>
21 #include <boost/asio/detail/handler_cont_helpers.hpp>
22 #include <boost/asio/detail/handler_invoke_helpers.hpp>
23 #include <boost/asio/detail/type_traits.hpp>
24 #include <boost/asio/detail/variadic_templates.hpp>
25 #include <boost/asio/execution/executor.hpp>
26 #include <boost/asio/execution/outstanding_work.hpp>
27 #include <boost/asio/executor_work_guard.hpp>
28 #include <boost/asio/is_executor.hpp>
29 #include <boost/asio/system_executor.hpp>
30
31 #include <boost/asio/detail/push_options.hpp>
32
33 namespace boost {
34 namespace asio {
35
36 namespace detail
37 {
38 template <typename Executor, typename = void>
39 class composed_work_guard
40 {
41 public:
42 typedef typename decay<
43 typename prefer_result<Executor,
44 execution::outstanding_work_t::tracked_t
45 >::type
46 >::type executor_type;
47
composed_work_guard(const Executor & ex)48 composed_work_guard(const Executor& ex)
49 : executor_(boost::asio::prefer(ex, execution::outstanding_work.tracked))
50 {
51 }
52
reset()53 void reset()
54 {
55 }
56
get_executor() const57 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
58 {
59 return executor_;
60 }
61
62 private:
63 executor_type executor_;
64 };
65
66 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
67
68 template <typename Executor>
69 struct composed_work_guard<Executor,
70 typename enable_if<
71 !execution::is_executor<Executor>::value
72 >::type> : executor_work_guard<Executor>
73 {
composed_work_guardboost::asio::detail::composed_work_guard74 composed_work_guard(const Executor& ex)
75 : executor_work_guard<Executor>(ex)
76 {
77 }
78 };
79
80 #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
81
82 template <typename>
83 struct composed_io_executors;
84
85 template <>
86 struct composed_io_executors<void()>
87 {
composed_io_executorsboost::asio::detail::composed_io_executors88 composed_io_executors() BOOST_ASIO_NOEXCEPT
89 : head_(system_executor())
90 {
91 }
92
93 typedef system_executor head_type;
94 system_executor head_;
95 };
96
make_composed_io_executors()97 inline composed_io_executors<void()> make_composed_io_executors()
98 {
99 return composed_io_executors<void()>();
100 }
101
102 template <typename Head>
103 struct composed_io_executors<void(Head)>
104 {
composed_io_executorsboost::asio::detail::composed_io_executors105 explicit composed_io_executors(const Head& ex) BOOST_ASIO_NOEXCEPT
106 : head_(ex)
107 {
108 }
109
110 typedef Head head_type;
111 Head head_;
112 };
113
114 template <typename Head>
115 inline composed_io_executors<void(Head)>
make_composed_io_executors(const Head & head)116 make_composed_io_executors(const Head& head)
117 {
118 return composed_io_executors<void(Head)>(head);
119 }
120
121 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
122
123 template <typename Head, typename... Tail>
124 struct composed_io_executors<void(Head, Tail...)>
125 {
composed_io_executorsboost::asio::detail::composed_io_executors126 explicit composed_io_executors(const Head& head,
127 const Tail&... tail) BOOST_ASIO_NOEXCEPT
128 : head_(head),
129 tail_(tail...)
130 {
131 }
132
resetboost::asio::detail::composed_io_executors133 void reset()
134 {
135 head_.reset();
136 tail_.reset();
137 }
138
139 typedef Head head_type;
140 Head head_;
141 composed_io_executors<void(Tail...)> tail_;
142 };
143
144 template <typename Head, typename... Tail>
145 inline composed_io_executors<void(Head, Tail...)>
make_composed_io_executors(const Head & head,const Tail &...tail)146 make_composed_io_executors(const Head& head, const Tail&... tail)
147 {
148 return composed_io_executors<void(Head, Tail...)>(head, tail...);
149 }
150
151 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
152
153 #define BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF(n) \
154 template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
155 struct composed_io_executors<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
156 { \
157 explicit composed_io_executors(const Head& head, \
158 BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) BOOST_ASIO_NOEXCEPT \
159 : head_(head), \
160 tail_(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) \
161 { \
162 } \
163 \
164 void reset() \
165 { \
166 head_.reset(); \
167 tail_.reset(); \
168 } \
169 \
170 typedef Head head_type; \
171 Head head_; \
172 composed_io_executors<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
173 }; \
174 \
175 template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
176 inline composed_io_executors<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
177 make_composed_io_executors(const Head& head, \
178 BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
179 { \
180 return composed_io_executors< \
181 void(Head, BOOST_ASIO_VARIADIC_TARGS(n))>( \
182 head, BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)); \
183 } \
184 /**/
185 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF)
186 #undef BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF
187
188 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
189
190 template <typename>
191 struct composed_work;
192
193 template <>
194 struct composed_work<void()>
195 {
196 typedef composed_io_executors<void()> executors_type;
197
composed_workboost::asio::detail::composed_work198 composed_work(const executors_type&) BOOST_ASIO_NOEXCEPT
199 : head_(system_executor())
200 {
201 }
202
resetboost::asio::detail::composed_work203 void reset()
204 {
205 head_.reset();
206 }
207
208 typedef system_executor head_type;
209 composed_work_guard<system_executor> head_;
210 };
211
212 template <typename Head>
213 struct composed_work<void(Head)>
214 {
215 typedef composed_io_executors<void(Head)> executors_type;
216
composed_workboost::asio::detail::composed_work217 explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT
218 : head_(ex.head_)
219 {
220 }
221
resetboost::asio::detail::composed_work222 void reset()
223 {
224 head_.reset();
225 }
226
227 typedef Head head_type;
228 composed_work_guard<Head> head_;
229 };
230
231 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
232
233 template <typename Head, typename... Tail>
234 struct composed_work<void(Head, Tail...)>
235 {
236 typedef composed_io_executors<void(Head, Tail...)> executors_type;
237
composed_workboost::asio::detail::composed_work238 explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT
239 : head_(ex.head_),
240 tail_(ex.tail_)
241 {
242 }
243
resetboost::asio::detail::composed_work244 void reset()
245 {
246 head_.reset();
247 tail_.reset();
248 }
249
250 typedef Head head_type;
251 composed_work_guard<Head> head_;
252 composed_work<void(Tail...)> tail_;
253 };
254
255 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
256
257 #define BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \
258 template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
259 struct composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
260 { \
261 typedef composed_io_executors<void(Head, \
262 BOOST_ASIO_VARIADIC_TARGS(n))> executors_type; \
263 \
264 explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT \
265 : head_(ex.head_), \
266 tail_(ex.tail_) \
267 { \
268 } \
269 \
270 void reset() \
271 { \
272 head_.reset(); \
273 tail_.reset(); \
274 } \
275 \
276 typedef Head head_type; \
277 composed_work_guard<Head> head_; \
278 composed_work<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
279 }; \
280 /**/
281 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF)
282 #undef BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF
283
284 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
285
286 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
287 template <typename Impl, typename Work, typename Handler, typename Signature>
288 class composed_op;
289
290 template <typename Impl, typename Work, typename Handler,
291 typename R, typename... Args>
292 class composed_op<Impl, Work, Handler, R(Args...)>
293 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
294 template <typename Impl, typename Work, typename Handler, typename Signature>
295 class composed_op
296 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
297 {
298 public:
299 template <typename I, typename W, typename H>
composed_op(BOOST_ASIO_MOVE_ARG (I)impl,BOOST_ASIO_MOVE_ARG (W)work,BOOST_ASIO_MOVE_ARG (H)handler)300 composed_op(BOOST_ASIO_MOVE_ARG(I) impl,
301 BOOST_ASIO_MOVE_ARG(W) work,
302 BOOST_ASIO_MOVE_ARG(H) handler)
303 : impl_(BOOST_ASIO_MOVE_CAST(I)(impl)),
304 work_(BOOST_ASIO_MOVE_CAST(W)(work)),
305 handler_(BOOST_ASIO_MOVE_CAST(H)(handler)),
306 invocations_(0)
307 {
308 }
309
310 #if defined(BOOST_ASIO_HAS_MOVE)
composed_op(composed_op && other)311 composed_op(composed_op&& other)
312 : impl_(BOOST_ASIO_MOVE_CAST(Impl)(other.impl_)),
313 work_(BOOST_ASIO_MOVE_CAST(Work)(other.work_)),
314 handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
315 invocations_(other.invocations_)
316 {
317 }
318 #endif // defined(BOOST_ASIO_HAS_MOVE)
319
320 typedef typename associated_executor<Handler,
321 typename composed_work_guard<
322 typename Work::head_type
323 >::executor_type
324 >::type executor_type;
325
get_executor() const326 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
327 {
328 return (get_associated_executor)(handler_, work_.head_.get_executor());
329 }
330
331 typedef typename associated_allocator<Handler,
332 std::allocator<void> >::type allocator_type;
333
get_allocator() const334 allocator_type get_allocator() const BOOST_ASIO_NOEXCEPT
335 {
336 return (get_associated_allocator)(handler_, std::allocator<void>());
337 }
338
339 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
340
341 template<typename... T>
operator ()(BOOST_ASIO_MOVE_ARG (T)...t)342 void operator()(BOOST_ASIO_MOVE_ARG(T)... t)
343 {
344 if (invocations_ < ~0u)
345 ++invocations_;
346 impl_(*this, BOOST_ASIO_MOVE_CAST(T)(t)...);
347 }
348
complete(Args...args)349 void complete(Args... args)
350 {
351 this->work_.reset();
352 this->handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
353 }
354
355 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
356
operator ()()357 void operator()()
358 {
359 if (invocations_ < ~0u)
360 ++invocations_;
361 impl_(*this);
362 }
363
complete()364 void complete()
365 {
366 this->work_.reset();
367 this->handler_();
368 }
369
370 #define BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF(n) \
371 template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
372 void operator()(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
373 { \
374 if (invocations_ < ~0u) \
375 ++invocations_; \
376 impl_(*this, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
377 } \
378 \
379 template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
380 void complete(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
381 { \
382 this->work_.reset(); \
383 this->handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
384 } \
385 /**/
386 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF)
387 #undef BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF
388
389 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
390
391 //private:
392 Impl impl_;
393 Work work_;
394 Handler handler_;
395 unsigned invocations_;
396 };
397
398 template <typename Impl, typename Work, typename Handler, typename Signature>
399 inline asio_handler_allocate_is_deprecated
asio_handler_allocate(std::size_t size,composed_op<Impl,Work,Handler,Signature> * this_handler)400 asio_handler_allocate(std::size_t size,
401 composed_op<Impl, Work, Handler, Signature>* this_handler)
402 {
403 #if defined(BOOST_ASIO_NO_DEPRECATED)
404 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
405 return asio_handler_allocate_is_no_longer_used();
406 #else // defined(BOOST_ASIO_NO_DEPRECATED)
407 return boost_asio_handler_alloc_helpers::allocate(
408 size, this_handler->handler_);
409 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
410 }
411
412 template <typename Impl, typename Work, typename Handler, typename Signature>
413 inline asio_handler_deallocate_is_deprecated
asio_handler_deallocate(void * pointer,std::size_t size,composed_op<Impl,Work,Handler,Signature> * this_handler)414 asio_handler_deallocate(void* pointer, std::size_t size,
415 composed_op<Impl, Work, Handler, Signature>* this_handler)
416 {
417 boost_asio_handler_alloc_helpers::deallocate(
418 pointer, size, this_handler->handler_);
419 #if defined(BOOST_ASIO_NO_DEPRECATED)
420 return asio_handler_deallocate_is_no_longer_used();
421 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
422 }
423
424 template <typename Impl, typename Work, typename Handler, typename Signature>
asio_handler_is_continuation(composed_op<Impl,Work,Handler,Signature> * this_handler)425 inline bool asio_handler_is_continuation(
426 composed_op<Impl, Work, Handler, Signature>* this_handler)
427 {
428 return this_handler->invocations_ > 1 ? true
429 : boost_asio_handler_cont_helpers::is_continuation(
430 this_handler->handler_);
431 }
432
433 template <typename Function, typename Impl,
434 typename Work, typename Handler, typename Signature>
435 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(Function & function,composed_op<Impl,Work,Handler,Signature> * this_handler)436 asio_handler_invoke(Function& function,
437 composed_op<Impl, Work, Handler, Signature>* this_handler)
438 {
439 boost_asio_handler_invoke_helpers::invoke(
440 function, this_handler->handler_);
441 #if defined(BOOST_ASIO_NO_DEPRECATED)
442 return asio_handler_invoke_is_no_longer_used();
443 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
444 }
445
446 template <typename Function, typename Impl,
447 typename Work, typename Handler, typename Signature>
448 inline asio_handler_invoke_is_deprecated
asio_handler_invoke(const Function & function,composed_op<Impl,Work,Handler,Signature> * this_handler)449 asio_handler_invoke(const Function& function,
450 composed_op<Impl, Work, Handler, Signature>* this_handler)
451 {
452 boost_asio_handler_invoke_helpers::invoke(
453 function, this_handler->handler_);
454 #if defined(BOOST_ASIO_NO_DEPRECATED)
455 return asio_handler_invoke_is_no_longer_used();
456 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
457 }
458
459 template <typename Signature, typename Executors>
460 class initiate_composed_op
461 {
462 public:
463 typedef typename composed_io_executors<Executors>::head_type executor_type;
464
465 template <typename T>
initiate_composed_op(int,BOOST_ASIO_MOVE_ARG (T)executors)466 explicit initiate_composed_op(int, BOOST_ASIO_MOVE_ARG(T) executors)
467 : executors_(BOOST_ASIO_MOVE_CAST(T)(executors))
468 {
469 }
470
get_executor() const471 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
472 {
473 return executors_.head_;
474 }
475
476 template <typename Handler, typename Impl>
operator ()(BOOST_ASIO_MOVE_ARG (Handler)handler,BOOST_ASIO_MOVE_ARG (Impl)impl) const477 void operator()(BOOST_ASIO_MOVE_ARG(Handler) handler,
478 BOOST_ASIO_MOVE_ARG(Impl) impl) const
479 {
480 composed_op<typename decay<Impl>::type, composed_work<Executors>,
481 typename decay<Handler>::type, Signature>(
482 BOOST_ASIO_MOVE_CAST(Impl)(impl),
483 composed_work<Executors>(executors_),
484 BOOST_ASIO_MOVE_CAST(Handler)(handler))();
485 }
486
487 private:
488 composed_io_executors<Executors> executors_;
489 };
490
491 template <typename Signature, typename Executors>
make_initiate_composed_op(BOOST_ASIO_MOVE_ARG (composed_io_executors<Executors>)executors)492 inline initiate_composed_op<Signature, Executors> make_initiate_composed_op(
493 BOOST_ASIO_MOVE_ARG(composed_io_executors<Executors>) executors)
494 {
495 return initiate_composed_op<Signature, Executors>(0,
496 BOOST_ASIO_MOVE_CAST(composed_io_executors<Executors>)(executors));
497 }
498
499 template <typename IoObject>
500 inline typename IoObject::executor_type
get_composed_io_executor(IoObject & io_object,typename enable_if<!is_executor<IoObject>::value>::type * =0,typename enable_if<!execution::is_executor<IoObject>::value>::type * =0)501 get_composed_io_executor(IoObject& io_object,
502 typename enable_if<
503 !is_executor<IoObject>::value
504 >::type* = 0,
505 typename enable_if<
506 !execution::is_executor<IoObject>::value
507 >::type* = 0)
508 {
509 return io_object.get_executor();
510 }
511
512 template <typename Executor>
get_composed_io_executor(const Executor & ex,typename enable_if<is_executor<Executor>::value||execution::is_executor<Executor>::value>::type * =0)513 inline const Executor& get_composed_io_executor(const Executor& ex,
514 typename enable_if<
515 is_executor<Executor>::value
516 || execution::is_executor<Executor>::value
517 >::type* = 0)
518 {
519 return ex;
520 }
521 } // namespace detail
522
523 #if !defined(GENERATING_DOCUMENTATION)
524 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
525
526 template <typename CompletionToken, typename Signature,
527 typename Implementation, typename... IoObjectsOrExecutors>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,Signature)528 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
529 async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
530 BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
531 BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors)
532 {
533 return async_initiate<CompletionToken, Signature>(
534 detail::make_initiate_composed_op<Signature>(
535 detail::make_composed_io_executors(
536 detail::get_composed_io_executor(
537 BOOST_ASIO_MOVE_CAST(IoObjectsOrExecutors)(
538 io_objects_or_executors))...)),
539 token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation));
540 }
541
542 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
543
544 template <typename CompletionToken, typename Signature, typename Implementation>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,Signature)545 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
546 async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
547 BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
548 {
549 return async_initiate<CompletionToken, Signature>(
550 detail::make_initiate_composed_op<Signature>(
551 detail::make_composed_io_executors()),
552 token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation));
553 }
554
555 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \
556 BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_##n
557
558 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 \
559 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1))
560 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 \
561 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
562 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2))
563 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 \
564 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
565 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
566 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3))
567 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 \
568 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
569 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
570 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
571 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4))
572 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 \
573 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
574 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
575 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
576 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
577 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5))
578 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6 \
579 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
580 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
581 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
582 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
583 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5)), \
584 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T6)(x6))
585 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7 \
586 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
587 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
588 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
589 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
590 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5)), \
591 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T6)(x6)), \
592 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T7)(x7))
593 # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8 \
594 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
595 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
596 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
597 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
598 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5)), \
599 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T6)(x6)), \
600 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T7)(x7)), \
601 detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T8)(x8))
602
603 #define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
604 template <typename CompletionToken, typename Signature, \
605 typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
606 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) \
607 async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
608 BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
609 BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
610 { \
611 return async_initiate<CompletionToken, Signature>( \
612 detail::make_initiate_composed_op<Signature>( \
613 detail::make_composed_io_executors( \
614 BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \
615 token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation)); \
616 } \
617 /**/
618 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
619 #undef BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF
620
621 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR
622 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1
623 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2
624 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3
625 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4
626 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5
627 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6
628 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7
629 #undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8
630
631 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
632 #endif // !defined(GENERATING_DOCUMENTATION)
633
634 } // namespace asio
635 } // namespace boost
636
637 #include <boost/asio/detail/pop_options.hpp>
638
639 #endif // BOOST_ASIO_IMPL_COMPOSE_HPP
640