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