bind_handler.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. //
  2. // detail/bind_handler.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2024 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 bool asio_handler_is_continuation(
  431. move_binder1<Handler, Arg1>* this_handler)
  432. {
  433. return boost_asio_handler_cont_helpers::is_continuation(
  434. this_handler->handler_);
  435. }
  436. template <typename Handler, typename Arg1, typename Arg2>
  437. class move_binder2
  438. {
  439. public:
  440. move_binder2(int, Handler&& handler,
  441. const Arg1& arg1, Arg2&& arg2)
  442. : handler_(static_cast<Handler&&>(handler)),
  443. arg1_(arg1),
  444. arg2_(static_cast<Arg2&&>(arg2))
  445. {
  446. }
  447. move_binder2(move_binder2&& other)
  448. : handler_(static_cast<Handler&&>(other.handler_)),
  449. arg1_(static_cast<Arg1&&>(other.arg1_)),
  450. arg2_(static_cast<Arg2&&>(other.arg2_))
  451. {
  452. }
  453. void operator()()
  454. {
  455. static_cast<Handler&&>(handler_)(
  456. static_cast<const Arg1&>(arg1_),
  457. static_cast<Arg2&&>(arg2_));
  458. }
  459. //private:
  460. Handler handler_;
  461. Arg1 arg1_;
  462. Arg2 arg2_;
  463. };
  464. template <typename Handler, typename Arg1, typename Arg2>
  465. inline bool asio_handler_is_continuation(
  466. move_binder2<Handler, Arg1, Arg2>* this_handler)
  467. {
  468. return boost_asio_handler_cont_helpers::is_continuation(
  469. this_handler->handler_);
  470. }
  471. } // namespace detail
  472. template <template <typename, typename> class Associator,
  473. typename Handler, typename DefaultCandidate>
  474. struct associator<Associator,
  475. detail::binder0<Handler>, DefaultCandidate>
  476. : Associator<Handler, DefaultCandidate>
  477. {
  478. static typename Associator<Handler, DefaultCandidate>::type get(
  479. const detail::binder0<Handler>& h) noexcept
  480. {
  481. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  482. }
  483. static auto get(const detail::binder0<Handler>& h,
  484. const DefaultCandidate& c) noexcept
  485. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  486. {
  487. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  488. }
  489. };
  490. template <template <typename, typename> class Associator,
  491. typename Handler, typename Arg1, typename DefaultCandidate>
  492. struct associator<Associator,
  493. detail::binder1<Handler, Arg1>, DefaultCandidate>
  494. : Associator<Handler, DefaultCandidate>
  495. {
  496. static typename Associator<Handler, DefaultCandidate>::type get(
  497. const detail::binder1<Handler, Arg1>& h) noexcept
  498. {
  499. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  500. }
  501. static auto get(const detail::binder1<Handler, Arg1>& h,
  502. const DefaultCandidate& c) noexcept
  503. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  504. {
  505. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  506. }
  507. };
  508. template <template <typename, typename> class Associator,
  509. typename Handler, typename Arg1, typename Arg2,
  510. typename DefaultCandidate>
  511. struct associator<Associator,
  512. detail::binder2<Handler, Arg1, Arg2>, DefaultCandidate>
  513. : Associator<Handler, DefaultCandidate>
  514. {
  515. static typename Associator<Handler, DefaultCandidate>::type get(
  516. const detail::binder2<Handler, Arg1, Arg2>& h) noexcept
  517. {
  518. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  519. }
  520. static auto get(const detail::binder2<Handler, Arg1, Arg2>& h,
  521. const DefaultCandidate& c) noexcept
  522. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  523. {
  524. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  525. }
  526. };
  527. template <template <typename, typename> class Associator,
  528. typename Handler, typename Arg1, typename Arg2, typename Arg3,
  529. typename DefaultCandidate>
  530. struct associator<Associator,
  531. detail::binder3<Handler, Arg1, Arg2, Arg3>, DefaultCandidate>
  532. : Associator<Handler, DefaultCandidate>
  533. {
  534. static typename Associator<Handler, DefaultCandidate>::type get(
  535. const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) noexcept
  536. {
  537. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  538. }
  539. static auto get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,
  540. const DefaultCandidate& c) noexcept
  541. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  542. {
  543. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  544. }
  545. };
  546. template <template <typename, typename> class Associator,
  547. typename Handler, typename Arg1, typename Arg2, typename Arg3,
  548. typename Arg4, typename DefaultCandidate>
  549. struct associator<Associator,
  550. detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>, DefaultCandidate>
  551. : Associator<Handler, DefaultCandidate>
  552. {
  553. static typename Associator<Handler, DefaultCandidate>::type get(
  554. const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h) noexcept
  555. {
  556. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  557. }
  558. static auto get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,
  559. const DefaultCandidate& c) noexcept
  560. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  561. {
  562. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  563. }
  564. };
  565. template <template <typename, typename> class Associator,
  566. typename Handler, typename Arg1, typename Arg2, typename Arg3,
  567. typename Arg4, typename Arg5, typename DefaultCandidate>
  568. struct associator<Associator,
  569. detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>, DefaultCandidate>
  570. : Associator<Handler, DefaultCandidate>
  571. {
  572. static typename Associator<Handler, DefaultCandidate>::type get(
  573. const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h) noexcept
  574. {
  575. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  576. }
  577. static auto get(
  578. const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,
  579. const DefaultCandidate& c) noexcept
  580. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  581. {
  582. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  583. }
  584. };
  585. template <template <typename, typename> class Associator,
  586. typename Handler, typename Arg1, typename DefaultCandidate>
  587. struct associator<Associator,
  588. detail::move_binder1<Handler, Arg1>, DefaultCandidate>
  589. : Associator<Handler, DefaultCandidate>
  590. {
  591. static typename Associator<Handler, DefaultCandidate>::type get(
  592. const detail::move_binder1<Handler, Arg1>& h) noexcept
  593. {
  594. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  595. }
  596. static auto get(const detail::move_binder1<Handler, Arg1>& h,
  597. const DefaultCandidate& c) noexcept
  598. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  599. {
  600. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  601. }
  602. };
  603. template <template <typename, typename> class Associator,
  604. typename Handler, typename Arg1, typename Arg2, typename DefaultCandidate>
  605. struct associator<Associator,
  606. detail::move_binder2<Handler, Arg1, Arg2>, DefaultCandidate>
  607. : Associator<Handler, DefaultCandidate>
  608. {
  609. static typename Associator<Handler, DefaultCandidate>::type get(
  610. const detail::move_binder2<Handler, Arg1, Arg2>& h) noexcept
  611. {
  612. return Associator<Handler, DefaultCandidate>::get(h.handler_);
  613. }
  614. static auto get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
  615. const DefaultCandidate& c) noexcept
  616. -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
  617. {
  618. return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
  619. }
  620. };
  621. } // namespace asio
  622. } // namespace boost
  623. #include <boost/asio/detail/pop_options.hpp>
  624. #endif // BOOST_ASIO_DETAIL_BIND_HANDLER_HPP