Clementine
connect.hpp
1 //
2 // execution/connect.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 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 ASIO_EXECUTION_CONNECT_HPP
12 #define 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 "asio/detail/config.hpp"
19 #include "asio/detail/type_traits.hpp"
20 #include "asio/execution/detail/as_invocable.hpp"
21 #include "asio/execution/detail/as_operation.hpp"
22 #include "asio/execution/detail/as_receiver.hpp"
23 #include "asio/execution/executor.hpp"
24 #include "asio/execution/operation_state.hpp"
25 #include "asio/execution/receiver.hpp"
26 #include "asio/execution/sender.hpp"
27 #include "asio/traits/connect_member.hpp"
28 #include "asio/traits/connect_free.hpp"
29 
30 #include "asio/detail/push_options.hpp"
31 
32 #if defined(GENERATING_DOCUMENTATION)
33 
34 namespace asio {
35 namespace execution {
36 
38 
97 inline constexpr unspecified connect = unspecified;
98 
101 
106 template <typename S, typename R>
107 struct can_connect :
108  integral_constant<bool, automatically_determined>
109 {
110 };
111 
113 template <typename S, typename R>
114 struct connect_result
115 {
117 
121  typedef automatically_determined type;
122 };
123 
125 template <typename S, typename R>
126 using connect_result_t = typename connect_result<S, R>::type;
127 
128 } // namespace execution
129 } // namespace asio
130 
131 #else // defined(GENERATING_DOCUMENTATION)
132 
133 namespace asio_execution_connect_fn {
134 
135 using asio::conditional;
136 using asio::declval;
137 using asio::enable_if;
145 using asio::false_type;
146 using asio::remove_cvref;
149 
150 void connect();
151 
152 enum overload_type
153 {
154  call_member,
155  call_free,
156  adapter,
157  ill_formed
158 };
159 
160 template <typename S, typename R, typename = void>
162 {
163  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
164  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
165  typedef void result_type;
166 };
167 
168 template <typename S, typename R>
169 struct call_traits<S, void(R),
170  typename enable_if<
171  (
172  connect_member<S, R>::is_valid
173  &&
174  is_operation_state<typename connect_member<S, R>::result_type>::value
175  &&
176  is_sender<typename remove_cvref<S>::type>::value
177  )
178  >::type> :
179  connect_member<S, R>
180 {
181  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
182 };
183 
184 template <typename S, typename R>
185 struct call_traits<S, void(R),
186  typename enable_if<
187  (
188  !connect_member<S, R>::is_valid
189  &&
190  connect_free<S, R>::is_valid
191  &&
192  is_operation_state<typename connect_free<S, R>::result_type>::value
193  &&
194  is_sender<typename remove_cvref<S>::type>::value
195  )
196  >::type> :
197  connect_free<S, R>
198 {
199  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
200 };
201 
202 template <typename S, typename R>
203 struct call_traits<S, void(R),
204  typename enable_if<
205  (
206  !connect_member<S, R>::is_valid
207  &&
208  !connect_free<S, R>::is_valid
209  &&
210  is_receiver<R>::value
211  &&
212  conditional<
213  !is_as_receiver<
214  typename remove_cvref<R>::type
215  >::value,
216  is_executor_of<
217  typename remove_cvref<S>::type,
218  as_invocable<typename remove_cvref<R>::type, S>
219  >,
220  false_type
221  >::type::value
222  )
223  >::type>
224 {
225  ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);
226  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
228 };
229 
230 struct impl
231 {
232 #if defined(ASIO_HAS_MOVE)
233  template <typename S, typename R>
234  ASIO_CONSTEXPR typename enable_if<
235  call_traits<S, void(R)>::overload == call_member,
236  typename call_traits<S, void(R)>::result_type
237  >::type
238  operator()(S&& s, R&& r) const
239  ASIO_NOEXCEPT_IF((
240  call_traits<S, void(R)>::is_noexcept))
241  {
242  return ASIO_MOVE_CAST(S)(s).connect(ASIO_MOVE_CAST(R)(r));
243  }
244 
245  template <typename S, typename R>
246  ASIO_CONSTEXPR typename enable_if<
247  call_traits<S, void(R)>::overload == call_free,
248  typename call_traits<S, void(R)>::result_type
249  >::type
250  operator()(S&& s, R&& r) const
251  ASIO_NOEXCEPT_IF((
252  call_traits<S, void(R)>::is_noexcept))
253  {
254  return connect(ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));
255  }
256 
257  template <typename S, typename R>
258  ASIO_CONSTEXPR typename enable_if<
259  call_traits<S, void(R)>::overload == adapter,
260  typename call_traits<S, void(R)>::result_type
261  >::type
262  operator()(S&& s, R&& r) const
263  ASIO_NOEXCEPT_IF((
264  call_traits<S, void(R)>::is_noexcept))
265  {
266  return typename call_traits<S, void(R)>::result_type(
267  ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));
268  }
269 #else // defined(ASIO_HAS_MOVE)
270  template <typename S, typename R>
271  ASIO_CONSTEXPR typename enable_if<
273  typename call_traits<S&, void(R&)>::result_type
274  >::type
275  operator()(S& s, R& r) const
276  ASIO_NOEXCEPT_IF((
277  call_traits<S&, void(R&)>::is_noexcept))
278  {
279  return s.connect(r);
280  }
281 
282  template <typename S, typename R>
283  ASIO_CONSTEXPR typename enable_if<
285  typename call_traits<const S&, void(R&)>::result_type
286  >::type
287  operator()(const S& s, R& r) const
288  ASIO_NOEXCEPT_IF((
289  call_traits<const S&, void(R&)>::is_noexcept))
290  {
291  return s.connect(r);
292  }
293 
294  template <typename S, typename R>
295  ASIO_CONSTEXPR typename enable_if<
296  call_traits<S&, void(R&)>::overload == call_free,
297  typename call_traits<S&, void(R&)>::result_type
298  >::type
299  operator()(S& s, R& r) const
300  ASIO_NOEXCEPT_IF((
301  call_traits<S&, void(R&)>::is_noexcept))
302  {
303  return connect(s, r);
304  }
305 
306  template <typename S, typename R>
307  ASIO_CONSTEXPR typename enable_if<
308  call_traits<const S&, void(R&)>::overload == call_free,
309  typename call_traits<const S&, void(R&)>::result_type
310  >::type
311  operator()(const S& s, R& r) const
312  ASIO_NOEXCEPT_IF((
313  call_traits<const S&, void(R&)>::is_noexcept))
314  {
315  return connect(s, r);
316  }
317 
318  template <typename S, typename R>
319  ASIO_CONSTEXPR typename enable_if<
320  call_traits<S&, void(R&)>::overload == adapter,
321  typename call_traits<S&, void(R&)>::result_type
322  >::type
323  operator()(S& s, R& r) const
324  ASIO_NOEXCEPT_IF((
325  call_traits<S&, void(R&)>::is_noexcept))
326  {
327  return typename call_traits<S&, void(R&)>::result_type(s, r);
328  }
329 
330  template <typename S, typename R>
331  ASIO_CONSTEXPR typename enable_if<
332  call_traits<const S&, void(R&)>::overload == adapter,
333  typename call_traits<const S&, void(R&)>::result_type
334  >::type
335  operator()(const S& s, R& r) const
336  ASIO_NOEXCEPT_IF((
337  call_traits<const S&, void(R&)>::is_noexcept))
338  {
339  return typename call_traits<const S&, void(R&)>::result_type(s, r);
340  }
341 
342  template <typename S, typename R>
343  ASIO_CONSTEXPR typename enable_if<
345  typename call_traits<S&, void(const R&)>::result_type
346  >::type
347  operator()(S& s, const R& r) const
348  ASIO_NOEXCEPT_IF((
349  call_traits<S&, void(const R&)>::is_noexcept))
350  {
351  return s.connect(r);
352  }
353 
354  template <typename S, typename R>
355  ASIO_CONSTEXPR typename enable_if<
357  typename call_traits<const S&, void(const R&)>::result_type
358  >::type
359  operator()(const S& s, const R& r) const
360  ASIO_NOEXCEPT_IF((
361  call_traits<const S&, void(const R&)>::is_noexcept))
362  {
363  return s.connect(r);
364  }
365 
366  template <typename S, typename R>
367  ASIO_CONSTEXPR typename enable_if<
368  call_traits<S&, void(const R&)>::overload == call_free,
369  typename call_traits<S&, void(const R&)>::result_type
370  >::type
371  operator()(S& s, const R& r) const
372  ASIO_NOEXCEPT_IF((
373  call_traits<S&, void(const R&)>::is_noexcept))
374  {
375  return connect(s, r);
376  }
377 
378  template <typename S, typename R>
379  ASIO_CONSTEXPR typename enable_if<
380  call_traits<const S&, void(const R&)>::overload == call_free,
381  typename call_traits<const S&, void(const R&)>::result_type
382  >::type
383  operator()(const S& s, const R& r) const
384  ASIO_NOEXCEPT_IF((
385  call_traits<const S&, void(const R&)>::is_noexcept))
386  {
387  return connect(s, r);
388  }
389 
390  template <typename S, typename R>
391  ASIO_CONSTEXPR typename enable_if<
392  call_traits<S&, void(const R&)>::overload == adapter,
393  typename call_traits<S&, void(const R&)>::result_type
394  >::type
395  operator()(S& s, const R& r) const
396  ASIO_NOEXCEPT_IF((
397  call_traits<S&, void(const R&)>::is_noexcept))
398  {
399  return typename call_traits<S&, void(const R&)>::result_type(s, r);
400  }
401 
402  template <typename S, typename R>
403  ASIO_CONSTEXPR typename enable_if<
404  call_traits<const S&, void(const R&)>::overload == adapter,
405  typename call_traits<const S&, void(const R&)>::result_type
406  >::type
407  operator()(const S& s, const R& r) const
408  ASIO_NOEXCEPT_IF((
409  call_traits<const S&, void(const R&)>::is_noexcept))
410  {
411  return typename call_traits<const S&, void(const R&)>::result_type(s, r);
412  }
413 #endif // defined(ASIO_HAS_MOVE)
414 };
415 
416 template <typename T = impl>
418 {
419  static const T instance;
420 };
421 
422 template <typename T>
423 const T static_instance<T>::instance = {};
424 
425 } // namespace asio_execution_connect_fn
426 namespace asio {
427 namespace execution {
428 namespace {
429 
430 static ASIO_CONSTEXPR const asio_execution_connect_fn::impl&
432 
433 } // namespace
434 
435 template <typename S, typename R>
436 struct can_connect :
437  integral_constant<bool,
438  asio_execution_connect_fn::call_traits<S, void(R)>::overload !=
439  asio_execution_connect_fn::ill_formed>
440 {
441 };
442 
443 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
444 
445 template <typename S, typename R>
446 constexpr bool can_connect_v = can_connect<S, R>::value;
447 
448 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
449 
450 template <typename S, typename R>
452  integral_constant<bool,
453  asio_execution_connect_fn::call_traits<S, void(R)>::is_noexcept>
454 {
455 };
456 
457 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
458 
459 template <typename S, typename R>
460 constexpr bool is_nothrow_connect_v
462 
463 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
464 
465 template <typename S, typename R>
467 {
469  S, void(R)>::result_type type;
470 };
471 
472 #if defined(ASIO_HAS_ALIAS_TEMPLATES)
473 
474 template <typename S, typename R>
475 using connect_result_t = typename connect_result<S, R>::type;
476 
477 #endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
478 
479 } // namespace execution
480 } // namespace asio
481 
482 #endif // defined(GENERATING_DOCUMENTATION)
483 
484 #include "asio/detail/pop_options.hpp"
485 
486 #endif // ASIO_EXECUTION_CONNECT_HPP
Definition: connect_free.hpp:38
Definition: as_invocable.hpp:84
Definition: blocking.hpp:208
The is_sender trait detects whether a type T satisfies the execution::sender concept.
Definition: sender.hpp:183
The is_executor_of trait detects whether a type T satisfies the execution::executor_of concept for so...
Definition: executor.hpp:147
The is_operation_state trait detects whether a type T satisfies the execution::operation_state concep...
Definition: operation_state.hpp:53
The is_receiver trait detects whether a type T satisfies the execution::receiver concept.
Definition: receiver.hpp:81
Definition: connect.hpp:230
Definition: connect.hpp:161
Definition: connect.hpp:133
Definition: type_traits.hpp:97
Definition: as_operation.hpp:33
Definition: connect_member.hpp:38
Definition: connect.hpp:466
Definition: connect.hpp:451
Definition: connect.hpp:436
Iterator connect(basic_socket< Protocol, Executor > &s, Iterator begin, Iterator end, ConnectCondition connect_condition, asio::error_code &ec)
Establishes a socket connection by trying each endpoint in a sequence.
Definition: connect.hpp:229
Definition: handler_work.hpp:37
Definition: type_traits.hpp:128
Definition: as_receiver.hpp:66
Definition: any_io_executor.hpp:28