Clementine
blocking.hpp
1 //
2 // execution/blocking.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_BLOCKING_HPP
12 #define ASIO_EXECUTION_BLOCKING_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/execute.hpp"
21 #include "asio/execution/executor.hpp"
22 #include "asio/execution/scheduler.hpp"
23 #include "asio/execution/sender.hpp"
24 #include "asio/is_applicable_property.hpp"
25 #include "asio/prefer.hpp"
26 #include "asio/query.hpp"
27 #include "asio/require.hpp"
28 #include "asio/traits/query_free.hpp"
29 #include "asio/traits/query_member.hpp"
30 #include "asio/traits/query_static_constexpr_member.hpp"
31 #include "asio/traits/static_query.hpp"
32 #include "asio/traits/static_require.hpp"
33 
34 #include "asio/detail/push_options.hpp"
35 
36 namespace asio {
37 
38 #if defined(GENERATING_DOCUMENTATION)
39 
40 namespace execution {
41 
44 struct blocking_t
45 {
47  template <typename T>
48  static constexpr bool is_applicable_property_v =
49  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
50 
52  static constexpr bool is_requirable = false;
53 
55  static constexpr bool is_preferable = false;
56 
58  typedef blocking_t polymorphic_query_result_type;
59 
63  struct possibly_t
64  {
67  template <typename T>
68  static constexpr bool is_applicable_property_v =
69  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
70 
72  static constexpr bool is_requirable = true;
73 
75  static constexpr bool is_preferable = true;
76 
78  typedef blocking_t polymorphic_query_result_type;
79 
81  constexpr possibly_t();
82 
84 
87  static constexpr blocking_t value();
88  };
89 
93  struct always_t
94  {
97  template <typename T>
98  static constexpr bool is_applicable_property_v =
99  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
100 
102  static constexpr bool is_requirable = true;
103 
105  static constexpr bool is_preferable = false;
106 
108  typedef blocking_t polymorphic_query_result_type;
109 
111  constexpr always_t();
112 
114 
117  static constexpr blocking_t value();
118  };
119 
123  struct never_t
124  {
127  template <typename T>
128  static constexpr bool is_applicable_property_v =
129  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
130 
132  static constexpr bool is_requirable = true;
133 
135  static constexpr bool is_preferable = true;
136 
138  typedef blocking_t polymorphic_query_result_type;
139 
141  constexpr never_t();
142 
144 
147  static constexpr blocking_t value();
148  };
149 
151  static constexpr possibly_t possibly;
152 
154  static constexpr always_t always;
155 
157  static constexpr never_t never;
158 
160  constexpr blocking_t();
161 
163  constexpr blocking_t(possibly_t);
164 
166  constexpr blocking_t(always_t);
167 
169  constexpr blocking_t(never_t);
170 
172  friend constexpr bool operator==(
173  const blocking_t& a, const blocking_t& b) noexcept;
174 
176  friend constexpr bool operator!=(
177  const blocking_t& a, const blocking_t& b) noexcept;
178 };
179 
181 constexpr blocking_t blocking;
182 
183 } // namespace execution
184 
185 #else // defined(GENERATING_DOCUMENTATION)
186 
187 namespace execution {
188 namespace detail {
189 namespace blocking {
190 
191 template <int I> struct possibly_t;
192 template <int I> struct always_t;
193 template <int I> struct never_t;
194 
195 } // namespace blocking
196 namespace blocking_adaptation {
197 
198 template <int I> struct allowed_t;
199 
200 template <typename Executor, typename Function>
201 void blocking_execute(
202  ASIO_MOVE_ARG(Executor) ex,
203  ASIO_MOVE_ARG(Function) func);
204 
205 } // namespace blocking_adaptation
206 
207 template <int I = 0>
209 {
210 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
211  template <typename T>
212  ASIO_STATIC_CONSTEXPR(bool,
213  is_applicable_property_v = is_executor<T>::value
215 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
216 
217  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
218  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
220 
224 
225  ASIO_CONSTEXPR blocking_t()
226  : value_(-1)
227  {
228  }
229 
230  ASIO_CONSTEXPR blocking_t(possibly_t)
231  : value_(0)
232  {
233  }
234 
235  ASIO_CONSTEXPR blocking_t(always_t)
236  : value_(1)
237  {
238  }
239 
240  ASIO_CONSTEXPR blocking_t(never_t)
241  : value_(2)
242  {
243  }
244 
245 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
246  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
247  template <typename T>
248  static ASIO_CONSTEXPR
250  static_query()
251  ASIO_NOEXCEPT_IF((
253  {
255  }
256 
257  template <typename T>
258  static ASIO_CONSTEXPR
260  static_query(
261  typename enable_if<
265  >::type* = 0) ASIO_NOEXCEPT
266  {
268  }
269 
270  template <typename T>
271  static ASIO_CONSTEXPR
273  static_query(
274  typename enable_if<
279  >::type* = 0) ASIO_NOEXCEPT
280  {
282  }
283 
284  template <typename T>
285  static ASIO_CONSTEXPR
287  static_query(
288  typename enable_if<
294  >::type* = 0) ASIO_NOEXCEPT
295  {
297  }
298 
299  template <typename E, typename T = decltype(blocking_t::static_query<E>())>
300  static ASIO_CONSTEXPR const T static_query_v
301  = blocking_t::static_query<E>();
302 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
303  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
304 
305  friend ASIO_CONSTEXPR bool operator==(
306  const blocking_t& a, const blocking_t& b)
307  {
308  return a.value_ == b.value_;
309  }
310 
311  friend ASIO_CONSTEXPR bool operator!=(
312  const blocking_t& a, const blocking_t& b)
313  {
314  return a.value_ != b.value_;
315  }
316 
318  {
319  ASIO_CONSTEXPR convertible_from_blocking_t(blocking_t) {}
320  };
321 
322  template <typename Executor>
323  friend ASIO_CONSTEXPR blocking_t query(
324  const Executor& ex, convertible_from_blocking_t,
325  typename enable_if<
327  >::type* = 0)
328 #if !defined(__clang__) // Clang crashes if noexcept is used here.
329 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
330  ASIO_NOEXCEPT_IF((
331  is_nothrow_query<const Executor&, blocking_t<>::possibly_t>::value))
332 #else // defined(ASIO_MSVC)
333  ASIO_NOEXCEPT_IF((
335 #endif // defined(ASIO_MSVC)
336 #endif // !defined(__clang__)
337  {
338  return asio::query(ex, possibly_t());
339  }
340 
341  template <typename Executor>
342  friend ASIO_CONSTEXPR blocking_t query(
343  const Executor& ex, convertible_from_blocking_t,
344  typename enable_if<
347  >::type* = 0)
348 #if !defined(__clang__) // Clang crashes if noexcept is used here.
349 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
350  ASIO_NOEXCEPT_IF((
351  is_nothrow_query<const Executor&, blocking_t<>::always_t>::value))
352 #else // defined(ASIO_MSVC)
353  ASIO_NOEXCEPT_IF((
355 #endif // defined(ASIO_MSVC)
356 #endif // !defined(__clang__)
357  {
358  return asio::query(ex, always_t());
359  }
360 
361  template <typename Executor>
362  friend ASIO_CONSTEXPR blocking_t query(
363  const Executor& ex, convertible_from_blocking_t,
364  typename enable_if<
368  >::type* = 0)
369 #if !defined(__clang__) // Clang crashes if noexcept is used here.
370 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
371  ASIO_NOEXCEPT_IF((
372  is_nothrow_query<const Executor&, blocking_t<>::never_t>::value))
373 #else // defined(ASIO_MSVC)
374  ASIO_NOEXCEPT_IF((
376 #endif // defined(ASIO_MSVC)
377 #endif // !defined(__clang__)
378  {
379  return asio::query(ex, never_t());
380  }
381 
382  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(possibly_t, possibly);
383  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(always_t, always);
384  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(never_t, never);
385 
386 #if !defined(ASIO_HAS_CONSTEXPR)
387  static const blocking_t instance;
388 #endif // !defined(ASIO_HAS_CONSTEXPR)
389 
390 private:
391  int value_;
392 };
393 
394 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
395  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
396 template <int I> template <typename E, typename T>
398 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
399  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
400 
401 #if !defined(ASIO_HAS_CONSTEXPR)
402 template <int I>
404 #endif
405 
406 template <int I>
408 
409 template <int I>
411 
412 template <int I>
414 
415 namespace blocking {
416 
417 template <int I = 0>
418 struct possibly_t
419 {
420 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
421  template <typename T>
422  ASIO_STATIC_CONSTEXPR(bool,
423  is_applicable_property_v = is_executor<T>::value
425 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
426 
427  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
428  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
430 
431  ASIO_CONSTEXPR possibly_t()
432  {
433  }
434 
435 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
436  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
437  template <typename T>
438  static ASIO_CONSTEXPR
440  static_query()
441  ASIO_NOEXCEPT_IF((
443  {
445  }
446 
447  template <typename T>
448  static ASIO_CONSTEXPR possibly_t static_query(
449  typename enable_if<
453  && !can_query<T, always_t<I> >::value
454  && !can_query<T, never_t<I> >::value
455  >::type* = 0) ASIO_NOEXCEPT
456  {
457  return possibly_t();
458  }
459 
460  template <typename E, typename T = decltype(possibly_t::static_query<E>())>
461  static ASIO_CONSTEXPR const T static_query_v
462  = possibly_t::static_query<E>();
463 #endif // defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
464  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
465 
466  static ASIO_CONSTEXPR blocking_t<I> value()
467  {
468  return possibly_t();
469  }
470 
471  friend ASIO_CONSTEXPR bool operator==(
472  const possibly_t&, const possibly_t&)
473  {
474  return true;
475  }
476 
477  friend ASIO_CONSTEXPR bool operator!=(
478  const possibly_t&, const possibly_t&)
479  {
480  return false;
481  }
482 
483  friend ASIO_CONSTEXPR bool operator==(
484  const possibly_t&, const always_t<I>&)
485  {
486  return false;
487  }
488 
489  friend ASIO_CONSTEXPR bool operator!=(
490  const possibly_t&, const always_t<I>&)
491  {
492  return true;
493  }
494 
495  friend ASIO_CONSTEXPR bool operator==(
496  const possibly_t&, const never_t<I>&)
497  {
498  return false;
499  }
500 
501  friend ASIO_CONSTEXPR bool operator!=(
502  const possibly_t&, const never_t<I>&)
503  {
504  return true;
505  }
506 };
507 
508 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
509  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
510 template <int I> template <typename E, typename T>
512 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
513  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
514 
515 template <typename Executor>
516 class adapter
517 {
518 public:
519  adapter(int, const Executor& e) ASIO_NOEXCEPT
520  : executor_(e)
521  {
522  }
523 
524  adapter(const adapter& other) ASIO_NOEXCEPT
525  : executor_(other.executor_)
526  {
527  }
528 
529 #if defined(ASIO_HAS_MOVE)
530  adapter(adapter&& other) ASIO_NOEXCEPT
531  : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))
532  {
533  }
534 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
535 
536  template <int I>
537  static ASIO_CONSTEXPR always_t<I> query(
538  blocking_t<I>) ASIO_NOEXCEPT
539  {
540  return always_t<I>();
541  }
542 
543  template <int I>
544  static ASIO_CONSTEXPR always_t<I> query(
545  possibly_t<I>) ASIO_NOEXCEPT
546  {
547  return always_t<I>();
548  }
549 
550  template <int I>
551  static ASIO_CONSTEXPR always_t<I> query(
552  always_t<I>) ASIO_NOEXCEPT
553  {
554  return always_t<I>();
555  }
556 
557  template <int I>
558  static ASIO_CONSTEXPR always_t<I> query(
559  never_t<I>) ASIO_NOEXCEPT
560  {
561  return always_t<I>();
562  }
563 
564  template <typename Property>
565  typename enable_if<
567  typename query_result<const Executor&, Property>::type
568  >::type query(const Property& p) const
569  ASIO_NOEXCEPT_IF((
571  {
572  return asio::query(executor_, p);
573  }
574 
575  template <int I>
576  typename enable_if<
579  >::type require(possibly_t<I>) const ASIO_NOEXCEPT
580  {
581  return asio::require(executor_, possibly_t<I>());
582  }
583 
584  template <int I>
585  typename enable_if<
588  >::type require(never_t<I>) const ASIO_NOEXCEPT
589  {
590  return asio::require(executor_, never_t<I>());
591  }
592 
593  template <typename Property>
594  typename enable_if<
596  adapter<typename decay<
597  typename require_result<const Executor&, Property>::type
598  >::type>
599  >::type require(const Property& p) const
600  ASIO_NOEXCEPT_IF((
602  {
603  return adapter<typename decay<
604  typename require_result<const Executor&, Property>::type
605  >::type>(0, asio::require(executor_, p));
606  }
607 
608  template <typename Property>
609  typename enable_if<
611  adapter<typename decay<
612  typename prefer_result<const Executor&, Property>::type
613  >::type>
614  >::type prefer(const Property& p) const
615  ASIO_NOEXCEPT_IF((
617  {
618  return adapter<typename decay<
619  typename prefer_result<const Executor&, Property>::type
620  >::type>(0, asio::prefer(executor_, p));
621  }
622 
623  template <typename Function>
624  typename enable_if<
626  >::type execute(ASIO_MOVE_ARG(Function) f) const
627  {
628  blocking_adaptation::blocking_execute(
629  executor_, ASIO_MOVE_CAST(Function)(f));
630  }
631 
632  friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT
633  {
634  return a.executor_ == b.executor_;
635  }
636 
637  friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT
638  {
639  return a.executor_ != b.executor_;
640  }
641 
642 private:
643  Executor executor_;
644 };
645 
646 template <int I = 0>
647 struct always_t
648 {
649 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
650  template <typename T>
651  ASIO_STATIC_CONSTEXPR(bool,
652  is_applicable_property_v = is_executor<T>::value
654 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
655 
656  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
657  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
658  typedef blocking_t<I> polymorphic_query_result_type;
659 
660  ASIO_CONSTEXPR always_t()
661  {
662  }
663 
664 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
665  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
666  template <typename T>
667  static ASIO_CONSTEXPR
669  static_query()
670  ASIO_NOEXCEPT_IF((
672  {
674  }
675 
676  template <typename E, typename T = decltype(always_t::static_query<E>())>
677  static ASIO_CONSTEXPR const T static_query_v
678  = always_t::static_query<E>();
679 #endif // defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
680  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
681 
682  static ASIO_CONSTEXPR blocking_t<I> value()
683  {
684  return always_t();
685  }
686 
687  friend ASIO_CONSTEXPR bool operator==(
688  const always_t&, const always_t&)
689  {
690  return true;
691  }
692 
693  friend ASIO_CONSTEXPR bool operator!=(
694  const always_t&, const always_t&)
695  {
696  return false;
697  }
698 
699  friend ASIO_CONSTEXPR bool operator==(
700  const always_t&, const possibly_t<I>&)
701  {
702  return false;
703  }
704 
705  friend ASIO_CONSTEXPR bool operator!=(
706  const always_t&, const possibly_t<I>&)
707  {
708  return true;
709  }
710 
711  friend ASIO_CONSTEXPR bool operator==(
712  const always_t&, const never_t<I>&)
713  {
714  return false;
715  }
716 
717  friend ASIO_CONSTEXPR bool operator!=(
718  const always_t&, const never_t<I>&)
719  {
720  return true;
721  }
722 
723  template <typename Executor>
724  friend adapter<Executor> require(
725  const Executor& e, const always_t&,
726  typename enable_if<
729  const Executor&,
731  >::is_valid
732  >::type* = 0)
733  {
734  return adapter<Executor>(0, e);
735  }
736 };
737 
738 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
739  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
740 template <int I> template <typename E, typename T>
742 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
743  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
744 
745 template <int I>
746 struct never_t
747 {
748 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
749  template <typename T>
750  ASIO_STATIC_CONSTEXPR(bool,
751  is_applicable_property_v = is_executor<T>::value
753 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
754 
755  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
756  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
757  typedef blocking_t<I> polymorphic_query_result_type;
758 
759  ASIO_CONSTEXPR never_t()
760  {
761  }
762 
763 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
764  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
765  template <typename T>
766  static ASIO_CONSTEXPR
768  static_query()
769  ASIO_NOEXCEPT_IF((
771  {
773  }
774 
775  template <typename E, typename T = decltype(never_t::static_query<E>())>
776  static ASIO_CONSTEXPR const T static_query_v
777  = never_t::static_query<E>();
778 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
779  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
780 
781  static ASIO_CONSTEXPR blocking_t<I> value()
782  {
783  return never_t();
784  }
785 
786  friend ASIO_CONSTEXPR bool operator==(
787  const never_t&, const never_t&)
788  {
789  return true;
790  }
791 
792  friend ASIO_CONSTEXPR bool operator!=(
793  const never_t&, const never_t&)
794  {
795  return false;
796  }
797 
798  friend ASIO_CONSTEXPR bool operator==(
799  const never_t&, const possibly_t<I>&)
800  {
801  return false;
802  }
803 
804  friend ASIO_CONSTEXPR bool operator!=(
805  const never_t&, const possibly_t<I>&)
806  {
807  return true;
808  }
809 
810  friend ASIO_CONSTEXPR bool operator==(
811  const never_t&, const always_t<I>&)
812  {
813  return false;
814  }
815 
816  friend ASIO_CONSTEXPR bool operator!=(
817  const never_t&, const always_t<I>&)
818  {
819  return true;
820  }
821 };
822 
823 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
824  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
825 template <int I> template <typename E, typename T>
827 #endif // defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
828 
829 } // namespace blocking
830 } // namespace detail
831 
833 
834 #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
835 constexpr blocking_t blocking;
836 #else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
837 namespace { static const blocking_t& blocking = blocking_t::instance; }
838 #endif
839 
840 } // namespace execution
841 
842 #if !defined(ASIO_HAS_VARIABLE_TEMPLATES)
843 
844 template <typename T>
845 struct is_applicable_property<T, execution::blocking_t>
846  : integral_constant<bool,
847  execution::is_executor<T>::value
848  || execution::is_sender<T>::value
849  || execution::is_scheduler<T>::value>
850 {
851 };
852 
853 template <typename T>
854 struct is_applicable_property<T, execution::blocking_t::possibly_t>
855  : integral_constant<bool,
856  execution::is_executor<T>::value
857  || execution::is_sender<T>::value
858  || execution::is_scheduler<T>::value>
859 {
860 };
861 
862 template <typename T>
863 struct is_applicable_property<T, execution::blocking_t::always_t>
864  : integral_constant<bool,
865  execution::is_executor<T>::value
866  || execution::is_sender<T>::value
867  || execution::is_scheduler<T>::value>
868 {
869 };
870 
871 template <typename T>
872 struct is_applicable_property<T, execution::blocking_t::never_t>
873  : integral_constant<bool,
874  execution::is_executor<T>::value
875  || execution::is_sender<T>::value
876  || execution::is_scheduler<T>::value>
877 {
878 };
879 
880 #endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)
881 
882 namespace traits {
883 
884 #if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
885 
886 template <typename T>
887 struct query_free_default<T, execution::blocking_t,
888  typename enable_if<
889  can_query<T, execution::blocking_t::possibly_t>::value
890  >::type>
891 {
892  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
893  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
895 
897 };
898 
899 template <typename T>
900 struct query_free_default<T, execution::blocking_t,
901  typename enable_if<
902  !can_query<T, execution::blocking_t::possibly_t>::value
903  && can_query<T, execution::blocking_t::always_t>::value
904  >::type>
905 {
906  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
907  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
909 
911 };
912 
913 template <typename T>
914 struct query_free_default<T, execution::blocking_t,
915  typename enable_if<
916  !can_query<T, execution::blocking_t::possibly_t>::value
917  && !can_query<T, execution::blocking_t::always_t>::value
918  && can_query<T, execution::blocking_t::never_t>::value
919  >::type>
920 {
921  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
922  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
924 
926 };
927 
928 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
929 
930 #if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
931  || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
932 
933 template <typename T>
934 struct static_query<T, execution::blocking_t,
935  typename enable_if<
936  traits::query_static_constexpr_member<T,
937  execution::blocking_t>::is_valid
938  >::type>
939 {
940  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
941  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
942 
943  typedef typename traits::query_static_constexpr_member<T,
944  execution::blocking_t>::result_type result_type;
945 
946  static ASIO_CONSTEXPR result_type value()
947  {
949  execution::blocking_t>::value();
950  }
951 };
952 
953 template <typename T>
954 struct static_query<T, execution::blocking_t,
955  typename enable_if<
956  !traits::query_static_constexpr_member<T, execution::blocking_t>::is_valid
957  && !traits::query_member<T, execution::blocking_t>::is_valid
958  && traits::static_query<T, execution::blocking_t::possibly_t>::is_valid
959  >::type>
960 {
961  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
962  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
963 
964  typedef typename traits::static_query<T,
965  execution::blocking_t::possibly_t>::result_type result_type;
966 
967  static ASIO_CONSTEXPR result_type value()
968  {
970  }
971 };
972 
973 template <typename T>
974 struct static_query<T, execution::blocking_t,
975  typename enable_if<
976  !traits::query_static_constexpr_member<T, execution::blocking_t>::is_valid
977  && !traits::query_member<T, execution::blocking_t>::is_valid
978  && !traits::static_query<T, execution::blocking_t::possibly_t>::is_valid
979  && traits::static_query<T, execution::blocking_t::always_t>::is_valid
980  >::type>
981 {
982  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
983  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
984 
985  typedef typename traits::static_query<T,
986  execution::blocking_t::always_t>::result_type result_type;
987 
988  static ASIO_CONSTEXPR result_type value()
989  {
991  }
992 };
993 
994 template <typename T>
995 struct static_query<T, execution::blocking_t,
996  typename enable_if<
997  !traits::query_static_constexpr_member<T, execution::blocking_t>::is_valid
998  && !traits::query_member<T, execution::blocking_t>::is_valid
999  && !traits::static_query<T, execution::blocking_t::possibly_t>::is_valid
1000  && !traits::static_query<T, execution::blocking_t::always_t>::is_valid
1001  && traits::static_query<T, execution::blocking_t::never_t>::is_valid
1002  >::type>
1003 {
1004  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1005  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1006 
1007  typedef typename traits::static_query<T,
1008  execution::blocking_t::never_t>::result_type result_type;
1009 
1010  static ASIO_CONSTEXPR result_type value()
1011  {
1013  }
1014 };
1015 
1016 template <typename T>
1017 struct static_query<T, execution::blocking_t::possibly_t,
1018  typename enable_if<
1019  traits::query_static_constexpr_member<T,
1020  execution::blocking_t::possibly_t>::is_valid
1021  >::type>
1022 {
1023  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1024  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1025 
1026  typedef typename traits::query_static_constexpr_member<T,
1027  execution::blocking_t::possibly_t>::result_type result_type;
1028 
1029  static ASIO_CONSTEXPR result_type value()
1030  {
1033  }
1034 };
1035 
1036 template <typename T>
1037 struct static_query<T, execution::blocking_t::possibly_t,
1038  typename enable_if<
1039  !traits::query_static_constexpr_member<T,
1040  execution::blocking_t::possibly_t>::is_valid
1041  && !traits::query_member<T, execution::blocking_t::possibly_t>::is_valid
1042  && !traits::query_free<T, execution::blocking_t::possibly_t>::is_valid
1043  && !can_query<T, execution::blocking_t::always_t>::value
1044  && !can_query<T, execution::blocking_t::never_t>::value
1045  >::type>
1046 {
1047  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1048  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1049 
1051 
1052  static ASIO_CONSTEXPR result_type value()
1053  {
1054  return result_type();
1055  }
1056 };
1057 
1058 template <typename T>
1059 struct static_query<T, execution::blocking_t::always_t,
1060  typename enable_if<
1061  traits::query_static_constexpr_member<T,
1062  execution::blocking_t::always_t>::is_valid
1063  >::type>
1064 {
1065  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1066  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1067 
1068  typedef typename traits::query_static_constexpr_member<T,
1069  execution::blocking_t::always_t>::result_type result_type;
1070 
1071  static ASIO_CONSTEXPR result_type value()
1072  {
1075  }
1076 };
1077 
1078 template <typename T>
1079 struct static_query<T, execution::blocking_t::never_t,
1080  typename enable_if<
1081  traits::query_static_constexpr_member<T,
1082  execution::blocking_t::never_t>::is_valid
1083  >::type>
1084 {
1085  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1086  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1087 
1088  typedef typename traits::query_static_constexpr_member<T,
1089  execution::blocking_t::never_t>::result_type result_type;
1090 
1091  static ASIO_CONSTEXPR result_type value()
1092  {
1095  }
1096 };
1097 
1098 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
1099  // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
1100 
1101 #if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
1102 
1103 template <typename T>
1104 struct static_require<T, execution::blocking_t::possibly_t,
1105  typename enable_if<
1106  static_query<T, execution::blocking_t::possibly_t>::is_valid
1107  >::type>
1108 {
1109  ASIO_STATIC_CONSTEXPR(bool, is_valid =
1110  (is_same<typename static_query<T,
1111  execution::blocking_t::possibly_t>::result_type,
1113 };
1114 
1115 template <typename T>
1116 struct static_require<T, execution::blocking_t::always_t,
1117  typename enable_if<
1118  static_query<T, execution::blocking_t::always_t>::is_valid
1119  >::type>
1120 {
1121  ASIO_STATIC_CONSTEXPR(bool, is_valid =
1122  (is_same<typename static_query<T,
1123  execution::blocking_t::always_t>::result_type,
1125 };
1126 
1127 template <typename T>
1128 struct static_require<T, execution::blocking_t::never_t,
1129  typename enable_if<
1130  static_query<T, execution::blocking_t::never_t>::is_valid
1131  >::type>
1132 {
1133  ASIO_STATIC_CONSTEXPR(bool, is_valid =
1134  (is_same<typename static_query<T,
1135  execution::blocking_t::never_t>::result_type,
1137 };
1138 
1139 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
1140 
1141 #if !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
1142 
1143 template <typename T>
1144 struct require_free_default<T, execution::blocking_t::always_t,
1145  typename enable_if<
1146  is_same<T, typename decay<T>::type>::value
1147  && execution::is_executor<T>::value
1148  && traits::static_require<
1149  const T&,
1150  execution::detail::blocking_adaptation::allowed_t<0>
1151  >::is_valid
1152  >::type>
1153 {
1154  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1155  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
1157 };
1158 
1159 #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
1160 
1161 #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
1162 
1163 template <typename Executor>
1165  execution::detail::blocking::adapter<Executor> >
1166 {
1167  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1168  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1169 };
1170 
1171 #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
1172 
1173 #if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
1174 
1175 template <typename Executor, typename Function>
1177  execution::detail::blocking::adapter<Executor>, Function>
1178 {
1179  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1180  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
1181  typedef void result_type;
1182 };
1183 
1184 #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
1185 
1186 #if !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
1187 
1188 template <typename Executor, int I>
1190  execution::detail::blocking::adapter<Executor>,
1192 {
1193  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1194  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1196 
1197  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
1198  {
1199  return result_type();
1200  }
1201 };
1202 
1203 template <typename Executor, int I>
1205  execution::detail::blocking::adapter<Executor>,
1207 {
1208  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1209  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1211 
1212  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
1213  {
1214  return result_type();
1215  }
1216 };
1217 
1218 template <typename Executor, int I>
1220  execution::detail::blocking::adapter<Executor>,
1222 {
1223  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1224  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1226 
1227  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
1228  {
1229  return result_type();
1230  }
1231 };
1232 
1233 template <typename Executor, int I>
1235  execution::detail::blocking::adapter<Executor>,
1237 {
1238  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1239  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1241 
1242  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
1243  {
1244  return result_type();
1245  }
1246 };
1247 
1248 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
1249 
1250 #if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
1251 
1252 template <typename Executor, typename Property>
1254  execution::detail::blocking::adapter<Executor>, Property,
1255  typename enable_if<
1256  can_query<const Executor&, Property>::value
1257  >::type>
1258 {
1259  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1260  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1262  typedef typename query_result<Executor, Property>::type result_type;
1263 };
1264 
1265 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
1266 
1267 #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1268 
1269 template <typename Executor, int I>
1271  execution::detail::blocking::adapter<Executor>,
1273  typename enable_if<
1274  can_require<
1275  const Executor&,
1276  execution::detail::blocking::possibly_t<I>
1277  >::value
1278  >::type>
1279 {
1280  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1281  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1282  (is_nothrow_require<const Executor&,
1284  typedef typename require_result<const Executor&,
1285  execution::detail::blocking::possibly_t<I> >::type result_type;
1286 };
1287 
1288 template <typename Executor, int I>
1290  execution::detail::blocking::adapter<Executor>,
1292  typename enable_if<
1293  can_require<
1294  const Executor&,
1295  execution::detail::blocking::never_t<I>
1296  >::value
1297  >::type>
1298 {
1299  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1300  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1301  (is_nothrow_require<const Executor&,
1303  typedef typename require_result<const Executor&,
1304  execution::detail::blocking::never_t<I> >::type result_type;
1305 };
1306 
1307 template <typename Executor, typename Property>
1309  execution::detail::blocking::adapter<Executor>, Property,
1310  typename enable_if<
1311  can_require<const Executor&, Property>::value
1312  >::type>
1313 {
1314  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1315  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1317  typedef execution::detail::blocking::adapter<typename decay<
1318  typename require_result<Executor, Property>::type
1319  >::type> result_type;
1320 };
1321 
1322 #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1323 
1324 #if !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1325 
1326 template <typename Executor, typename Property>
1328  execution::detail::blocking::adapter<Executor>, Property,
1329  typename enable_if<
1330  can_prefer<const Executor&, Property>::value
1331  >::type>
1332 {
1333  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1334  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1336  typedef execution::detail::blocking::adapter<typename decay<
1337  typename prefer_result<Executor, Property>::type
1338  >::type> result_type;
1339 };
1340 
1341 #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1342 
1343 } // namespace traits
1344 
1345 #endif // defined(GENERATING_DOCUMENTATION)
1346 
1347 } // namespace asio
1348 
1349 #include "asio/detail/pop_options.hpp"
1350 
1351 #endif // ASIO_EXECUTION_BLOCKING_HPP
Definition: static_require.hpp:37
Definition: prefer.hpp:574
Definition: require.hpp:491
Definition: any_executor.hpp:249
Definition: prefer_member.hpp:38
Definition: blocking.hpp:208
Definition: require_free.hpp:35
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: blocking.hpp:193
Definition: execute.hpp:243
Definition: query_member.hpp:38
Definition: static_query.hpp:42
Definition: execute_member.hpp:38
Definition: chrono.h:284
Definition: require.hpp:442
Definition: type_traits.hpp:97
Definition: require_member.hpp:38
Definition: query.hpp:253
Definition: require.hpp:390
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: prefer.hpp:522
Definition: is_applicable_property.hpp:46
Definition: blocking.hpp:516
Definition: any_io_executor.hpp:28
Definition: equality_comparable.hpp:36
The is_executor trait detects whether a type T satisfies the execution::executor concept.
Definition: executor.hpp:109