Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:44

0001 //
0002 // deferred.hpp
0003 // ~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // defined(_MSC_VER) && (_MSC_VER >= 1200)
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 /// Trait for detecting objects that are usable as deferred operations.
0031 template <typename T>
0032 struct is_deferred : false_type
0033 {
0034 };
0035 
0036 /// Helper type to wrap multiple completion signatures.
0037 template <typename... Signatures>
0038 struct deferred_signatures
0039 {
0040 };
0041 
0042 namespace detail {
0043 
0044 // Helper trait for getting the completion signatures of the tail in a sequence
0045 // when invoked with the specified arguments.
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 // Completion handler for the head component of a deferred sequence.
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 //private:
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 // Two-step application of variadic Signatures to determine correct base type.
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 } // namespace detail
0155 
0156 /// Used to represent an empty deferred action.
0157 struct deferred_noop
0158 {
0159   /// No effect.
0160   template <typename... Args>
0161   void operator()(Args&&...) &&
0162   {
0163   }
0164 
0165   /// No effect.
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 // !defined(GENERATING_DOCUMENTATION)
0178 
0179 /// Tag type to disambiguate deferred constructors.
0180 struct deferred_init_tag {};
0181 
0182 /// Wraps a function object so that it may be used as an element in a deferred
0183 /// composition.
0184 template <typename Function>
0185 class deferred_function
0186 {
0187 public:
0188   /// Constructor. 
0189   template <typename F>
0190   constexpr explicit deferred_function(deferred_init_tag, F&& function)
0191     : function_(static_cast<F&&>(function))
0192   {
0193   }
0194 
0195 //private:
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 // !defined(GENERATING_DOCUMENTATION)
0221 
0222 /// Encapsulates deferred values.
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   /// Construct a deferred asynchronous operation from the arguments to an
0261   /// initiation function object.
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   /// Initiate the deferred operation using the supplied completion token.
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 // !defined(GENERATING_DOCUMENTATION)
0301 
0302 /// Encapsulates a deferred asynchronous operation.
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         initiation_t(initiation_), token, std::get<I>(init_args_)...))
0330   {
0331     return async_initiate<CompletionToken, Signature>(
0332         initiation_t(initiation_), token, std::get<I>(init_args_)...);
0333   }
0334 
0335 public:
0336   /// Construct a deferred asynchronous operation from the arguments to an
0337   /// initiation function object.
0338   template <typename I, typename... A>
0339   constexpr explicit deferred_async_operation(
0340       deferred_init_tag, I&& initiation, A&&... init_args)
0341     : initiation_(static_cast<I&&>(initiation)),
0342       init_args_(static_cast<A&&>(init_args)...)
0343   {
0344   }
0345 
0346   /// Initiate the asynchronous operation using the supplied completion token.
0347   template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>
0348   auto operator()(CompletionToken&& token) &&
0349     -> decltype(
0350       this->invoke_helper(
0351         static_cast<CompletionToken&&>(token),
0352         detail::index_sequence_for<InitArgs...>()))
0353   {
0354     return this->invoke_helper(
0355         static_cast<CompletionToken&&>(token),
0356         detail::index_sequence_for<InitArgs...>());
0357   }
0358 
0359   template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>
0360   auto operator()(CompletionToken&& token) const &
0361     -> decltype(
0362       this->const_invoke_helper(
0363         static_cast<CompletionToken&&>(token),
0364         detail::index_sequence_for<InitArgs...>()))
0365   {
0366     return this->const_invoke_helper(
0367         static_cast<CompletionToken&&>(token),
0368         detail::index_sequence_for<InitArgs...>());
0369   }
0370 };
0371 
0372 /// Encapsulates a deferred asynchronous operation thas has multiple completion
0373 /// signatures.
0374 template <typename... Signatures, typename Initiation, typename... InitArgs>
0375 class BOOST_ASIO_NODISCARD deferred_async_operation<
0376     deferred_signatures<Signatures...>, Initiation, InitArgs...>
0377 {
0378 private:
0379   typedef decay_t<Initiation> initiation_t;
0380   initiation_t initiation_;
0381   typedef std::tuple<decay_t<InitArgs>...> init_args_t;
0382   init_args_t init_args_;
0383 
0384   template <typename CompletionToken, std::size_t... I>
0385   auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)
0386     -> decltype(
0387       async_initiate<CompletionToken, Signatures...>(
0388         static_cast<initiation_t&&>(initiation_), token,
0389         std::get<I>(static_cast<init_args_t&&>(init_args_))...))
0390   {
0391     return async_initiate<CompletionToken, Signatures...>(
0392         static_cast<initiation_t&&>(initiation_), token,
0393         std::get<I>(static_cast<init_args_t&&>(init_args_))...);
0394   }
0395 
0396   template <typename CompletionToken, std::size_t... I>
0397   auto const_invoke_helper(CompletionToken&& token,
0398       detail::index_sequence<I...>) const &
0399     -> decltype(
0400       async_initiate<CompletionToken, Signatures...>(
0401         initiation_t(initiation_), token, std::get<I>(init_args_)...))
0402   {
0403     return async_initiate<CompletionToken, Signatures...>(
0404         initiation_t(initiation_), token, std::get<I>(init_args_)...);
0405   }
0406 
0407 public:
0408   /// Construct a deferred asynchronous operation from the arguments to an
0409   /// initiation function object.
0410   template <typename I, typename... A>
0411   constexpr explicit deferred_async_operation(
0412       deferred_init_tag, I&& initiation, A&&... init_args)
0413     : initiation_(static_cast<I&&>(initiation)),
0414       init_args_(static_cast<A&&>(init_args)...)
0415   {
0416   }
0417 
0418   /// Initiate the asynchronous operation using the supplied completion token.
0419   template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>
0420   auto operator()(CompletionToken&& token) &&
0421     -> decltype(
0422       this->invoke_helper(
0423         static_cast<CompletionToken&&>(token),
0424         detail::index_sequence_for<InitArgs...>()))
0425   {
0426     return this->invoke_helper(
0427         static_cast<CompletionToken&&>(token),
0428         detail::index_sequence_for<InitArgs...>());
0429   }
0430 
0431   template <BOOST_ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>
0432   auto operator()(CompletionToken&& token) const &
0433     -> decltype(
0434       this->const_invoke_helper(
0435         static_cast<CompletionToken&&>(token),
0436         detail::index_sequence_for<InitArgs...>()))
0437   {
0438     return this->const_invoke_helper(
0439         static_cast<CompletionToken&&>(token),
0440         detail::index_sequence_for<InitArgs...>());
0441   }
0442 };
0443 
0444 #if !defined(GENERATING_DOCUMENTATION)
0445 template <typename Signature, typename Initiation, typename... InitArgs>
0446 struct is_deferred<
0447     deferred_async_operation<Signature, Initiation, InitArgs...>> : true_type
0448 {
0449 };
0450 #endif // !defined(GENERATING_DOCUMENTATION)
0451 
0452 /// Defines a link between two consecutive operations in a sequence.
0453 template <typename Head, typename Tail>
0454 class BOOST_ASIO_NODISCARD deferred_sequence :
0455   public detail::deferred_sequence_types<Head, Tail>::base
0456 {
0457 public:
0458   template <typename H, typename T>
0459   constexpr explicit deferred_sequence(deferred_init_tag, H&& head, T&& tail)
0460     : detail::deferred_sequence_types<Head, Tail>::base(
0461         static_cast<H&&>(head), static_cast<T&&>(tail))
0462   {
0463   }
0464 
0465 #if defined(GENERATING_DOCUMENTATION)
0466   template <typename CompletionToken>
0467   auto operator()(CompletionToken&& token) &&;
0468 
0469   template <typename CompletionToken>
0470   auto operator()(CompletionToken&& token) const &;
0471 #endif // defined(GENERATING_DOCUMENTATION)
0472 };
0473 
0474 #if !defined(GENERATING_DOCUMENTATION)
0475 template <typename Head, typename Tail>
0476 struct is_deferred<deferred_sequence<Head, Tail>> : true_type
0477 {
0478 };
0479 #endif // !defined(GENERATING_DOCUMENTATION)
0480 
0481 /// Used to represent a deferred conditional branch.
0482 template <typename OnTrue = deferred_noop, typename OnFalse = deferred_noop>
0483 class BOOST_ASIO_NODISCARD deferred_conditional
0484 {
0485 private:
0486   template <typename T, typename F> friend class deferred_conditional;
0487 
0488   // Helper constructor.
0489   template <typename T, typename F>
0490   explicit deferred_conditional(bool b, T&& on_true, F&& on_false)
0491     : on_true_(static_cast<T&&>(on_true)),
0492       on_false_(static_cast<F&&>(on_false)),
0493       bool_(b)
0494   {
0495   }
0496 
0497   OnTrue on_true_;
0498   OnFalse on_false_;
0499   bool bool_;
0500 
0501 public:
0502   /// Construct a deferred conditional with the value to determine which branch
0503   /// will be executed.
0504   constexpr explicit deferred_conditional(bool b)
0505     : on_true_(),
0506       on_false_(),
0507       bool_(b)
0508   {
0509   }
0510 
0511   /// Invoke the conditional branch bsaed on the stored value.
0512   template <typename... Args>
0513   auto operator()(Args&&... args) &&
0514     -> decltype(static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...))
0515   {
0516     if (bool_)
0517     {
0518       return static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...);
0519     }
0520     else
0521     {
0522       return static_cast<OnFalse&&>(on_false_)(static_cast<Args&&>(args)...);
0523     }
0524   }
0525 
0526   template <typename... Args>
0527   auto operator()(Args&&... args) const &
0528     -> decltype(on_true_(static_cast<Args&&>(args)...))
0529   {
0530     if (bool_)
0531     {
0532       return on_true_(static_cast<Args&&>(args)...);
0533     }
0534     else
0535     {
0536       return on_false_(static_cast<Args&&>(args)...);
0537     }
0538   }
0539 
0540   /// Set the true branch of the conditional.
0541   template <typename T>
0542   deferred_conditional<T, OnFalse> then(T on_true,
0543       constraint_t<
0544         is_deferred<T>::value
0545       >* = 0,
0546       constraint_t<
0547         is_same<
0548           conditional_t<true, OnTrue, T>,
0549           deferred_noop
0550         >::value
0551       >* = 0) &&
0552   {
0553     return deferred_conditional<T, OnFalse>(
0554         bool_, static_cast<T&&>(on_true),
0555         static_cast<OnFalse&&>(on_false_));
0556   }
0557 
0558   /// Set the false branch of the conditional.
0559   template <typename T>
0560   deferred_conditional<OnTrue, T> otherwise(T on_false,
0561       constraint_t<
0562         is_deferred<T>::value
0563       >* = 0,
0564       constraint_t<
0565         !is_same<
0566           conditional_t<true, OnTrue, T>,
0567           deferred_noop
0568         >::value
0569       >* = 0,
0570       constraint_t<
0571         is_same<
0572           conditional_t<true, OnFalse, T>,
0573           deferred_noop
0574         >::value
0575       >* = 0) &&
0576   {
0577     return deferred_conditional<OnTrue, T>(
0578         bool_, static_cast<OnTrue&&>(on_true_),
0579         static_cast<T&&>(on_false));
0580   }
0581 };
0582 
0583 #if !defined(GENERATING_DOCUMENTATION)
0584 template <typename OnTrue, typename OnFalse>
0585 struct is_deferred<deferred_conditional<OnTrue, OnFalse>> : true_type
0586 {
0587 };
0588 #endif // !defined(GENERATING_DOCUMENTATION)
0589 
0590 /// Class used to specify that an asynchronous operation should return a
0591 /// function object to lazily launch the operation.
0592 /**
0593  * The deferred_t class is used to indicate that an asynchronous operation
0594  * should return a function object which is itself an initiation function. A
0595  * deferred_t object may be passed as a completion token to an asynchronous
0596  * operation, typically using the special value @c boost::asio::deferred. For
0597  * example:
0598  *
0599  * @code auto my_deferred_op
0600  *   = my_socket.async_read_some(my_buffer,
0601  *       boost::asio::deferred); @endcode
0602  *
0603  * The initiating function (async_read_some in the above example) returns a
0604  * function object that will lazily initiate the operation.
0605  */
0606 class deferred_t
0607 {
0608 public:
0609   /// Default constructor.
0610   constexpr deferred_t()
0611   {
0612   }
0613 
0614   /// Adapts an executor to add the @c deferred_t completion token as the
0615   /// default.
0616   template <typename InnerExecutor>
0617   struct executor_with_default : InnerExecutor
0618   {
0619     /// Specify @c deferred_t as the default completion token type.
0620     typedef deferred_t default_completion_token_type;
0621 
0622     /// Construct the adapted executor from the inner executor type.
0623     template <typename InnerExecutor1>
0624     executor_with_default(const InnerExecutor1& ex,
0625         constraint_t<
0626           conditional_t<
0627             !is_same<InnerExecutor1, executor_with_default>::value,
0628             is_convertible<InnerExecutor1, InnerExecutor>,
0629             false_type
0630           >::value
0631         > = 0) noexcept
0632       : InnerExecutor(ex)
0633     {
0634     }
0635   };
0636 
0637   /// Type alias to adapt an I/O object to use @c deferred_t as its
0638   /// default completion token type.
0639   template <typename T>
0640   using as_default_on_t = typename T::template rebind_executor<
0641       executor_with_default<typename T::executor_type>>::other;
0642 
0643   /// Function helper to adapt an I/O object to use @c deferred_t as its
0644   /// default completion token type.
0645   template <typename T>
0646   static typename decay_t<T>::template rebind_executor<
0647       executor_with_default<typename decay_t<T>::executor_type>
0648     >::other
0649   as_default_on(T&& object)
0650   {
0651     return typename decay_t<T>::template rebind_executor<
0652         executor_with_default<typename decay_t<T>::executor_type>
0653       >::other(static_cast<T&&>(object));
0654   }
0655 
0656   /// Creates a new deferred from a function.
0657   template <typename Function>
0658   constraint_t<
0659     !is_deferred<decay_t<Function>>::value,
0660     deferred_function<decay_t<Function>>
0661   > operator()(Function&& function) const
0662   {
0663     return deferred_function<decay_t<Function>>(
0664         deferred_init_tag{}, static_cast<Function&&>(function));
0665   }
0666 
0667   /// Passes through anything that is already deferred.
0668   template <typename T>
0669   constraint_t<
0670     is_deferred<decay_t<T>>::value,
0671     decay_t<T>
0672   > operator()(T&& t) const
0673   {
0674     return static_cast<T&&>(t);
0675   }
0676 
0677   /// Returns a deferred operation that returns the provided values.
0678   template <typename... Args>
0679   static constexpr deferred_values<decay_t<Args>...> values(Args&&... args)
0680   {
0681     return deferred_values<decay_t<Args>...>(
0682         deferred_init_tag{}, static_cast<Args&&>(args)...);
0683   }
0684 
0685   /// Creates a conditional object for branching deferred operations.
0686   static constexpr deferred_conditional<> when(bool b)
0687   {
0688     return deferred_conditional<>(b);
0689   }
0690 };
0691 
0692 /// Pipe operator used to chain deferred operations.
0693 template <typename Head, typename Tail>
0694 inline auto operator|(Head head, Tail&& tail)
0695   -> constraint_t<
0696       is_deferred<Head>::value,
0697       decltype(static_cast<Head&&>(head)(static_cast<Tail&&>(tail)))
0698     >
0699 {
0700   return static_cast<Head&&>(head)(static_cast<Tail&&>(tail));
0701 }
0702 
0703 /// A @ref completion_token object used to specify that an asynchronous
0704 /// operation should return a function object to lazily launch the operation.
0705 /**
0706  * See the documentation for boost::asio::deferred_t for a usage example.
0707  */
0708 constexpr deferred_t deferred;
0709 
0710 } // namespace asio
0711 } // namespace boost
0712 
0713 #include <boost/asio/detail/pop_options.hpp>
0714 
0715 #include <boost/asio/impl/deferred.hpp>
0716 
0717 #endif // BOOST_ASIO_DEFERRED_HPP