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.

291 lines
7.7KB

  1. //
  2. // basic_io_object.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_BASIC_IO_OBJECT_HPP
  11. #define ASIO_BASIC_IO_OBJECT_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/io_context.hpp"
  17. #include "asio/detail/push_options.hpp"
  18. namespace asio {
  19. #if defined(ASIO_HAS_MOVE)
  20. namespace detail
  21. {
  22. // Type trait used to determine whether a service supports move.
  23. template <typename IoObjectService>
  24. class service_has_move
  25. {
  26. private:
  27. typedef IoObjectService service_type;
  28. typedef typename service_type::implementation_type implementation_type;
  29. template <typename T, typename U>
  30. static auto asio_service_has_move_eval(T* t, U* u)
  31. -> decltype(t->move_construct(*u, *u), char());
  32. static char (&asio_service_has_move_eval(...))[2];
  33. public:
  34. static const bool value =
  35. sizeof(asio_service_has_move_eval(
  36. static_cast<service_type*>(0),
  37. static_cast<implementation_type*>(0))) == 1;
  38. };
  39. }
  40. #endif // defined(ASIO_HAS_MOVE)
  41. /// Base class for all I/O objects.
  42. /**
  43. * @note All I/O objects are non-copyable. However, when using C++0x, certain
  44. * I/O objects do support move construction and move assignment.
  45. */
  46. #if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  47. template <typename IoObjectService>
  48. #else
  49. template <typename IoObjectService,
  50. bool Movable = detail::service_has_move<IoObjectService>::value>
  51. #endif
  52. class basic_io_object
  53. {
  54. public:
  55. /// The type of the service that will be used to provide I/O operations.
  56. typedef IoObjectService service_type;
  57. /// The underlying implementation type of I/O object.
  58. typedef typename service_type::implementation_type implementation_type;
  59. #if !defined(ASIO_NO_DEPRECATED)
  60. /// (Deprecated: Use get_executor().) Get the io_context associated with the
  61. /// object.
  62. /**
  63. * This function may be used to obtain the io_context object that the I/O
  64. * object uses to dispatch handlers for asynchronous operations.
  65. *
  66. * @return A reference to the io_context object that the I/O object will use
  67. * to dispatch handlers. Ownership is not transferred to the caller.
  68. */
  69. asio::io_context& get_io_context()
  70. {
  71. return service_.get_io_context();
  72. }
  73. /// (Deprecated: Use get_executor().) Get the io_context associated with the
  74. /// object.
  75. /**
  76. * This function may be used to obtain the io_context object that the I/O
  77. * object uses to dispatch handlers for asynchronous operations.
  78. *
  79. * @return A reference to the io_context object that the I/O object will use
  80. * to dispatch handlers. Ownership is not transferred to the caller.
  81. */
  82. asio::io_context& get_io_service()
  83. {
  84. return service_.get_io_context();
  85. }
  86. #endif // !defined(ASIO_NO_DEPRECATED)
  87. /// The type of the executor associated with the object.
  88. typedef asio::io_context::executor_type executor_type;
  89. /// Get the executor associated with the object.
  90. executor_type get_executor() ASIO_NOEXCEPT
  91. {
  92. return service_.get_io_context().get_executor();
  93. }
  94. protected:
  95. /// Construct a basic_io_object.
  96. /**
  97. * Performs:
  98. * @code get_service().construct(get_implementation()); @endcode
  99. */
  100. explicit basic_io_object(asio::io_context& io_context)
  101. : service_(asio::use_service<IoObjectService>(io_context))
  102. {
  103. service_.construct(implementation_);
  104. }
  105. #if defined(GENERATING_DOCUMENTATION)
  106. /// Move-construct a basic_io_object.
  107. /**
  108. * Performs:
  109. * @code get_service().move_construct(
  110. * get_implementation(), other.get_implementation()); @endcode
  111. *
  112. * @note Available only for services that support movability,
  113. */
  114. basic_io_object(basic_io_object&& other);
  115. /// Move-assign a basic_io_object.
  116. /**
  117. * Performs:
  118. * @code get_service().move_assign(get_implementation(),
  119. * other.get_service(), other.get_implementation()); @endcode
  120. *
  121. * @note Available only for services that support movability,
  122. */
  123. basic_io_object& operator=(basic_io_object&& other);
  124. /// Perform a converting move-construction of a basic_io_object.
  125. template <typename IoObjectService1>
  126. basic_io_object(IoObjectService1& other_service,
  127. typename IoObjectService1::implementation_type& other_implementation);
  128. #endif // defined(GENERATING_DOCUMENTATION)
  129. /// Protected destructor to prevent deletion through this type.
  130. /**
  131. * Performs:
  132. * @code get_service().destroy(get_implementation()); @endcode
  133. */
  134. ~basic_io_object()
  135. {
  136. service_.destroy(implementation_);
  137. }
  138. /// Get the service associated with the I/O object.
  139. service_type& get_service()
  140. {
  141. return service_;
  142. }
  143. /// Get the service associated with the I/O object.
  144. const service_type& get_service() const
  145. {
  146. return service_;
  147. }
  148. /// Get the underlying implementation of the I/O object.
  149. implementation_type& get_implementation()
  150. {
  151. return implementation_;
  152. }
  153. /// Get the underlying implementation of the I/O object.
  154. const implementation_type& get_implementation() const
  155. {
  156. return implementation_;
  157. }
  158. private:
  159. basic_io_object(const basic_io_object&);
  160. basic_io_object& operator=(const basic_io_object&);
  161. // The service associated with the I/O object.
  162. service_type& service_;
  163. /// The underlying implementation of the I/O object.
  164. implementation_type implementation_;
  165. };
  166. #if defined(ASIO_HAS_MOVE)
  167. // Specialisation for movable objects.
  168. template <typename IoObjectService>
  169. class basic_io_object<IoObjectService, true>
  170. {
  171. public:
  172. typedef IoObjectService service_type;
  173. typedef typename service_type::implementation_type implementation_type;
  174. #if !defined(ASIO_NO_DEPRECATED)
  175. asio::io_context& get_io_context()
  176. {
  177. return service_->get_io_context();
  178. }
  179. asio::io_context& get_io_service()
  180. {
  181. return service_->get_io_context();
  182. }
  183. #endif // !defined(ASIO_NO_DEPRECATED)
  184. typedef asio::io_context::executor_type executor_type;
  185. executor_type get_executor() ASIO_NOEXCEPT
  186. {
  187. return service_->get_io_context().get_executor();
  188. }
  189. protected:
  190. explicit basic_io_object(asio::io_context& io_context)
  191. : service_(&asio::use_service<IoObjectService>(io_context))
  192. {
  193. service_->construct(implementation_);
  194. }
  195. basic_io_object(basic_io_object&& other)
  196. : service_(&other.get_service())
  197. {
  198. service_->move_construct(implementation_, other.implementation_);
  199. }
  200. template <typename IoObjectService1>
  201. basic_io_object(IoObjectService1& other_service,
  202. typename IoObjectService1::implementation_type& other_implementation)
  203. : service_(&asio::use_service<IoObjectService>(
  204. other_service.get_io_context()))
  205. {
  206. service_->converting_move_construct(implementation_,
  207. other_service, other_implementation);
  208. }
  209. ~basic_io_object()
  210. {
  211. service_->destroy(implementation_);
  212. }
  213. basic_io_object& operator=(basic_io_object&& other)
  214. {
  215. service_->move_assign(implementation_,
  216. *other.service_, other.implementation_);
  217. service_ = other.service_;
  218. return *this;
  219. }
  220. service_type& get_service()
  221. {
  222. return *service_;
  223. }
  224. const service_type& get_service() const
  225. {
  226. return *service_;
  227. }
  228. implementation_type& get_implementation()
  229. {
  230. return implementation_;
  231. }
  232. const implementation_type& get_implementation() const
  233. {
  234. return implementation_;
  235. }
  236. private:
  237. basic_io_object(const basic_io_object&);
  238. void operator=(const basic_io_object&);
  239. IoObjectService* service_;
  240. implementation_type implementation_;
  241. };
  242. #endif // defined(ASIO_HAS_MOVE)
  243. } // namespace asio
  244. #include "asio/detail/pop_options.hpp"
  245. #endif // ASIO_BASIC_IO_OBJECT_HPP