bind_cancellation_slot.hpp 22 KB

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