File indexing completed on 2025-07-15 08:28:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DEFERRED_HPP
0012 #define BOOST_ASIO_DEFERRED_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 <tuple>
0020 #include <boost/asio/associator.hpp>
0021 #include <boost/asio/async_result.hpp>
0022 #include <boost/asio/detail/type_traits.hpp>
0023 #include <boost/asio/detail/utility.hpp>
0024
0025 #include <boost/asio/detail/push_options.hpp>
0026
0027 namespace boost {
0028 namespace asio {
0029
0030
0031 template <typename T>
0032 struct is_deferred : false_type
0033 {
0034 };
0035
0036
0037 template <typename... Signatures>
0038 struct deferred_signatures
0039 {
0040 };
0041
0042 namespace detail {
0043
0044
0045
0046
0047 template <typename Tail, typename... Signatures>
0048 struct deferred_sequence_signatures;
0049
0050 template <typename Tail, typename R, typename... Args, typename... Signatures>
0051 struct deferred_sequence_signatures<Tail, R(Args...), Signatures...>
0052 : completion_signature_of<decltype(declval<Tail>()(declval<Args>()...))>
0053 {
0054 static_assert(
0055 !is_same<decltype(declval<Tail>()(declval<Args>()...)), void>::value,
0056 "deferred functions must produce a deferred return type");
0057 };
0058
0059
0060 template <typename Handler, typename Tail>
0061 class deferred_sequence_handler
0062 {
0063 public:
0064 template <typename H, typename T>
0065 explicit deferred_sequence_handler(H&& handler, T&& tail)
0066 : handler_(static_cast<H&&>(handler)),
0067 tail_(static_cast<T&&>(tail))
0068 {
0069 }
0070
0071 template <typename... Args>
0072 void operator()(Args&&... args)
0073 {
0074 static_cast<Tail&&>(tail_)(
0075 static_cast<Args&&>(args)...)(
0076 static_cast<Handler&&>(handler_));
0077 }
0078
0079
0080 Handler handler_;
0081 Tail tail_;
0082 };
0083
0084 template <typename Head, typename Tail, typename... Signatures>
0085 class deferred_sequence_base
0086 {
0087 private:
0088 struct initiate
0089 {
0090 template <typename Handler>
0091 void operator()(Handler&& handler, Head head, Tail&& tail)
0092 {
0093 static_cast<Head&&>(head)(
0094 deferred_sequence_handler<decay_t<Handler>, decay_t<Tail>>(
0095 static_cast<Handler&&>(handler), static_cast<Tail&&>(tail)));
0096 }
0097 };
0098
0099 Head head_;
0100 Tail tail_;
0101
0102 public:
0103 template <typename H, typename T>
0104 constexpr explicit deferred_sequence_base(H&& head, T&& tail)
0105 : head_(static_cast<H&&>(head)),
0106 tail_(static_cast<T&&>(tail))
0107 {
0108 }
0109
0110 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>
0111 auto operator()(CompletionToken&& token) &&
0112 -> decltype(
0113 async_initiate<CompletionToken, Signatures...>(
0114 initiate(), token, static_cast<Head&&>(this->head_),
0115 static_cast<Tail&&>(this->tail_)))
0116 {
0117 return async_initiate<CompletionToken, Signatures...>(initiate(),
0118 token, static_cast<Head&&>(head_), static_cast<Tail&&>(tail_));
0119 }
0120
0121 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>
0122 auto operator()(CompletionToken&& token) const &
0123 -> decltype(
0124 async_initiate<CompletionToken, Signatures...>(
0125 initiate(), token, this->head_, this->tail_))
0126 {
0127 return async_initiate<CompletionToken, Signatures...>(
0128 initiate(), token, head_, tail_);
0129 }
0130 };
0131
0132
0133
0134 template <typename Head, typename Tail>
0135 struct deferred_sequence_types
0136 {
0137 template <typename... Signatures>
0138 struct op1
0139 {
0140 typedef deferred_sequence_base<Head, Tail, Signatures...> type;
0141 };
0142
0143 template <typename... Signatures>
0144 struct op2
0145 {
0146 typedef typename deferred_sequence_signatures<Tail, Signatures...>::template
0147 apply<op1>::type::type type;
0148 };
0149
0150 typedef typename completion_signature_of<Head>::template
0151 apply<op2>::type::type base;
0152 };
0153
0154 }
0155
0156
0157 struct deferred_noop
0158 {
0159
0160 template <typename... Args>
0161 void operator()(Args&&...) &&
0162 {
0163 }
0164
0165
0166 template <typename... Args>
0167 void operator()(Args&&...) const &
0168 {
0169 }
0170 };
0171
0172 #if !defined(GENERATING_DOCUMENTATION)
0173 template <>
0174 struct is_deferred<deferred_noop> : true_type
0175 {
0176 };
0177 #endif
0178
0179
0180 struct deferred_init_tag {};
0181
0182
0183
0184 template <typename Function>
0185 class deferred_function
0186 {
0187 public:
0188
0189 template <typename F>
0190 constexpr explicit deferred_function(deferred_init_tag, F&& function)
0191 : function_(static_cast<F&&>(function))
0192 {
0193 }
0194
0195
0196 Function function_;
0197
0198 public:
0199 template <typename... Args>
0200 auto operator()(Args&&... args) &&
0201 -> decltype(
0202 static_cast<Function&&>(this->function_)(static_cast<Args&&>(args)...))
0203 {
0204 return static_cast<Function&&>(function_)(static_cast<Args&&>(args)...);
0205 }
0206
0207 template <typename... Args>
0208 auto operator()(Args&&... args) const &
0209 -> decltype(Function(function_)(static_cast<Args&&>(args)...))
0210 {
0211 return Function(function_)(static_cast<Args&&>(args)...);
0212 }
0213 };
0214
0215 #if !defined(GENERATING_DOCUMENTATION)
0216 template <typename Function>
0217 struct is_deferred<deferred_function<Function>> : true_type
0218 {
0219 };
0220 #endif
0221
0222
0223 template <typename... Values>
0224 class BOOST_ASIO_NODISCARD deferred_values
0225 {
0226 private:
0227 std::tuple<Values...> values_;
0228
0229 struct initiate
0230 {
0231 template <typename Handler, typename... V>
0232 void operator()(Handler handler, V&&... values)
0233 {
0234 static_cast<Handler&&>(handler)(static_cast<V&&>(values)...);
0235 }
0236 };
0237
0238 template <typename CompletionToken, std::size_t... I>
0239 auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)
0240 -> decltype(
0241 async_initiate<CompletionToken, void(Values...)>(initiate(), token,
0242 std::get<I>(static_cast<std::tuple<Values...>&&>(this->values_))...))
0243 {
0244 return async_initiate<CompletionToken, void(Values...)>(initiate(), token,
0245 std::get<I>(static_cast<std::tuple<Values...>&&>(values_))...);
0246 }
0247
0248 template <typename CompletionToken, std::size_t... I>
0249 auto const_invoke_helper(CompletionToken&& token,
0250 detail::index_sequence<I...>)
0251 -> decltype(
0252 async_initiate<CompletionToken, void(Values...)>(
0253 initiate(), token, std::get<I>(values_)...))
0254 {
0255 return async_initiate<CompletionToken, void(Values...)>(
0256 initiate(), token, std::get<I>(values_)...);
0257 }
0258
0259 public:
0260
0261
0262 template <typename... V>
0263 constexpr explicit deferred_values(
0264 deferred_init_tag, V&&... values)
0265 : values_(static_cast<V&&>(values)...)
0266 {
0267 }
0268
0269
0270 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(Values...)) CompletionToken>
0271 auto operator()(CompletionToken&& token) &&
0272 -> decltype(
0273 this->invoke_helper(
0274 static_cast<CompletionToken&&>(token),
0275 detail::index_sequence_for<Values...>()))
0276 {
0277 return this->invoke_helper(
0278 static_cast<CompletionToken&&>(token),
0279 detail::index_sequence_for<Values...>());
0280 }
0281
0282 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(Values...)) CompletionToken>
0283 auto operator()(CompletionToken&& token) const &
0284 -> decltype(
0285 this->const_invoke_helper(
0286 static_cast<CompletionToken&&>(token),
0287 detail::index_sequence_for<Values...>()))
0288 {
0289 return this->const_invoke_helper(
0290 static_cast<CompletionToken&&>(token),
0291 detail::index_sequence_for<Values...>());
0292 }
0293 };
0294
0295 #if !defined(GENERATING_DOCUMENTATION)
0296 template <typename... Values>
0297 struct is_deferred<deferred_values<Values...>> : true_type
0298 {
0299 };
0300 #endif
0301
0302
0303 template <typename Signature, typename Initiation, typename... InitArgs>
0304 class BOOST_ASIO_NODISCARD deferred_async_operation
0305 {
0306 private:
0307 typedef decay_t<Initiation> initiation_t;
0308 initiation_t initiation_;
0309 typedef std::tuple<decay_t<InitArgs>...> init_args_t;
0310 init_args_t init_args_;
0311
0312 template <typename CompletionToken, std::size_t... I>
0313 auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)
0314 -> decltype(
0315 async_initiate<CompletionToken, Signature>(
0316 static_cast<initiation_t&&>(initiation_), token,
0317 std::get<I>(static_cast<init_args_t&&>(init_args_))...))
0318 {
0319 return async_initiate<CompletionToken, Signature>(
0320 static_cast<initiation_t&&>(initiation_), token,
0321 std::get<I>(static_cast<init_args_t&&>(init_args_))...);
0322 }
0323
0324 template <typename CompletionToken, std::size_t... I>
0325 auto const_invoke_helper(CompletionToken&& token,
0326 detail::index_sequence<I...>) const &
0327 -> decltype(
0328 async_initiate<CompletionToken, Signature>(
0329 conditional_t<true, initiation_t, CompletionToken>(initiation_),
0330 token, std::get<I>(init_args_)...))
0331 {
0332 return async_initiate<CompletionToken, Signature>(
0333 initiation_t(initiation_), token, std::get<I>(init_args_)...);
0334 }
0335
0336 public:
0337
0338
0339 template <typename I, typename... A>
0340 constexpr explicit deferred_async_operation(
0341 deferred_init_tag, I&& initiation, A&&... init_args)
0342 : initiation_(static_cast<I&&>(initiation)),
0343 init_args_(static_cast<A&&>(init_args)...)
0344 {
0345 }
0346
0347
0348 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>
0349 auto operator()(CompletionToken&& token) &&
0350 -> decltype(
0351 this->invoke_helper(
0352 static_cast<CompletionToken&&>(token),
0353 detail::index_sequence_for<InitArgs...>()))
0354 {
0355 return this->invoke_helper(
0356 static_cast<CompletionToken&&>(token),
0357 detail::index_sequence_for<InitArgs...>());
0358 }
0359
0360 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>
0361 auto operator()(CompletionToken&& token) const &
0362 -> decltype(
0363 this->const_invoke_helper(
0364 static_cast<CompletionToken&&>(token),
0365 detail::index_sequence_for<InitArgs...>()))
0366 {
0367 return this->const_invoke_helper(
0368 static_cast<CompletionToken&&>(token),
0369 detail::index_sequence_for<InitArgs...>());
0370 }
0371 };
0372
0373
0374
0375 template <typename... Signatures, typename Initiation, typename... InitArgs>
0376 class BOOST_ASIO_NODISCARD deferred_async_operation<
0377 deferred_signatures<Signatures...>, Initiation, InitArgs...>
0378 {
0379 private:
0380 typedef decay_t<Initiation> initiation_t;
0381 initiation_t initiation_;
0382 typedef std::tuple<decay_t<InitArgs>...> init_args_t;
0383 init_args_t init_args_;
0384
0385 template <typename CompletionToken, std::size_t... I>
0386 auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)
0387 -> decltype(
0388 async_initiate<CompletionToken, Signatures...>(
0389 static_cast<initiation_t&&>(initiation_), token,
0390 std::get<I>(static_cast<init_args_t&&>(init_args_))...))
0391 {
0392 return async_initiate<CompletionToken, Signatures...>(
0393 static_cast<initiation_t&&>(initiation_), token,
0394 std::get<I>(static_cast<init_args_t&&>(init_args_))...);
0395 }
0396
0397 template <typename CompletionToken, std::size_t... I>
0398 auto const_invoke_helper(CompletionToken&& token,
0399 detail::index_sequence<I...>) const &
0400 -> decltype(
0401 async_initiate<CompletionToken, Signatures...>(
0402 initiation_t(initiation_), token, std::get<I>(init_args_)...))
0403 {
0404 return async_initiate<CompletionToken, Signatures...>(
0405 initiation_t(initiation_), token, std::get<I>(init_args_)...);
0406 }
0407
0408 public:
0409
0410
0411 template <typename I, typename... A>
0412 constexpr explicit deferred_async_operation(
0413 deferred_init_tag, I&& initiation, A&&... init_args)
0414 : initiation_(static_cast<I&&>(initiation)),
0415 init_args_(static_cast<A&&>(init_args)...)
0416 {
0417 }
0418
0419
0420 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>
0421 auto operator()(CompletionToken&& token) &&
0422 -> decltype(
0423 this->invoke_helper(
0424 static_cast<CompletionToken&&>(token),
0425 detail::index_sequence_for<InitArgs...>()))
0426 {
0427 return this->invoke_helper(
0428 static_cast<CompletionToken&&>(token),
0429 detail::index_sequence_for<InitArgs...>());
0430 }
0431
0432 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>
0433 auto operator()(CompletionToken&& token) const &
0434 -> decltype(
0435 this->const_invoke_helper(
0436 static_cast<CompletionToken&&>(token),
0437 detail::index_sequence_for<InitArgs...>()))
0438 {
0439 return this->const_invoke_helper(
0440 static_cast<CompletionToken&&>(token),
0441 detail::index_sequence_for<InitArgs...>());
0442 }
0443 };
0444
0445 #if !defined(GENERATING_DOCUMENTATION)
0446 template <typename Signature, typename Initiation, typename... InitArgs>
0447 struct is_deferred<
0448 deferred_async_operation<Signature, Initiation, InitArgs...>> : true_type
0449 {
0450 };
0451 #endif
0452
0453
0454 template <typename Head, typename Tail>
0455 class BOOST_ASIO_NODISCARD deferred_sequence :
0456 public detail::deferred_sequence_types<Head, Tail>::base
0457 {
0458 public:
0459 template <typename H, typename T>
0460 constexpr explicit deferred_sequence(deferred_init_tag, H&& head, T&& tail)
0461 : detail::deferred_sequence_types<Head, Tail>::base(
0462 static_cast<H&&>(head), static_cast<T&&>(tail))
0463 {
0464 }
0465
0466 #if defined(GENERATING_DOCUMENTATION)
0467 template <typename CompletionToken>
0468 auto operator()(CompletionToken&& token) &&;
0469
0470 template <typename CompletionToken>
0471 auto operator()(CompletionToken&& token) const &;
0472 #endif
0473 };
0474
0475 #if !defined(GENERATING_DOCUMENTATION)
0476 template <typename Head, typename Tail>
0477 struct is_deferred<deferred_sequence<Head, Tail>> : true_type
0478 {
0479 };
0480 #endif
0481
0482
0483 template <typename OnTrue = deferred_noop, typename OnFalse = deferred_noop>
0484 class BOOST_ASIO_NODISCARD deferred_conditional
0485 {
0486 private:
0487 template <typename T, typename F> friend class deferred_conditional;
0488
0489
0490 template <typename T, typename F>
0491 explicit deferred_conditional(bool b, T&& on_true, F&& on_false)
0492 : on_true_(static_cast<T&&>(on_true)),
0493 on_false_(static_cast<F&&>(on_false)),
0494 bool_(b)
0495 {
0496 }
0497
0498 OnTrue on_true_;
0499 OnFalse on_false_;
0500 bool bool_;
0501
0502 public:
0503
0504
0505 constexpr explicit deferred_conditional(bool b)
0506 : on_true_(),
0507 on_false_(),
0508 bool_(b)
0509 {
0510 }
0511
0512
0513 template <typename... Args>
0514 auto operator()(Args&&... args) &&
0515 -> decltype(static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...))
0516 {
0517 if (bool_)
0518 {
0519 return static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...);
0520 }
0521 else
0522 {
0523 return static_cast<OnFalse&&>(on_false_)(static_cast<Args&&>(args)...);
0524 }
0525 }
0526
0527 template <typename... Args>
0528 auto operator()(Args&&... args) const &
0529 -> decltype(on_true_(static_cast<Args&&>(args)...))
0530 {
0531 if (bool_)
0532 {
0533 return on_true_(static_cast<Args&&>(args)...);
0534 }
0535 else
0536 {
0537 return on_false_(static_cast<Args&&>(args)...);
0538 }
0539 }
0540
0541
0542 template <typename T>
0543 deferred_conditional<T, OnFalse> then(T on_true,
0544 constraint_t<
0545 is_deferred<T>::value
0546 >* = 0,
0547 constraint_t<
0548 is_same<
0549 conditional_t<true, OnTrue, T>,
0550 deferred_noop
0551 >::value
0552 >* = 0) &&
0553 {
0554 return deferred_conditional<T, OnFalse>(
0555 bool_, static_cast<T&&>(on_true),
0556 static_cast<OnFalse&&>(on_false_));
0557 }
0558
0559
0560 template <typename T>
0561 deferred_conditional<OnTrue, T> otherwise(T on_false,
0562 constraint_t<
0563 is_deferred<T>::value
0564 >* = 0,
0565 constraint_t<
0566 !is_same<
0567 conditional_t<true, OnTrue, T>,
0568 deferred_noop
0569 >::value
0570 >* = 0,
0571 constraint_t<
0572 is_same<
0573 conditional_t<true, OnFalse, T>,
0574 deferred_noop
0575 >::value
0576 >* = 0) &&
0577 {
0578 return deferred_conditional<OnTrue, T>(
0579 bool_, static_cast<OnTrue&&>(on_true_),
0580 static_cast<T&&>(on_false));
0581 }
0582 };
0583
0584 #if !defined(GENERATING_DOCUMENTATION)
0585 template <typename OnTrue, typename OnFalse>
0586 struct is_deferred<deferred_conditional<OnTrue, OnFalse>> : true_type
0587 {
0588 };
0589 #endif
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610 class deferred_t
0611 {
0612 public:
0613
0614 constexpr deferred_t()
0615 {
0616 }
0617
0618
0619
0620 template <typename InnerExecutor>
0621 struct executor_with_default : InnerExecutor
0622 {
0623
0624 typedef deferred_t default_completion_token_type;
0625
0626
0627 template <typename InnerExecutor1>
0628 executor_with_default(const InnerExecutor1& ex,
0629 constraint_t<
0630 conditional_t<
0631 !is_same<InnerExecutor1, executor_with_default>::value,
0632 is_convertible<InnerExecutor1, InnerExecutor>,
0633 false_type
0634 >::value
0635 > = 0) noexcept
0636 : InnerExecutor(ex)
0637 {
0638 }
0639 };
0640
0641
0642
0643 template <typename T>
0644 using as_default_on_t = typename T::template rebind_executor<
0645 executor_with_default<typename T::executor_type>>::other;
0646
0647
0648
0649 template <typename T>
0650 static typename decay_t<T>::template rebind_executor<
0651 executor_with_default<typename decay_t<T>::executor_type>
0652 >::other
0653 as_default_on(T&& object)
0654 {
0655 return typename decay_t<T>::template rebind_executor<
0656 executor_with_default<typename decay_t<T>::executor_type>
0657 >::other(static_cast<T&&>(object));
0658 }
0659
0660
0661 template <typename Function>
0662 constraint_t<
0663 !is_deferred<decay_t<Function>>::value,
0664 deferred_function<decay_t<Function>>
0665 > operator()(Function&& function) const
0666 {
0667 return deferred_function<decay_t<Function>>(
0668 deferred_init_tag{}, static_cast<Function&&>(function));
0669 }
0670
0671
0672 template <typename T>
0673 constraint_t<
0674 is_deferred<decay_t<T>>::value,
0675 decay_t<T>
0676 > operator()(T&& t) const
0677 {
0678 return static_cast<T&&>(t);
0679 }
0680
0681
0682 template <typename... Args>
0683 static constexpr deferred_values<decay_t<Args>...> values(Args&&... args)
0684 {
0685 return deferred_values<decay_t<Args>...>(
0686 deferred_init_tag{}, static_cast<Args&&>(args)...);
0687 }
0688
0689
0690 static constexpr deferred_conditional<> when(bool b)
0691 {
0692 return deferred_conditional<>(b);
0693 }
0694 };
0695
0696
0697 template <typename Head, typename Tail>
0698 inline auto operator|(Head head, Tail&& tail)
0699 -> constraint_t<
0700 is_deferred<Head>::value,
0701 decltype(static_cast<Head&&>(head)(static_cast<Tail&&>(tail)))
0702 >
0703 {
0704 return static_cast<Head&&>(head)(static_cast<Tail&&>(tail));
0705 }
0706
0707
0708
0709
0710
0711
0712 BOOST_ASIO_INLINE_VARIABLE constexpr deferred_t deferred;
0713
0714 }
0715 }
0716
0717 #include <boost/asio/detail/pop_options.hpp>
0718
0719 #include <boost/asio/impl/deferred.hpp>
0720
0721 #endif