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_START_HPP
12 #define BOOST_ASIO_EXECUTION_START_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/traits/start_member.hpp>
21 #include <boost/asio/traits/start_free.hpp>
23 #include <boost/asio/detail/push_options.hpp>
25 #if defined(GENERATING_DOCUMENTATION)
31 /// A customisation point that notifies an operation state object to start
32 /// its associated operation.
34 * The name <tt>execution::start</tt> denotes a customisation point object.
35 * The expression <tt>execution::start(R)</tt> for some subexpression
36 * <tt>R</tt> is expression-equivalent to:
38 * @li <tt>R.start()</tt>, if that expression is valid.
40 * @li Otherwise, <tt>start(R)</tt>, if that expression is valid, with
41 * overload resolution performed in a context that includes the declaration
42 * <tt>void start();</tt> and that does not include a declaration of
43 * <tt>execution::start</tt>.
45 * @li Otherwise, <tt>execution::start(R)</tt> is ill-formed.
47 inline constexpr unspecified start = unspecified;
49 /// A type trait that determines whether a @c start expression is
52 * Class template @c can_start is a trait that is derived from
53 * @c true_type if the expression <tt>execution::start(std::declval<R>(),
54 * std::declval<E>())</tt> is well formed; otherwise @c false_type.
58 integral_constant<bool, automatically_determined>
62 } // namespace execution
66 #else // defined(GENERATING_DOCUMENTATION)
68 namespace boost_asio_execution_start_fn {
70 using boost::asio::decay;
71 using boost::asio::declval;
72 using boost::asio::enable_if;
73 using boost::asio::traits::start_free;
74 using boost::asio::traits::start_member;
85 template <typename R, typename = void, typename = void>
88 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
89 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
90 typedef void result_type;
96 start_member<R>::is_valid
100 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
103 template <typename R>
104 struct call_traits<R,
106 !start_member<R>::is_valid
109 start_free<R>::is_valid
113 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
118 #if defined(BOOST_ASIO_HAS_MOVE)
119 template <typename R>
120 BOOST_ASIO_CONSTEXPR typename enable_if<
121 call_traits<R>::overload == call_member,
122 typename call_traits<R>::result_type
124 operator()(R&& r) const
125 BOOST_ASIO_NOEXCEPT_IF((
126 call_traits<R>::is_noexcept))
128 return BOOST_ASIO_MOVE_CAST(R)(r).start();
131 template <typename R>
132 BOOST_ASIO_CONSTEXPR typename enable_if<
133 call_traits<R>::overload == call_free,
134 typename call_traits<R>::result_type
136 operator()(R&& r) const
137 BOOST_ASIO_NOEXCEPT_IF((
138 call_traits<R>::is_noexcept))
140 return start(BOOST_ASIO_MOVE_CAST(R)(r));
142 #else // defined(BOOST_ASIO_HAS_MOVE)
143 template <typename R>
144 BOOST_ASIO_CONSTEXPR typename enable_if<
145 call_traits<R&>::overload == call_member,
146 typename call_traits<R&>::result_type
148 operator()(R& r) const
149 BOOST_ASIO_NOEXCEPT_IF((
150 call_traits<R&>::is_noexcept))
155 template <typename R>
156 BOOST_ASIO_CONSTEXPR typename enable_if<
157 call_traits<const R&>::overload == call_member,
158 typename call_traits<const R&>::result_type
160 operator()(const R& r) const
161 BOOST_ASIO_NOEXCEPT_IF((
162 call_traits<const R&>::is_noexcept))
167 template <typename R>
168 BOOST_ASIO_CONSTEXPR typename enable_if<
169 call_traits<R&>::overload == call_free,
170 typename call_traits<R&>::result_type
172 operator()(R& r) const
173 BOOST_ASIO_NOEXCEPT_IF((
174 call_traits<R&>::is_noexcept))
179 template <typename R>
180 BOOST_ASIO_CONSTEXPR typename enable_if<
181 call_traits<const R&>::overload == call_free,
182 typename call_traits<const R&>::result_type
184 operator()(const R& r) const
185 BOOST_ASIO_NOEXCEPT_IF((
186 call_traits<const R&>::is_noexcept))
190 #endif // defined(BOOST_ASIO_HAS_MOVE)
193 template <typename T = impl>
194 struct static_instance
196 static const T instance;
199 template <typename T>
200 const T static_instance<T>::instance = {};
202 } // namespace boost_asio_execution_start_fn
205 namespace execution {
208 static BOOST_ASIO_CONSTEXPR const boost_asio_execution_start_fn::impl&
209 start = boost_asio_execution_start_fn::static_instance<>::instance;
213 template <typename R>
215 integral_constant<bool,
216 boost_asio_execution_start_fn::call_traits<R>::overload !=
217 boost_asio_execution_start_fn::ill_formed>
221 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
223 template <typename R>
224 constexpr bool can_start_v = can_start<R>::value;
226 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
228 template <typename R>
229 struct is_nothrow_start :
230 integral_constant<bool,
231 boost_asio_execution_start_fn::call_traits<R>::is_noexcept>
235 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
237 template <typename R>
238 constexpr bool is_nothrow_start_v
239 = is_nothrow_start<R>::value;
241 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
243 } // namespace execution
247 #endif // defined(GENERATING_DOCUMENTATION)
249 #include <boost/asio/detail/pop_options.hpp>
251 #endif // BOOST_ASIO_EXECUTION_START_HPP