basic_io_object.hpp 7.9 KB

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