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