Clementine
outstanding_work.hpp
1 //
2 // execution/outstanding_work.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_OUTSTANDING_WORK_HPP
12 #define ASIO_EXECUTION_OUTSTANDING_WORK_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 
40 struct outstanding_work_t
41 {
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 outstanding_work_t polymorphic_query_result_type;
56 
59  struct untracked_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 outstanding_work_t polymorphic_query_result_type;
75 
77  constexpr untracked_t();
78 
80 
83  static constexpr outstanding_work_t value();
84  };
85 
88  struct tracked_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 outstanding_work_t polymorphic_query_result_type;
104 
106  constexpr tracked_t();
107 
109 
112  static constexpr outstanding_work_t value();
113  };
114 
117  static constexpr untracked_t untracked;
118 
121  static constexpr tracked_t tracked;
122 
124  constexpr outstanding_work_t();
125 
127  constexpr outstanding_work_t(untracked_t);
128 
130  constexpr outstanding_work_t(tracked_t);
131 
133  friend constexpr bool operator==(
134  const outstanding_work_t& a, const outstanding_work_t& b) noexcept;
135 
137  friend constexpr bool operator!=(
138  const outstanding_work_t& a, const outstanding_work_t& b) noexcept;
139 };
140 
142 constexpr outstanding_work_t outstanding_work;
143 
144 } // namespace execution
145 
146 #else // defined(GENERATING_DOCUMENTATION)
147 
148 namespace execution {
149 namespace detail {
150 namespace outstanding_work {
151 
152 template <int I> struct untracked_t;
153 template <int I> struct tracked_t;
154 
155 } // namespace outstanding_work
156 
157 template <int I = 0>
159 {
160 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
161  template <typename T>
162  ASIO_STATIC_CONSTEXPR(bool,
163  is_applicable_property_v = is_executor<T>::value
165 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
166 
167  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
168  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
170 
173 
174  ASIO_CONSTEXPR outstanding_work_t()
175  : value_(-1)
176  {
177  }
178 
179  ASIO_CONSTEXPR outstanding_work_t(untracked_t)
180  : value_(0)
181  {
182  }
183 
184  ASIO_CONSTEXPR outstanding_work_t(tracked_t)
185  : value_(1)
186  {
187  }
188 
189 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
190  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
191  template <typename T>
192  static ASIO_CONSTEXPR
194  T, outstanding_work_t>::result_type
195  static_query()
196  ASIO_NOEXCEPT_IF((
198  T, outstanding_work_t
199  >::is_noexcept))
200  {
202  T, outstanding_work_t>::value();
203  }
204 
205  template <typename T>
206  static ASIO_CONSTEXPR
208  static_query(
209  typename enable_if<
211  T, outstanding_work_t>::is_valid
214  >::type* = 0) ASIO_NOEXCEPT
215  {
217  }
218 
219  template <typename T>
220  static ASIO_CONSTEXPR
222  static_query(
223  typename enable_if<
225  T, outstanding_work_t>::is_valid
229  >::type* = 0) ASIO_NOEXCEPT
230  {
232  }
233 
234  template <typename E,
235  typename T = decltype(outstanding_work_t::static_query<E>())>
236  static ASIO_CONSTEXPR const T static_query_v
237  = outstanding_work_t::static_query<E>();
238 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
239  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
240 
241  friend ASIO_CONSTEXPR bool operator==(
242  const outstanding_work_t& a, const outstanding_work_t& b)
243  {
244  return a.value_ == b.value_;
245  }
246 
247  friend ASIO_CONSTEXPR bool operator!=(
248  const outstanding_work_t& a, const outstanding_work_t& b)
249  {
250  return a.value_ != b.value_;
251  }
252 
254  {
255  ASIO_CONSTEXPR convertible_from_outstanding_work_t(outstanding_work_t)
256  {
257  }
258  };
259 
260  template <typename Executor>
261  friend ASIO_CONSTEXPR outstanding_work_t query(
262  const Executor& ex, convertible_from_outstanding_work_t,
263  typename enable_if<
265  >::type* = 0)
266 #if !defined(__clang__) // Clang crashes if noexcept is used here.
267 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
268  ASIO_NOEXCEPT_IF((
269  is_nothrow_query<const Executor&,
271 #else // defined(ASIO_MSVC)
272  ASIO_NOEXCEPT_IF((
274 #endif // defined(ASIO_MSVC)
275 #endif // !defined(__clang__)
276  {
277  return asio::query(ex, untracked_t());
278  }
279 
280  template <typename Executor>
281  friend ASIO_CONSTEXPR outstanding_work_t query(
282  const Executor& ex, convertible_from_outstanding_work_t,
283  typename enable_if<
286  >::type* = 0)
287 #if !defined(__clang__) // Clang crashes if noexcept is used here.
288 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
289  ASIO_NOEXCEPT_IF((
290  is_nothrow_query<const Executor&,
292 #else // defined(ASIO_MSVC)
293  ASIO_NOEXCEPT_IF((
295 #endif // defined(ASIO_MSVC)
296 #endif // !defined(__clang__)
297  {
298  return asio::query(ex, tracked_t());
299  }
300 
301  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(untracked_t, untracked);
302  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(tracked_t, tracked);
303 
304 #if !defined(ASIO_HAS_CONSTEXPR)
305  static const outstanding_work_t instance;
306 #endif // !defined(ASIO_HAS_CONSTEXPR)
307 
308 private:
309  int value_;
310 };
311 
312 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
313  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
314 template <int I> template <typename E, typename T>
316 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
317  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
318 
319 #if !defined(ASIO_HAS_CONSTEXPR)
320 template <int I>
322 #endif
323 
324 template <int I>
327 
328 template <int I>
331 
332 namespace outstanding_work {
333 
334 template <int I = 0>
335 struct untracked_t
336 {
337 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
338  template <typename T>
339  ASIO_STATIC_CONSTEXPR(bool,
340  is_applicable_property_v = is_executor<T>::value
342 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
343 
344  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
345  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
347 
348  ASIO_CONSTEXPR untracked_t()
349  {
350  }
351 
352 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
353  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
354  template <typename T>
355  static ASIO_CONSTEXPR
357  static_query()
358  ASIO_NOEXCEPT_IF((
360  {
362  }
363 
364  template <typename T>
365  static ASIO_CONSTEXPR untracked_t static_query(
366  typename enable_if<
370  && !can_query<T, tracked_t<I> >::value
371  >::type* = 0) ASIO_NOEXCEPT
372  {
373  return untracked_t();
374  }
375 
376  template <typename E, typename T = decltype(untracked_t::static_query<E>())>
377  static ASIO_CONSTEXPR const T static_query_v
378  = untracked_t::static_query<E>();
379 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
380  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
381 
382  static ASIO_CONSTEXPR outstanding_work_t<I> value()
383  {
384  return untracked_t();
385  }
386 
387  friend ASIO_CONSTEXPR bool operator==(
388  const untracked_t&, const untracked_t&)
389  {
390  return true;
391  }
392 
393  friend ASIO_CONSTEXPR bool operator!=(
394  const untracked_t&, const untracked_t&)
395  {
396  return false;
397  }
398 };
399 
400 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
401  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
402 template <int I> template <typename E, typename T>
404 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
405  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
406 
407 template <int I = 0>
408 struct tracked_t
409 {
410 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
411  template <typename T>
412  ASIO_STATIC_CONSTEXPR(bool,
413  is_applicable_property_v = is_executor<T>::value
415 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
416 
417  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
418  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
420 
421  ASIO_CONSTEXPR tracked_t()
422  {
423  }
424 
425 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
426  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
427  template <typename T>
428  static ASIO_CONSTEXPR
430  static_query()
431  ASIO_NOEXCEPT_IF((
433  {
435  }
436 
437  template <typename E, typename T = decltype(tracked_t::static_query<E>())>
438  static ASIO_CONSTEXPR const T static_query_v
439  = tracked_t::static_query<E>();
440 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
441  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
442 
443  static ASIO_CONSTEXPR outstanding_work_t<I> value()
444  {
445  return tracked_t();
446  }
447 
448  friend ASIO_CONSTEXPR bool operator==(
449  const tracked_t&, const tracked_t&)
450  {
451  return true;
452  }
453 
454  friend ASIO_CONSTEXPR bool operator!=(
455  const tracked_t&, const tracked_t&)
456  {
457  return false;
458  }
459 };
460 
461 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
462  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
463 template <int I> template <typename E, typename T>
465 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
466  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
467 
468 } // namespace outstanding_work
469 } // namespace detail
470 
472 
473 #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
474 constexpr outstanding_work_t outstanding_work;
475 #else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
476 namespace { static const outstanding_work_t&
477  outstanding_work = outstanding_work_t::instance; }
478 #endif
479 
480 } // namespace execution
481 
482 #if !defined(ASIO_HAS_VARIABLE_TEMPLATES)
483 
484 template <typename T>
485 struct is_applicable_property<T, execution::outstanding_work_t>
486  : integral_constant<bool,
487  execution::is_executor<T>::value
488  || execution::is_sender<T>::value
489  || execution::is_scheduler<T>::value>
490 {
491 };
492 
493 template <typename T>
494 struct is_applicable_property<T, execution::outstanding_work_t::untracked_t>
495  : integral_constant<bool,
496  execution::is_executor<T>::value
497  || execution::is_sender<T>::value
498  || execution::is_scheduler<T>::value>
499 {
500 };
501 
502 template <typename T>
503 struct is_applicable_property<T, execution::outstanding_work_t::tracked_t>
504  : integral_constant<bool,
505  execution::is_executor<T>::value
506  || execution::is_sender<T>::value
507  || execution::is_scheduler<T>::value>
508 {
509 };
510 
511 #endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)
512 
513 namespace traits {
514 
515 #if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
516 
517 template <typename T>
518 struct query_free_default<T, execution::outstanding_work_t,
519  typename enable_if<
520  can_query<T, execution::outstanding_work_t::untracked_t>::value
521  >::type>
522 {
523  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
524  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
526 
528 };
529 
530 template <typename T>
531 struct query_free_default<T, execution::outstanding_work_t,
532  typename enable_if<
533  !can_query<T, execution::outstanding_work_t::untracked_t>::value
534  && can_query<T, execution::outstanding_work_t::tracked_t>::value
535  >::type>
536 {
537  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
538  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
540 
542 };
543 
544 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
545 
546 #if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
547  || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
548 
549 template <typename T>
550 struct static_query<T, execution::outstanding_work_t,
551  typename enable_if<
552  traits::query_static_constexpr_member<T,
553  execution::outstanding_work_t>::is_valid
554  >::type>
555 {
556  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
557  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
558 
559  typedef typename traits::query_static_constexpr_member<T,
560  execution::outstanding_work_t>::result_type result_type;
561 
562  static ASIO_CONSTEXPR result_type value()
563  {
566  }
567 };
568 
569 template <typename T>
570 struct static_query<T, execution::outstanding_work_t,
571  typename enable_if<
572  !traits::query_static_constexpr_member<T,
573  execution::outstanding_work_t>::is_valid
574  && !traits::query_member<T,
575  execution::outstanding_work_t>::is_valid
576  && traits::static_query<T,
577  execution::outstanding_work_t::untracked_t>::is_valid
578  >::type>
579 {
580  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
581  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
582 
583  typedef typename traits::static_query<T,
584  execution::outstanding_work_t::untracked_t>::result_type result_type;
585 
586  static ASIO_CONSTEXPR result_type value()
587  {
588  return traits::static_query<T,
590  }
591 };
592 
593 template <typename T>
594 struct static_query<T, execution::outstanding_work_t,
595  typename enable_if<
596  !traits::query_static_constexpr_member<T,
597  execution::outstanding_work_t>::is_valid
598  && !traits::query_member<T,
599  execution::outstanding_work_t>::is_valid
600  && !traits::static_query<T,
601  execution::outstanding_work_t::untracked_t>::is_valid
602  && traits::static_query<T,
603  execution::outstanding_work_t::tracked_t>::is_valid
604  >::type>
605 {
606  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
607  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
608 
609  typedef typename traits::static_query<T,
610  execution::outstanding_work_t::tracked_t>::result_type result_type;
611 
612  static ASIO_CONSTEXPR result_type value()
613  {
614  return traits::static_query<T,
616  }
617 };
618 
619 template <typename T>
620 struct static_query<T, execution::outstanding_work_t::untracked_t,
621  typename enable_if<
622  traits::query_static_constexpr_member<T,
623  execution::outstanding_work_t::untracked_t>::is_valid
624  >::type>
625 {
626  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
627  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
628 
629  typedef typename traits::query_static_constexpr_member<T,
630  execution::outstanding_work_t::untracked_t>::result_type result_type;
631 
632  static ASIO_CONSTEXPR result_type value()
633  {
636  }
637 };
638 
639 template <typename T>
640 struct static_query<T, execution::outstanding_work_t::untracked_t,
641  typename enable_if<
642  !traits::query_static_constexpr_member<T,
643  execution::outstanding_work_t::untracked_t>::is_valid
644  && !traits::query_member<T,
645  execution::outstanding_work_t::untracked_t>::is_valid
646  && !traits::query_free<T,
647  execution::outstanding_work_t::untracked_t>::is_valid
648  && !can_query<T, execution::outstanding_work_t::tracked_t>::value
649  >::type>
650 {
651  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
652  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
653 
655 
656  static ASIO_CONSTEXPR result_type value()
657  {
658  return result_type();
659  }
660 };
661 
662 template <typename T>
663 struct static_query<T, execution::outstanding_work_t::tracked_t,
664  typename enable_if<
665  traits::query_static_constexpr_member<T,
666  execution::outstanding_work_t::tracked_t>::is_valid
667  >::type>
668 {
669  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
670  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
671 
672  typedef typename traits::query_static_constexpr_member<T,
673  execution::outstanding_work_t::tracked_t>::result_type result_type;
674 
675  static ASIO_CONSTEXPR result_type value()
676  {
679  }
680 };
681 
682 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
683  // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
684 
685 #if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
686 
687 template <typename T>
688 struct static_require<T, execution::outstanding_work_t::untracked_t,
689  typename enable_if<
690  static_query<T, execution::outstanding_work_t::untracked_t>::is_valid
691  >::type>
692 {
693  ASIO_STATIC_CONSTEXPR(bool, is_valid =
694  (is_same<typename static_query<T,
697 };
698 
699 template <typename T>
700 struct static_require<T, execution::outstanding_work_t::tracked_t,
701  typename enable_if<
702  static_query<T, execution::outstanding_work_t::tracked_t>::is_valid
703  >::type>
704 {
705  ASIO_STATIC_CONSTEXPR(bool, is_valid =
706  (is_same<typename static_query<T,
709 };
710 
711 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
712 
713 } // namespace traits
714 
715 #endif // defined(GENERATING_DOCUMENTATION)
716 
717 } // namespace asio
718 
719 #include "asio/detail/pop_options.hpp"
720 
721 #endif // ASIO_EXECUTION_OUTSTANDING_WORK_HPP
Definition: static_require.hpp:37
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: outstanding_work.hpp:158
Definition: outstanding_work.hpp:153
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: is_applicable_property.hpp:46
Definition: any_io_executor.hpp:28
Definition: outstanding_work.hpp:152
The is_executor trait detects whether a type T satisfies the execution::executor concept.
Definition: executor.hpp:109