]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/impl/use_future.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / impl / use_future.hpp
1 //
2 // impl/use_future.hpp
3 // ~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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_USE_FUTURE_HPP
12 #define BOOST_ASIO_IMPL_USE_FUTURE_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 <future>
20 #include <tuple>
21 #include <boost/asio/async_result.hpp>
22 #include <boost/asio/detail/memory.hpp>
23 #include <boost/system/error_code.hpp>
24 #include <boost/asio/packaged_task.hpp>
25 #include <boost/system/system_error.hpp>
26 #include <boost/asio/system_executor.hpp>
27
28 #include <boost/asio/detail/push_options.hpp>
29
30 namespace boost {
31 namespace asio {
32 namespace detail {
33
34 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
35
36 template <typename T, typename F, typename... Args>
37 inline void promise_invoke_and_set(std::promise<T>& p,
38 F& f, BOOST_ASIO_MOVE_ARG(Args)... args)
39 {
40 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
41 try
42 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
43 {
44 p.set_value(f(BOOST_ASIO_MOVE_CAST(Args)(args)...));
45 }
46 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
47 catch (...)
48 {
49 p.set_exception(std::current_exception());
50 }
51 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
52 }
53
54 template <typename F, typename... Args>
55 inline void promise_invoke_and_set(std::promise<void>& p,
56 F& f, BOOST_ASIO_MOVE_ARG(Args)... args)
57 {
58 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
59 try
60 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
61 {
62 f(BOOST_ASIO_MOVE_CAST(Args)(args)...);
63 p.set_value();
64 }
65 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
66 catch (...)
67 {
68 p.set_exception(std::current_exception());
69 }
70 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
71 }
72
73 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
74
75 template <typename T, typename F>
76 inline void promise_invoke_and_set(std::promise<T>& p, F& f)
77 {
78 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
79 try
80 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
81 {
82 p.set_value(f());
83 }
84 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
85 catch (...)
86 {
87 p.set_exception(std::current_exception());
88 }
89 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
90 }
91
92 template <typename F, typename Args>
93 inline void promise_invoke_and_set(std::promise<void>& p, F& f)
94 {
95 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
96 try
97 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
98 {
99 f();
100 p.set_value();
101 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
102 }
103 catch (...)
104 {
105 p.set_exception(std::current_exception());
106 }
107 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
108 }
109
110 #if defined(BOOST_ASIO_NO_EXCEPTIONS)
111
112 #define BOOST_ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \
113 template <typename T, typename F, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
114 inline void promise_invoke_and_set(std::promise<T>& p, \
115 F& f, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
116 { \
117 p.set_value(f(BOOST_ASIO_VARIADIC_MOVE_ARGS(n))); \
118 } \
119 \
120 template <typename F, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
121 inline void promise_invoke_and_set(std::promise<void>& p, \
122 F& f, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
123 { \
124 f(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
125 p.set_value(); \
126 } \
127 /**/
128 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_PROMISE_INVOKE_DEF)
129 #undef BOOST_ASIO_PRIVATE_PROMISE_INVOKE_DEF
130
131 #else // defined(BOOST_ASIO_NO_EXCEPTIONS)
132
133 #define BOOST_ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \
134 template <typename T, typename F, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
135 inline void promise_invoke_and_set(std::promise<T>& p, \
136 F& f, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
137 { \
138 try \
139 { \
140 p.set_value(f(BOOST_ASIO_VARIADIC_MOVE_ARGS(n))); \
141 } \
142 catch (...) \
143 { \
144 p.set_exception(std::current_exception()); \
145 } \
146 } \
147 \
148 template <typename F, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
149 inline void promise_invoke_and_set(std::promise<void>& p, \
150 F& f, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
151 { \
152 try \
153 { \
154 f(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
155 p.set_value(); \
156 } \
157 catch (...) \
158 { \
159 p.set_exception(std::current_exception()); \
160 } \
161 } \
162 /**/
163 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_PROMISE_INVOKE_DEF)
164 #undef BOOST_ASIO_PRIVATE_PROMISE_INVOKE_DEF
165
166 #endif // defined(BOOST_ASIO_NO_EXCEPTIONS)
167
168 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
169
170 // A function object adapter to invoke a nullary function object and capture
171 // any exception thrown into a promise.
172 template <typename T, typename F>
173 class promise_invoker
174 {
175 public:
176 promise_invoker(const shared_ptr<std::promise<T> >& p,
177 BOOST_ASIO_MOVE_ARG(F) f)
178 : p_(p), f_(BOOST_ASIO_MOVE_CAST(F)(f))
179 {
180 }
181
182 void operator()()
183 {
184 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
185 try
186 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
187 {
188 f_();
189 }
190 #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
191 catch (...)
192 {
193 p_->set_exception(std::current_exception());
194 }
195 #endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
196 }
197
198 private:
199 shared_ptr<std::promise<T> > p_;
200 typename decay<F>::type f_;
201 };
202
203 // An executor that adapts the system_executor to capture any exeption thrown
204 // by a submitted function object and save it into a promise.
205 template <typename T>
206 class promise_executor
207 {
208 public:
209 explicit promise_executor(const shared_ptr<std::promise<T> >& p)
210 : p_(p)
211 {
212 }
213
214 execution_context& context() const BOOST_ASIO_NOEXCEPT
215 {
216 return system_executor().context();
217 }
218
219 void on_work_started() const BOOST_ASIO_NOEXCEPT {}
220 void on_work_finished() const BOOST_ASIO_NOEXCEPT {}
221
222 template <typename F, typename A>
223 void dispatch(BOOST_ASIO_MOVE_ARG(F) f, const A&) const
224 {
225 promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f))();
226 }
227
228 template <typename F, typename A>
229 void post(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
230 {
231 system_executor().post(
232 promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f)), a);
233 }
234
235 template <typename F, typename A>
236 void defer(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
237 {
238 system_executor().defer(
239 promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f)), a);
240 }
241
242 friend bool operator==(const promise_executor& a,
243 const promise_executor& b) BOOST_ASIO_NOEXCEPT
244 {
245 return a.p_ == b.p_;
246 }
247
248 friend bool operator!=(const promise_executor& a,
249 const promise_executor& b) BOOST_ASIO_NOEXCEPT
250 {
251 return a.p_ != b.p_;
252 }
253
254 private:
255 shared_ptr<std::promise<T> > p_;
256 };
257
258 // The base class for all completion handlers that create promises.
259 template <typename T>
260 class promise_creator
261 {
262 public:
263 typedef promise_executor<T> executor_type;
264
265 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
266 {
267 return executor_type(p_);
268 }
269
270 typedef std::future<T> future_type;
271
272 future_type get_future()
273 {
274 return p_->get_future();
275 }
276
277 protected:
278 template <typename Allocator>
279 void create_promise(const Allocator& a)
280 {
281 BOOST_ASIO_REBIND_ALLOC(Allocator, char) b(a);
282 p_ = std::allocate_shared<std::promise<T>>(b, std::allocator_arg, b);
283 }
284
285 shared_ptr<std::promise<T> > p_;
286 };
287
288 // For completion signature void().
289 class promise_handler_0
290 : public promise_creator<void>
291 {
292 public:
293 void operator()()
294 {
295 this->p_->set_value();
296 }
297 };
298
299 // For completion signature void(error_code).
300 class promise_handler_ec_0
301 : public promise_creator<void>
302 {
303 public:
304 void operator()(const boost::system::error_code& ec)
305 {
306 if (ec)
307 {
308 this->p_->set_exception(
309 std::make_exception_ptr(
310 boost::system::system_error(ec)));
311 }
312 else
313 {
314 this->p_->set_value();
315 }
316 }
317 };
318
319 // For completion signature void(exception_ptr).
320 class promise_handler_ex_0
321 : public promise_creator<void>
322 {
323 public:
324 void operator()(const std::exception_ptr& ex)
325 {
326 if (ex)
327 {
328 this->p_->set_exception(ex);
329 }
330 else
331 {
332 this->p_->set_value();
333 }
334 }
335 };
336
337 // For completion signature void(T).
338 template <typename T>
339 class promise_handler_1
340 : public promise_creator<T>
341 {
342 public:
343 template <typename Arg>
344 void operator()(BOOST_ASIO_MOVE_ARG(Arg) arg)
345 {
346 this->p_->set_value(BOOST_ASIO_MOVE_CAST(Arg)(arg));
347 }
348 };
349
350 // For completion signature void(error_code, T).
351 template <typename T>
352 class promise_handler_ec_1
353 : public promise_creator<T>
354 {
355 public:
356 template <typename Arg>
357 void operator()(const boost::system::error_code& ec,
358 BOOST_ASIO_MOVE_ARG(Arg) arg)
359 {
360 if (ec)
361 {
362 this->p_->set_exception(
363 std::make_exception_ptr(
364 boost::system::system_error(ec)));
365 }
366 else
367 this->p_->set_value(BOOST_ASIO_MOVE_CAST(Arg)(arg));
368 }
369 };
370
371 // For completion signature void(exception_ptr, T).
372 template <typename T>
373 class promise_handler_ex_1
374 : public promise_creator<T>
375 {
376 public:
377 template <typename Arg>
378 void operator()(const std::exception_ptr& ex,
379 BOOST_ASIO_MOVE_ARG(Arg) arg)
380 {
381 if (ex)
382 this->p_->set_exception(ex);
383 else
384 this->p_->set_value(BOOST_ASIO_MOVE_CAST(Arg)(arg));
385 }
386 };
387
388 // For completion signature void(T1, ..., Tn);
389 template <typename T>
390 class promise_handler_n
391 : public promise_creator<T>
392 {
393 public:
394 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
395
396 template <typename... Args>
397 void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
398 {
399 this->p_->set_value(
400 std::forward_as_tuple(
401 BOOST_ASIO_MOVE_CAST(Args)(args)...));
402 }
403
404 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
405
406 #define BOOST_ASIO_PRIVATE_CALL_OP_DEF(n) \
407 template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
408 void operator()(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
409 {\
410 this->p_->set_value( \
411 std::forward_as_tuple( \
412 BOOST_ASIO_VARIADIC_MOVE_ARGS(n))); \
413 } \
414 /**/
415 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_CALL_OP_DEF)
416 #undef BOOST_ASIO_PRIVATE_CALL_OP_DEF
417
418 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
419 };
420
421 // For completion signature void(error_code, T1, ..., Tn);
422 template <typename T>
423 class promise_handler_ec_n
424 : public promise_creator<T>
425 {
426 public:
427 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
428
429 template <typename... Args>
430 void operator()(const boost::system::error_code& ec,
431 BOOST_ASIO_MOVE_ARG(Args)... args)
432 {
433 if (ec)
434 {
435 this->p_->set_exception(
436 std::make_exception_ptr(
437 boost::system::system_error(ec)));
438 }
439 else
440 {
441 this->p_->set_value(
442 std::forward_as_tuple(
443 BOOST_ASIO_MOVE_CAST(Args)(args)...));
444 }
445 }
446
447 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
448
449 #define BOOST_ASIO_PRIVATE_CALL_OP_DEF(n) \
450 template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
451 void operator()(const boost::system::error_code& ec, \
452 BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
453 {\
454 if (ec) \
455 { \
456 this->p_->set_exception( \
457 std::make_exception_ptr( \
458 boost::system::system_error(ec))); \
459 } \
460 else \
461 { \
462 this->p_->set_value( \
463 std::forward_as_tuple( \
464 BOOST_ASIO_VARIADIC_MOVE_ARGS(n))); \
465 } \
466 } \
467 /**/
468 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_CALL_OP_DEF)
469 #undef BOOST_ASIO_PRIVATE_CALL_OP_DEF
470
471 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
472 };
473
474 // For completion signature void(exception_ptr, T1, ..., Tn);
475 template <typename T>
476 class promise_handler_ex_n
477 : public promise_creator<T>
478 {
479 public:
480 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
481
482 template <typename... Args>
483 void operator()(const std::exception_ptr& ex,
484 BOOST_ASIO_MOVE_ARG(Args)... args)
485 {
486 if (ex)
487 this->p_->set_exception(ex);
488 else
489 {
490 this->p_->set_value(
491 std::forward_as_tuple(
492 BOOST_ASIO_MOVE_CAST(Args)(args)...));
493 }
494 }
495
496 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
497
498 #define BOOST_ASIO_PRIVATE_CALL_OP_DEF(n) \
499 template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
500 void operator()(const std::exception_ptr& ex, \
501 BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
502 {\
503 if (ex) \
504 this->p_->set_exception(ex); \
505 else \
506 { \
507 this->p_->set_value( \
508 std::forward_as_tuple( \
509 BOOST_ASIO_VARIADIC_MOVE_ARGS(n))); \
510 } \
511 } \
512 /**/
513 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_CALL_OP_DEF)
514 #undef BOOST_ASIO_PRIVATE_CALL_OP_DEF
515
516 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
517 };
518
519 // Helper template to choose the appropriate concrete promise handler
520 // implementation based on the supplied completion signature.
521 template <typename> class promise_handler_selector;
522
523 template <>
524 class promise_handler_selector<void()>
525 : public promise_handler_0 {};
526
527 template <>
528 class promise_handler_selector<void(boost::system::error_code)>
529 : public promise_handler_ec_0 {};
530
531 template <>
532 class promise_handler_selector<void(std::exception_ptr)>
533 : public promise_handler_ex_0 {};
534
535 template <typename Arg>
536 class promise_handler_selector<void(Arg)>
537 : public promise_handler_1<Arg> {};
538
539 template <typename Arg>
540 class promise_handler_selector<void(boost::system::error_code, Arg)>
541 : public promise_handler_ec_1<Arg> {};
542
543 template <typename Arg>
544 class promise_handler_selector<void(std::exception_ptr, Arg)>
545 : public promise_handler_ex_1<Arg> {};
546
547 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
548
549 template <typename... Arg>
550 class promise_handler_selector<void(Arg...)>
551 : public promise_handler_n<std::tuple<Arg...> > {};
552
553 template <typename... Arg>
554 class promise_handler_selector<void(boost::system::error_code, Arg...)>
555 : public promise_handler_ec_n<std::tuple<Arg...> > {};
556
557 template <typename... Arg>
558 class promise_handler_selector<void(std::exception_ptr, Arg...)>
559 : public promise_handler_ex_n<std::tuple<Arg...> > {};
560
561 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
562
563 #define BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF(n) \
564 template <typename Arg, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
565 class promise_handler_selector< \
566 void(Arg, BOOST_ASIO_VARIADIC_TARGS(n))> \
567 : public promise_handler_n< \
568 std::tuple<Arg, BOOST_ASIO_VARIADIC_TARGS(n)> > {}; \
569 \
570 template <typename Arg, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
571 class promise_handler_selector< \
572 void(boost::system::error_code, Arg, BOOST_ASIO_VARIADIC_TARGS(n))> \
573 : public promise_handler_ec_n< \
574 std::tuple<Arg, BOOST_ASIO_VARIADIC_TARGS(n)> > {}; \
575 \
576 template <typename Arg, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
577 class promise_handler_selector< \
578 void(std::exception_ptr, Arg, BOOST_ASIO_VARIADIC_TARGS(n))> \
579 : public promise_handler_ex_n< \
580 std::tuple<Arg, BOOST_ASIO_VARIADIC_TARGS(n)> > {}; \
581 /**/
582 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF)
583 #undef BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF
584
585 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
586
587 // Completion handlers produced from the use_future completion token, when not
588 // using use_future::operator().
589 template <typename Signature, typename Allocator>
590 class promise_handler
591 : public promise_handler_selector<Signature>
592 {
593 public:
594 typedef Allocator allocator_type;
595 typedef void result_type;
596
597 promise_handler(use_future_t<Allocator> u)
598 : allocator_(u.get_allocator())
599 {
600 this->create_promise(allocator_);
601 }
602
603 allocator_type get_allocator() const BOOST_ASIO_NOEXCEPT
604 {
605 return allocator_;
606 }
607
608 private:
609 Allocator allocator_;
610 };
611
612 template <typename Function, typename Signature, typename Allocator>
613 inline void asio_handler_invoke(Function& f,
614 promise_handler<Signature, Allocator>* h)
615 {
616 typename promise_handler<Signature, Allocator>::executor_type
617 ex(h->get_executor());
618 ex.dispatch(BOOST_ASIO_MOVE_CAST(Function)(f), std::allocator<void>());
619 }
620
621 template <typename Function, typename Signature, typename Allocator>
622 inline void asio_handler_invoke(const Function& f,
623 promise_handler<Signature, Allocator>* h)
624 {
625 typename promise_handler<Signature, Allocator>::executor_type
626 ex(h->get_executor());
627 ex.dispatch(f, std::allocator<void>());
628 }
629
630 // Helper base class for async_result specialisation.
631 template <typename Signature, typename Allocator>
632 class promise_async_result
633 {
634 public:
635 typedef promise_handler<Signature, Allocator> completion_handler_type;
636 typedef typename completion_handler_type::future_type return_type;
637
638 explicit promise_async_result(completion_handler_type& h)
639 : future_(h.get_future())
640 {
641 }
642
643 return_type get()
644 {
645 return BOOST_ASIO_MOVE_CAST(return_type)(future_);
646 }
647
648 private:
649 return_type future_;
650 };
651
652 // Return value from use_future::operator().
653 template <typename Function, typename Allocator>
654 class packaged_token
655 {
656 public:
657 packaged_token(Function f, const Allocator& a)
658 : function_(BOOST_ASIO_MOVE_CAST(Function)(f)),
659 allocator_(a)
660 {
661 }
662
663 //private:
664 Function function_;
665 Allocator allocator_;
666 };
667
668 // Completion handlers produced from the use_future completion token, when
669 // using use_future::operator().
670 template <typename Function, typename Allocator, typename Result>
671 class packaged_handler
672 : public promise_creator<Result>
673 {
674 public:
675 typedef Allocator allocator_type;
676 typedef void result_type;
677
678 packaged_handler(packaged_token<Function, Allocator> t)
679 : function_(BOOST_ASIO_MOVE_CAST(Function)(t.function_)),
680 allocator_(t.allocator_)
681 {
682 this->create_promise(allocator_);
683 }
684
685 allocator_type get_allocator() const BOOST_ASIO_NOEXCEPT
686 {
687 return allocator_;
688 }
689
690 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
691
692 template <typename... Args>
693 void operator()(BOOST_ASIO_MOVE_ARG(Args)... args)
694 {
695 (promise_invoke_and_set)(*this->p_,
696 function_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
697 }
698
699 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
700
701 void operator()()
702 {
703 (promise_invoke_and_set)(*this->p_, function_);
704 }
705
706 #define BOOST_ASIO_PRIVATE_CALL_OP_DEF(n) \
707 template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
708 void operator()(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
709 {\
710 (promise_invoke_and_set)(*this->p_, \
711 function_, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
712 } \
713 /**/
714 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_CALL_OP_DEF)
715 #undef BOOST_ASIO_PRIVATE_CALL_OP_DEF
716
717 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
718
719 private:
720 Function function_;
721 Allocator allocator_;
722 };
723
724 template <typename Function,
725 typename Function1, typename Allocator, typename Result>
726 inline void asio_handler_invoke(Function& f,
727 packaged_handler<Function1, Allocator, Result>* h)
728 {
729 typename packaged_handler<Function1, Allocator, Result>::executor_type
730 ex(h->get_executor());
731 ex.dispatch(BOOST_ASIO_MOVE_CAST(Function)(f), std::allocator<void>());
732 }
733
734 template <typename Function,
735 typename Function1, typename Allocator, typename Result>
736 inline void asio_handler_invoke(const Function& f,
737 packaged_handler<Function1, Allocator, Result>* h)
738 {
739 typename packaged_handler<Function1, Allocator, Result>::executor_type
740 ex(h->get_executor());
741 ex.dispatch(f, std::allocator<void>());
742 }
743
744 // Helper base class for async_result specialisation.
745 template <typename Function, typename Allocator, typename Result>
746 class packaged_async_result
747 {
748 public:
749 typedef packaged_handler<Function, Allocator, Result> completion_handler_type;
750 typedef typename completion_handler_type::future_type return_type;
751
752 explicit packaged_async_result(completion_handler_type& h)
753 : future_(h.get_future())
754 {
755 }
756
757 return_type get()
758 {
759 return BOOST_ASIO_MOVE_CAST(return_type)(future_);
760 }
761
762 private:
763 return_type future_;
764 };
765
766 } // namespace detail
767
768 template <typename Allocator> template <typename Function>
769 inline detail::packaged_token<typename decay<Function>::type, Allocator>
770 use_future_t<Allocator>::operator()(BOOST_ASIO_MOVE_ARG(Function) f) const
771 {
772 return detail::packaged_token<typename decay<Function>::type, Allocator>(
773 BOOST_ASIO_MOVE_CAST(Function)(f), allocator_);
774 }
775
776 #if !defined(GENERATING_DOCUMENTATION)
777
778 #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
779
780 template <typename Allocator, typename Result, typename... Args>
781 class async_result<use_future_t<Allocator>, Result(Args...)>
782 : public detail::promise_async_result<
783 void(typename decay<Args>::type...), Allocator>
784 {
785 public:
786 explicit async_result(
787 typename detail::promise_async_result<void(typename decay<Args>::type...),
788 Allocator>::completion_handler_type& h)
789 : detail::promise_async_result<
790 void(typename decay<Args>::type...), Allocator>(h)
791 {
792 }
793 };
794
795 template <typename Function, typename Allocator,
796 typename Result, typename... Args>
797 class async_result<detail::packaged_token<Function, Allocator>, Result(Args...)>
798 : public detail::packaged_async_result<Function, Allocator,
799 typename result_of<Function(Args...)>::type>
800 {
801 public:
802 explicit async_result(
803 typename detail::packaged_async_result<Function, Allocator,
804 typename result_of<Function(Args...)>::type>::completion_handler_type& h)
805 : detail::packaged_async_result<Function, Allocator,
806 typename result_of<Function(Args...)>::type>(h)
807 {
808 }
809 };
810
811 #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
812
813 template <typename Allocator, typename Result>
814 class async_result<use_future_t<Allocator>, Result()>
815 : public detail::promise_async_result<void(), Allocator>
816 {
817 public:
818 explicit async_result(
819 typename detail::promise_async_result<
820 void(), Allocator>::completion_handler_type& h)
821 : detail::promise_async_result<void(), Allocator>(h)
822 {
823 }
824 };
825
826 template <typename Function, typename Allocator, typename Result>
827 class async_result<detail::packaged_token<Function, Allocator>, Result()>
828 : public detail::packaged_async_result<Function, Allocator,
829 typename result_of<Function()>::type>
830 {
831 public:
832 explicit async_result(
833 typename detail::packaged_async_result<Function, Allocator,
834 typename result_of<Function()>::type>::completion_handler_type& h)
835 : detail::packaged_async_result<Function, Allocator,
836 typename result_of<Function()>::type>(h)
837 {
838 }
839 };
840
841 #define BOOST_ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \
842 template <typename Allocator, \
843 typename Result, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
844 class async_result<use_future_t<Allocator>, \
845 Result(BOOST_ASIO_VARIADIC_TARGS(n))> \
846 : public detail::promise_async_result< \
847 void(BOOST_ASIO_VARIADIC_DECAY(n)), Allocator> \
848 { \
849 public: \
850 explicit async_result( \
851 typename detail::promise_async_result< \
852 void(BOOST_ASIO_VARIADIC_DECAY(n)), \
853 Allocator>::completion_handler_type& h) \
854 : detail::promise_async_result< \
855 void(BOOST_ASIO_VARIADIC_DECAY(n)), Allocator>(h) \
856 { \
857 } \
858 }; \
859 \
860 template <typename Function, typename Allocator, \
861 typename Result, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
862 class async_result<detail::packaged_token<Function, Allocator>, \
863 Result(BOOST_ASIO_VARIADIC_TARGS(n))> \
864 : public detail::packaged_async_result<Function, Allocator, \
865 typename result_of<Function(BOOST_ASIO_VARIADIC_TARGS(n))>::type> \
866 { \
867 public: \
868 explicit async_result( \
869 typename detail::packaged_async_result<Function, Allocator, \
870 typename result_of<Function(BOOST_ASIO_VARIADIC_TARGS(n))>::type \
871 >::completion_handler_type& h) \
872 : detail::packaged_async_result<Function, Allocator, \
873 typename result_of<Function(BOOST_ASIO_VARIADIC_TARGS(n))>::type>(h) \
874 { \
875 } \
876 }; \
877 /**/
878 BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_RESULT_DEF)
879 #undef BOOST_ASIO_PRIVATE_ASYNC_RESULT_DEF
880
881 #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
882
883 #if !defined(BOOST_ASIO_NO_DEPRECATED)
884
885 template <typename Allocator, typename Signature>
886 struct handler_type<use_future_t<Allocator>, Signature>
887 {
888 typedef typename async_result<use_future_t<Allocator>,
889 Signature>::completion_handler_type type;
890 };
891
892 template <typename Signature, typename Allocator>
893 class async_result<detail::promise_handler<Signature, Allocator> >
894 : public detail::promise_async_result<Signature, Allocator>
895 {
896 public:
897 typedef typename detail::promise_async_result<
898 Signature, Allocator>::return_type type;
899
900 explicit async_result(
901 typename detail::promise_async_result<
902 Signature, Allocator>::completion_handler_type& h)
903 : detail::promise_async_result<Signature, Allocator>(h)
904 {
905 }
906 };
907
908 template <typename Function, typename Allocator, typename Signature>
909 struct handler_type<detail::packaged_token<Function, Allocator>, Signature>
910 {
911 typedef typename async_result<detail::packaged_token<Function, Allocator>,
912 Signature>::completion_handler_type type;
913 };
914
915 template <typename Function, typename Allocator, typename Result>
916 class async_result<detail::packaged_handler<Function, Allocator, Result> >
917 : public detail::packaged_async_result<Function, Allocator, Result>
918 {
919 public:
920 typedef typename detail::packaged_async_result<
921 Function, Allocator, Result>::return_type type;
922
923 explicit async_result(
924 typename detail::packaged_async_result<
925 Function, Allocator, Result>::completion_handler_type& h)
926 : detail::packaged_async_result<Function, Allocator, Result>(h)
927 {
928 }
929 };
930
931 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
932
933 #endif // !defined(GENERATING_DOCUMENTATION)
934
935 } // namespace asio
936 } // namespace boost
937
938 #include <boost/asio/detail/pop_options.hpp>
939
940 #endif // BOOST_ASIO_IMPL_USE_FUTURE_HPP