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.

295 lines
7.7KB

  1. //
  2. // package.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_USE_PACKAGE_HPP
  11. #define ASIO_USE_PACKAGE_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 <future>
  17. #include <memory>
  18. #include "asio/async_result.hpp"
  19. #include "asio/detail/type_traits.hpp"
  20. #include "asio/detail/variadic_templates.hpp"
  21. #include "asio/handler_type.hpp"
  22. #include "asio/detail/push_options.hpp"
  23. namespace asio {
  24. /// Class to enable lazy construction of a packaged_task from a completion
  25. /// token.
  26. /**
  27. * The packaged_token class is used to adapt a function object as a packaged
  28. * task. When this adapter is passed as a completion token to an asynchronous
  29. * operation, the result of the function object is retuned via a std::future.
  30. *
  31. * Use the @ref package function rather than using this class directly.
  32. */
  33. template <typename Function, typename Allocator = std::allocator<void> >
  34. class packaged_token
  35. {
  36. public:
  37. /// The allocator type. The allocator is used when constructing the
  38. /// @c std::promise object for a given asynchronous operation.
  39. typedef Allocator allocator_type;
  40. /// Construct using specified allocator.
  41. explicit packaged_token(Function f)
  42. : func_(std::move(f))
  43. {
  44. }
  45. /// Construct using specified allocator.
  46. packaged_token(Function f, const Allocator& allocator)
  47. : func_(std::move(f)),
  48. allocator_(allocator)
  49. {
  50. }
  51. /// Obtain allocator.
  52. allocator_type get_allocator() const ASIO_NOEXCEPT
  53. {
  54. return allocator_;
  55. }
  56. private:
  57. template <class, class> friend class packaged_handler;
  58. Function func_;
  59. Allocator allocator_;
  60. };
  61. /// A packaged_task with an associated allocator.
  62. template <typename Signature, typename Allocator>
  63. class packaged_handler : public std::packaged_task<Signature>
  64. {
  65. public:
  66. /// The allocator type. The allocator is used when constructing the
  67. /// @c std::promise object for a given asynchronous operation.
  68. typedef Allocator allocator_type;
  69. /// Construct from a packaged token.
  70. template <typename Function>
  71. packaged_handler(
  72. packaged_token<Function, Allocator>&& token)
  73. #if defined(_MSC_VER)
  74. : std::packaged_task<Signature>(std::move(token.func_)),
  75. #elif defined(ASIO_HAS_CLANG_LIBCXX)
  76. : std::packaged_task<Signature>(std::allocator_arg,
  77. typename std::allocator_traits<
  78. Allocator>::template rebind_alloc<char>(token.allocator_),
  79. std::move(token.func_)),
  80. #else
  81. : std::packaged_task<Signature>(std::allocator_arg,
  82. token.allocator_, std::move(token.func_)),
  83. #endif
  84. allocator_(token.allocator_)
  85. {
  86. }
  87. /// Move construct from another packaged handler.
  88. packaged_handler(packaged_handler&& other)
  89. : std::packaged_task<Signature>(
  90. static_cast<std::packaged_task<Signature>&&>(other)),
  91. allocator_(other.allocator_)
  92. {
  93. }
  94. /// Obtain allocator.
  95. allocator_type get_allocator() const ASIO_NOEXCEPT
  96. {
  97. return allocator_;
  98. }
  99. private:
  100. Allocator allocator_;
  101. };
  102. /// Wrap a function object in a packaged task.
  103. /**
  104. * The @c package function is used to adapt a function object as a packaged
  105. * task. When this adapter is passed as a completion token to an asynchronous
  106. * operation, the result of the function object is retuned via a std::future.
  107. *
  108. * @par Example
  109. *
  110. * @code std::future<std::size_t> fut =
  111. * my_socket.async_read_some(buffer,
  112. * package([](asio::error_code ec, std::size_t n)
  113. * {
  114. * return ec ? 0 : n;
  115. * }));
  116. * ...
  117. * std::size_t n = fut.get(); @endcode
  118. */
  119. template <typename Function>
  120. inline packaged_token<typename decay<Function>::type, std::allocator<void> >
  121. package(ASIO_MOVE_ARG(Function) function)
  122. {
  123. return packaged_token<typename decay<Function>::type, std::allocator<void> >(
  124. ASIO_MOVE_CAST(Function)(function), std::allocator<void>());
  125. }
  126. /// Wrap a function object in a packaged task.
  127. /**
  128. * The @c package function is used to adapt a function object as a packaged
  129. * task. When this adapter is passed as a completion token to an asynchronous
  130. * operation, the result of the function object is retuned via a std::future.
  131. *
  132. * @par Example
  133. *
  134. * @code std::future<std::size_t> fut =
  135. * my_socket.async_read_some(buffer,
  136. * package([](asio::error_code ec, std::size_t n)
  137. * {
  138. * return ec ? 0 : n;
  139. * }));
  140. * ...
  141. * std::size_t n = fut.get(); @endcode
  142. */
  143. template <typename Function, typename Allocator>
  144. inline packaged_token<typename decay<Function>::type, Allocator> package(
  145. ASIO_MOVE_ARG(Function) function, const Allocator& a)
  146. {
  147. return packaged_token<typename decay<Function>::type, Allocator>(
  148. ASIO_MOVE_CAST(Function)(function), a);
  149. }
  150. #if !defined(GENERATING_DOCUMENTATION)
  151. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  152. template <typename Function, typename Allocator, typename R, typename... Args>
  153. struct handler_type<packaged_token<Function, Allocator>, R(Args...)>
  154. {
  155. typedef packaged_handler<
  156. typename result_of<Function(Args...)>::type(Args...),
  157. Allocator> type;
  158. };
  159. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  160. template <typename Function, typename Allocator, typename R>
  161. struct handler_type<packaged_token<Function, Allocator>, R()>
  162. {
  163. typedef packaged_handler<
  164. typename result_of<Function()>::type(),
  165. Allocator> type;
  166. };
  167. #define ASIO_PRIVATE_HANDLER_TYPE_DEF(n) \
  168. template <typename Function, typename Allocator, \
  169. typename R, ASIO_VARIADIC_TPARAMS(n)> \
  170. struct handler_type< \
  171. packaged_token<Function, Allocator>, R(ASIO_VARIADIC_TARGS(n))> \
  172. { \
  173. typedef packaged_handler< \
  174. typename result_of< \
  175. Function(ASIO_VARIADIC_TARGS(n))>::type( \
  176. ASIO_VARIADIC_TARGS(n)), \
  177. Allocator> type; \
  178. }; \
  179. /**/
  180. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_HANDLER_TYPE_DEF)
  181. #undef ASIO_PRIVATE_HANDLER_TYPE_DEF
  182. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  183. #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
  184. template <typename R, typename... Args>
  185. class async_result<std::packaged_task<R(Args...)> >
  186. {
  187. public:
  188. typedef std::future<R> type;
  189. explicit async_result(std::packaged_task<R(Args...)>& h)
  190. : future_(h.get_future())
  191. {
  192. }
  193. type get()
  194. {
  195. return std::move(future_);
  196. }
  197. private:
  198. type future_;
  199. };
  200. #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  201. template <typename R>
  202. class async_result<std::packaged_task<R()> >
  203. {
  204. public:
  205. typedef std::future<R> type;
  206. explicit async_result(std::packaged_task<R()>& h)
  207. : future_(h.get_future())
  208. {
  209. }
  210. type get()
  211. {
  212. return std::move(future_);
  213. }
  214. private:
  215. type future_;
  216. };
  217. #define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \
  218. template <typename R, ASIO_VARIADIC_TPARAMS(n)> \
  219. class async_result<std::packaged_task<R(ASIO_VARIADIC_TARGS(n))> > \
  220. { \
  221. public: \
  222. typedef std::future<R> type; \
  223. \
  224. explicit async_result( \
  225. std::packaged_task<R(ASIO_VARIADIC_TARGS(n))>& h) \
  226. : future_(h.get_future()) \
  227. { \
  228. } \
  229. \
  230. type get() \
  231. { \
  232. return std::move(future_); \
  233. } \
  234. \
  235. private: \
  236. type future_; \
  237. }; \
  238. /**/
  239. ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF)
  240. #undef ASIO_PRIVATE_ASYNC_RESULT_DEF
  241. #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
  242. template <typename Signature, typename Allocator>
  243. class async_result<packaged_handler<Signature, Allocator>>
  244. : public async_result<std::packaged_task<Signature>>
  245. {
  246. public:
  247. explicit async_result(packaged_handler<Signature, Allocator>& h)
  248. : async_result<std::packaged_task<Signature>>(h) {}
  249. };
  250. #endif // !defined(GENERATING_DOCUMENTATION)
  251. } // namespace asio
  252. #include "asio/detail/pop_options.hpp"
  253. #endif // ASIO_USE_PACKAGE_HPP