11 #ifndef ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP 12 #define ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 #include "asio/detail/config.hpp" 19 #include "asio/detail/event.hpp" 20 #include "asio/detail/mutex.hpp" 21 #include "asio/detail/type_traits.hpp" 22 #include "asio/execution/execute.hpp" 23 #include "asio/execution/executor.hpp" 24 #include "asio/execution/scheduler.hpp" 25 #include "asio/execution/sender.hpp" 26 #include "asio/is_applicable_property.hpp" 27 #include "asio/prefer.hpp" 28 #include "asio/query.hpp" 29 #include "asio/require.hpp" 30 #include "asio/traits/prefer_member.hpp" 31 #include "asio/traits/query_free.hpp" 32 #include "asio/traits/query_member.hpp" 33 #include "asio/traits/query_static_constexpr_member.hpp" 34 #include "asio/traits/require_member.hpp" 35 #include "asio/traits/static_query.hpp" 36 #include "asio/traits/static_require.hpp" 38 #include "asio/detail/push_options.hpp" 42 #if defined(GENERATING_DOCUMENTATION) 48 struct blocking_adaptation_t
53 static constexpr
bool is_applicable_property_v =
54 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
57 static constexpr
bool is_requirable =
false;
60 static constexpr
bool is_preferable =
false;
63 typedef blocking_adaptation_t polymorphic_query_result_type;
71 static constexpr
bool is_applicable_property_v =
72 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
75 static constexpr
bool is_requirable =
true;
78 static constexpr
bool is_preferable =
true;
81 typedef blocking_adaptation_t polymorphic_query_result_type;
84 constexpr disallowed_t();
90 static constexpr blocking_adaptation_t value();
99 static constexpr
bool is_applicable_property_v =
100 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
103 static constexpr
bool is_requirable =
true;
106 static constexpr
bool is_preferable =
false;
109 typedef blocking_adaptation_t polymorphic_query_result_type;
112 constexpr allowed_t();
118 static constexpr blocking_adaptation_t value();
123 static constexpr disallowed_t disallowed;
127 static constexpr allowed_t allowed;
130 constexpr blocking_adaptation_t();
133 constexpr blocking_adaptation_t(disallowed_t);
136 constexpr blocking_adaptation_t(allowed_t);
139 friend constexpr
bool operator==(
140 const blocking_adaptation_t& a,
const blocking_adaptation_t& b) noexcept;
143 friend constexpr
bool operator!=(
144 const blocking_adaptation_t& a,
const blocking_adaptation_t& b) noexcept;
148 constexpr blocking_adaptation_t blocking_adaptation;
152 #else // defined(GENERATING_DOCUMENTATION) 156 namespace blocking_adaptation {
166 #if defined(ASIO_HAS_VARIABLE_TEMPLATES) 167 template <
typename T>
168 ASIO_STATIC_CONSTEXPR(
bool,
171 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) 185 ASIO_CONSTEXPR blocking_adaptation_t(disallowed_t)
190 ASIO_CONSTEXPR blocking_adaptation_t(allowed_t)
195 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 196 && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 197 template <
typename T>
198 static ASIO_CONSTEXPR
200 T, blocking_adaptation_t>::result_type
204 T, blocking_adaptation_t
208 T, blocking_adaptation_t>::value();
211 template <
typename T>
212 static ASIO_CONSTEXPR
217 T, blocking_adaptation_t>::is_valid
220 >::type* = 0) ASIO_NOEXCEPT
225 template <
typename T>
226 static ASIO_CONSTEXPR
231 T, blocking_adaptation_t>::is_valid
235 >::type* = 0) ASIO_NOEXCEPT
240 template <
typename E,
241 typename T = decltype(blocking_adaptation_t::static_query<E>())>
242 static ASIO_CONSTEXPR
const T static_query_v
243 = blocking_adaptation_t::static_query<E>();
244 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 247 friend ASIO_CONSTEXPR
bool operator==(
248 const blocking_adaptation_t& a,
const blocking_adaptation_t& b)
250 return a.value_ == b.value_;
253 friend ASIO_CONSTEXPR
bool operator!=(
254 const blocking_adaptation_t& a,
const blocking_adaptation_t& b)
256 return a.value_ != b.value_;
262 blocking_adaptation_t)
267 template <
typename Executor>
268 friend ASIO_CONSTEXPR blocking_adaptation_t query(
273 #if !defined(__clang__) // Clang crashes if noexcept is used here. 274 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified. 278 #else // defined(ASIO_MSVC) 281 #endif // defined(ASIO_MSVC) 282 #endif // !defined(__clang__) 284 return asio::query(ex, disallowed_t());
287 template <
typename Executor>
288 friend ASIO_CONSTEXPR blocking_adaptation_t query(
294 #if !defined(__clang__) // Clang crashes if noexcept is used here. 295 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified. 299 #else // defined(ASIO_MSVC) 302 #endif // defined(ASIO_MSVC) 303 #endif // !defined(__clang__) 305 return asio::query(ex, allowed_t());
308 ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed);
309 ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed);
311 #if !defined(ASIO_HAS_CONSTEXPR) 312 static const blocking_adaptation_t instance;
313 #endif // !defined(ASIO_HAS_CONSTEXPR) 319 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 320 && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 321 template <
int I>
template <
typename E,
typename T>
323 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 326 #if !defined(ASIO_HAS_CONSTEXPR) 339 namespace blocking_adaptation {
344 #if defined(ASIO_HAS_VARIABLE_TEMPLATES) 345 template <
typename T>
346 ASIO_STATIC_CONSTEXPR(
bool,
349 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) 359 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 360 && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 361 template <
typename T>
362 static ASIO_CONSTEXPR
371 template <
typename T>
378 >::type* = 0) ASIO_NOEXCEPT
383 template <
typename E,
typename T = decltype(disallowed_t::static_query<E>())>
384 static ASIO_CONSTEXPR
const T static_query_v
385 = disallowed_t::static_query<E>();
386 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 394 friend ASIO_CONSTEXPR
bool operator==(
400 friend ASIO_CONSTEXPR
bool operator!=(
407 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 408 && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 409 template <
int I>
template <
typename E,
typename T>
411 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 414 template <
typename Executor>
418 adapter(
int,
const Executor& e) ASIO_NOEXCEPT
424 : executor_(other.executor_)
428 #if defined(ASIO_HAS_MOVE) 430 : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))
433 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 456 template <
typename Property>
459 typename query_result<const Executor&, Property>::type
460 >::type query(
const Property& p)
const 464 return asio::query(executor_, p);
473 template <
typename Property>
477 typename require_result<const Executor&, Property>::type
479 >::type require(
const Property& p)
const 484 typename require_result<const Executor&, Property>::type
485 >::type>(0, asio::require(executor_, p));
488 template <
typename Property>
492 typename prefer_result<const Executor&, Property>::type
494 >::type prefer(
const Property& p)
const 499 typename prefer_result<const Executor&, Property>::type
500 >::type>(0, asio::prefer(executor_, p));
503 template <
typename Function>
506 >::type execute(ASIO_MOVE_ARG(Function) f)
const 508 execution::execute(executor_, ASIO_MOVE_CAST(Function)(f));
511 friend bool operator==(
const adapter& a,
const adapter& b) ASIO_NOEXCEPT
513 return a.executor_ == b.executor_;
516 friend bool operator!=(
const adapter& a,
const adapter& b) ASIO_NOEXCEPT
518 return a.executor_ != b.executor_;
528 #if defined(ASIO_HAS_VARIABLE_TEMPLATES) 529 template <
typename T>
530 ASIO_STATIC_CONSTEXPR(
bool,
533 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) 543 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 544 && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 545 template <
typename T>
546 static ASIO_CONSTEXPR
555 template <
typename E,
typename T = decltype(allowed_t::static_query<E>())>
556 static ASIO_CONSTEXPR
const T static_query_v
557 = allowed_t::static_query<E>();
558 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 566 friend ASIO_CONSTEXPR
bool operator==(
572 friend ASIO_CONSTEXPR
bool operator!=(
578 template <
typename Executor>
589 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 590 && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 591 template <
int I>
template <
typename E,
typename T>
593 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 596 template <
typename Function>
600 template <
typename F>
602 : func_(ASIO_MOVE_CAST(F)(f)),
607 template <
typename Executor>
608 void execute_and_wait(ASIO_MOVE_ARG(Executor) ex)
611 execution::execute(ASIO_MOVE_CAST(Executor)(ex), h);
613 while (!is_complete_)
622 state_->is_complete_ =
true;
623 state_->event_.unlock_and_signal_one_for_destruction(lock);
646 template <
typename Executor,
typename Function>
647 void blocking_execute(
648 ASIO_MOVE_ARG(Executor) ex,
649 ASIO_MOVE_ARG(Function) func)
651 typedef typename decay<Function>::type func_t;
653 state.execute_and_wait(ex);
661 #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 662 constexpr blocking_adaptation_t blocking_adaptation;
663 #else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 664 namespace {
static const blocking_adaptation_t&
665 blocking_adaptation = blocking_adaptation_t::instance; }
670 #if !defined(ASIO_HAS_VARIABLE_TEMPLATES) 672 template <
typename T>
674 : integral_constant<bool,
675 execution::is_executor<T>::value
676 || execution::is_sender<T>::value
677 || execution::is_scheduler<T>::value>
681 template <
typename T>
683 : integral_constant<bool,
684 execution::is_executor<T>::value
685 || execution::is_sender<T>::value
686 || execution::is_scheduler<T>::value>
690 template <
typename T>
692 : integral_constant<bool,
693 execution::is_executor<T>::value
694 || execution::is_sender<T>::value
695 || execution::is_scheduler<T>::value>
699 #endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES) 703 #if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 705 template <
typename T>
708 can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
711 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
718 template <
typename T>
721 !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
722 && can_query<T, execution::blocking_adaptation_t::allowed_t>::value
725 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
726 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
732 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 734 #if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 735 || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 737 template <
typename T>
740 traits::query_static_constexpr_member<T,
741 execution::blocking_adaptation_t>::is_valid
744 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
745 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
750 static ASIO_CONSTEXPR result_type value()
757 template <
typename T>
760 !traits::query_static_constexpr_member<T,
761 execution::blocking_adaptation_t>::is_valid
762 && !traits::query_member<T,
763 execution::blocking_adaptation_t>::is_valid
764 && traits::static_query<T,
765 execution::blocking_adaptation_t::disallowed_t>::is_valid
768 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
769 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
774 static ASIO_CONSTEXPR result_type value()
781 template <
typename T>
784 !traits::query_static_constexpr_member<T,
785 execution::blocking_adaptation_t>::is_valid
786 && !traits::query_member<T,
787 execution::blocking_adaptation_t>::is_valid
788 && !traits::static_query<T,
789 execution::blocking_adaptation_t::disallowed_t>::is_valid
790 && traits::static_query<T,
791 execution::blocking_adaptation_t::allowed_t>::is_valid
794 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
795 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
800 static ASIO_CONSTEXPR result_type value()
807 template <
typename T>
810 traits::query_static_constexpr_member<T,
811 execution::blocking_adaptation_t::disallowed_t>::is_valid
814 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
815 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
820 static ASIO_CONSTEXPR result_type value()
827 template <
typename T>
830 !traits::query_static_constexpr_member<T,
831 execution::blocking_adaptation_t::disallowed_t>::is_valid
832 && !traits::query_member<T,
833 execution::blocking_adaptation_t::disallowed_t>::is_valid
834 && !traits::query_free<T,
835 execution::blocking_adaptation_t::disallowed_t>::is_valid
836 && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value
839 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
840 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
844 static ASIO_CONSTEXPR result_type value()
846 return result_type();
850 template <
typename T>
853 traits::query_static_constexpr_member<T,
854 execution::blocking_adaptation_t::allowed_t>::is_valid
857 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
858 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
863 static ASIO_CONSTEXPR result_type value()
870 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 873 #if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) 875 template <
typename T>
878 static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid
881 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
887 template <
typename T>
890 static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid
893 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
899 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) 901 #if !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT) 903 template <
typename T>
906 is_same<T, typename decay<T>::type>::value
907 && execution::is_executor<T>::value
910 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
911 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
false);
915 #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT) 917 #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) 919 template <
typename Executor>
921 execution::detail::blocking_adaptation::adapter<Executor> >
923 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
924 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
927 #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) 929 #if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) 931 template <
typename Executor,
typename Function>
933 execution::detail::blocking_adaptation::adapter<Executor>, Function>
935 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
936 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
false);
937 typedef void result_type;
940 #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) 942 #if !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) 944 template <
typename Executor,
int I>
946 execution::detail::blocking_adaptation::adapter<Executor>,
949 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
950 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
953 static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
955 return result_type();
959 template <
typename Executor,
int I>
961 execution::detail::blocking_adaptation::adapter<Executor>,
964 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
965 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
968 static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
970 return result_type();
974 template <
typename Executor,
int I>
976 execution::detail::blocking_adaptation::adapter<Executor>,
979 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
980 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
983 static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
985 return result_type();
989 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) 991 #if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) 993 template <
typename Executor,
typename Property>
995 execution::detail::blocking_adaptation::adapter<Executor>, Property,
997 can_query<const Executor&, Property>::value
1000 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
1001 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
1003 typedef typename query_result<Executor, Property>::type result_type;
1006 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) 1008 #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) 1010 template <
typename Executor,
int I>
1012 execution::detail::blocking_adaptation::adapter<Executor>,
1015 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
1016 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
true);
1017 typedef Executor result_type;
1020 template <
typename Executor,
typename Property>
1022 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1024 can_require<const Executor&, Property>::value
1027 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
1028 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
1031 typename require_result<Executor, Property>::type
1035 #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) 1037 #if !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) 1039 template <
typename Executor,
typename Property>
1041 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1043 can_prefer<const Executor&, Property>::value
1046 ASIO_STATIC_CONSTEXPR(
bool, is_valid =
true);
1047 ASIO_STATIC_CONSTEXPR(
bool, is_noexcept =
1050 typename prefer_result<Executor, Property>::type
1054 #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) 1058 #endif // defined(GENERATING_DOCUMENTATION) 1062 #include "asio/detail/pop_options.hpp" 1064 #endif // ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP Definition: static_require.hpp:37
Definition: prefer.hpp:574
Definition: null_mutex.hpp:30
Definition: any_executor.hpp:249
Definition: blocking.hpp:198
Definition: scoped_lock.hpp:27
Definition: blocking_adaptation.hpp:415
Definition: prefer_member.hpp:38
Definition: blocking_adaptation.hpp:158
Definition: require_free.hpp:35
Definition: query.hpp:269
Definition: blocking_adaptation.hpp:164
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: execute.hpp:243
Definition: query_member.hpp:38
Definition: blocking_adaptation.hpp:629
Definition: static_query.hpp:42
Definition: execute_member.hpp:38
Definition: require.hpp:442
Definition: type_traits.hpp:97
Definition: require_member.hpp:38
Definition: query.hpp:253
Definition: blocking_adaptation.hpp:617
Definition: require.hpp:390
Definition: query_free.hpp:35
Definition: null_event.hpp:26
Definition: blocking_adaptation.hpp:259
Definition: query_free.hpp:38
Definition: query_static_constexpr_member.hpp:42
Definition: blocking_adaptation.hpp:597
Definition: any_executor.hpp:256
Definition: handler_work.hpp:37
Definition: prefer.hpp:522
Definition: is_applicable_property.hpp:46
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