]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/execution/connect.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / execution / connect.hpp
1 //
2 // execution/connect.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 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_CONNECT_HPP
12 #define BOOST_ASIO_EXECUTION_CONNECT_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/execution/detail/as_invocable.hpp>
21 #include <boost/asio/execution/detail/as_operation.hpp>
22 #include <boost/asio/execution/detail/as_receiver.hpp>
23 #include <boost/asio/execution/executor.hpp>
24 #include <boost/asio/execution/operation_state.hpp>
25 #include <boost/asio/execution/receiver.hpp>
26 #include <boost/asio/execution/sender.hpp>
27 #include <boost/asio/traits/connect_member.hpp>
28 #include <boost/asio/traits/connect_free.hpp>
29
30 #include <boost/asio/detail/push_options.hpp>
31
32 #if defined(GENERATING_DOCUMENTATION)
33
34 namespace boost {
35 namespace asio {
36 namespace execution {
37
38 /// A customisation point that connects a sender to a receiver.
39 /**
40 * The name <tt>execution::connect</tt> denotes a customisation point object.
41 * For some subexpressions <tt>s</tt> and <tt>r</tt>, let <tt>S</tt> be a type
42 * such that <tt>decltype((s))</tt> is <tt>S</tt> and let <tt>R</tt> be a type
43 * such that <tt>decltype((r))</tt> is <tt>R</tt>. The expression
44 * <tt>execution::connect(s, r)</tt> is expression-equivalent to:
45 *
46 * @li <tt>s.connect(r)</tt>, if that expression is valid, if its type
47 * satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies
48 * <tt>sender</tt>.
49 *
50 * @li Otherwise, <tt>connect(s, r)</tt>, if that expression is valid, if its
51 * type satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies
52 * <tt>sender</tt>, with overload resolution performed in a context that
53 * includes the declaration <tt>void connect();</tt> and that does not include
54 * a declaration of <tt>execution::connect</tt>.
55 *
56 * @li Otherwise, <tt>as_operation{s, r}</tt>, if <tt>r</tt> is not an instance
57 * of <tt>as_receiver<F, S></tt> for some type <tt>F</tt>, and if
58 * <tt>receiver_of<R> && executor_of<remove_cvref_t<S>,
59 * as_invocable<remove_cvref_t<R>, S>></tt> is <tt>true</tt>, where
60 * <tt>as_operation</tt> is an implementation-defined class equivalent to
61 * @code template <class S, class R>
62 * struct as_operation
63 * {
64 * remove_cvref_t<S> e_;
65 * remove_cvref_t<R> r_;
66 * void start() noexcept try {
67 * execution::execute(std::move(e_),
68 * as_invocable<remove_cvref_t<R>, S>{r_});
69 * } catch(...) {
70 * execution::set_error(std::move(r_), current_exception());
71 * }
72 * }; @endcode
73 * and <tt>as_invocable</tt> is a class template equivalent to the following:
74 * @code template<class R>
75 * struct as_invocable
76 * {
77 * R* r_;
78 * explicit as_invocable(R& r) noexcept
79 * : r_(std::addressof(r)) {}
80 * as_invocable(as_invocable && other) noexcept
81 * : r_(std::exchange(other.r_, nullptr)) {}
82 * ~as_invocable() {
83 * if(r_)
84 * execution::set_done(std::move(*r_));
85 * }
86 * void operator()() & noexcept try {
87 * execution::set_value(std::move(*r_));
88 * r_ = nullptr;
89 * } catch(...) {
90 * execution::set_error(std::move(*r_), current_exception());
91 * r_ = nullptr;
92 * }
93 * };
94 * @endcode
95 *
96 * @li Otherwise, <tt>execution::connect(s, r)</tt> is ill-formed.
97 */
98 inline constexpr unspecified connect = unspecified;
99
100 /// A type trait that determines whether a @c connect expression is
101 /// well-formed.
102 /**
103 * Class template @c can_connect is a trait that is derived from
104 * @c true_type if the expression <tt>execution::connect(std::declval<S>(),
105 * std::declval<R>())</tt> is well formed; otherwise @c false_type.
106 */
107 template <typename S, typename R>
108 struct can_connect :
109 integral_constant<bool, automatically_determined>
110 {
111 };
112
113 /// A type trait to determine the result of a @c connect expression.
114 template <typename S, typename R>
115 struct connect_result
116 {
117 /// The type of the connect expression.
118 /**
119 * The type of the expression <tt>execution::connect(std::declval<S>(),
120 * std::declval<R>())</tt>.
121 */
122 typedef automatically_determined type;
123 };
124
125 /// A type alis to determine the result of a @c connect expression.
126 template <typename S, typename R>
127 using connect_result_t = typename connect_result<S, R>::type;
128
129 } // namespace execution
130 } // namespace asio
131 } // namespace boost
132
133 #else // defined(GENERATING_DOCUMENTATION)
134
135 namespace boost_asio_execution_connect_fn {
136
137 using boost::asio::conditional;
138 using boost::asio::declval;
139 using boost::asio::enable_if;
140 using boost::asio::execution::detail::as_invocable;
141 using boost::asio::execution::detail::as_operation;
142 using boost::asio::execution::detail::is_as_receiver;
143 using boost::asio::execution::is_executor_of;
144 using boost::asio::execution::is_operation_state;
145 using boost::asio::execution::is_receiver;
146 using boost::asio::execution::is_sender;
147 using boost::asio::false_type;
148 using boost::asio::remove_cvref;
149 using boost::asio::traits::connect_free;
150 using boost::asio::traits::connect_member;
151
152 void connect();
153
154 enum overload_type
155 {
156 call_member,
157 call_free,
158 adapter,
159 ill_formed
160 };
161
162 template <typename S, typename R, typename = void,
163 typename = void, typename = void, typename = void>
164 struct call_traits
165 {
166 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
167 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
168 typedef void result_type;
169 };
170
171 template <typename S, typename R>
172 struct call_traits<S, void(R),
173 typename enable_if<
174 connect_member<S, R>::is_valid
175 >::type,
176 typename enable_if<
177 is_operation_state<typename connect_member<S, R>::result_type>::value
178 >::type,
179 typename enable_if<
180 is_sender<typename remove_cvref<S>::type>::value
181 >::type> :
182 connect_member<S, R>
183 {
184 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
185 };
186
187 template <typename S, typename R>
188 struct call_traits<S, void(R),
189 typename enable_if<
190 !connect_member<S, R>::is_valid
191 >::type,
192 typename enable_if<
193 connect_free<S, R>::is_valid
194 >::type,
195 typename enable_if<
196 is_operation_state<typename connect_free<S, R>::result_type>::value
197 >::type,
198 typename enable_if<
199 is_sender<typename remove_cvref<S>::type>::value
200 >::type> :
201 connect_free<S, R>
202 {
203 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
204 };
205
206 template <typename S, typename R>
207 struct call_traits<S, void(R),
208 typename enable_if<
209 !connect_member<S, R>::is_valid
210 >::type,
211 typename enable_if<
212 !connect_free<S, R>::is_valid
213 >::type,
214 typename enable_if<
215 is_receiver<R>::value
216 >::type,
217 typename enable_if<
218 conditional<
219 !is_as_receiver<
220 typename remove_cvref<R>::type
221 >::value,
222 is_executor_of<
223 typename remove_cvref<S>::type,
224 as_invocable<typename remove_cvref<R>::type, S>
225 >,
226 false_type
227 >::type::value
228 >::type>
229 {
230 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);
231 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
232 typedef as_operation<S, R> result_type;
233 };
234
235 struct impl
236 {
237 #if defined(BOOST_ASIO_HAS_MOVE)
238 template <typename S, typename R>
239 BOOST_ASIO_CONSTEXPR typename enable_if<
240 call_traits<S, void(R)>::overload == call_member,
241 typename call_traits<S, void(R)>::result_type
242 >::type
243 operator()(S&& s, R&& r) const
244 BOOST_ASIO_NOEXCEPT_IF((
245 call_traits<S, void(R)>::is_noexcept))
246 {
247 return BOOST_ASIO_MOVE_CAST(S)(s).connect(BOOST_ASIO_MOVE_CAST(R)(r));
248 }
249
250 template <typename S, typename R>
251 BOOST_ASIO_CONSTEXPR typename enable_if<
252 call_traits<S, void(R)>::overload == call_free,
253 typename call_traits<S, void(R)>::result_type
254 >::type
255 operator()(S&& s, R&& r) const
256 BOOST_ASIO_NOEXCEPT_IF((
257 call_traits<S, void(R)>::is_noexcept))
258 {
259 return connect(BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(R)(r));
260 }
261
262 template <typename S, typename R>
263 BOOST_ASIO_CONSTEXPR typename enable_if<
264 call_traits<S, void(R)>::overload == adapter,
265 typename call_traits<S, void(R)>::result_type
266 >::type
267 operator()(S&& s, R&& r) const
268 BOOST_ASIO_NOEXCEPT_IF((
269 call_traits<S, void(R)>::is_noexcept))
270 {
271 return typename call_traits<S, void(R)>::result_type(
272 BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(R)(r));
273 }
274 #else // defined(BOOST_ASIO_HAS_MOVE)
275 template <typename S, typename R>
276 BOOST_ASIO_CONSTEXPR typename enable_if<
277 call_traits<S&, void(R&)>::overload == call_member,
278 typename call_traits<S&, void(R&)>::result_type
279 >::type
280 operator()(S& s, R& r) const
281 BOOST_ASIO_NOEXCEPT_IF((
282 call_traits<S&, void(R&)>::is_noexcept))
283 {
284 return s.connect(r);
285 }
286
287 template <typename S, typename R>
288 BOOST_ASIO_CONSTEXPR typename enable_if<
289 call_traits<const S&, void(R&)>::overload == call_member,
290 typename call_traits<const S&, void(R&)>::result_type
291 >::type
292 operator()(const S& s, R& r) const
293 BOOST_ASIO_NOEXCEPT_IF((
294 call_traits<const S&, void(R&)>::is_noexcept))
295 {
296 return s.connect(r);
297 }
298
299 template <typename S, typename R>
300 BOOST_ASIO_CONSTEXPR typename enable_if<
301 call_traits<S&, void(R&)>::overload == call_free,
302 typename call_traits<S&, void(R&)>::result_type
303 >::type
304 operator()(S& s, R& r) const
305 BOOST_ASIO_NOEXCEPT_IF((
306 call_traits<S&, void(R&)>::is_noexcept))
307 {
308 return connect(s, r);
309 }
310
311 template <typename S, typename R>
312 BOOST_ASIO_CONSTEXPR typename enable_if<
313 call_traits<const S&, void(R&)>::overload == call_free,
314 typename call_traits<const S&, void(R&)>::result_type
315 >::type
316 operator()(const S& s, R& r) const
317 BOOST_ASIO_NOEXCEPT_IF((
318 call_traits<const S&, void(R&)>::is_noexcept))
319 {
320 return connect(s, r);
321 }
322
323 template <typename S, typename R>
324 BOOST_ASIO_CONSTEXPR typename enable_if<
325 call_traits<S&, void(R&)>::overload == adapter,
326 typename call_traits<S&, void(R&)>::result_type
327 >::type
328 operator()(S& s, R& r) const
329 BOOST_ASIO_NOEXCEPT_IF((
330 call_traits<S&, void(R&)>::is_noexcept))
331 {
332 return typename call_traits<S&, void(R&)>::result_type(s, r);
333 }
334
335 template <typename S, typename R>
336 BOOST_ASIO_CONSTEXPR typename enable_if<
337 call_traits<const S&, void(R&)>::overload == adapter,
338 typename call_traits<const S&, void(R&)>::result_type
339 >::type
340 operator()(const S& s, R& r) const
341 BOOST_ASIO_NOEXCEPT_IF((
342 call_traits<const S&, void(R&)>::is_noexcept))
343 {
344 return typename call_traits<const S&, void(R&)>::result_type(s, r);
345 }
346
347 template <typename S, typename R>
348 BOOST_ASIO_CONSTEXPR typename enable_if<
349 call_traits<S&, void(const R&)>::overload == call_member,
350 typename call_traits<S&, void(const R&)>::result_type
351 >::type
352 operator()(S& s, const R& r) const
353 BOOST_ASIO_NOEXCEPT_IF((
354 call_traits<S&, void(const R&)>::is_noexcept))
355 {
356 return s.connect(r);
357 }
358
359 template <typename S, typename R>
360 BOOST_ASIO_CONSTEXPR typename enable_if<
361 call_traits<const S&, void(const R&)>::overload == call_member,
362 typename call_traits<const S&, void(const R&)>::result_type
363 >::type
364 operator()(const S& s, const R& r) const
365 BOOST_ASIO_NOEXCEPT_IF((
366 call_traits<const S&, void(const R&)>::is_noexcept))
367 {
368 return s.connect(r);
369 }
370
371 template <typename S, typename R>
372 BOOST_ASIO_CONSTEXPR typename enable_if<
373 call_traits<S&, void(const R&)>::overload == call_free,
374 typename call_traits<S&, void(const R&)>::result_type
375 >::type
376 operator()(S& s, const R& r) const
377 BOOST_ASIO_NOEXCEPT_IF((
378 call_traits<S&, void(const R&)>::is_noexcept))
379 {
380 return connect(s, r);
381 }
382
383 template <typename S, typename R>
384 BOOST_ASIO_CONSTEXPR typename enable_if<
385 call_traits<const S&, void(const R&)>::overload == call_free,
386 typename call_traits<const S&, void(const R&)>::result_type
387 >::type
388 operator()(const S& s, const R& r) const
389 BOOST_ASIO_NOEXCEPT_IF((
390 call_traits<const S&, void(const R&)>::is_noexcept))
391 {
392 return connect(s, r);
393 }
394
395 template <typename S, typename R>
396 BOOST_ASIO_CONSTEXPR typename enable_if<
397 call_traits<S&, void(const R&)>::overload == adapter,
398 typename call_traits<S&, void(const R&)>::result_type
399 >::type
400 operator()(S& s, const R& r) const
401 BOOST_ASIO_NOEXCEPT_IF((
402 call_traits<S&, void(const R&)>::is_noexcept))
403 {
404 return typename call_traits<S&, void(const R&)>::result_type(s, r);
405 }
406
407 template <typename S, typename R>
408 BOOST_ASIO_CONSTEXPR typename enable_if<
409 call_traits<const S&, void(const R&)>::overload == adapter,
410 typename call_traits<const S&, void(const R&)>::result_type
411 >::type
412 operator()(const S& s, const R& r) const
413 BOOST_ASIO_NOEXCEPT_IF((
414 call_traits<const S&, void(const R&)>::is_noexcept))
415 {
416 return typename call_traits<const S&, void(const R&)>::result_type(s, r);
417 }
418 #endif // defined(BOOST_ASIO_HAS_MOVE)
419 };
420
421 template <typename T = impl>
422 struct static_instance
423 {
424 static const T instance;
425 };
426
427 template <typename T>
428 const T static_instance<T>::instance = {};
429
430 } // namespace boost_asio_execution_connect_fn
431 namespace boost {
432 namespace asio {
433 namespace execution {
434 namespace {
435
436 static BOOST_ASIO_CONSTEXPR const boost_asio_execution_connect_fn::impl&
437 connect = boost_asio_execution_connect_fn::static_instance<>::instance;
438
439 } // namespace
440
441 template <typename S, typename R>
442 struct can_connect :
443 integral_constant<bool,
444 boost_asio_execution_connect_fn::call_traits<S, void(R)>::overload !=
445 boost_asio_execution_connect_fn::ill_formed>
446 {
447 };
448
449 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
450
451 template <typename S, typename R>
452 constexpr bool can_connect_v = can_connect<S, R>::value;
453
454 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
455
456 template <typename S, typename R>
457 struct is_nothrow_connect :
458 integral_constant<bool,
459 boost_asio_execution_connect_fn::call_traits<S, void(R)>::is_noexcept>
460 {
461 };
462
463 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
464
465 template <typename S, typename R>
466 constexpr bool is_nothrow_connect_v
467 = is_nothrow_connect<S, R>::value;
468
469 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
470
471 template <typename S, typename R>
472 struct connect_result
473 {
474 typedef typename boost_asio_execution_connect_fn::call_traits<
475 S, void(R)>::result_type type;
476 };
477
478 #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
479
480 template <typename S, typename R>
481 using connect_result_t = typename connect_result<S, R>::type;
482
483 #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
484
485 } // namespace execution
486 } // namespace asio
487 } // namespace boost
488
489 #endif // defined(GENERATING_DOCUMENTATION)
490
491 #include <boost/asio/detail/pop_options.hpp>
492
493 #endif // BOOST_ASIO_EXECUTION_CONNECT_HPP