associated_executor.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // associated_executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2018 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/detail/type_traits.hpp>
  17. #include <boost/asio/is_executor.hpp>
  18. #include <boost/asio/system_executor.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. namespace detail {
  23. template <typename>
  24. struct associated_executor_check
  25. {
  26. typedef void type;
  27. };
  28. template <typename T, typename E, typename = void>
  29. struct associated_executor_impl
  30. {
  31. typedef E type;
  32. static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
  33. {
  34. return e;
  35. }
  36. };
  37. template <typename T, typename E>
  38. struct associated_executor_impl<T, E,
  39. typename associated_executor_check<typename T::executor_type>::type>
  40. {
  41. typedef typename T::executor_type type;
  42. static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
  43. {
  44. return t.get_executor();
  45. }
  46. };
  47. } // namespace detail
  48. /// Traits type used to obtain the executor associated with an object.
  49. /**
  50. * A program may specialise this traits type if the @c T template parameter in
  51. * the specialisation is a user-defined type. The template parameter @c
  52. * Executor shall be a type meeting the Executor requirements.
  53. *
  54. * Specialisations shall meet the following requirements, where @c t is a const
  55. * reference to an object of type @c T, and @c e is an object of type @c
  56. * Executor.
  57. *
  58. * @li Provide a nested typedef @c type that identifies a type meeting the
  59. * Executor requirements.
  60. *
  61. * @li Provide a noexcept static member function named @c get, callable as @c
  62. * get(t) and with return type @c type.
  63. *
  64. * @li Provide a noexcept static member function named @c get, callable as @c
  65. * get(t,e) and with return type @c type.
  66. */
  67. template <typename T, typename Executor = system_executor>
  68. struct associated_executor
  69. {
  70. /// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
  71. /// Otherwise @c Executor.
  72. #if defined(GENERATING_DOCUMENTATION)
  73. typedef see_below type;
  74. #else // defined(GENERATING_DOCUMENTATION)
  75. typedef typename detail::associated_executor_impl<T, Executor>::type type;
  76. #endif // defined(GENERATING_DOCUMENTATION)
  77. /// If @c T has a nested type @c executor_type, returns
  78. /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
  79. static type get(const T& t,
  80. const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
  81. {
  82. return detail::associated_executor_impl<T, Executor>::get(t, ex);
  83. }
  84. };
  85. /// Helper function to obtain an object's associated executor.
  86. /**
  87. * @returns <tt>associated_executor<T>::get(t)</tt>
  88. */
  89. template <typename T>
  90. inline typename associated_executor<T>::type
  91. get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
  92. {
  93. return associated_executor<T>::get(t);
  94. }
  95. /// Helper function to obtain an object's associated executor.
  96. /**
  97. * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
  98. */
  99. template <typename T, typename Executor>
  100. inline typename associated_executor<T, Executor>::type
  101. get_associated_executor(const T& t, const Executor& ex,
  102. typename enable_if<is_executor<
  103. Executor>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
  104. {
  105. return associated_executor<T, Executor>::get(t, ex);
  106. }
  107. /// Helper function to obtain an object's associated executor.
  108. /**
  109. * @returns <tt>associated_executor<T, typename
  110. * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
  111. */
  112. template <typename T, typename ExecutionContext>
  113. inline typename associated_executor<T,
  114. typename ExecutionContext::executor_type>::type
  115. get_associated_executor(const T& t, ExecutionContext& ctx,
  116. typename enable_if<is_convertible<ExecutionContext&,
  117. execution_context&>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
  118. {
  119. return associated_executor<T,
  120. typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
  121. }
  122. #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
  123. template <typename T, typename Executor = system_executor>
  124. using associated_executor_t = typename associated_executor<T, Executor>::type;
  125. #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
  126. } // namespace asio
  127. } // namespace boost
  128. #include <boost/asio/detail/pop_options.hpp>
  129. #endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP