associated_executor.hpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //
  2. // associated_executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 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_ASSOCIATED_EXECUTOR_HPP
  11. #define BOOST_ASIO_ASSOCIATED_EXECUTOR_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/associator.hpp>
  17. #include <boost/asio/detail/functional.hpp>
  18. #include <boost/asio/detail/type_traits.hpp>
  19. #include <boost/asio/execution/executor.hpp>
  20. #include <boost/asio/is_executor.hpp>
  21. #include <boost/asio/system_executor.hpp>
  22. #include <boost/asio/detail/push_options.hpp>
  23. namespace boost {
  24. namespace asio {
  25. template <typename T, typename Executor>
  26. struct associated_executor;
  27. namespace detail {
  28. template <typename T, typename = void>
  29. struct has_executor_type : false_type
  30. {
  31. };
  32. template <typename T>
  33. struct has_executor_type<T,
  34. typename void_type<typename T::executor_type>::type>
  35. : true_type
  36. {
  37. };
  38. template <typename T, typename E, typename = void, typename = void>
  39. struct associated_executor_impl
  40. {
  41. typedef void asio_associated_executor_is_unspecialised;
  42. typedef E type;
  43. static type get(const T&) BOOST_ASIO_NOEXCEPT
  44. {
  45. return type();
  46. }
  47. static const type& get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
  48. {
  49. return e;
  50. }
  51. };
  52. template <typename T, typename E>
  53. struct associated_executor_impl<T, E,
  54. typename void_type<typename T::executor_type>::type>
  55. {
  56. typedef typename T::executor_type type;
  57. static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
  58. const T& t) BOOST_ASIO_NOEXCEPT
  59. BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor()))
  60. {
  61. return t.get_executor();
  62. }
  63. static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
  64. const T& t, const E&) BOOST_ASIO_NOEXCEPT
  65. BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor()))
  66. {
  67. return t.get_executor();
  68. }
  69. };
  70. template <typename T, typename E>
  71. struct associated_executor_impl<T, E,
  72. typename enable_if<
  73. !has_executor_type<T>::value
  74. >::type,
  75. typename void_type<
  76. typename associator<associated_executor, T, E>::type
  77. >::type> : associator<associated_executor, T, E>
  78. {
  79. };
  80. } // namespace detail
  81. /// Traits type used to obtain the executor associated with an object.
  82. /**
  83. * A program may specialise this traits type if the @c T template parameter in
  84. * the specialisation is a user-defined type. The template parameter @c
  85. * Executor shall be a type meeting the Executor requirements.
  86. *
  87. * Specialisations shall meet the following requirements, where @c t is a const
  88. * reference to an object of type @c T, and @c e is an object of type @c
  89. * Executor.
  90. *
  91. * @li Provide a nested typedef @c type that identifies a type meeting the
  92. * Executor requirements.
  93. *
  94. * @li Provide a noexcept static member function named @c get, callable as @c
  95. * get(t) and with return type @c type or a (possibly const) reference to @c
  96. * type.
  97. *
  98. * @li Provide a noexcept static member function named @c get, callable as @c
  99. * get(t,e) and with return type @c type or a (possibly const) reference to @c
  100. * type.
  101. */
  102. template <typename T, typename Executor = system_executor>
  103. struct associated_executor
  104. #if !defined(GENERATING_DOCUMENTATION)
  105. : detail::associated_executor_impl<T, Executor>
  106. #endif // !defined(GENERATING_DOCUMENTATION)
  107. {
  108. #if defined(GENERATING_DOCUMENTATION)
  109. /// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
  110. /// Otherwise @c Executor.
  111. typedef see_below type;
  112. /// If @c T has a nested type @c executor_type, returns
  113. /// <tt>t.get_executor()</tt>. Otherwise returns @c type().
  114. static decltype(auto) get(const T& t) BOOST_ASIO_NOEXCEPT;
  115. /// If @c T has a nested type @c executor_type, returns
  116. /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
  117. static decltype(auto) get(const T& t, const Executor& ex) BOOST_ASIO_NOEXCEPT;
  118. #endif // defined(GENERATING_DOCUMENTATION)
  119. };
  120. /// Helper function to obtain an object's associated executor.
  121. /**
  122. * @returns <tt>associated_executor<T>::get(t)</tt>
  123. */
  124. template <typename T>
  125. BOOST_ASIO_NODISCARD inline typename associated_executor<T>::type
  126. get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
  127. {
  128. return associated_executor<T>::get(t);
  129. }
  130. /// Helper function to obtain an object's associated executor.
  131. /**
  132. * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
  133. */
  134. template <typename T, typename Executor>
  135. BOOST_ASIO_NODISCARD inline BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
  136. typename associated_executor<T, Executor>::type)
  137. get_associated_executor(const T& t, const Executor& ex,
  138. typename constraint<
  139. is_executor<Executor>::value || execution::is_executor<Executor>::value
  140. >::type = 0) BOOST_ASIO_NOEXCEPT
  141. BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
  142. associated_executor<T, Executor>::get(t, ex)))
  143. {
  144. return associated_executor<T, Executor>::get(t, ex);
  145. }
  146. /// Helper function to obtain an object's associated executor.
  147. /**
  148. * @returns <tt>associated_executor<T, typename
  149. * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
  150. */
  151. template <typename T, typename ExecutionContext>
  152. BOOST_ASIO_NODISCARD inline typename associated_executor<T,
  153. typename ExecutionContext::executor_type>::type
  154. get_associated_executor(const T& t, ExecutionContext& ctx,
  155. typename constraint<is_convertible<ExecutionContext&,
  156. execution_context&>::value>::type = 0) BOOST_ASIO_NOEXCEPT
  157. {
  158. return associated_executor<T,
  159. typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
  160. }
  161. #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
  162. template <typename T, typename Executor = system_executor>
  163. using associated_executor_t = typename associated_executor<T, Executor>::type;
  164. #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
  165. namespace detail {
  166. template <typename T, typename E, typename = void>
  167. struct associated_executor_forwarding_base
  168. {
  169. };
  170. template <typename T, typename E>
  171. struct associated_executor_forwarding_base<T, E,
  172. typename enable_if<
  173. is_same<
  174. typename associated_executor<T,
  175. E>::asio_associated_executor_is_unspecialised,
  176. void
  177. >::value
  178. >::type>
  179. {
  180. typedef void asio_associated_executor_is_unspecialised;
  181. };
  182. } // namespace detail
  183. #if defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER) \
  184. || defined(GENERATING_DOCUMENTATION)
  185. /// Specialisation of associated_executor for @c std::reference_wrapper.
  186. template <typename T, typename Executor>
  187. struct associated_executor<reference_wrapper<T>, Executor>
  188. #if !defined(GENERATING_DOCUMENTATION)
  189. : detail::associated_executor_forwarding_base<T, Executor>
  190. #endif // !defined(GENERATING_DOCUMENTATION)
  191. {
  192. /// Forwards @c type to the associator specialisation for the unwrapped type
  193. /// @c T.
  194. typedef typename associated_executor<T, Executor>::type type;
  195. /// Forwards the request to get the executor to the associator specialisation
  196. /// for the unwrapped type @c T.
  197. static type get(reference_wrapper<T> t) BOOST_ASIO_NOEXCEPT
  198. {
  199. return associated_executor<T, Executor>::get(t.get());
  200. }
  201. /// Forwards the request to get the executor to the associator specialisation
  202. /// for the unwrapped type @c T.
  203. static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
  204. reference_wrapper<T> t, const Executor& ex) BOOST_ASIO_NOEXCEPT
  205. BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
  206. associated_executor<T, Executor>::get(t.get(), ex)))
  207. {
  208. return associated_executor<T, Executor>::get(t.get(), ex);
  209. }
  210. };
  211. #endif // defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER)
  212. // || defined(GENERATING_DOCUMENTATION)
  213. } // namespace asio
  214. } // namespace boost
  215. #include <boost/asio/detail/pop_options.hpp>
  216. #endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP