File indexing completed on 2025-12-16 09:43:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP
0012 #define BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/event.hpp>
0020 #include <boost/asio/detail/mutex.hpp>
0021 #include <boost/asio/detail/type_traits.hpp>
0022 #include <boost/asio/execution/executor.hpp>
0023 #include <boost/asio/is_applicable_property.hpp>
0024 #include <boost/asio/prefer.hpp>
0025 #include <boost/asio/query.hpp>
0026 #include <boost/asio/require.hpp>
0027 #include <boost/asio/traits/prefer_member.hpp>
0028 #include <boost/asio/traits/query_free.hpp>
0029 #include <boost/asio/traits/query_member.hpp>
0030 #include <boost/asio/traits/query_static_constexpr_member.hpp>
0031 #include <boost/asio/traits/require_member.hpp>
0032 #include <boost/asio/traits/static_query.hpp>
0033 #include <boost/asio/traits/static_require.hpp>
0034
0035 #include <boost/asio/detail/push_options.hpp>
0036
0037 namespace boost {
0038 namespace asio {
0039
0040 #if defined(GENERATING_DOCUMENTATION)
0041
0042 namespace execution {
0043
0044
0045
0046 struct blocking_adaptation_t
0047 {
0048
0049 template <typename T>
0050 static constexpr bool is_applicable_property_v = is_executor_v<T>;
0051
0052
0053 static constexpr bool is_requirable = false;
0054
0055
0056 static constexpr bool is_preferable = false;
0057
0058
0059 typedef blocking_adaptation_t polymorphic_query_result_type;
0060
0061
0062 struct disallowed_t
0063 {
0064
0065 template <typename T>
0066 static constexpr bool is_applicable_property_v = is_executor_v<T>;
0067
0068
0069 static constexpr bool is_requirable = true;
0070
0071
0072 static constexpr bool is_preferable = true;
0073
0074
0075 typedef blocking_adaptation_t polymorphic_query_result_type;
0076
0077
0078 constexpr disallowed_t();
0079
0080
0081
0082
0083
0084 static constexpr blocking_adaptation_t value();
0085 };
0086
0087
0088 struct allowed_t
0089 {
0090
0091 template <typename T>
0092 static constexpr bool is_applicable_property_v = is_executor_v<T>;
0093
0094
0095 static constexpr bool is_requirable = true;
0096
0097
0098 static constexpr bool is_preferable = false;
0099
0100
0101 typedef blocking_adaptation_t polymorphic_query_result_type;
0102
0103
0104 constexpr allowed_t();
0105
0106
0107
0108
0109
0110 static constexpr blocking_adaptation_t value();
0111 };
0112
0113
0114
0115 static constexpr disallowed_t disallowed;
0116
0117
0118
0119 static constexpr allowed_t allowed;
0120
0121
0122 constexpr blocking_adaptation_t();
0123
0124
0125 constexpr blocking_adaptation_t(disallowed_t);
0126
0127
0128 constexpr blocking_adaptation_t(allowed_t);
0129
0130
0131 friend constexpr bool operator==(
0132 const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
0133
0134
0135 friend constexpr bool operator!=(
0136 const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
0137 };
0138
0139
0140 constexpr blocking_adaptation_t blocking_adaptation;
0141
0142 }
0143
0144 #else
0145
0146 namespace execution {
0147 namespace detail {
0148 namespace blocking_adaptation {
0149
0150 template <int I> struct disallowed_t;
0151 template <int I> struct allowed_t;
0152
0153 }
0154
0155 template <int I = 0>
0156 struct blocking_adaptation_t
0157 {
0158 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0159 template <typename T>
0160 static constexpr bool is_applicable_property_v = is_executor<T>::value;
0161 #endif
0162
0163 static constexpr bool is_requirable = false;
0164 static constexpr bool is_preferable = false;
0165 typedef blocking_adaptation_t polymorphic_query_result_type;
0166
0167 typedef detail::blocking_adaptation::disallowed_t<I> disallowed_t;
0168 typedef detail::blocking_adaptation::allowed_t<I> allowed_t;
0169
0170 constexpr blocking_adaptation_t()
0171 : value_(-1)
0172 {
0173 }
0174
0175 constexpr blocking_adaptation_t(disallowed_t)
0176 : value_(0)
0177 {
0178 }
0179
0180 constexpr blocking_adaptation_t(allowed_t)
0181 : value_(1)
0182 {
0183 }
0184
0185 template <typename T>
0186 struct proxy
0187 {
0188 #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
0189 struct type
0190 {
0191 template <typename P>
0192 auto query(P&& p) const
0193 noexcept(
0194 noexcept(
0195 declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))
0196 )
0197 )
0198 -> decltype(
0199 declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))
0200 );
0201 };
0202 #else
0203 typedef T type;
0204 #endif
0205 };
0206
0207 template <typename T>
0208 struct static_proxy
0209 {
0210 #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
0211 struct type
0212 {
0213 template <typename P>
0214 static constexpr auto query(P&& p)
0215 noexcept(
0216 noexcept(
0217 conditional_t<true, T, P>::query(static_cast<P&&>(p))
0218 )
0219 )
0220 -> decltype(
0221 conditional_t<true, T, P>::query(static_cast<P&&>(p))
0222 )
0223 {
0224 return T::query(static_cast<P&&>(p));
0225 }
0226 };
0227 #else
0228 typedef T type;
0229 #endif
0230 };
0231
0232 template <typename T>
0233 struct query_member :
0234 traits::query_member<typename proxy<T>::type, blocking_adaptation_t> {};
0235
0236 template <typename T>
0237 struct query_static_constexpr_member :
0238 traits::query_static_constexpr_member<
0239 typename static_proxy<T>::type, blocking_adaptation_t> {};
0240
0241 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0242 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0243 template <typename T>
0244 static constexpr typename query_static_constexpr_member<T>::result_type
0245 static_query()
0246 noexcept(query_static_constexpr_member<T>::is_noexcept)
0247 {
0248 return query_static_constexpr_member<T>::value();
0249 }
0250
0251 template <typename T>
0252 static constexpr
0253 typename traits::static_query<T, disallowed_t>::result_type
0254 static_query(
0255 enable_if_t<
0256 !query_static_constexpr_member<T>::is_valid
0257 >* = 0,
0258 enable_if_t<
0259 !query_member<T>::is_valid
0260 >* = 0,
0261 enable_if_t<
0262 traits::static_query<T, disallowed_t>::is_valid
0263 >* = 0) noexcept
0264 {
0265 return traits::static_query<T, disallowed_t>::value();
0266 }
0267
0268 template <typename T>
0269 static constexpr
0270 typename traits::static_query<T, allowed_t>::result_type
0271 static_query(
0272 enable_if_t<
0273 !query_static_constexpr_member<T>::is_valid
0274 >* = 0,
0275 enable_if_t<
0276 !query_member<T>::is_valid
0277 >* = 0,
0278 enable_if_t<
0279 !traits::static_query<T, disallowed_t>::is_valid
0280 >* = 0,
0281 enable_if_t<
0282 traits::static_query<T, allowed_t>::is_valid
0283 >* = 0) noexcept
0284 {
0285 return traits::static_query<T, allowed_t>::value();
0286 }
0287
0288 template <typename E,
0289 typename T = decltype(blocking_adaptation_t::static_query<E>())>
0290 static constexpr const T static_query_v
0291 = blocking_adaptation_t::static_query<E>();
0292 #endif
0293
0294
0295 friend constexpr bool operator==(
0296 const blocking_adaptation_t& a, const blocking_adaptation_t& b)
0297 {
0298 return a.value_ == b.value_;
0299 }
0300
0301 friend constexpr bool operator!=(
0302 const blocking_adaptation_t& a, const blocking_adaptation_t& b)
0303 {
0304 return a.value_ != b.value_;
0305 }
0306
0307 struct convertible_from_blocking_adaptation_t
0308 {
0309 constexpr convertible_from_blocking_adaptation_t(
0310 blocking_adaptation_t)
0311 {
0312 }
0313 };
0314
0315 template <typename Executor>
0316 friend constexpr blocking_adaptation_t query(
0317 const Executor& ex, convertible_from_blocking_adaptation_t,
0318 enable_if_t<
0319 can_query<const Executor&, disallowed_t>::value
0320 >* = 0)
0321 #if !defined(__clang__)
0322 #if defined(BOOST_ASIO_MSVC)
0323 noexcept(is_nothrow_query<const Executor&,
0324 blocking_adaptation_t<>::disallowed_t>::value)
0325 #else
0326 noexcept(is_nothrow_query<const Executor&, disallowed_t>::value)
0327 #endif
0328 #endif
0329 {
0330 return boost::asio::query(ex, disallowed_t());
0331 }
0332
0333 template <typename Executor>
0334 friend constexpr blocking_adaptation_t query(
0335 const Executor& ex, convertible_from_blocking_adaptation_t,
0336 enable_if_t<
0337 !can_query<const Executor&, disallowed_t>::value
0338 >* = 0,
0339 enable_if_t<
0340 can_query<const Executor&, allowed_t>::value
0341 >* = 0)
0342 #if !defined(__clang__)
0343 #if defined(BOOST_ASIO_MSVC)
0344 noexcept(is_nothrow_query<const Executor&,
0345 blocking_adaptation_t<>::allowed_t>::value)
0346 #else
0347 noexcept(is_nothrow_query<const Executor&, allowed_t>::value)
0348 #endif
0349 #endif
0350 {
0351 return boost::asio::query(ex, allowed_t());
0352 }
0353
0354 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed);
0355 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed);
0356
0357 private:
0358 int value_;
0359 };
0360
0361 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0362 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0363 template <int I> template <typename E, typename T>
0364 const T blocking_adaptation_t<I>::static_query_v;
0365 #endif
0366
0367
0368 template <int I>
0369 const typename blocking_adaptation_t<I>::disallowed_t
0370 blocking_adaptation_t<I>::disallowed;
0371
0372 template <int I>
0373 const typename blocking_adaptation_t<I>::allowed_t
0374 blocking_adaptation_t<I>::allowed;
0375
0376 namespace blocking_adaptation {
0377
0378 template <int I = 0>
0379 struct disallowed_t
0380 {
0381 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0382 template <typename T>
0383 static constexpr bool is_applicable_property_v = is_executor<T>::value;
0384 #endif
0385
0386 static constexpr bool is_requirable = true;
0387 static constexpr bool is_preferable = true;
0388 typedef blocking_adaptation_t<I> polymorphic_query_result_type;
0389
0390 constexpr disallowed_t()
0391 {
0392 }
0393
0394 template <typename T>
0395 struct query_member :
0396 traits::query_member<
0397 typename blocking_adaptation_t<I>::template proxy<T>::type,
0398 disallowed_t> {};
0399
0400 template <typename T>
0401 struct query_static_constexpr_member :
0402 traits::query_static_constexpr_member<
0403 typename blocking_adaptation_t<I>::template static_proxy<T>::type,
0404 disallowed_t> {};
0405
0406 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0407 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0408 template <typename T>
0409 static constexpr
0410 typename query_static_constexpr_member<T>::result_type
0411 static_query()
0412 noexcept(query_static_constexpr_member<T>::is_noexcept)
0413 {
0414 return query_static_constexpr_member<T>::value();
0415 }
0416
0417 template <typename T>
0418 static constexpr disallowed_t static_query(
0419 enable_if_t<
0420 !query_static_constexpr_member<T>::is_valid
0421 >* = 0,
0422 enable_if_t<
0423 !query_member<T>::is_valid
0424 >* = 0,
0425 enable_if_t<
0426 !traits::query_free<T, disallowed_t>::is_valid
0427 >* = 0,
0428 enable_if_t<
0429 !can_query<T, allowed_t<I>>::value
0430 >* = 0) noexcept
0431 {
0432 return disallowed_t();
0433 }
0434
0435 template <typename E, typename T = decltype(disallowed_t::static_query<E>())>
0436 static constexpr const T static_query_v
0437 = disallowed_t::static_query<E>();
0438 #endif
0439
0440
0441 static constexpr blocking_adaptation_t<I> value()
0442 {
0443 return disallowed_t();
0444 }
0445
0446 friend constexpr bool operator==(const disallowed_t&, const disallowed_t&)
0447 {
0448 return true;
0449 }
0450
0451 friend constexpr bool operator!=(const disallowed_t&, const disallowed_t&)
0452 {
0453 return false;
0454 }
0455
0456 friend constexpr bool operator==(const disallowed_t&, const allowed_t<I>&)
0457 {
0458 return false;
0459 }
0460
0461 friend constexpr bool operator!=(const disallowed_t&, const allowed_t<I>&)
0462 {
0463 return true;
0464 }
0465 };
0466
0467 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0468 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0469 template <int I> template <typename E, typename T>
0470 const T disallowed_t<I>::static_query_v;
0471 #endif
0472
0473
0474 template <typename>
0475 struct is_blocking_adaptation_t : false_type
0476 {
0477 };
0478
0479 template <int I>
0480 struct is_blocking_adaptation_t<blocking_adaptation_t<I>> : true_type
0481 {
0482 };
0483
0484 template <typename>
0485 struct is_allowed_t : false_type
0486 {
0487 };
0488
0489 template <int I>
0490 struct is_allowed_t<allowed_t<I>> : true_type
0491 {
0492 };
0493
0494 template <typename>
0495 struct is_disallowed_t : false_type
0496 {
0497 };
0498
0499 template <int I>
0500 struct is_disallowed_t<disallowed_t<I>> : true_type
0501 {
0502 };
0503
0504 template <typename Executor>
0505 class adapter
0506 {
0507 public:
0508 adapter(int, const Executor& e) noexcept
0509 : executor_(e)
0510 {
0511 }
0512
0513 adapter(const adapter& other) noexcept
0514 : executor_(other.executor_)
0515 {
0516 }
0517
0518 adapter(adapter&& other) noexcept
0519 : executor_(static_cast<Executor&&>(other.executor_))
0520 {
0521 }
0522
0523 template <int I>
0524 static constexpr allowed_t<I> query(blocking_adaptation_t<I>) noexcept
0525 {
0526 return allowed_t<I>();
0527 }
0528
0529 template <int I>
0530 static constexpr allowed_t<I> query(allowed_t<I>) noexcept
0531 {
0532 return allowed_t<I>();
0533 }
0534
0535 template <int I>
0536 static constexpr allowed_t<I> query(disallowed_t<I>) noexcept
0537 {
0538 return allowed_t<I>();
0539 }
0540
0541 template <typename Property>
0542 enable_if_t<
0543 can_query<const Executor&, Property>::value
0544 && !is_blocking_adaptation_t<Property>::value
0545 && !is_allowed_t<Property>::value
0546 && !is_disallowed_t<Property>::value,
0547 query_result_t<const Executor&, Property>
0548 > query(const Property& p) const
0549 noexcept(is_nothrow_query<const Executor&, Property>::value)
0550 {
0551 return boost::asio::query(executor_, p);
0552 }
0553
0554 template <int I>
0555 Executor require(disallowed_t<I>) const noexcept
0556 {
0557 return executor_;
0558 }
0559
0560 template <typename Property>
0561 enable_if_t<
0562 can_require<const Executor&, Property>::value
0563 && !is_blocking_adaptation_t<Property>::value
0564 && !is_allowed_t<Property>::value
0565 && !is_disallowed_t<Property>::value,
0566 adapter<decay_t<require_result_t<const Executor&, Property>>>
0567 > require(const Property& p) const
0568 noexcept(is_nothrow_require<const Executor&, Property>::value)
0569 {
0570 return adapter<decay_t<require_result_t<const Executor&, Property>>>(
0571 0, boost::asio::require(executor_, p));
0572 }
0573
0574 template <typename Property>
0575 enable_if_t<
0576 can_prefer<const Executor&, Property>::value
0577 && !is_blocking_adaptation_t<Property>::value
0578 && !is_allowed_t<Property>::value
0579 && !is_disallowed_t<Property>::value,
0580 adapter<decay_t<prefer_result_t<const Executor&, Property>>>
0581 > prefer(const Property& p) const
0582 noexcept(is_nothrow_prefer<const Executor&, Property>::value)
0583 {
0584 return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(
0585 0, boost::asio::prefer(executor_, p));
0586 }
0587
0588 template <typename Function>
0589 enable_if_t<
0590 traits::execute_member<const Executor&, Function>::is_valid
0591 > execute(Function&& f) const
0592 {
0593 executor_.execute(static_cast<Function&&>(f));
0594 }
0595
0596 friend bool operator==(const adapter& a, const adapter& b) noexcept
0597 {
0598 return a.executor_ == b.executor_;
0599 }
0600
0601 friend bool operator!=(const adapter& a, const adapter& b) noexcept
0602 {
0603 return a.executor_ != b.executor_;
0604 }
0605
0606 private:
0607 Executor executor_;
0608 };
0609
0610 template <int I = 0>
0611 struct allowed_t
0612 {
0613 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0614 template <typename T>
0615 static constexpr bool is_applicable_property_v = is_executor<T>::value;
0616 #endif
0617
0618 static constexpr bool is_requirable = true;
0619 static constexpr bool is_preferable = false;
0620 typedef blocking_adaptation_t<I> polymorphic_query_result_type;
0621
0622 constexpr allowed_t()
0623 {
0624 }
0625
0626 template <typename T>
0627 struct query_member :
0628 traits::query_member<
0629 typename blocking_adaptation_t<I>::template proxy<T>::type,
0630 allowed_t> {};
0631
0632 template <typename T>
0633 struct query_static_constexpr_member :
0634 traits::query_static_constexpr_member<
0635 typename blocking_adaptation_t<I>::template static_proxy<T>::type,
0636 allowed_t> {};
0637
0638 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0639 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0640 template <typename T>
0641 static constexpr typename query_static_constexpr_member<T>::result_type
0642 static_query()
0643 noexcept(query_static_constexpr_member<T>::is_noexcept)
0644 {
0645 return query_static_constexpr_member<T>::value();
0646 }
0647
0648 template <typename E, typename T = decltype(allowed_t::static_query<E>())>
0649 static constexpr const T static_query_v = allowed_t::static_query<E>();
0650 #endif
0651
0652
0653 static constexpr blocking_adaptation_t<I> value()
0654 {
0655 return allowed_t();
0656 }
0657
0658 friend constexpr bool operator==(const allowed_t&, const allowed_t&)
0659 {
0660 return true;
0661 }
0662
0663 friend constexpr bool operator!=(const allowed_t&, const allowed_t&)
0664 {
0665 return false;
0666 }
0667
0668 friend constexpr bool operator==(const allowed_t&, const disallowed_t<I>&)
0669 {
0670 return false;
0671 }
0672
0673 friend constexpr bool operator!=(const allowed_t&, const disallowed_t<I>&)
0674 {
0675 return true;
0676 }
0677
0678 template <typename Executor>
0679 friend adapter<Executor> require(
0680 const Executor& e, const allowed_t&,
0681 enable_if_t<
0682 is_executor<Executor>::value
0683 >* = 0)
0684 {
0685 return adapter<Executor>(0, e);
0686 }
0687 };
0688
0689 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0690 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0691 template <int I> template <typename E, typename T>
0692 const T allowed_t<I>::static_query_v;
0693 #endif
0694
0695
0696 template <typename Function>
0697 class blocking_execute_state
0698 {
0699 public:
0700 template <typename F>
0701 blocking_execute_state(F&& f)
0702 : func_(static_cast<F&&>(f)),
0703 is_complete_(false)
0704 {
0705 }
0706
0707 template <typename Executor>
0708 void execute_and_wait(Executor&& ex)
0709 {
0710 handler h = { this };
0711 ex.execute(h);
0712 boost::asio::detail::mutex::scoped_lock lock(mutex_);
0713 while (!is_complete_)
0714 event_.wait(lock);
0715 }
0716
0717 struct cleanup
0718 {
0719 ~cleanup()
0720 {
0721 boost::asio::detail::mutex::scoped_lock lock(state_->mutex_);
0722 state_->is_complete_ = true;
0723 state_->event_.unlock_and_signal_one_for_destruction(lock);
0724 }
0725
0726 blocking_execute_state* state_;
0727 };
0728
0729 struct handler
0730 {
0731 void operator()()
0732 {
0733 cleanup c = { state_ };
0734 state_->func_();
0735 }
0736
0737 blocking_execute_state* state_;
0738 };
0739
0740 Function func_;
0741 boost::asio::detail::mutex mutex_;
0742 boost::asio::detail::event event_;
0743 bool is_complete_;
0744 };
0745
0746 template <typename Executor, typename Function>
0747 void blocking_execute(
0748 Executor&& ex,
0749 Function&& func)
0750 {
0751 typedef decay_t<Function> func_t;
0752 blocking_execute_state<func_t> state(static_cast<Function&&>(func));
0753 state.execute_and_wait(ex);
0754 }
0755
0756 }
0757 }
0758
0759 typedef detail::blocking_adaptation_t<> blocking_adaptation_t;
0760
0761 BOOST_ASIO_INLINE_VARIABLE constexpr blocking_adaptation_t blocking_adaptation;
0762
0763 }
0764
0765 #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0766
0767 template <typename T>
0768 struct is_applicable_property<T, execution::blocking_adaptation_t>
0769 : integral_constant<bool, execution::is_executor<T>::value>
0770 {
0771 };
0772
0773 template <typename T>
0774 struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t>
0775 : integral_constant<bool, execution::is_executor<T>::value>
0776 {
0777 };
0778
0779 template <typename T>
0780 struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t>
0781 : integral_constant<bool, execution::is_executor<T>::value>
0782 {
0783 };
0784
0785 #endif
0786
0787 namespace traits {
0788
0789 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
0790
0791 template <typename T>
0792 struct query_free_default<T, execution::blocking_adaptation_t,
0793 enable_if_t<
0794 can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
0795 >>
0796 {
0797 static constexpr bool is_valid = true;
0798 static constexpr bool is_noexcept =
0799 is_nothrow_query<T, execution::blocking_adaptation_t::disallowed_t>::value;
0800
0801 typedef execution::blocking_adaptation_t result_type;
0802 };
0803
0804 template <typename T>
0805 struct query_free_default<T, execution::blocking_adaptation_t,
0806 enable_if_t<
0807 !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
0808 && can_query<T, execution::blocking_adaptation_t::allowed_t>::value
0809 >>
0810 {
0811 static constexpr bool is_valid = true;
0812 static constexpr bool is_noexcept =
0813 is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value;
0814
0815 typedef execution::blocking_adaptation_t result_type;
0816 };
0817
0818 #endif
0819
0820 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0821 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0822
0823 template <typename T>
0824 struct static_query<T, execution::blocking_adaptation_t,
0825 enable_if_t<
0826 execution::detail::blocking_adaptation_t<0>::
0827 query_static_constexpr_member<T>::is_valid
0828 >>
0829 {
0830 static constexpr bool is_valid = true;
0831 static constexpr bool is_noexcept = true;
0832
0833 typedef typename execution::detail::blocking_adaptation_t<0>::
0834 query_static_constexpr_member<T>::result_type result_type;
0835
0836 static constexpr result_type value()
0837 {
0838 return execution::detail::blocking_adaptation_t<0>::
0839 query_static_constexpr_member<T>::value();
0840 }
0841 };
0842
0843 template <typename T>
0844 struct static_query<T, execution::blocking_adaptation_t,
0845 enable_if_t<
0846 !execution::detail::blocking_adaptation_t<0>::
0847 query_static_constexpr_member<T>::is_valid
0848 && !execution::detail::blocking_adaptation_t<0>::
0849 query_member<T>::is_valid
0850 && traits::static_query<T,
0851 execution::blocking_adaptation_t::disallowed_t>::is_valid
0852 >>
0853 {
0854 static constexpr bool is_valid = true;
0855 static constexpr bool is_noexcept = true;
0856
0857 typedef typename traits::static_query<T,
0858 execution::blocking_adaptation_t::disallowed_t>::result_type result_type;
0859
0860 static constexpr result_type value()
0861 {
0862 return traits::static_query<T,
0863 execution::blocking_adaptation_t::disallowed_t>::value();
0864 }
0865 };
0866
0867 template <typename T>
0868 struct static_query<T, execution::blocking_adaptation_t,
0869 enable_if_t<
0870 !execution::detail::blocking_adaptation_t<0>::
0871 query_static_constexpr_member<T>::is_valid
0872 && !execution::detail::blocking_adaptation_t<0>::
0873 query_member<T>::is_valid
0874 && !traits::static_query<T,
0875 execution::blocking_adaptation_t::disallowed_t>::is_valid
0876 && traits::static_query<T,
0877 execution::blocking_adaptation_t::allowed_t>::is_valid
0878 >>
0879 {
0880 static constexpr bool is_valid = true;
0881 static constexpr bool is_noexcept = true;
0882
0883 typedef typename traits::static_query<T,
0884 execution::blocking_adaptation_t::allowed_t>::result_type result_type;
0885
0886 static constexpr result_type value()
0887 {
0888 return traits::static_query<T,
0889 execution::blocking_adaptation_t::allowed_t>::value();
0890 }
0891 };
0892
0893 template <typename T>
0894 struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
0895 enable_if_t<
0896 execution::detail::blocking_adaptation::disallowed_t<0>::
0897 query_static_constexpr_member<T>::is_valid
0898 >>
0899 {
0900 static constexpr bool is_valid = true;
0901 static constexpr bool is_noexcept = true;
0902
0903 typedef typename execution::detail::blocking_adaptation::disallowed_t<0>::
0904 query_static_constexpr_member<T>::result_type result_type;
0905
0906 static constexpr result_type value()
0907 {
0908 return execution::detail::blocking_adaptation::disallowed_t<0>::
0909 query_static_constexpr_member<T>::value();
0910 }
0911 };
0912
0913 template <typename T>
0914 struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
0915 enable_if_t<
0916 !execution::detail::blocking_adaptation::disallowed_t<0>::
0917 query_static_constexpr_member<T>::is_valid
0918 && !execution::detail::blocking_adaptation::disallowed_t<0>::
0919 query_member<T>::is_valid
0920 && !traits::query_free<T,
0921 execution::blocking_adaptation_t::disallowed_t>::is_valid
0922 && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value
0923 >>
0924 {
0925 static constexpr bool is_valid = true;
0926 static constexpr bool is_noexcept = true;
0927
0928 typedef execution::blocking_adaptation_t::disallowed_t result_type;
0929
0930 static constexpr result_type value()
0931 {
0932 return result_type();
0933 }
0934 };
0935
0936 template <typename T>
0937 struct static_query<T, execution::blocking_adaptation_t::allowed_t,
0938 enable_if_t<
0939 execution::detail::blocking_adaptation::allowed_t<0>::
0940 query_static_constexpr_member<T>::is_valid
0941 >>
0942 {
0943 static constexpr bool is_valid = true;
0944 static constexpr bool is_noexcept = true;
0945
0946 typedef typename execution::detail::blocking_adaptation::allowed_t<0>::
0947 query_static_constexpr_member<T>::result_type result_type;
0948
0949 static constexpr result_type value()
0950 {
0951 return execution::detail::blocking_adaptation::allowed_t<0>::
0952 query_static_constexpr_member<T>::value();
0953 }
0954 };
0955
0956 #endif
0957
0958
0959 #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
0960
0961 template <typename T>
0962 struct require_free_default<T, execution::blocking_adaptation_t::allowed_t,
0963 enable_if_t<
0964 is_same<T, decay_t<T>>::value
0965 && execution::is_executor<T>::value
0966 >>
0967 {
0968 static constexpr bool is_valid = true;
0969 static constexpr bool is_noexcept = false;
0970 typedef execution::detail::blocking_adaptation::adapter<T> result_type;
0971 };
0972
0973 #endif
0974
0975 #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
0976
0977 template <typename Executor>
0978 struct equality_comparable<
0979 execution::detail::blocking_adaptation::adapter<Executor>>
0980 {
0981 static constexpr bool is_valid = true;
0982 static constexpr bool is_noexcept = true;
0983 };
0984
0985 #endif
0986
0987 #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
0988
0989 template <typename Executor, typename Function>
0990 struct execute_member<
0991 execution::detail::blocking_adaptation::adapter<Executor>, Function>
0992 {
0993 static constexpr bool is_valid = true;
0994 static constexpr bool is_noexcept = false;
0995 typedef void result_type;
0996 };
0997
0998 #endif
0999
1000 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
1001
1002 template <typename Executor, int I>
1003 struct query_static_constexpr_member<
1004 execution::detail::blocking_adaptation::adapter<Executor>,
1005 execution::detail::blocking_adaptation_t<I>>
1006 {
1007 static constexpr bool is_valid = true;
1008 static constexpr bool is_noexcept = true;
1009 typedef execution::blocking_adaptation_t::allowed_t result_type;
1010
1011 static constexpr result_type value() noexcept
1012 {
1013 return result_type();
1014 }
1015 };
1016
1017 template <typename Executor, int I>
1018 struct query_static_constexpr_member<
1019 execution::detail::blocking_adaptation::adapter<Executor>,
1020 execution::detail::blocking_adaptation::allowed_t<I>>
1021 {
1022 static constexpr bool is_valid = true;
1023 static constexpr bool is_noexcept = true;
1024 typedef execution::blocking_adaptation_t::allowed_t result_type;
1025
1026 static constexpr result_type value() noexcept
1027 {
1028 return result_type();
1029 }
1030 };
1031
1032 template <typename Executor, int I>
1033 struct query_static_constexpr_member<
1034 execution::detail::blocking_adaptation::adapter<Executor>,
1035 execution::detail::blocking_adaptation::disallowed_t<I>>
1036 {
1037 static constexpr bool is_valid = true;
1038 static constexpr bool is_noexcept = true;
1039 typedef execution::blocking_adaptation_t::allowed_t result_type;
1040
1041 static constexpr result_type value() noexcept
1042 {
1043 return result_type();
1044 }
1045 };
1046
1047 #endif
1048
1049 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
1050
1051 template <typename Executor, typename Property>
1052 struct query_member<
1053 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1054 enable_if_t<
1055 can_query<const Executor&, Property>::value
1056 >>
1057 {
1058 static constexpr bool is_valid = true;
1059 static constexpr bool is_noexcept =
1060 is_nothrow_query<Executor, Property>::value;
1061 typedef query_result_t<Executor, Property> result_type;
1062 };
1063
1064 #endif
1065
1066 #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1067
1068 template <typename Executor, int I>
1069 struct require_member<
1070 execution::detail::blocking_adaptation::adapter<Executor>,
1071 execution::detail::blocking_adaptation::disallowed_t<I>>
1072 {
1073 static constexpr bool is_valid = true;
1074 static constexpr bool is_noexcept = true;
1075 typedef Executor result_type;
1076 };
1077
1078 template <typename Executor, typename Property>
1079 struct require_member<
1080 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1081 enable_if_t<
1082 can_require<const Executor&, Property>::value
1083 >>
1084 {
1085 static constexpr bool is_valid = true;
1086 static constexpr bool is_noexcept =
1087 is_nothrow_require<Executor, Property>::value;
1088 typedef execution::detail::blocking_adaptation::adapter<
1089 decay_t<require_result_t<Executor, Property>>> result_type;
1090 };
1091
1092 #endif
1093
1094 #if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1095
1096 template <typename Executor, typename Property>
1097 struct prefer_member<
1098 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1099 enable_if_t<
1100 can_prefer<const Executor&, Property>::value
1101 >>
1102 {
1103 static constexpr bool is_valid = true;
1104 static constexpr bool is_noexcept =
1105 is_nothrow_prefer<Executor, Property>::value;
1106 typedef execution::detail::blocking_adaptation::adapter<
1107 decay_t<prefer_result_t<Executor, Property>>> result_type;
1108 };
1109
1110 #endif
1111
1112 }
1113
1114 #endif
1115
1116 }
1117 }
1118
1119 #include <boost/asio/detail/pop_options.hpp>
1120
1121 #endif