executor.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. //
  2. // execution/executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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_EXECUTION_EXECUTOR_HPP
  11. #define ASIO_EXECUTION_EXECUTOR_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/detail/type_traits.hpp"
  17. #include "asio/execution/execute.hpp"
  18. #include "asio/execution/invocable_archetype.hpp"
  19. #include "asio/traits/equality_comparable.hpp"
  20. #if defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT) \
  21. && defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) \
  22. && defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  23. # define ASIO_HAS_DEDUCED_EXECUTION_IS_EXECUTOR_TRAIT 1
  24. #endif // defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
  25. // && defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  26. // && defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  27. #include "asio/detail/push_options.hpp"
  28. namespace asio {
  29. namespace execution {
  30. namespace detail {
  31. template <typename T, typename F,
  32. typename = void, typename = void, typename = void, typename = void,
  33. typename = void, typename = void, typename = void, typename = void>
  34. struct is_executor_of_impl : false_type
  35. {
  36. };
  37. template <typename T, typename F>
  38. struct is_executor_of_impl<T, F,
  39. typename enable_if<
  40. can_execute<typename add_const<T>::type, F>::value
  41. >::type,
  42. typename void_type<
  43. typename result_of<typename decay<F>::type&()>::type
  44. >::type,
  45. typename enable_if<
  46. is_constructible<typename decay<F>::type, F>::value
  47. >::type,
  48. typename enable_if<
  49. is_move_constructible<typename decay<F>::type>::value
  50. >::type,
  51. #if defined(ASIO_HAS_NOEXCEPT)
  52. typename enable_if<
  53. is_nothrow_copy_constructible<T>::value
  54. >::type,
  55. typename enable_if<
  56. is_nothrow_destructible<T>::value
  57. >::type,
  58. #else // defined(ASIO_HAS_NOEXCEPT)
  59. typename enable_if<
  60. is_copy_constructible<T>::value
  61. >::type,
  62. typename enable_if<
  63. is_destructible<T>::value
  64. >::type,
  65. #endif // defined(ASIO_HAS_NOEXCEPT)
  66. typename enable_if<
  67. traits::equality_comparable<T>::is_valid
  68. >::type,
  69. typename enable_if<
  70. traits::equality_comparable<T>::is_noexcept
  71. >::type> : true_type
  72. {
  73. };
  74. template <typename T, typename = void>
  75. struct executor_shape
  76. {
  77. typedef std::size_t type;
  78. };
  79. template <typename T>
  80. struct executor_shape<T,
  81. typename void_type<
  82. typename T::shape_type
  83. >::type>
  84. {
  85. typedef typename T::shape_type type;
  86. };
  87. template <typename T, typename Default, typename = void>
  88. struct executor_index
  89. {
  90. typedef Default type;
  91. };
  92. template <typename T, typename Default>
  93. struct executor_index<T, Default,
  94. typename void_type<
  95. typename T::index_type
  96. >::type>
  97. {
  98. typedef typename T::index_type type;
  99. };
  100. } // namespace detail
  101. /// The is_executor trait detects whether a type T satisfies the
  102. /// execution::executor concept.
  103. /**
  104. * Class template @c is_executor is a UnaryTypeTrait that is derived from @c
  105. * true_type if the type @c T meets the concept definition for an executor,
  106. * otherwise @c false_type.
  107. */
  108. template <typename T>
  109. struct is_executor :
  110. #if defined(GENERATING_DOCUMENTATION)
  111. integral_constant<bool, automatically_determined>
  112. #else // defined(GENERATING_DOCUMENTATION)
  113. detail::is_executor_of_impl<T, invocable_archetype>
  114. #endif // defined(GENERATING_DOCUMENTATION)
  115. {
  116. };
  117. #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
  118. template <typename T>
  119. ASIO_CONSTEXPR const bool is_executor_v = is_executor<T>::value;
  120. #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
  121. #if defined(ASIO_HAS_CONCEPTS)
  122. template <typename T>
  123. ASIO_CONCEPT executor = is_executor<T>::value;
  124. #define ASIO_EXECUTION_EXECUTOR ::asio::execution::executor
  125. #else // defined(ASIO_HAS_CONCEPTS)
  126. #define ASIO_EXECUTION_EXECUTOR typename
  127. #endif // defined(ASIO_HAS_CONCEPTS)
  128. /// The is_executor_of trait detects whether a type T satisfies the
  129. /// execution::executor_of concept for some set of value arguments.
  130. /**
  131. * Class template @c is_executor_of is a type trait that is derived from @c
  132. * true_type if the type @c T meets the concept definition for an executor
  133. * that is invocable with a function object of type @c F, otherwise @c
  134. * false_type.
  135. */
  136. template <typename T, typename F>
  137. struct is_executor_of :
  138. #if defined(GENERATING_DOCUMENTATION)
  139. integral_constant<bool, automatically_determined>
  140. #else // defined(GENERATING_DOCUMENTATION)
  141. integral_constant<bool,
  142. is_executor<T>::value && detail::is_executor_of_impl<T, F>::value
  143. >
  144. #endif // defined(GENERATING_DOCUMENTATION)
  145. {
  146. };
  147. #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
  148. template <typename T, typename F>
  149. ASIO_CONSTEXPR const bool is_executor_of_v =
  150. is_executor_of<T, F>::value;
  151. #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
  152. #if defined(ASIO_HAS_CONCEPTS)
  153. template <typename T, typename F>
  154. ASIO_CONCEPT executor_of = is_executor_of<T, F>::value;
  155. #define ASIO_EXECUTION_EXECUTOR_OF(f) \
  156. ::asio::execution::executor_of<f>
  157. #else // defined(ASIO_HAS_CONCEPTS)
  158. #define ASIO_EXECUTION_EXECUTOR_OF typename
  159. #endif // defined(ASIO_HAS_CONCEPTS)
  160. /// The executor_shape trait detects the type used by an executor to represent
  161. /// the shape of a bulk operation.
  162. /**
  163. * Class template @c executor_shape is a type trait with a nested type alias
  164. * @c type whose type is @c T::shape_type if @c T::shape_type is valid,
  165. * otherwise @c std::size_t.
  166. */
  167. template <typename T>
  168. struct executor_shape
  169. #if !defined(GENERATING_DOCUMENTATION)
  170. : detail::executor_shape<T>
  171. #endif // !defined(GENERATING_DOCUMENTATION)
  172. {
  173. #if defined(GENERATING_DOCUMENTATION)
  174. /// @c T::shape_type if @c T::shape_type is valid, otherwise @c std::size_t.
  175. typedef automatically_determined type;
  176. #endif // defined(GENERATING_DOCUMENTATION)
  177. };
  178. #if defined(ASIO_HAS_ALIAS_TEMPLATES)
  179. template <typename T>
  180. using executor_shape_t = typename executor_shape<T>::type;
  181. #endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
  182. /// The executor_index trait detects the type used by an executor to represent
  183. /// an index within a bulk operation.
  184. /**
  185. * Class template @c executor_index is a type trait with a nested type alias
  186. * @c type whose type is @c T::index_type if @c T::index_type is valid,
  187. * otherwise @c executor_shape_t<T>.
  188. */
  189. template <typename T>
  190. struct executor_index
  191. #if !defined(GENERATING_DOCUMENTATION)
  192. : detail::executor_index<T, typename executor_shape<T>::type>
  193. #endif // !defined(GENERATING_DOCUMENTATION)
  194. {
  195. #if defined(GENERATING_DOCUMENTATION)
  196. /// @c T::index_type if @c T::index_type is valid, otherwise
  197. /// @c executor_shape_t<T>.
  198. typedef automatically_determined type;
  199. #endif // defined(GENERATING_DOCUMENTATION)
  200. };
  201. #if defined(ASIO_HAS_ALIAS_TEMPLATES)
  202. template <typename T>
  203. using executor_index_t = typename executor_index<T>::type;
  204. #endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
  205. } // namespace execution
  206. } // namespace asio
  207. #include "asio/detail/pop_options.hpp"
  208. #endif // ASIO_EXECUTION_EXECUTOR_HPP