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