2 // execution/schedule.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_EXECUTION_SCHEDULE_HPP
12 #define BOOST_ASIO_EXECUTION_SCHEDULE_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/detail/type_traits.hpp>
20 #include <boost/asio/execution/executor.hpp>
21 #include <boost/asio/traits/schedule_member.hpp>
22 #include <boost/asio/traits/schedule_free.hpp>
24 #include <boost/asio/detail/push_options.hpp>
26 #if defined(GENERATING_DOCUMENTATION)
32 /// A customisation point that is used to obtain a sender from a scheduler.
34 * The name <tt>execution::schedule</tt> denotes a customisation point object.
35 * For some subexpression <tt>s</tt>, let <tt>S</tt> be a type such that
36 * <tt>decltype((s))</tt> is <tt>S</tt>. The expression
37 * <tt>execution::schedule(s)</tt> is expression-equivalent to:
39 * @li <tt>s.schedule()</tt>, if that expression is valid and its type models
42 * @li Otherwise, <tt>schedule(s)</tt>, if that expression is valid and its
43 * type models <tt>sender</tt> with overload resolution performed in a context
44 * that includes the declaration <tt>void schedule();</tt> and that does not
45 * include a declaration of <tt>execution::schedule</tt>.
47 * @li Otherwise, <tt>S</tt> if <tt>S</tt> satisfies <tt>executor</tt>.
49 * @li Otherwise, <tt>execution::schedule(s)</tt> is ill-formed.
51 inline constexpr unspecified schedule = unspecified;
53 /// A type trait that determines whether a @c schedule expression is
56 * Class template @c can_schedule is a trait that is derived from @c true_type
57 * if the expression <tt>execution::schedule(std::declval<S>())</tt> is well
58 * formed; otherwise @c false_type.
62 integral_constant<bool, automatically_determined>
66 } // namespace execution
70 #else // defined(GENERATING_DOCUMENTATION)
72 namespace boost_asio_execution_schedule_fn {
74 using boost::asio::decay;
75 using boost::asio::declval;
76 using boost::asio::enable_if;
77 using boost::asio::execution::is_executor;
78 using boost::asio::traits::schedule_free;
79 using boost::asio::traits::schedule_member;
91 template <typename S, typename = void, typename = void, typename = void>
94 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
95 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
96 typedef void result_type;
100 struct call_traits<S,
102 schedule_member<S>::is_valid
106 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
109 template <typename S>
110 struct call_traits<S,
112 !schedule_member<S>::is_valid
115 schedule_free<S>::is_valid
119 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
122 template <typename S>
123 struct call_traits<S,
125 !schedule_member<S>::is_valid
128 !schedule_free<S>::is_valid
131 is_executor<typename decay<S>::type>::value
134 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);
135 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
137 #if defined(BOOST_ASIO_HAS_MOVE)
138 typedef BOOST_ASIO_MOVE_ARG(S) result_type;
139 #else // defined(BOOST_ASIO_HAS_MOVE)
140 typedef BOOST_ASIO_MOVE_ARG(typename decay<S>::type) result_type;
141 #endif // defined(BOOST_ASIO_HAS_MOVE)
146 template <typename S>
147 BOOST_ASIO_CONSTEXPR typename enable_if<
148 call_traits<S>::overload == identity,
149 typename call_traits<S>::result_type
151 operator()(BOOST_ASIO_MOVE_ARG(S) s) const
152 BOOST_ASIO_NOEXCEPT_IF((
153 call_traits<S>::is_noexcept))
155 return BOOST_ASIO_MOVE_CAST(S)(s);
158 #if defined(BOOST_ASIO_HAS_MOVE)
159 template <typename S>
160 BOOST_ASIO_CONSTEXPR typename enable_if<
161 call_traits<S>::overload == call_member,
162 typename call_traits<S>::result_type
164 operator()(S&& s) const
165 BOOST_ASIO_NOEXCEPT_IF((
166 call_traits<S>::is_noexcept))
168 return BOOST_ASIO_MOVE_CAST(S)(s).schedule();
171 template <typename S>
172 BOOST_ASIO_CONSTEXPR typename enable_if<
173 call_traits<S>::overload == call_free,
174 typename call_traits<S>::result_type
176 operator()(S&& s) const
177 BOOST_ASIO_NOEXCEPT_IF((
178 call_traits<S>::is_noexcept))
180 return schedule(BOOST_ASIO_MOVE_CAST(S)(s));
182 #else // defined(BOOST_ASIO_HAS_MOVE)
183 template <typename S>
184 BOOST_ASIO_CONSTEXPR typename enable_if<
185 call_traits<S&>::overload == call_member,
186 typename call_traits<S&>::result_type
188 operator()(S& s) const
189 BOOST_ASIO_NOEXCEPT_IF((
190 call_traits<S&>::is_noexcept))
195 template <typename S>
196 BOOST_ASIO_CONSTEXPR typename enable_if<
197 call_traits<const S&>::overload == call_member,
198 typename call_traits<const S&>::result_type
200 operator()(const S& s) const
201 BOOST_ASIO_NOEXCEPT_IF((
202 call_traits<const S&>::is_noexcept))
207 template <typename S>
208 BOOST_ASIO_CONSTEXPR typename enable_if<
209 call_traits<S&>::overload == call_free,
210 typename call_traits<S&>::result_type
212 operator()(S& s) const
213 BOOST_ASIO_NOEXCEPT_IF((
214 call_traits<S&>::is_noexcept))
219 template <typename S>
220 BOOST_ASIO_CONSTEXPR typename enable_if<
221 call_traits<const S&>::overload == call_free,
222 typename call_traits<const S&>::result_type
224 operator()(const S& s) const
225 BOOST_ASIO_NOEXCEPT_IF((
226 call_traits<const S&>::is_noexcept))
230 #endif // defined(BOOST_ASIO_HAS_MOVE)
233 template <typename T = impl>
234 struct static_instance
236 static const T instance;
239 template <typename T>
240 const T static_instance<T>::instance = {};
242 } // namespace boost_asio_execution_schedule_fn
245 namespace execution {
248 static BOOST_ASIO_CONSTEXPR const boost_asio_execution_schedule_fn::impl&
249 schedule = boost_asio_execution_schedule_fn::static_instance<>::instance;
253 template <typename S>
254 struct can_schedule :
255 integral_constant<bool,
256 boost_asio_execution_schedule_fn::call_traits<S>::overload !=
257 boost_asio_execution_schedule_fn::ill_formed>
261 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
263 template <typename S>
264 constexpr bool can_schedule_v = can_schedule<S>::value;
266 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
268 template <typename S>
269 struct is_nothrow_schedule :
270 integral_constant<bool,
271 boost_asio_execution_schedule_fn::call_traits<S>::is_noexcept>
275 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
277 template <typename S>
278 constexpr bool is_nothrow_schedule_v
279 = is_nothrow_schedule<S>::value;
281 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
283 } // namespace execution
287 #endif // defined(GENERATING_DOCUMENTATION)
289 #include <boost/asio/detail/pop_options.hpp>
291 #endif // BOOST_ASIO_EXECUTION_SCHEDULE_HPP