Clementine
relationship.hpp
1 //
2 // execution/relationship.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_RELATIONSHIP_HPP
12 #define ASIO_EXECUTION_RELATIONSHIP_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/executor.hpp"
21 #include "asio/execution/scheduler.hpp"
22 #include "asio/execution/sender.hpp"
23 #include "asio/is_applicable_property.hpp"
24 #include "asio/query.hpp"
25 #include "asio/traits/query_free.hpp"
26 #include "asio/traits/query_member.hpp"
27 #include "asio/traits/query_static_constexpr_member.hpp"
28 #include "asio/traits/static_query.hpp"
29 #include "asio/traits/static_require.hpp"
30 
31 #include "asio/detail/push_options.hpp"
32 
33 namespace asio {
34 
35 #if defined(GENERATING_DOCUMENTATION)
36 
37 namespace execution {
38 
41 struct relationship_t
42 {
44  template <typename T>
45  static constexpr bool is_applicable_property_v =
46  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
47 
49  static constexpr bool is_requirable = false;
50 
52  static constexpr bool is_preferable = false;
53 
55  typedef relationship_t polymorphic_query_result_type;
56 
59  struct fork_t
60  {
63  template <typename T>
64  static constexpr bool is_applicable_property_v =
65  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
66 
68  static constexpr bool is_requirable = true;
69 
71  static constexpr bool is_preferable = true;
72 
74  typedef relationship_t polymorphic_query_result_type;
75 
77  constexpr fork_t();
78 
80 
83  static constexpr relationship_t value();
84  };
85 
88  struct continuation_t
89  {
92  template <typename T>
93  static constexpr bool is_applicable_property_v =
94  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
95 
97  static constexpr bool is_requirable = true;
98 
100  static constexpr bool is_preferable = true;
101 
103  typedef relationship_t polymorphic_query_result_type;
104 
106  constexpr continuation_t();
107 
109 
112  static constexpr relationship_t value();
113  };
114 
116  static constexpr fork_t fork;
117 
120  static constexpr continuation_t continuation;
121 
123  constexpr relationship_t();
124 
126  constexpr relationship_t(fork_t);
127 
129  constexpr relationship_t(continuation_t);
130 
132  friend constexpr bool operator==(
133  const relationship_t& a, const relationship_t& b) noexcept;
134 
136  friend constexpr bool operator!=(
137  const relationship_t& a, const relationship_t& b) noexcept;
138 };
139 
141 constexpr relationship_t relationship;
142 
143 } // namespace execution
144 
145 #else // defined(GENERATING_DOCUMENTATION)
146 
147 namespace execution {
148 namespace detail {
149 namespace relationship {
150 
151 template <int I> struct fork_t;
152 template <int I> struct continuation_t;
153 
154 } // namespace relationship
155 
156 template <int I = 0>
158 {
159 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
160  template <typename T>
161  ASIO_STATIC_CONSTEXPR(bool,
162  is_applicable_property_v = is_executor<T>::value
164 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
165 
166  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
167  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
169 
172 
173  ASIO_CONSTEXPR relationship_t()
174  : value_(-1)
175  {
176  }
177 
178  ASIO_CONSTEXPR relationship_t(fork_t)
179  : value_(0)
180  {
181  }
182 
183  ASIO_CONSTEXPR relationship_t(continuation_t)
184  : value_(1)
185  {
186  }
187 
188 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
189  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
190  template <typename T>
191  static ASIO_CONSTEXPR
193  T, relationship_t>::result_type
194  static_query()
195  ASIO_NOEXCEPT_IF((
197  T, relationship_t
198  >::is_noexcept))
199  {
201  T, relationship_t>::value();
202  }
203 
204  template <typename T>
205  static ASIO_CONSTEXPR
207  static_query(
208  typename enable_if<
210  T, relationship_t>::is_valid
213  >::type* = 0) ASIO_NOEXCEPT
214  {
216  }
217 
218  template <typename T>
219  static ASIO_CONSTEXPR
221  static_query(
222  typename enable_if<
224  T, relationship_t>::is_valid
228  >::type* = 0) ASIO_NOEXCEPT
229  {
231  }
232 
233  template <typename E,
234  typename T = decltype(relationship_t::static_query<E>())>
235  static ASIO_CONSTEXPR const T static_query_v
236  = relationship_t::static_query<E>();
237 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
238  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
239 
240  friend ASIO_CONSTEXPR bool operator==(
241  const relationship_t& a, const relationship_t& b)
242  {
243  return a.value_ == b.value_;
244  }
245 
246  friend ASIO_CONSTEXPR bool operator!=(
247  const relationship_t& a, const relationship_t& b)
248  {
249  return a.value_ != b.value_;
250  }
251 
253  {
254  ASIO_CONSTEXPR convertible_from_relationship_t(relationship_t)
255  {
256  }
257  };
258 
259  template <typename Executor>
260  friend ASIO_CONSTEXPR relationship_t query(
261  const Executor& ex, convertible_from_relationship_t,
262  typename enable_if<
264  >::type* = 0)
265 #if !defined(__clang__) // Clang crashes if noexcept is used here.
266 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
267  ASIO_NOEXCEPT_IF((
268  is_nothrow_query<const Executor&, relationship_t<>::fork_t>::value))
269 #else // defined(ASIO_MSVC)
270  ASIO_NOEXCEPT_IF((
272 #endif // defined(ASIO_MSVC)
273 #endif // !defined(__clang__)
274  {
275  return asio::query(ex, fork_t());
276  }
277 
278  template <typename Executor>
279  friend ASIO_CONSTEXPR relationship_t query(
280  const Executor& ex, convertible_from_relationship_t,
281  typename enable_if<
284  >::type* = 0)
285 #if !defined(__clang__) // Clang crashes if noexcept is used here.
286 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
287  ASIO_NOEXCEPT_IF((
288  is_nothrow_query<const Executor&,
290 #else // defined(ASIO_MSVC)
291  ASIO_NOEXCEPT_IF((
293 #endif // defined(ASIO_MSVC)
294 #endif // !defined(__clang__)
295  {
296  return asio::query(ex, continuation_t());
297  }
298 
299  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(fork_t, fork);
300  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(continuation_t, continuation);
301 
302 #if !defined(ASIO_HAS_CONSTEXPR)
303  static const relationship_t instance;
304 #endif // !defined(ASIO_HAS_CONSTEXPR)
305 
306 private:
307  int value_;
308 };
309 
310 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
311  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
312 template <int I> template <typename E, typename T>
314 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
315  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
316 
317 #if !defined(ASIO_HAS_CONSTEXPR)
318 template <int I>
320 #endif
321 
322 template <int I>
323 const typename relationship_t<I>::fork_t
325 
326 template <int I>
329 
330 namespace relationship {
331 
332 template <int I = 0>
333 struct fork_t
334 {
335 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
336  template <typename T>
337  ASIO_STATIC_CONSTEXPR(bool,
338  is_applicable_property_v = is_executor<T>::value
340 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
341 
342  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
343  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
345 
346  ASIO_CONSTEXPR fork_t()
347  {
348  }
349 
350 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
351  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
352  template <typename T>
353  static ASIO_CONSTEXPR
355  static_query()
356  ASIO_NOEXCEPT_IF((
358  {
360  }
361 
362  template <typename T>
363  static ASIO_CONSTEXPR fork_t static_query(
364  typename enable_if<
368  && !can_query<T, continuation_t<I> >::value
369  >::type* = 0) ASIO_NOEXCEPT
370  {
371  return fork_t();
372  }
373 
374  template <typename E, typename T = decltype(fork_t::static_query<E>())>
375  static ASIO_CONSTEXPR const T static_query_v
376  = fork_t::static_query<E>();
377 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
378  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
379 
380  static ASIO_CONSTEXPR relationship_t<I> value()
381  {
382  return fork_t();
383  }
384 
385  friend ASIO_CONSTEXPR bool operator==(
386  const fork_t&, const fork_t&)
387  {
388  return true;
389  }
390 
391  friend ASIO_CONSTEXPR bool operator!=(
392  const fork_t&, const fork_t&)
393  {
394  return false;
395  }
396 };
397 
398 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
399  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
400 template <int I> template <typename E, typename T>
402 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
403  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
404 
405 template <int I = 0>
406 struct continuation_t
407 {
408 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
409  template <typename T>
410  ASIO_STATIC_CONSTEXPR(bool,
411  is_applicable_property_v = is_executor<T>::value
413 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
414 
415  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
416  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
418 
419  ASIO_CONSTEXPR continuation_t()
420  {
421  }
422 
423 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
424  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
425  template <typename T>
426  static ASIO_CONSTEXPR
428  static_query()
429  ASIO_NOEXCEPT_IF((
431  {
433  }
434 
435  template <typename E,
436  typename T = decltype(continuation_t::static_query<E>())>
437  static ASIO_CONSTEXPR const T static_query_v
438  = continuation_t::static_query<E>();
439 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
440  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
441 
442  static ASIO_CONSTEXPR relationship_t<I> value()
443  {
444  return continuation_t();
445  }
446 
447  friend ASIO_CONSTEXPR bool operator==(
448  const continuation_t&, const continuation_t&)
449  {
450  return true;
451  }
452 
453  friend ASIO_CONSTEXPR bool operator!=(
454  const continuation_t&, const continuation_t&)
455  {
456  return false;
457  }
458 };
459 
460 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
461  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
462 template <int I> template <typename E, typename T>
464 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
465  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
466 
467 } // namespace relationship
468 } // namespace detail
469 
471 
472 #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
473 constexpr relationship_t relationship;
474 #else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
475 namespace { static const relationship_t&
476  relationship = relationship_t::instance; }
477 #endif
478 
479 } // namespace execution
480 
481 #if !defined(ASIO_HAS_VARIABLE_TEMPLATES)
482 
483 template <typename T>
484 struct is_applicable_property<T, execution::relationship_t>
485  : integral_constant<bool,
486  execution::is_executor<T>::value
487  || execution::is_sender<T>::value
488  || execution::is_scheduler<T>::value>
489 {
490 };
491 
492 template <typename T>
493 struct is_applicable_property<T, execution::relationship_t::fork_t>
494  : integral_constant<bool,
495  execution::is_executor<T>::value
496  || execution::is_sender<T>::value
497  || execution::is_scheduler<T>::value>
498 {
499 };
500 
501 template <typename T>
502 struct is_applicable_property<T, execution::relationship_t::continuation_t>
503  : integral_constant<bool,
504  execution::is_executor<T>::value
505  || execution::is_sender<T>::value
506  || execution::is_scheduler<T>::value>
507 {
508 };
509 
510 #endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)
511 
512 namespace traits {
513 
514 #if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
515 
516 template <typename T>
517 struct query_free_default<T, execution::relationship_t,
518  typename enable_if<
519  can_query<T, execution::relationship_t::fork_t>::value
520  >::type>
521 {
522  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
523  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
525 
527 };
528 
529 template <typename T>
530 struct query_free_default<T, execution::relationship_t,
531  typename enable_if<
532  !can_query<T, execution::relationship_t::fork_t>::value
533  && can_query<T, execution::relationship_t::continuation_t>::value
534  >::type>
535 {
536  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
537  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
539 
541 };
542 
543 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
544 
545 #if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
546  || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
547 
548 template <typename T>
549 struct static_query<T, execution::relationship_t,
550  typename enable_if<
551  traits::query_static_constexpr_member<T,
552  execution::relationship_t>::is_valid
553  >::type>
554 {
555  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
556  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
557 
558  typedef typename traits::query_static_constexpr_member<T,
559  execution::relationship_t>::result_type result_type;
560 
561  static ASIO_CONSTEXPR result_type value()
562  {
564  execution::relationship_t>::value();
565  }
566 };
567 
568 template <typename T>
569 struct static_query<T, execution::relationship_t,
570  typename enable_if<
571  !traits::query_static_constexpr_member<T,
572  execution::relationship_t>::is_valid
573  && !traits::query_member<T,
574  execution::relationship_t>::is_valid
575  && traits::static_query<T,
576  execution::relationship_t::fork_t>::is_valid
577  >::type>
578 {
579  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
580  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
581 
582  typedef typename traits::static_query<T,
583  execution::relationship_t::fork_t>::result_type result_type;
584 
585  static ASIO_CONSTEXPR result_type value()
586  {
587  return traits::static_query<T,
589  }
590 };
591 
592 template <typename T>
593 struct static_query<T, execution::relationship_t,
594  typename enable_if<
595  !traits::query_static_constexpr_member<T,
596  execution::relationship_t>::is_valid
597  && !traits::query_member<T,
598  execution::relationship_t>::is_valid
599  && !traits::static_query<T,
600  execution::relationship_t::fork_t>::is_valid
601  && traits::static_query<T,
602  execution::relationship_t::continuation_t>::is_valid
603  >::type>
604 {
605  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
606  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
607 
608  typedef typename traits::static_query<T,
609  execution::relationship_t::continuation_t>::result_type result_type;
610 
611  static ASIO_CONSTEXPR result_type value()
612  {
613  return traits::static_query<T,
615  }
616 };
617 
618 template <typename T>
619 struct static_query<T, execution::relationship_t::fork_t,
620  typename enable_if<
621  traits::query_static_constexpr_member<T,
622  execution::relationship_t::fork_t>::is_valid
623  >::type>
624 {
625  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
626  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
627 
628  typedef typename traits::query_static_constexpr_member<T,
629  execution::relationship_t::fork_t>::result_type result_type;
630 
631  static ASIO_CONSTEXPR result_type value()
632  {
635  }
636 };
637 
638 template <typename T>
639 struct static_query<T, execution::relationship_t::fork_t,
640  typename enable_if<
641  !traits::query_static_constexpr_member<T,
642  execution::relationship_t::fork_t>::is_valid
643  && !traits::query_member<T,
644  execution::relationship_t::fork_t>::is_valid
645  && !traits::query_free<T,
646  execution::relationship_t::fork_t>::is_valid
647  && !can_query<T, execution::relationship_t::continuation_t>::value
648  >::type>
649 {
650  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
651  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
652 
654 
655  static ASIO_CONSTEXPR result_type value()
656  {
657  return result_type();
658  }
659 };
660 
661 template <typename T>
662 struct static_query<T, execution::relationship_t::continuation_t,
663  typename enable_if<
664  traits::query_static_constexpr_member<T,
665  execution::relationship_t::continuation_t>::is_valid
666  >::type>
667 {
668  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
669  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
670 
671  typedef typename traits::query_static_constexpr_member<T,
672  execution::relationship_t::continuation_t>::result_type result_type;
673 
674  static ASIO_CONSTEXPR result_type value()
675  {
678  }
679 };
680 
681 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
682  // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
683 
684 #if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
685 
686 template <typename T>
687 struct static_require<T, execution::relationship_t::fork_t,
688  typename enable_if<
689  static_query<T, execution::relationship_t::fork_t>::is_valid
690  >::type>
691 {
692  ASIO_STATIC_CONSTEXPR(bool, is_valid =
693  (is_same<typename static_query<T,
694  execution::relationship_t::fork_t>::result_type,
696 };
697 
698 template <typename T>
699 struct static_require<T, execution::relationship_t::continuation_t,
700  typename enable_if<
701  static_query<T, execution::relationship_t::continuation_t>::is_valid
702  >::type>
703 {
704  ASIO_STATIC_CONSTEXPR(bool, is_valid =
705  (is_same<typename static_query<T,
708 };
709 
710 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
711 
712 } // namespace traits
713 
714 #endif // defined(GENERATING_DOCUMENTATION)
715 
716 } // namespace asio
717 
718 #include "asio/detail/pop_options.hpp"
719 
720 #endif // ASIO_EXECUTION_RELATIONSHIP_HPP
Definition: static_require.hpp:37
Definition: relationship.hpp:157
Definition: any_executor.hpp:249
Definition: query.hpp:269
The is_scheduler trait detects whether a type T satisfies the execution::scheduler concept...
Definition: scheduler.hpp:48
The is_sender trait detects whether a type T satisfies the execution::sender concept.
Definition: sender.hpp:183
Definition: query_member.hpp:38
Definition: static_query.hpp:42
Definition: chrono.h:284
Definition: type_traits.hpp:97
Definition: query.hpp:253
Definition: query_free.hpp:35
Definition: query_free.hpp:38
Definition: query_static_constexpr_member.hpp:42
Definition: any_executor.hpp:256
Definition: handler_work.hpp:37
Definition: relationship.hpp:151
Definition: is_applicable_property.hpp:46
Definition: any_io_executor.hpp:28
The is_executor trait detects whether a type T satisfies the execution::executor concept.
Definition: executor.hpp:109