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