bind_handler.hpp 18 KB

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