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