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.

460 lines
12KB

  1. //
  2. // detail/bind_handler.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 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. #if defined(ASIO_HAS_MOVE)
  195. template <typename Handler, typename Arg1>
  196. class move_binder1
  197. {
  198. public:
  199. move_binder1(int, ASIO_MOVE_ARG(Handler) handler,
  200. ASIO_MOVE_ARG(Arg1) arg1)
  201. : handler_(ASIO_MOVE_CAST(Handler)(handler)),
  202. arg1_(ASIO_MOVE_CAST(Arg1)(arg1))
  203. {
  204. }
  205. move_binder1(move_binder1&& other)
  206. : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),
  207. arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_))
  208. {
  209. }
  210. void operator()()
  211. {
  212. handler_(ASIO_MOVE_CAST(Arg1)(arg1_));
  213. }
  214. //private:
  215. Handler handler_;
  216. Arg1 arg1_;
  217. };
  218. template <typename Handler, typename Arg1>
  219. inline void* asio_handler_allocate(std::size_t size,
  220. move_binder1<Handler, Arg1>* this_handler)
  221. {
  222. return asio_handler_alloc_helpers::allocate(
  223. size, this_handler->handler_);
  224. }
  225. template <typename Handler, typename Arg1>
  226. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  227. move_binder1<Handler, Arg1>* this_handler)
  228. {
  229. asio_handler_alloc_helpers::deallocate(
  230. pointer, size, this_handler->handler_);
  231. }
  232. template <typename Handler, typename Arg1>
  233. inline bool asio_handler_is_continuation(
  234. move_binder1<Handler, Arg1>* this_handler)
  235. {
  236. return asio_handler_cont_helpers::is_continuation(
  237. this_handler->handler_);
  238. }
  239. template <typename Function, typename Handler, typename Arg1>
  240. inline void asio_handler_invoke(ASIO_MOVE_ARG(Function) function,
  241. move_binder1<Handler, Arg1>* this_handler)
  242. {
  243. asio_handler_invoke_helpers::invoke(
  244. ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
  245. }
  246. template <typename Handler, typename Arg1, typename Arg2>
  247. class move_binder2
  248. {
  249. public:
  250. move_binder2(int, ASIO_MOVE_ARG(Handler) handler,
  251. const Arg1& arg1, ASIO_MOVE_ARG(Arg2) arg2)
  252. : handler_(ASIO_MOVE_CAST(Handler)(handler)),
  253. arg1_(arg1),
  254. arg2_(ASIO_MOVE_CAST(Arg2)(arg2))
  255. {
  256. }
  257. move_binder2(move_binder2&& other)
  258. : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),
  259. arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),
  260. arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_))
  261. {
  262. }
  263. void operator()()
  264. {
  265. handler_(static_cast<const Arg1&>(arg1_),
  266. ASIO_MOVE_CAST(Arg2)(arg2_));
  267. }
  268. //private:
  269. Handler handler_;
  270. Arg1 arg1_;
  271. Arg2 arg2_;
  272. };
  273. template <typename Handler, typename Arg1, typename Arg2>
  274. inline void* asio_handler_allocate(std::size_t size,
  275. move_binder2<Handler, Arg1, Arg2>* this_handler)
  276. {
  277. return asio_handler_alloc_helpers::allocate(
  278. size, this_handler->handler_);
  279. }
  280. template <typename Handler, typename Arg1, typename Arg2>
  281. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  282. move_binder2<Handler, Arg1, Arg2>* this_handler)
  283. {
  284. asio_handler_alloc_helpers::deallocate(
  285. pointer, size, this_handler->handler_);
  286. }
  287. template <typename Handler, typename Arg1, typename Arg2>
  288. inline bool asio_handler_is_continuation(
  289. move_binder2<Handler, Arg1, Arg2>* this_handler)
  290. {
  291. return asio_handler_cont_helpers::is_continuation(
  292. this_handler->handler_);
  293. }
  294. template <typename Function, typename Handler, typename Arg1, typename Arg2>
  295. inline void asio_handler_invoke(ASIO_MOVE_ARG(Function) function,
  296. move_binder2<Handler, Arg1, Arg2>* this_handler)
  297. {
  298. asio_handler_invoke_helpers::invoke(
  299. ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
  300. }
  301. #endif // defined(ASIO_HAS_MOVE)
  302. } // namespace detail
  303. template <typename Handler, typename Arg1, typename Allocator>
  304. struct associated_allocator<detail::binder1<Handler, Arg1>, Allocator>
  305. {
  306. typedef typename associated_allocator<Handler, Allocator>::type type;
  307. static type get(const detail::binder1<Handler, Arg1>& h,
  308. const Allocator& a = Allocator()) ASIO_NOEXCEPT
  309. {
  310. return associated_allocator<Handler, Allocator>::get(h.handler_, a);
  311. }
  312. };
  313. template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
  314. struct associated_allocator<detail::binder2<Handler, Arg1, Arg2>, Allocator>
  315. {
  316. typedef typename associated_allocator<Handler, Allocator>::type type;
  317. static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
  318. const Allocator& a = Allocator()) ASIO_NOEXCEPT
  319. {
  320. return associated_allocator<Handler, Allocator>::get(h.handler_, a);
  321. }
  322. };
  323. template <typename Handler, typename Arg1, typename Executor>
  324. struct associated_executor<detail::binder1<Handler, Arg1>, Executor>
  325. {
  326. typedef typename associated_executor<Handler, Executor>::type type;
  327. static type get(const detail::binder1<Handler, Arg1>& h,
  328. const Executor& ex = Executor()) ASIO_NOEXCEPT
  329. {
  330. return associated_executor<Handler, Executor>::get(h.handler_, ex);
  331. }
  332. };
  333. template <typename Handler, typename Arg1, typename Arg2, typename Executor>
  334. struct associated_executor<detail::binder2<Handler, Arg1, Arg2>, Executor>
  335. {
  336. typedef typename associated_executor<Handler, Executor>::type type;
  337. static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
  338. const Executor& ex = Executor()) ASIO_NOEXCEPT
  339. {
  340. return associated_executor<Handler, Executor>::get(h.handler_, ex);
  341. }
  342. };
  343. #if defined(ASIO_HAS_MOVE)
  344. template <typename Handler, typename Arg1, typename Allocator>
  345. struct associated_allocator<detail::move_binder1<Handler, Arg1>, Allocator>
  346. {
  347. typedef typename associated_allocator<Handler, Allocator>::type type;
  348. static type get(const detail::move_binder1<Handler, Arg1>& h,
  349. const Allocator& a = Allocator()) ASIO_NOEXCEPT
  350. {
  351. return associated_allocator<Handler, Allocator>::get(h.handler_, a);
  352. }
  353. };
  354. template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
  355. struct associated_allocator<
  356. detail::move_binder2<Handler, Arg1, Arg2>, Allocator>
  357. {
  358. typedef typename associated_allocator<Handler, Allocator>::type type;
  359. static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
  360. const Allocator& a = Allocator()) ASIO_NOEXCEPT
  361. {
  362. return associated_allocator<Handler, Allocator>::get(h.handler_, a);
  363. }
  364. };
  365. template <typename Handler, typename Arg1, typename Executor>
  366. struct associated_executor<detail::move_binder1<Handler, Arg1>, Executor>
  367. {
  368. typedef typename associated_executor<Handler, Executor>::type type;
  369. static type get(const detail::move_binder1<Handler, Arg1>& h,
  370. const Executor& ex = Executor()) ASIO_NOEXCEPT
  371. {
  372. return associated_executor<Handler, Executor>::get(h.handler_, ex);
  373. }
  374. };
  375. template <typename Handler, typename Arg1, typename Arg2, typename Executor>
  376. struct associated_executor<detail::move_binder2<Handler, Arg1, Arg2>, Executor>
  377. {
  378. typedef typename associated_executor<Handler, Executor>::type type;
  379. static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
  380. const Executor& ex = Executor()) ASIO_NOEXCEPT
  381. {
  382. return associated_executor<Handler, Executor>::get(h.handler_, ex);
  383. }
  384. };
  385. #endif // defined(ASIO_HAS_MOVE)
  386. } // namespace asio
  387. #include "asio/detail/pop_options.hpp"
  388. #endif // ASIO_DETAIL_BIND_HANDLER_HPP