Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

817 lines
22KB

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