bind_handler.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. //
  2. // detail/bind_handler.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2025 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_DETAIL_BIND_HANDLER_HPP
  11. #define BOOST_ASIO_DETAIL_BIND_HANDLER_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/associator.hpp>
  17. #include <boost/asio/detail/handler_cont_helpers.hpp>
  18. #include <boost/asio/detail/type_traits.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. namespace detail {
  23. template <typename Handler>
  24. class binder0
  25. {
  26. public:
  27. template <typename T>
  28. binder0(int, T&& handler)
  29. : handler_(static_cast<T&&>(handler))
  30. {
  31. }
  32. binder0(Handler& handler)
  33. : handler_(static_cast<Handler&&>(handler))
  34. {
  35. }
  36. binder0(const binder0& other)
  37. : handler_(other.handler_)
  38. {
  39. }
  40. binder0(binder0&& other)
  41. : handler_(static_cast<Handler&&>(other.handler_))
  42. {
  43. }
  44. void operator()()
  45. {
  46. static_cast<Handler&&>(handler_)();
  47. }
  48. void operator()() const
  49. {
  50. handler_();
  51. }
  52. //private:
  53. Handler handler_;
  54. };
  55. template <typename Handler>
  56. inline bool asio_handler_is_continuation(
  57. binder0<Handler>* this_handler)
  58. {
  59. return boost_asio_handler_cont_helpers::is_continuation(
  60. this_handler->handler_);
  61. }
  62. template <typename Handler>
  63. inline binder0<decay_t<Handler>> bind_handler(
  64. Handler&& handler)
  65. {
  66. return binder0<decay_t<Handler>>(
  67. 0, static_cast<Handler&&>(handler));
  68. }
  69. template <typename Handler, typename Arg1>
  70. class binder1
  71. {
  72. public:
  73. template <typename T>
  74. binder1(int, T&& handler, const Arg1& arg1)
  75. : handler_(static_cast<T&&>(handler)),
  76. arg1_(arg1)
  77. {
  78. }
  79. binder1(Handler& handler, const Arg1& arg1)
  80. : handler_(static_cast<Handler&&>(handler)),
  81. arg1_(arg1)
  82. {
  83. }
  84. binder1(const binder1& other)
  85. : handler_(other.handler_),
  86. arg1_(other.arg1_)
  87. {
  88. }
  89. binder1(binder1&& other)
  90. : handler_(static_cast<Handler&&>(other.handler_)),
  91. arg1_(static_cast<Arg1&&>(other.arg1_))
  92. {
  93. }
  94. void operator()()
  95. {
  96. static_cast<Handler&&>(handler_)(
  97. static_cast<const Arg1&>(arg1_));
  98. }
  99. void operator()() const
  100. {
  101. handler_(arg1_);
  102. }
  103. //private:
  104. Handler handler_;
  105. Arg1 arg1_;
  106. };
  107. template <typename Handler, typename Arg1>
  108. inline bool asio_handler_is_continuation(
  109. binder1<Handler, Arg1>* this_handler)
  110. {
  111. return boost_asio_handler_cont_helpers::is_continuation(
  112. this_handler->handler_);
  113. }
  114. template <typename Handler, typename Arg1>
  115. inline binder1<decay_t<Handler>, Arg1> bind_handler(
  116. Handler&& handler, const Arg1& arg1)
  117. {
  118. return binder1<decay_t<Handler>, Arg1>(0,
  119. static_cast<Handler&&>(handler), arg1);
  120. }
  121. template <typename Handler, typename Arg1, typename Arg2>
  122. class binder2
  123. {
  124. public:
  125. template <typename T>
  126. binder2(int, T&& handler,
  127. const Arg1& arg1, const Arg2& arg2)
  128. : handler_(static_cast<T&&>(handler)),
  129. arg1_(arg1),
  130. arg2_(arg2)
  131. {
  132. }
  133. binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)
  134. : handler_(static_cast<Handler&&>(handler)),
  135. arg1_(arg1),
  136. arg2_(arg2)
  137. {
  138. }
  139. binder2(const binder2& other)
  140. : handler_(other.handler_),
  141. arg1_(other.arg1_),
  142. arg2_(other.arg2_)
  143. {
  144. }
  145. binder2(binder2&& other)
  146. : handler_(static_cast<Handler&&>(other.handler_)),
  147. arg1_(static_cast<Arg1&&>(other.arg1_)),
  148. arg2_(static_cast<Arg2&&>(other.arg2_))
  149. {
  150. }
  151. void operator()()
  152. {
  153. static_cast<Handler&&>(handler_)(
  154. static_cast<const Arg1&>(arg1_),
  155. static_cast<const Arg2&>(arg2_));
  156. }
  157. void operator()() const
  158. {
  159. handler_(arg1_, arg2_);
  160. }
  161. //private:
  162. Handler handler_;
  163. Arg1 arg1_;
  164. Arg2 arg2_;
  165. };
  166. template <typename Handler, typename Arg1, typename Arg2>
  167. inline bool asio_handler_is_continuation(
  168. binder2<Handler, Arg1, Arg2>* this_handler)
  169. {
  170. return boost_asio_handler_cont_helpers::is_continuation(
  171. this_handler->handler_);
  172. }
  173. template <typename Handler, typename Arg1, typename Arg2>
  174. inline binder2<decay_t<Handler>, Arg1, Arg2> bind_handler(
  175. Handler&& handler, const Arg1& arg1, const Arg2& arg2)
  176. {
  177. return binder2<decay_t<Handler>, Arg1, Arg2>(0,
  178. static_cast<Handler&&>(handler), arg1, arg2);
  179. }
  180. template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
  181. class binder3
  182. {
  183. public:
  184. template <typename T>
  185. binder3(int, T&& handler, const Arg1& arg1,
  186. const Arg2& arg2, const Arg3& arg3)
  187. : handler_(static_cast<T&&>(handler)),
  188. arg1_(arg1),
  189. arg2_(arg2),
  190. arg3_(arg3)
  191. {
  192. }
  193. binder3(Handler& handler, const Arg1& arg1,
  194. const Arg2& arg2, const Arg3& arg3)
  195. : handler_(static_cast<Handler&&>(handler)),
  196. arg1_(arg1),
  197. arg2_(arg2),
  198. arg3_(arg3)
  199. {
  200. }
  201. binder3(const binder3& other)
  202. : handler_(other.handler_),
  203. arg1_(other.arg1_),
  204. arg2_(other.arg2_),
  205. arg3_(other.arg3_)
  206. {
  207. }
  208. binder3(binder3&& other)
  209. : handler_(static_cast<Handler&&>(other.handler_)),
  210. arg1_(static_cast<Arg1&&>(other.arg1_)),
  211. arg2_(static_cast<Arg2&&>(other.arg2_)),
  212. arg3_(static_cast<Arg3&&>(other.arg3_))
  213. {
  214. }
  215. void operator()()
  216. {
  217. static_cast<Handler&&>(handler_)(
  218. static_cast<const Arg1&>(arg1_),
  219. static_cast<const Arg2&>(arg2_),
  220. static_cast<const Arg3&>(arg3_));
  221. }
  222. void operator()() const
  223. {
  224. handler_(arg1_, arg2_, arg3_);
  225. }
  226. //private:
  227. Handler handler_;
  228. Arg1 arg1_;
  229. Arg2 arg2_;
  230. Arg3 arg3_;
  231. };
  232. template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
  233. inline bool asio_handler_is_continuation(
  234. binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
  235. {
  236. return boost_asio_handler_cont_helpers::is_continuation(
  237. this_handler->handler_);
  238. }
  239. template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
  240. inline binder3<decay_t<Handler>, Arg1, Arg2, Arg3> bind_handler(
  241. Handler&& handler, const Arg1& arg1, const Arg2& arg2,
  242. const Arg3& arg3)
  243. {
  244. return binder3<decay_t<Handler>, Arg1, Arg2, Arg3>(0,
  245. static_cast<Handler&&>(handler), arg1, arg2, arg3);
  246. }
  247. template <typename Handler, typename Arg1,
  248. typename Arg2, typename Arg3, typename Arg4>
  249. class binder4
  250. {
  251. public:
  252. template <typename T>
  253. binder4(int, T&& handler, const Arg1& arg1,
  254. const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
  255. : handler_(static_cast<T&&>(handler)),
  256. arg1_(arg1),
  257. arg2_(arg2),
  258. arg3_(arg3),
  259. arg4_(arg4)
  260. {
  261. }
  262. binder4(Handler& handler, const Arg1& arg1,
  263. const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
  264. : handler_(static_cast<Handler&&>(handler)),
  265. arg1_(arg1),
  266. arg2_(arg2),
  267. arg3_(arg3),
  268. arg4_(arg4)
  269. {
  270. }
  271. binder4(const binder4& other)
  272. : handler_(other.handler_),
  273. arg1_(other.arg1_),
  274. arg2_(other.arg2_),
  275. arg3_(other.arg3_),
  276. arg4_(other.arg4_)
  277. {
  278. }
  279. binder4(binder4&& other)
  280. : handler_(static_cast<Handler&&>(other.handler_)),
  281. arg1_(static_cast<Arg1&&>(other.arg1_)),
  282. arg2_(static_cast<Arg2&&>(other.arg2_)),
  283. arg3_(static_cast<Arg3&&>(other.arg3_)),
  284. arg4_(static_cast<Arg4&&>(other.arg4_))
  285. {
  286. }
  287. void operator()()
  288. {
  289. static_cast<Handler&&>(handler_)(
  290. static_cast<const Arg1&>(arg1_),
  291. static_cast<const Arg2&>(arg2_),
  292. static_cast<const Arg3&>(arg3_),
  293. static_cast<const Arg4&>(arg4_));
  294. }
  295. void operator()() const
  296. {
  297. handler_(arg1_, arg2_, arg3_, arg4_);
  298. }
  299. //private:
  300. Handler handler_;
  301. Arg1 arg1_;
  302. Arg2 arg2_;
  303. Arg3 arg3_;
  304. Arg4 arg4_;
  305. };
  306. template <typename Handler, typename Arg1,
  307. typename Arg2, typename Arg3, typename Arg4>
  308. inline bool asio_handler_is_continuation(
  309. binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
  310. {
  311. return boost_asio_handler_cont_helpers::is_continuation(
  312. this_handler->handler_);
  313. }
  314. template <typename Handler, typename Arg1,
  315. typename Arg2, typename Arg3, typename Arg4>
  316. inline binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>
  317. bind_handler(Handler&& handler, const Arg1& arg1,
  318. const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
  319. {
  320. return binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>(0,
  321. static_cast<Handler&&>(handler), arg1, arg2, arg3, arg4);
  322. }
  323. template <typename Handler, typename Arg1, typename Arg2,
  324. typename Arg3, typename Arg4, typename Arg5>
  325. class binder5
  326. {
  327. public:
  328. template <typename T>
  329. binder5(int, T&& handler, const Arg1& arg1,
  330. const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
  331. : handler_(static_cast<T&&>(handler)),
  332. arg1_(arg1),
  333. arg2_(arg2),
  334. arg3_(arg3),
  335. arg4_(arg4),
  336. arg5_(arg5)
  337. {
  338. }
  339. binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2,
  340. const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
  341. : handler_(static_cast<Handler&&>(handler)),
  342. arg1_(arg1),
  343. arg2_(arg2),
  344. arg3_(arg3),
  345. arg4_(arg4),
  346. arg5_(arg5)
  347. {
  348. }
  349. binder5(const binder5& other)
  350. : handler_(other.handler_),
  351. arg1_(other.arg1_),
  352. arg2_(other.arg2_),
  353. arg3_(other.arg3_),
  354. arg4_(other.arg4_),
  355. arg5_(other.arg5_)
  356. {
  357. }
  358. binder5(binder5&& other)
  359. : handler_(static_cast<Handler&&>(other.handler_)),
  360. arg1_(static_cast<Arg1&&>(other.arg1_)),
  361. arg2_(static_cast<Arg2&&>(other.arg2_)),
  362. arg3_(static_cast<Arg3&&>(other.arg3_)),
  363. arg4_(static_cast<Arg4&&>(other.arg4_)),
  364. arg5_(static_cast<Arg5&&>(other.arg5_))
  365. {
  366. }
  367. void operator()()
  368. {
  369. static_cast<Handler&&>(handler_)(
  370. static_cast<const Arg1&>(arg1_),
  371. static_cast<const Arg2&>(arg2_),
  372. static_cast<const Arg3&>(arg3_),
  373. static_cast<const Arg4&>(arg4_),
  374. static_cast<const Arg5&>(arg5_));
  375. }
  376. void operator()() const
  377. {
  378. handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
  379. }
  380. //private:
  381. Handler handler_;
  382. Arg1 arg1_;
  383. Arg2 arg2_;
  384. Arg3 arg3_;
  385. Arg4 arg4_;
  386. Arg5 arg5_;
  387. };
  388. template <typename Handler, typename Arg1, typename Arg2,
  389. typename Arg3, typename Arg4, typename Arg5>
  390. inline bool asio_handler_is_continuation(
  391. binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
  392. {
  393. return boost_asio_handler_cont_helpers::is_continuation(
  394. this_handler->handler_);
  395. }
  396. template <typename Handler, typename Arg1, typename Arg2,
  397. typename Arg3, typename Arg4, typename Arg5>
  398. inline binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>
  399. bind_handler(Handler&& handler, const Arg1& arg1,
  400. const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
  401. {
  402. return binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>(0,
  403. static_cast<Handler&&>(handler), arg1, arg2, arg3, arg4, arg5);
  404. }
  405. template <typename Handler, typename Arg1>
  406. class move_binder1
  407. {
  408. public:
  409. move_binder1(int, Handler&& handler,
  410. Arg1&& arg1)
  411. : handler_(static_cast<Handler&&>(handler)),
  412. arg1_(static_cast<Arg1&&>(arg1))
  413. {
  414. }
  415. move_binder1(move_binder1&& other)
  416. : handler_(static_cast<Handler&&>(other.handler_)),
  417. arg1_(static_cast<Arg1&&>(other.arg1_))
  418. {
  419. }
  420. void operator()()
  421. {
  422. static_cast<Handler&&>(handler_)(
  423. static_cast<Arg1&&>(arg1_));
  424. }
  425. //private:
  426. Handler handler_;
  427. Arg1 arg1_;
  428. };
  429. template <typename Handler, typename Arg1>
  430. inline move_binder1<decay_t<Handler>, decay_t<Arg1>> move_bind_handler(
  431. Handler&& handler, Arg1&& arg1)
  432. {
  433. return move_binder1<decay_t<Handler>, decay_t<Arg1>>(0,
  434. static_cast<Handler&&>(handler), static_cast<Arg1&&>(arg1));
  435. }
  436. template <typename Handler, typename Arg1>
  437. inline bool asio_handler_is_continuation(
  438. move_binder1<Handler, Arg1>* this_handler)
  439. {
  440. return boost_asio_handler_cont_helpers::is_continuation(
  441. this_handler->handler_);
  442. }
  443. template <typename Handler, typename Arg1, typename Arg2>
  444. class move_binder2
  445. {
  446. public:
  447. move_binder2(int, Handler&& handler,
  448. const Arg1& arg1, Arg2&& arg2)
  449. : handler_(static_cast<Handler&&>(handler)),
  450. arg1_(arg1),
  451. arg2_(static_cast<Arg2&&>(arg2))
  452. {
  453. }
  454. move_binder2(move_binder2&& other)
  455. : handler_(static_cast<Handler&&>(other.handler_)),
  456. arg1_(static_cast<Arg1&&>(other.arg1_)),
  457. arg2_(static_cast<Arg2&&>(other.arg2_))
  458. {
  459. }
  460. void operator()()
  461. {
  462. static_cast<Handler&&>(handler_)(
  463. static_cast<const Arg1&>(arg1_),
  464. static_cast<Arg2&&>(arg2_));
  465. }
  466. //private:
  467. Handler handler_;
  468. Arg1 arg1_;
  469. Arg2 arg2_;
  470. };
  471. template <typename Handler, typename Arg1, typename Arg2>
  472. inline bool asio_handler_is_continuation(
  473. move_binder2<Handler, Arg1, Arg2>* this_handler)
  474. {
  475. return boost_asio_handler_cont_helpers::is_continuation(
  476. this_handler->handler_);
  477. }
  478. } // namespace detail
  479. template <template <typename, typename> class Associator,
  480. typename Handler, typename DefaultCandidate>
  481. struct associator<Associator,
  482. detail::binder0<Handler>, DefaultCandidate>
  483. : Associator<Handler, DefaultCandidate>
  484. {
  485. static typename Associator<Handler, DefaultCandidate>::type get(
  486. const detail::binder0<Handler>& h) noexcept
  487. {
  488. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  489. }
  490. static auto get(const detail::binder0<Handler>& h,
  491. const DefaultCandidate& c) noexcept
  492. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  493. {
  494. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  495. }
  496. };
  497. template <template <typename, typename> class Associator,
  498. typename Handler, typename Arg1, typename DefaultCandidate>
  499. struct associator<Associator,
  500. detail::binder1<Handler, Arg1>, DefaultCandidate>
  501. : Associator<Handler, DefaultCandidate>
  502. {
  503. static typename Associator<Handler, DefaultCandidate>::type get(
  504. const detail::binder1<Handler, Arg1>& h) noexcept
  505. {
  506. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  507. }
  508. static auto get(const detail::binder1<Handler, Arg1>& h,
  509. const DefaultCandidate& c) noexcept
  510. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  511. {
  512. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  513. }
  514. };
  515. template <template <typename, typename> class Associator,
  516. typename Handler, typename Arg1, typename Arg2,
  517. typename DefaultCandidate>
  518. struct associator<Associator,
  519. detail::binder2<Handler, Arg1, Arg2>, DefaultCandidate>
  520. : Associator<Handler, DefaultCandidate>
  521. {
  522. static typename Associator<Handler, DefaultCandidate>::type get(
  523. const detail::binder2<Handler, Arg1, Arg2>& h) noexcept
  524. {
  525. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  526. }
  527. static auto get(const detail::binder2<Handler, Arg1, Arg2>& h,
  528. const DefaultCandidate& c) noexcept
  529. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  530. {
  531. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  532. }
  533. };
  534. template <template <typename, typename> class Associator,
  535. typename Handler, typename Arg1, typename Arg2, typename Arg3,
  536. typename DefaultCandidate>
  537. struct associator<Associator,
  538. detail::binder3<Handler, Arg1, Arg2, Arg3>, DefaultCandidate>
  539. : Associator<Handler, DefaultCandidate>
  540. {
  541. static typename Associator<Handler, DefaultCandidate>::type get(
  542. const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) noexcept
  543. {
  544. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  545. }
  546. static auto get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,
  547. const DefaultCandidate& c) noexcept
  548. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  549. {
  550. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  551. }
  552. };
  553. template <template <typename, typename> class Associator,
  554. typename Handler, typename Arg1, typename Arg2, typename Arg3,
  555. typename Arg4, typename DefaultCandidate>
  556. struct associator<Associator,
  557. detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>, DefaultCandidate>
  558. : Associator<Handler, DefaultCandidate>
  559. {
  560. static typename Associator<Handler, DefaultCandidate>::type get(
  561. const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h) noexcept
  562. {
  563. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  564. }
  565. static auto get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,
  566. const DefaultCandidate& c) noexcept
  567. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  568. {
  569. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  570. }
  571. };
  572. template <template <typename, typename> class Associator,
  573. typename Handler, typename Arg1, typename Arg2, typename Arg3,
  574. typename Arg4, typename Arg5, typename DefaultCandidate>
  575. struct associator<Associator,
  576. detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>, DefaultCandidate>
  577. : Associator<Handler, DefaultCandidate>
  578. {
  579. static typename Associator<Handler, DefaultCandidate>::type get(
  580. const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h) noexcept
  581. {
  582. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  583. }
  584. static auto get(
  585. const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,
  586. const DefaultCandidate& c) noexcept
  587. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  588. {
  589. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  590. }
  591. };
  592. template <template <typename, typename> class Associator,
  593. typename Handler, typename Arg1, typename DefaultCandidate>
  594. struct associator<Associator,
  595. detail::move_binder1<Handler, Arg1>, DefaultCandidate>
  596. : Associator<Handler, DefaultCandidate>
  597. {
  598. static typename Associator<Handler, DefaultCandidate>::type get(
  599. const detail::move_binder1<Handler, Arg1>& h) noexcept
  600. {
  601. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  602. }
  603. static auto get(const detail::move_binder1<Handler, Arg1>& h,
  604. const DefaultCandidate& c) noexcept
  605. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  606. {
  607. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  608. }
  609. };
  610. template <template <typename, typename> class Associator,
  611. typename Handler, typename Arg1, typename Arg2, typename DefaultCandidate>
  612. struct associator<Associator,
  613. detail::move_binder2<Handler, Arg1, Arg2>, DefaultCandidate>
  614. : Associator<Handler, DefaultCandidate>
  615. {
  616. static typename Associator<Handler, DefaultCandidate>::type get(
  617. const detail::move_binder2<Handler, Arg1, Arg2>& h) noexcept
  618. {
  619. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  620. }
  621. static auto get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
  622. const DefaultCandidate& c) noexcept
  623. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  624. {
  625. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  626. }
  627. };
  628. } // namespace asio
  629. } // namespace boost
  630. #include <boost/asio/detail/pop_options.hpp>
  631. #endif // BOOST_ASIO_DETAIL_BIND_HANDLER_HPP