bind_cancellation_slot.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. //
  2. // bind_cancellation_slot.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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. #ifndef ASIO_BIND_CANCELLATION_SLOT_HPP
  11. #define ASIO_BIND_CANCELLATION_SLOT_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/type_traits.hpp"
  17. #include "asio/detail/variadic_templates.hpp"
  18. #include "asio/associated_cancellation_slot.hpp"
  19. #include "asio/associator.hpp"
  20. #include "asio/async_result.hpp"
  21. #include "asio/detail/push_options.hpp"
  22. namespace asio {
  23. namespace detail {
  24. // Helper to automatically define nested typedef result_type.
  25. template <typename T, typename = void>
  26. struct cancellation_slot_binder_result_type
  27. {
  28. protected:
  29. typedef void result_type_or_void;
  30. };
  31. template <typename T>
  32. struct cancellation_slot_binder_result_type<T,
  33. typename void_type<typename T::result_type>::type>
  34. {
  35. typedef typename T::result_type result_type;
  36. protected:
  37. typedef result_type result_type_or_void;
  38. };
  39. template <typename R>
  40. struct cancellation_slot_binder_result_type<R(*)()>
  41. {
  42. typedef R result_type;
  43. protected:
  44. typedef result_type result_type_or_void;
  45. };
  46. template <typename R>
  47. struct cancellation_slot_binder_result_type<R(&)()>
  48. {
  49. typedef R result_type;
  50. protected:
  51. typedef result_type result_type_or_void;
  52. };
  53. template <typename R, typename A1>
  54. struct cancellation_slot_binder_result_type<R(*)(A1)>
  55. {
  56. typedef R result_type;
  57. protected:
  58. typedef result_type result_type_or_void;
  59. };
  60. template <typename R, typename A1>
  61. struct cancellation_slot_binder_result_type<R(&)(A1)>
  62. {
  63. typedef R result_type;
  64. protected:
  65. typedef result_type result_type_or_void;
  66. };
  67. template <typename R, typename A1, typename A2>
  68. struct cancellation_slot_binder_result_type<R(*)(A1, A2)>
  69. {
  70. typedef R result_type;
  71. protected:
  72. typedef result_type result_type_or_void;
  73. };
  74. template <typename R, typename A1, typename A2>
  75. struct cancellation_slot_binder_result_type<R(&)(A1, A2)>
  76. {
  77. typedef R result_type;
  78. protected:
  79. typedef result_type result_type_or_void;
  80. };
  81. // Helper to automatically define nested typedef argument_type.
  82. template <typename T, typename = void>
  83. struct cancellation_slot_binder_argument_type {};
  84. template <typename T>
  85. struct cancellation_slot_binder_argument_type<T,
  86. typename void_type<typename T::argument_type>::type>
  87. {
  88. typedef typename T::argument_type argument_type;
  89. };
  90. template <typename R, typename A1>
  91. struct cancellation_slot_binder_argument_type<R(*)(A1)>
  92. {
  93. typedef A1 argument_type;
  94. };
  95. template <typename R, typename A1>
  96. struct cancellation_slot_binder_argument_type<R(&)(A1)>
  97. {
  98. typedef A1 argument_type;
  99. };
  100. // Helper to automatically define nested typedefs first_argument_type and
  101. // second_argument_type.
  102. template <typename T, typename = void>
  103. struct cancellation_slot_binder_argument_types {};
  104. template <typename T>
  105. struct cancellation_slot_binder_argument_types<T,
  106. typename void_type<typename T::first_argument_type>::type>
  107. {
  108. typedef typename T::first_argument_type first_argument_type;
  109. typedef typename T::second_argument_type second_argument_type;
  110. };
  111. template <typename R, typename A1, typename A2>
  112. struct cancellation_slot_binder_argument_type<R(*)(A1, A2)>
  113. {
  114. typedef A1 first_argument_type;
  115. typedef A2 second_argument_type;
  116. };
  117. template <typename R, typename A1, typename A2>
  118. struct cancellation_slot_binder_argument_type<R(&)(A1, A2)>
  119. {
  120. typedef A1 first_argument_type;
  121. typedef A2 second_argument_type;
  122. };
  123. // Helper to enable SFINAE on zero-argument operator() below.
  124. template <typename T, typename = void>
  125. struct cancellation_slot_binder_result_of0
  126. {
  127. typedef void type;
  128. };
  129. template <typename T>
  130. struct cancellation_slot_binder_result_of0<T,
  131. typename void_type<typename result_of<T()>::type>::type>
  132. {
  133. typedef typename result_of<T()>::type type;
  134. };
  135. } // namespace detail
  136. /// A call wrapper type to bind a cancellation slot of type @c CancellationSlot
  137. /// to an object of type @c T.
  138. template <typename T, typename CancellationSlot>
  139. class cancellation_slot_binder
  140. #if !defined(GENERATING_DOCUMENTATION)
  141. : public detail::cancellation_slot_binder_result_type<T>,
  142. public detail::cancellation_slot_binder_argument_type<T>,
  143. public detail::cancellation_slot_binder_argument_types<T>
  144. #endif // !defined(GENERATING_DOCUMENTATION)
  145. {
  146. public:
  147. /// The type of the target object.
  148. typedef T target_type;
  149. /// The type of the associated cancellation slot.
  150. typedef CancellationSlot cancellation_slot_type;
  151. #if defined(GENERATING_DOCUMENTATION)
  152. /// The return type if a function.
  153. /**
  154. * The type of @c result_type is based on the type @c T of the wrapper's
  155. * target object:
  156. *
  157. * @li if @c T is a pointer to function type, @c result_type is a synonym for
  158. * the return type of @c T;
  159. *
  160. * @li if @c T is a class type with a member type @c result_type, then @c
  161. * result_type is a synonym for @c T::result_type;
  162. *
  163. * @li otherwise @c result_type is not defined.
  164. */
  165. typedef see_below result_type;
  166. /// The type of the function's argument.
  167. /**
  168. * The type of @c argument_type is based on the type @c T of the wrapper's
  169. * target object:
  170. *
  171. * @li if @c T is a pointer to a function type accepting a single argument,
  172. * @c argument_type is a synonym for the return type of @c T;
  173. *
  174. * @li if @c T is a class type with a member type @c argument_type, then @c
  175. * argument_type is a synonym for @c T::argument_type;
  176. *
  177. * @li otherwise @c argument_type is not defined.
  178. */
  179. typedef see_below argument_type;
  180. /// The type of the function's first argument.
  181. /**
  182. * The type of @c first_argument_type is based on the type @c T of the
  183. * wrapper's target object:
  184. *
  185. * @li if @c T is a pointer to a function type accepting two arguments, @c
  186. * first_argument_type is a synonym for the return type of @c T;
  187. *
  188. * @li if @c T is a class type with a member type @c first_argument_type,
  189. * then @c first_argument_type is a synonym for @c T::first_argument_type;
  190. *
  191. * @li otherwise @c first_argument_type is not defined.
  192. */
  193. typedef see_below first_argument_type;
  194. /// The type of the function's second argument.
  195. /**
  196. * The type of @c second_argument_type is based on the type @c T of the
  197. * wrapper's target object:
  198. *
  199. * @li if @c T is a pointer to a function type accepting two arguments, @c
  200. * second_argument_type is a synonym for the return type of @c T;
  201. *
  202. * @li if @c T is a class type with a member type @c first_argument_type,
  203. * then @c second_argument_type is a synonym for @c T::second_argument_type;
  204. *
  205. * @li otherwise @c second_argument_type is not defined.
  206. */
  207. typedef see_below second_argument_type;
  208. #endif // defined(GENERATING_DOCUMENTATION)
  209. /// Construct a cancellation slot wrapper for the specified object.
  210. /**
  211. * This constructor is only valid if the type @c T is constructible from type
  212. * @c U.
  213. */
  214. template <typename U>
  215. cancellation_slot_binder(const cancellation_slot_type& s,
  216. ASIO_MOVE_ARG(U) u)
  217. : slot_(s),
  218. target_(ASIO_MOVE_CAST(U)(u))
  219. {
  220. }
  221. /// Copy constructor.
  222. cancellation_slot_binder(const cancellation_slot_binder& other)
  223. : slot_(other.get_cancellation_slot()),
  224. target_(other.get())
  225. {
  226. }
  227. /// Construct a copy, but specify a different cancellation slot.
  228. cancellation_slot_binder(const cancellation_slot_type& s,
  229. const cancellation_slot_binder& other)
  230. : slot_(s),
  231. target_(other.get())
  232. {
  233. }
  234. /// Construct a copy of a different cancellation slot wrapper type.
  235. /**
  236. * This constructor is only valid if the @c CancellationSlot type is
  237. * constructible from type @c OtherCancellationSlot, and the type @c T is
  238. * constructible from type @c U.
  239. */
  240. template <typename U, typename OtherCancellationSlot>
  241. cancellation_slot_binder(
  242. const cancellation_slot_binder<U, OtherCancellationSlot>& other)
  243. : slot_(other.get_cancellation_slot()),
  244. target_(other.get())
  245. {
  246. }
  247. /// Construct a copy of a different cancellation slot wrapper type, but
  248. /// specify a different cancellation slot.
  249. /**
  250. * This constructor is only valid if the type @c T is constructible from type
  251. * @c U.
  252. */
  253. template <typename U, typename OtherCancellationSlot>
  254. cancellation_slot_binder(const cancellation_slot_type& s,
  255. const cancellation_slot_binder<U, OtherCancellationSlot>& other)
  256. : slot_(s),
  257. target_(other.get())
  258. {
  259. }
  260. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  261. /// Move constructor.
  262. cancellation_slot_binder(cancellation_slot_binder&& other)
  263. : slot_(ASIO_MOVE_CAST(cancellation_slot_type)(
  264. other.get_cancellation_slot())),
  265. target_(ASIO_MOVE_CAST(T)(other.get()))
  266. {
  267. }
  268. /// Move construct the target object, but specify a different cancellation
  269. /// slot.
  270. cancellation_slot_binder(const cancellation_slot_type& s,
  271. cancellation_slot_binder&& other)
  272. : slot_(s),
  273. target_(ASIO_MOVE_CAST(T)(other.get()))
  274. {
  275. }
  276. /// Move construct from a different cancellation slot wrapper type.
  277. template <typename U, typename OtherCancellationSlot>
  278. cancellation_slot_binder(
  279. cancellation_slot_binder<U, OtherCancellationSlot>&& other)
  280. : slot_(ASIO_MOVE_CAST(OtherCancellationSlot)(
  281. other.get_cancellation_slot())),
  282. target_(ASIO_MOVE_CAST(U)(other.get()))
  283. {
  284. }
  285. /// Move construct from a different cancellation slot wrapper type, but
  286. /// specify a different cancellation slot.
  287. template <typename U, typename OtherCancellationSlot>
  288. cancellation_slot_binder(const cancellation_slot_type& s,
  289. cancellation_slot_binder<U, OtherCancellationSlot>&& other)
  290. : slot_(s),
  291. target_(ASIO_MOVE_CAST(U)(other.get()))
  292. {
  293. }
  294. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  295. /// Destructor.
  296. ~cancellation_slot_binder()
  297. {
  298. }
  299. /// Obtain a reference to the target object.
  300. target_type& get() ASIO_NOEXCEPT
  301. {
  302. return target_;
  303. }
  304. /// Obtain a reference to the target object.
  305. const target_type& get() const ASIO_NOEXCEPT
  306. {
  307. return target_;
  308. }
  309. /// Obtain the associated cancellation slot.
  310. cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT
  311. {
  312. return slot_;
  313. }
  314. #if defined(GENERATING_DOCUMENTATION)
  315. template <typename... Args> auto operator()(Args&& ...);
  316. template <typename... Args> auto operator()(Args&& ...) const;
  317. #elif defined(ASIO_HAS_VARIADIC_TEMPLATES)
  318. /// Forwarding function call operator.
  319. template <typename... Args>
  320. typename result_of<T(Args...)>::type operator()(
  321. ASIO_MOVE_ARG(Args)... args)
  322. {
  323. return target_(ASIO_MOVE_CAST(Args)(args)...);
  324. }
  325. /// Forwarding function call operator.
  326. template <typename... Args>
  327. typename result_of<T(Args...)>::type operator()(
  328. ASIO_MOVE_ARG(Args)... args) const
  329. {
  330. return target_(ASIO_MOVE_CAST(Args)(args)...);
  331. }
  332. #elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
  333. typename detail::cancellation_slot_binder_result_of0<T>::type operator()()
  334. {
  335. return target_();
  336. }
  337. typename detail::cancellation_slot_binder_result_of0<T>::type
  338. operator()() const
  339. {
  340. return target_();
  341. }
  342. #define ASIO_PRIVATE_BINDER_CALL_DEF(n) \
  343. template <ASIO_VARIADIC_TPARAMS(n)> \
  344. typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \
  345. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  346. { \
  347. return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \
  348. } \
  349. \
  350. template <ASIO_VARIADIC_TPARAMS(n)> \
  351. typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \
  352. ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  353. { \
  354. return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \
  355. } \
  356. /**/
  357. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)
  358. #undef ASIO_PRIVATE_BINDER_CALL_DEF
  359. #else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
  360. typedef typename detail::cancellation_slot_binder_result_type<
  361. T>::result_type_or_void result_type_or_void;
  362. result_type_or_void operator()()
  363. {
  364. return target_();
  365. }
  366. result_type_or_void operator()() const
  367. {
  368. return target_();
  369. }
  370. #define ASIO_PRIVATE_BINDER_CALL_DEF(n) \
  371. template <ASIO_VARIADIC_TPARAMS(n)> \
  372. result_type_or_void operator()( \
  373. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  374. { \
  375. return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \
  376. } \
  377. \
  378. template <ASIO_VARIADIC_TPARAMS(n)> \
  379. result_type_or_void operator()( \
  380. ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  381. { \
  382. return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \
  383. } \
  384. /**/
  385. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)
  386. #undef ASIO_PRIVATE_BINDER_CALL_DEF
  387. #endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
  388. private:
  389. CancellationSlot slot_;
  390. T target_;
  391. };
  392. /// Associate an object of type @c T with a cancellation slot of type
  393. /// @c CancellationSlot.
  394. template <typename CancellationSlot, typename T>
  395. ASIO_NODISCARD inline
  396. cancellation_slot_binder<typename decay<T>::type, CancellationSlot>
  397. bind_cancellation_slot(const CancellationSlot& s, ASIO_MOVE_ARG(T) t)
  398. {
  399. return cancellation_slot_binder<
  400. typename decay<T>::type, CancellationSlot>(
  401. s, ASIO_MOVE_CAST(T)(t));
  402. }
  403. #if !defined(GENERATING_DOCUMENTATION)
  404. namespace detail {
  405. template <typename TargetAsyncResult,
  406. typename CancellationSlot, typename = void>
  407. struct cancellation_slot_binder_async_result_completion_handler_type
  408. {
  409. };
  410. template <typename TargetAsyncResult, typename CancellationSlot>
  411. struct cancellation_slot_binder_async_result_completion_handler_type<
  412. TargetAsyncResult, CancellationSlot,
  413. typename void_type<
  414. typename TargetAsyncResult::completion_handler_type
  415. >::type>
  416. {
  417. typedef cancellation_slot_binder<
  418. typename TargetAsyncResult::completion_handler_type, CancellationSlot>
  419. completion_handler_type;
  420. };
  421. template <typename TargetAsyncResult, typename = void>
  422. struct cancellation_slot_binder_async_result_return_type
  423. {
  424. };
  425. template <typename TargetAsyncResult>
  426. struct cancellation_slot_binder_async_result_return_type<
  427. TargetAsyncResult,
  428. typename void_type<
  429. typename TargetAsyncResult::return_type
  430. >::type>
  431. {
  432. typedef typename TargetAsyncResult::return_type return_type;
  433. };
  434. } // namespace detail
  435. template <typename T, typename CancellationSlot, typename Signature>
  436. class async_result<cancellation_slot_binder<T, CancellationSlot>, Signature> :
  437. public detail::cancellation_slot_binder_async_result_completion_handler_type<
  438. async_result<T, Signature>, CancellationSlot>,
  439. public detail::cancellation_slot_binder_async_result_return_type<
  440. async_result<T, Signature> >
  441. {
  442. public:
  443. explicit async_result(cancellation_slot_binder<T, CancellationSlot>& b)
  444. : target_(b.get())
  445. {
  446. }
  447. typename async_result<T, Signature>::return_type get()
  448. {
  449. return target_.get();
  450. }
  451. template <typename Initiation>
  452. struct init_wrapper
  453. {
  454. template <typename Init>
  455. init_wrapper(const CancellationSlot& slot, ASIO_MOVE_ARG(Init) init)
  456. : slot_(slot),
  457. initiation_(ASIO_MOVE_CAST(Init)(init))
  458. {
  459. }
  460. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  461. template <typename Handler, typename... Args>
  462. void operator()(
  463. ASIO_MOVE_ARG(Handler) handler,
  464. ASIO_MOVE_ARG(Args)... args)
  465. {
  466. ASIO_MOVE_CAST(Initiation)(initiation_)(
  467. cancellation_slot_binder<
  468. typename decay<Handler>::type, CancellationSlot>(
  469. slot_, ASIO_MOVE_CAST(Handler)(handler)),
  470. ASIO_MOVE_CAST(Args)(args)...);
  471. }
  472. template <typename Handler, typename... Args>
  473. void operator()(
  474. ASIO_MOVE_ARG(Handler) handler,
  475. ASIO_MOVE_ARG(Args)... args) const
  476. {
  477. initiation_(
  478. cancellation_slot_binder<
  479. typename decay<Handler>::type, CancellationSlot>(
  480. slot_, ASIO_MOVE_CAST(Handler)(handler)),
  481. ASIO_MOVE_CAST(Args)(args)...);
  482. }
  483. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  484. template <typename Handler>
  485. void operator()(
  486. ASIO_MOVE_ARG(Handler) handler)
  487. {
  488. ASIO_MOVE_CAST(Initiation)(initiation_)(
  489. cancellation_slot_binder<
  490. typename decay<Handler>::type, CancellationSlot>(
  491. slot_, ASIO_MOVE_CAST(Handler)(handler)));
  492. }
  493. template <typename Handler>
  494. void operator()(
  495. ASIO_MOVE_ARG(Handler) handler) const
  496. {
  497. initiation_(
  498. cancellation_slot_binder<
  499. typename decay<Handler>::type, CancellationSlot>(
  500. slot_, ASIO_MOVE_CAST(Handler)(handler)));
  501. }
  502. #define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \
  503. template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \
  504. void operator()( \
  505. ASIO_MOVE_ARG(Handler) handler, \
  506. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  507. { \
  508. ASIO_MOVE_CAST(Initiation)(initiation_)( \
  509. cancellation_slot_binder< \
  510. typename decay<Handler>::type, CancellationSlot>( \
  511. slot_, ASIO_MOVE_CAST(Handler)(handler)), \
  512. ASIO_VARIADIC_MOVE_ARGS(n)); \
  513. } \
  514. \
  515. template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \
  516. void operator()( \
  517. ASIO_MOVE_ARG(Handler) handler, \
  518. ASIO_VARIADIC_MOVE_PARAMS(n)) const \
  519. { \
  520. initiation_( \
  521. cancellation_slot_binder< \
  522. typename decay<Handler>::type, CancellationSlot>( \
  523. slot_, ASIO_MOVE_CAST(Handler)(handler)), \
  524. ASIO_VARIADIC_MOVE_ARGS(n)); \
  525. } \
  526. /**/
  527. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)
  528. #undef ASIO_PRIVATE_INIT_WRAPPER_DEF
  529. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  530. CancellationSlot slot_;
  531. Initiation initiation_;
  532. };
  533. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  534. template <typename Initiation, typename RawCompletionToken, typename... Args>
  535. static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,
  536. (async_initiate<T, Signature>(
  537. declval<init_wrapper<typename decay<Initiation>::type> >(),
  538. declval<RawCompletionToken>().get(),
  539. declval<ASIO_MOVE_ARG(Args)>()...)))
  540. initiate(
  541. ASIO_MOVE_ARG(Initiation) initiation,
  542. ASIO_MOVE_ARG(RawCompletionToken) token,
  543. ASIO_MOVE_ARG(Args)... args)
  544. {
  545. return async_initiate<T, Signature>(
  546. init_wrapper<typename decay<Initiation>::type>(
  547. token.get_cancellation_slot(),
  548. ASIO_MOVE_CAST(Initiation)(initiation)),
  549. token.get(), ASIO_MOVE_CAST(Args)(args)...);
  550. }
  551. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  552. template <typename Initiation, typename RawCompletionToken>
  553. static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,
  554. (async_initiate<T, Signature>(
  555. declval<init_wrapper<typename decay<Initiation>::type> >(),
  556. declval<RawCompletionToken>().get())))
  557. initiate(
  558. ASIO_MOVE_ARG(Initiation) initiation,
  559. ASIO_MOVE_ARG(RawCompletionToken) token)
  560. {
  561. return async_initiate<T, Signature>(
  562. init_wrapper<typename decay<Initiation>::type>(
  563. token.get_cancellation_slot(),
  564. ASIO_MOVE_CAST(Initiation)(initiation)),
  565. token.get());
  566. }
  567. #define ASIO_PRIVATE_INITIATE_DEF(n) \
  568. template <typename Initiation, typename RawCompletionToken, \
  569. ASIO_VARIADIC_TPARAMS(n)> \
  570. static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \
  571. (async_initiate<T, Signature>( \
  572. declval<init_wrapper<typename decay<Initiation>::type> >(), \
  573. declval<RawCompletionToken>().get(), \
  574. ASIO_VARIADIC_MOVE_DECLVAL(n)))) \
  575. initiate( \
  576. ASIO_MOVE_ARG(Initiation) initiation, \
  577. ASIO_MOVE_ARG(RawCompletionToken) token, \
  578. ASIO_VARIADIC_MOVE_PARAMS(n)) \
  579. { \
  580. return async_initiate<T, Signature>( \
  581. init_wrapper<typename decay<Initiation>::type>( \
  582. token.get_cancellation_slot(), \
  583. ASIO_MOVE_CAST(Initiation)(initiation)), \
  584. token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \
  585. } \
  586. /**/
  587. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)
  588. #undef ASIO_PRIVATE_INITIATE_DEF
  589. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  590. private:
  591. async_result(const async_result&) ASIO_DELETED;
  592. async_result& operator=(const async_result&) ASIO_DELETED;
  593. async_result<T, Signature> target_;
  594. };
  595. template <template <typename, typename> class Associator,
  596. typename T, typename CancellationSlot, typename DefaultCandidate>
  597. struct associator<Associator,
  598. cancellation_slot_binder<T, CancellationSlot>,
  599. DefaultCandidate>
  600. {
  601. typedef typename Associator<T, DefaultCandidate>::type type;
  602. static type get(const cancellation_slot_binder<T, CancellationSlot>& b,
  603. const DefaultCandidate& c = DefaultCandidate()) ASIO_NOEXCEPT
  604. {
  605. return Associator<T, DefaultCandidate>::get(b.get(), c);
  606. }
  607. };
  608. template <typename T, typename CancellationSlot, typename CancellationSlot1>
  609. struct associated_cancellation_slot<
  610. cancellation_slot_binder<T, CancellationSlot>,
  611. CancellationSlot1>
  612. {
  613. typedef CancellationSlot type;
  614. static type get(const cancellation_slot_binder<T, CancellationSlot>& b,
  615. const CancellationSlot1& = CancellationSlot1()) ASIO_NOEXCEPT
  616. {
  617. return b.get_cancellation_slot();
  618. }
  619. };
  620. #endif // !defined(GENERATING_DOCUMENTATION)
  621. } // namespace asio
  622. #include "asio/detail/pop_options.hpp"
  623. #endif // ASIO_BIND_CANCELLATION_SLOT_HPP