• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // execution/start.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_START_HPP
12 #define BOOST_ASIO_EXECUTION_START_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/traits/start_member.hpp>
21 #include <boost/asio/traits/start_free.hpp>
22 
23 #include <boost/asio/detail/push_options.hpp>
24 
25 #if defined(GENERATING_DOCUMENTATION)
26 
27 namespace boost {
28 namespace asio {
29 namespace execution {
30 
31 /// A customisation point that notifies an operation state object to start
32 /// its associated operation.
33 /**
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:
37  *
38  * @li <tt>R.start()</tt>, if that expression is valid.
39  *
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>.
44  *
45  * @li Otherwise, <tt>execution::start(R)</tt> is ill-formed.
46  */
47 inline constexpr unspecified start = unspecified;
48 
49 /// A type trait that determines whether a @c start expression is
50 /// well-formed.
51 /**
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.
55  */
56 template <typename R>
57 struct can_start :
58   integral_constant<bool, automatically_determined>
59 {
60 };
61 
62 } // namespace execution
63 } // namespace asio
64 } // namespace boost
65 
66 #else // defined(GENERATING_DOCUMENTATION)
67 
68 namespace asio_execution_start_fn {
69 
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;
75 
76 void start();
77 
78 enum overload_type
79 {
80   call_member,
81   call_free,
82   ill_formed
83 };
84 
85 template <typename R, typename = void, typename = void>
86 struct call_traits
87 {
88   BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
89   BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
90   typedef void result_type;
91 };
92 
93 template <typename R>
94 struct call_traits<R,
95   typename enable_if<
96     start_member<R>::is_valid
97   >::type> :
98   start_member<R>
99 {
100   BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
101 };
102 
103 template <typename R>
104 struct call_traits<R,
105   typename enable_if<
106     !start_member<R>::is_valid
107   >::type,
108   typename enable_if<
109     start_free<R>::is_valid
110   >::type> :
111   start_free<R>
112 {
113   BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
114 };
115 
116 struct impl
117 {
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
123   >::type
operator ()asio_execution_start_fn::impl124   operator()(R&& r) const
125     BOOST_ASIO_NOEXCEPT_IF((
126       call_traits<R>::is_noexcept))
127   {
128     return BOOST_ASIO_MOVE_CAST(R)(r).start();
129   }
130 
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
135   >::type
operator ()asio_execution_start_fn::impl136   operator()(R&& r) const
137     BOOST_ASIO_NOEXCEPT_IF((
138       call_traits<R>::is_noexcept))
139   {
140     return start(BOOST_ASIO_MOVE_CAST(R)(r));
141   }
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
147   >::type
148   operator()(R& r) const
149     BOOST_ASIO_NOEXCEPT_IF((
150       call_traits<R&>::is_noexcept))
151   {
152     return r.start();
153   }
154 
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
159   >::type
160   operator()(const R& r) const
161     BOOST_ASIO_NOEXCEPT_IF((
162       call_traits<const R&>::is_noexcept))
163   {
164     return r.start();
165   }
166 
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
171   >::type
172   operator()(R& r) const
173     BOOST_ASIO_NOEXCEPT_IF((
174       call_traits<R&>::is_noexcept))
175   {
176     return start(r);
177   }
178 
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
183   >::type
184   operator()(const R& r) const
185     BOOST_ASIO_NOEXCEPT_IF((
186       call_traits<const R&>::is_noexcept))
187   {
188     return start(r);
189   }
190 #endif // defined(BOOST_ASIO_HAS_MOVE)
191 };
192 
193 template <typename T = impl>
194 struct static_instance
195 {
196   static const T instance;
197 };
198 
199 template <typename T>
200 const T static_instance<T>::instance = {};
201 
202 } // namespace asio_execution_start_fn
203 namespace boost {
204 namespace asio {
205 namespace execution {
206 namespace {
207 
208 static BOOST_ASIO_CONSTEXPR const asio_execution_start_fn::impl&
209   start = asio_execution_start_fn::static_instance<>::instance;
210 
211 } // namespace
212 
213 template <typename R>
214 struct can_start :
215   integral_constant<bool,
216     asio_execution_start_fn::call_traits<R>::overload !=
217       asio_execution_start_fn::ill_formed>
218 {
219 };
220 
221 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
222 
223 template <typename R>
224 constexpr bool can_start_v = can_start<R>::value;
225 
226 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
227 
228 template <typename R>
229 struct is_nothrow_start :
230   integral_constant<bool,
231     asio_execution_start_fn::call_traits<R>::is_noexcept>
232 {
233 };
234 
235 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
236 
237 template <typename R>
238 constexpr bool is_nothrow_start_v
239   = is_nothrow_start<R>::value;
240 
241 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
242 
243 } // namespace execution
244 } // namespace asio
245 } // namespace boost
246 
247 #endif // defined(GENERATING_DOCUMENTATION)
248 
249 #include <boost/asio/detail/pop_options.hpp>
250 
251 #endif // BOOST_ASIO_EXECUTION_START_HPP
252