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