1 // 2 // any_io_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_ANY_IO_EXECUTOR_HPP 12 #define BOOST_ASIO_ANY_IO_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 #if defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) 20 # include <boost/asio/executor.hpp> 21 #else // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) 22 # include <boost/asio/execution.hpp> 23 # include <boost/asio/execution_context.hpp> 24 #endif // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) 25 26 #include <boost/asio/detail/push_options.hpp> 27 28 namespace boost { 29 namespace asio { 30 31 #if defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) 32 33 typedef executor any_io_executor; 34 35 #else // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) 36 37 /// Polymorphic executor type for use with I/O objects. 38 /** 39 * The @c any_io_executor type is a polymorphic executor that supports the set 40 * of properties required by I/O objects. It is defined as the 41 * execution::any_executor class template parameterised as follows: 42 * @code execution::any_executor< 43 * execution::context_as_t<execution_context&>, 44 * execution::blocking_t::never_t, 45 * execution::prefer_only<execution::blocking_t::possibly_t>, 46 * execution::prefer_only<execution::outstanding_work_t::tracked_t>, 47 * execution::prefer_only<execution::outstanding_work_t::untracked_t>, 48 * execution::prefer_only<execution::relationship_t::fork_t>, 49 * execution::prefer_only<execution::relationship_t::continuation_t> 50 * > @endcode 51 */ 52 class any_io_executor : 53 #if defined(GENERATING_DOCUMENTATION) 54 public execution::any_executor<...> 55 #else // defined(GENERATING_DOCUMENTATION) 56 public execution::any_executor< 57 execution::context_as_t<execution_context&>, 58 execution::blocking_t::never_t, 59 execution::prefer_only<execution::blocking_t::possibly_t>, 60 execution::prefer_only<execution::outstanding_work_t::tracked_t>, 61 execution::prefer_only<execution::outstanding_work_t::untracked_t>, 62 execution::prefer_only<execution::relationship_t::fork_t>, 63 execution::prefer_only<execution::relationship_t::continuation_t> 64 > 65 #endif // defined(GENERATING_DOCUMENTATION) 66 { 67 public: 68 #if !defined(GENERATING_DOCUMENTATION) 69 typedef execution::any_executor< 70 execution::context_as_t<execution_context&>, 71 execution::blocking_t::never_t, 72 execution::prefer_only<execution::blocking_t::possibly_t>, 73 execution::prefer_only<execution::outstanding_work_t::tracked_t>, 74 execution::prefer_only<execution::outstanding_work_t::untracked_t>, 75 execution::prefer_only<execution::relationship_t::fork_t>, 76 execution::prefer_only<execution::relationship_t::continuation_t> 77 > base_type; 78 79 typedef void supportable_properties_type( 80 execution::context_as_t<execution_context&>, 81 execution::blocking_t::never_t, 82 execution::prefer_only<execution::blocking_t::possibly_t>, 83 execution::prefer_only<execution::outstanding_work_t::tracked_t>, 84 execution::prefer_only<execution::outstanding_work_t::untracked_t>, 85 execution::prefer_only<execution::relationship_t::fork_t>, 86 execution::prefer_only<execution::relationship_t::continuation_t> 87 ); 88 #endif // !defined(GENERATING_DOCUMENTATION) 89 90 /// Default constructor. 91 any_io_executor() BOOST_ASIO_NOEXCEPT 92 : base_type() 93 { 94 } 95 96 /// Construct in an empty state. Equivalent effects to default constructor. 97 any_io_executor(nullptr_t) BOOST_ASIO_NOEXCEPT 98 : base_type(nullptr_t()) 99 { 100 } 101 102 /// Copy constructor. 103 any_io_executor(const any_io_executor& e) BOOST_ASIO_NOEXCEPT 104 : base_type(static_cast<const base_type&>(e)) 105 { 106 } 107 108 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 109 /// Move constructor. 110 any_io_executor(any_io_executor&& e) BOOST_ASIO_NOEXCEPT 111 : base_type(static_cast<base_type&&>(e)) 112 { 113 } 114 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 115 116 /// Construct to point to the same target as another any_executor. 117 #if defined(GENERATING_DOCUMENTATION) 118 template <class... OtherSupportableProperties> 119 any_io_executor(execution::any_executor<OtherSupportableProperties...> e); 120 #else // defined(GENERATING_DOCUMENTATION) 121 template <typename OtherAnyExecutor> 122 any_io_executor(OtherAnyExecutor e, 123 typename constraint< 124 conditional< 125 !is_same<OtherAnyExecutor, any_io_executor>::value 126 && is_base_of<execution::detail::any_executor_base, 127 OtherAnyExecutor>::value, 128 typename execution::detail::supportable_properties< 129 0, supportable_properties_type>::template 130 is_valid_target<OtherAnyExecutor>, 131 false_type 132 >::type::value 133 >::type = 0) 134 : base_type(BOOST_ASIO_MOVE_CAST(OtherAnyExecutor)(e)) 135 { 136 } 137 #endif // defined(GENERATING_DOCUMENTATION) 138 139 /// Construct a polymorphic wrapper for the specified executor. 140 #if defined(GENERATING_DOCUMENTATION) 141 template <BOOST_ASIO_EXECUTION_EXECUTOR Executor> 142 any_io_executor(Executor e); 143 #else // defined(GENERATING_DOCUMENTATION) 144 template <BOOST_ASIO_EXECUTION_EXECUTOR Executor> 145 any_io_executor(Executor e, 146 typename constraint< 147 conditional< 148 !is_same<Executor, any_io_executor>::value 149 && !is_base_of<execution::detail::any_executor_base, 150 Executor>::value, 151 execution::detail::is_valid_target_executor< 152 Executor, supportable_properties_type>, 153 false_type 154 >::type::value 155 >::type = 0) 156 : base_type(BOOST_ASIO_MOVE_CAST(Executor)(e)) 157 { 158 } 159 #endif // defined(GENERATING_DOCUMENTATION) 160 161 /// Assignment operator. 162 any_io_executor& operator=(const any_io_executor& e) BOOST_ASIO_NOEXCEPT 163 { 164 base_type::operator=(static_cast<const base_type&>(e)); 165 return *this; 166 } 167 168 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 169 /// Move assignment operator. 170 any_io_executor& operator=(any_io_executor&& e) BOOST_ASIO_NOEXCEPT 171 { 172 base_type::operator=(static_cast<base_type&&>(e)); 173 return *this; 174 } 175 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 176 177 /// Assignment operator that sets the polymorphic wrapper to the empty state. 178 any_io_executor& operator=(nullptr_t) 179 { 180 base_type::operator=(nullptr_t()); 181 return *this; 182 } 183 184 /// Destructor. 185 ~any_io_executor() 186 { 187 } 188 189 /// Swap targets with another polymorphic wrapper. 190 void swap(any_io_executor& other) BOOST_ASIO_NOEXCEPT 191 { 192 static_cast<base_type&>(*this).swap(static_cast<base_type&>(other)); 193 } 194 195 /// Obtain a polymorphic wrapper with the specified property. 196 /** 197 * Do not call this function directly. It is intended for use with the 198 * boost::asio::require and boost::asio::prefer customisation points. 199 * 200 * For example: 201 * @code any_io_executor ex = ...; 202 * auto ex2 = boost::asio::require(ex, execution::blocking.possibly); @endcode 203 */ 204 template <typename Property> 205 any_io_executor require(const Property& p, 206 typename constraint< 207 traits::require_member<const base_type&, const Property&>::is_valid 208 >::type = 0) const 209 { 210 return static_cast<const base_type&>(*this).require(p); 211 } 212 213 /// Obtain a polymorphic wrapper with the specified property. 214 /** 215 * Do not call this function directly. It is intended for use with the 216 * boost::asio::prefer customisation point. 217 * 218 * For example: 219 * @code any_io_executor ex = ...; 220 * auto ex2 = boost::asio::prefer(ex, execution::blocking.possibly); @endcode 221 */ 222 template <typename Property> 223 any_io_executor prefer(const Property& p, 224 typename constraint< 225 traits::prefer_member<const base_type&, const Property&>::is_valid 226 >::type = 0) const 227 { 228 return static_cast<const base_type&>(*this).prefer(p); 229 } 230 }; 231 232 #if !defined(GENERATING_DOCUMENTATION) 233 234 namespace traits { 235 236 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) 237 238 template <> 239 struct equality_comparable<any_io_executor> 240 { 241 static const bool is_valid = true; 242 static const bool is_noexcept = true; 243 }; 244 245 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) 246 247 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) 248 249 template <typename F> 250 struct execute_member<any_io_executor, F> 251 { 252 static const bool is_valid = true; 253 static const bool is_noexcept = false; 254 typedef void result_type; 255 }; 256 257 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) 258 259 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) 260 261 template <typename Prop> 262 struct query_member<any_io_executor, Prop> : 263 query_member<any_io_executor::base_type, Prop> 264 { 265 }; 266 267 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) 268 269 #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) 270 271 template <typename Prop> 272 struct require_member<any_io_executor, Prop> : 273 require_member<any_io_executor::base_type, Prop> 274 { 275 typedef any_io_executor result_type; 276 }; 277 278 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) 279 280 #if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) 281 282 template <typename Prop> 283 struct prefer_member<any_io_executor, Prop> : 284 prefer_member<any_io_executor::base_type, Prop> 285 { 286 typedef any_io_executor result_type; 287 }; 288 289 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) 290 291 } // namespace traits 292 293 #endif // !defined(GENERATING_DOCUMENTATION) 294 295 #endif // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) 296 297 } // namespace asio 298 } // namespace boost 299 300 #include <boost/asio/detail/pop_options.hpp> 301 302 #endif // BOOST_ASIO_ANY_IO_EXECUTOR_HPP 303