Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/asio/bind_cancellation_slot.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //
0002 // bind_cancellation_slot.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 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_BIND_CANCELLATION_SLOT_HPP
0012 #define BOOST_ASIO_BIND_CANCELLATION_SLOT_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 <boost/asio/associated_cancellation_slot.hpp>
0020 #include <boost/asio/associated_executor.hpp>
0021 #include <boost/asio/associator.hpp>
0022 #include <boost/asio/async_result.hpp>
0023 #include <boost/asio/detail/initiation_base.hpp>
0024 #include <boost/asio/detail/type_traits.hpp>
0025 
0026 #include <boost/asio/detail/push_options.hpp>
0027 
0028 namespace boost {
0029 namespace asio {
0030 namespace detail {
0031 
0032 // Helper to automatically define nested typedef result_type.
0033 
0034 template <typename T, typename = void>
0035 struct cancellation_slot_binder_result_type
0036 {
0037 protected:
0038   typedef void result_type_or_void;
0039 };
0040 
0041 template <typename T>
0042 struct cancellation_slot_binder_result_type<T, void_t<typename T::result_type>>
0043 {
0044   typedef typename T::result_type result_type;
0045 protected:
0046   typedef result_type result_type_or_void;
0047 };
0048 
0049 template <typename R>
0050 struct cancellation_slot_binder_result_type<R(*)()>
0051 {
0052   typedef R result_type;
0053 protected:
0054   typedef result_type result_type_or_void;
0055 };
0056 
0057 template <typename R>
0058 struct cancellation_slot_binder_result_type<R(&)()>
0059 {
0060   typedef R result_type;
0061 protected:
0062   typedef result_type result_type_or_void;
0063 };
0064 
0065 template <typename R, typename A1>
0066 struct cancellation_slot_binder_result_type<R(*)(A1)>
0067 {
0068   typedef R result_type;
0069 protected:
0070   typedef result_type result_type_or_void;
0071 };
0072 
0073 template <typename R, typename A1>
0074 struct cancellation_slot_binder_result_type<R(&)(A1)>
0075 {
0076   typedef R result_type;
0077 protected:
0078   typedef result_type result_type_or_void;
0079 };
0080 
0081 template <typename R, typename A1, typename A2>
0082 struct cancellation_slot_binder_result_type<R(*)(A1, A2)>
0083 {
0084   typedef R result_type;
0085 protected:
0086   typedef result_type result_type_or_void;
0087 };
0088 
0089 template <typename R, typename A1, typename A2>
0090 struct cancellation_slot_binder_result_type<R(&)(A1, A2)>
0091 {
0092   typedef R result_type;
0093 protected:
0094   typedef result_type result_type_or_void;
0095 };
0096 
0097 // Helper to automatically define nested typedef argument_type.
0098 
0099 template <typename T, typename = void>
0100 struct cancellation_slot_binder_argument_type {};
0101 
0102 template <typename T>
0103 struct cancellation_slot_binder_argument_type<T,
0104     void_t<typename T::argument_type>>
0105 {
0106   typedef typename T::argument_type argument_type;
0107 };
0108 
0109 template <typename R, typename A1>
0110 struct cancellation_slot_binder_argument_type<R(*)(A1)>
0111 {
0112   typedef A1 argument_type;
0113 };
0114 
0115 template <typename R, typename A1>
0116 struct cancellation_slot_binder_argument_type<R(&)(A1)>
0117 {
0118   typedef A1 argument_type;
0119 };
0120 
0121 // Helper to automatically define nested typedefs first_argument_type and
0122 // second_argument_type.
0123 
0124 template <typename T, typename = void>
0125 struct cancellation_slot_binder_argument_types {};
0126 
0127 template <typename T>
0128 struct cancellation_slot_binder_argument_types<T,
0129     void_t<typename T::first_argument_type>>
0130 {
0131   typedef typename T::first_argument_type first_argument_type;
0132   typedef typename T::second_argument_type second_argument_type;
0133 };
0134 
0135 template <typename R, typename A1, typename A2>
0136 struct cancellation_slot_binder_argument_type<R(*)(A1, A2)>
0137 {
0138   typedef A1 first_argument_type;
0139   typedef A2 second_argument_type;
0140 };
0141 
0142 template <typename R, typename A1, typename A2>
0143 struct cancellation_slot_binder_argument_type<R(&)(A1, A2)>
0144 {
0145   typedef A1 first_argument_type;
0146   typedef A2 second_argument_type;
0147 };
0148 
0149 } // namespace detail
0150 
0151 /// A call wrapper type to bind a cancellation slot of type @c CancellationSlot
0152 /// to an object of type @c T.
0153 template <typename T, typename CancellationSlot>
0154 class cancellation_slot_binder
0155 #if !defined(GENERATING_DOCUMENTATION)
0156   : public detail::cancellation_slot_binder_result_type<T>,
0157     public detail::cancellation_slot_binder_argument_type<T>,
0158     public detail::cancellation_slot_binder_argument_types<T>
0159 #endif // !defined(GENERATING_DOCUMENTATION)
0160 {
0161 public:
0162   /// The type of the target object.
0163   typedef T target_type;
0164 
0165   /// The type of the associated cancellation slot.
0166   typedef CancellationSlot cancellation_slot_type;
0167 
0168 #if defined(GENERATING_DOCUMENTATION)
0169   /// The return type if a function.
0170   /**
0171    * The type of @c result_type is based on the type @c T of the wrapper's
0172    * target object:
0173    *
0174    * @li if @c T is a pointer to function type, @c result_type is a synonym for
0175    * the return type of @c T;
0176    *
0177    * @li if @c T is a class type with a member type @c result_type, then @c
0178    * result_type is a synonym for @c T::result_type;
0179    *
0180    * @li otherwise @c result_type is not defined.
0181    */
0182   typedef see_below result_type;
0183 
0184   /// The type of the function's argument.
0185   /**
0186    * The type of @c argument_type is based on the type @c T of the wrapper's
0187    * target object:
0188    *
0189    * @li if @c T is a pointer to a function type accepting a single argument,
0190    * @c argument_type is a synonym for the return type of @c T;
0191    *
0192    * @li if @c T is a class type with a member type @c argument_type, then @c
0193    * argument_type is a synonym for @c T::argument_type;
0194    *
0195    * @li otherwise @c argument_type is not defined.
0196    */
0197   typedef see_below argument_type;
0198 
0199   /// The type of the function's first argument.
0200   /**
0201    * The type of @c first_argument_type is based on the type @c T of the
0202    * wrapper's target object:
0203    *
0204    * @li if @c T is a pointer to a function type accepting two arguments, @c
0205    * first_argument_type is a synonym for the return type of @c T;
0206    *
0207    * @li if @c T is a class type with a member type @c first_argument_type,
0208    * then @c first_argument_type is a synonym for @c T::first_argument_type;
0209    *
0210    * @li otherwise @c first_argument_type is not defined.
0211    */
0212   typedef see_below first_argument_type;
0213 
0214   /// The type of the function's second argument.
0215   /**
0216    * The type of @c second_argument_type is based on the type @c T of the
0217    * wrapper's target object:
0218    *
0219    * @li if @c T is a pointer to a function type accepting two arguments, @c
0220    * second_argument_type is a synonym for the return type of @c T;
0221    *
0222    * @li if @c T is a class type with a member type @c first_argument_type,
0223    * then @c second_argument_type is a synonym for @c T::second_argument_type;
0224    *
0225    * @li otherwise @c second_argument_type is not defined.
0226    */
0227   typedef see_below second_argument_type;
0228 #endif // defined(GENERATING_DOCUMENTATION)
0229 
0230   /// Construct a cancellation slot wrapper for the specified object.
0231   /**
0232    * This constructor is only valid if the type @c T is constructible from type
0233    * @c U.
0234    */
0235   template <typename U>
0236   cancellation_slot_binder(const cancellation_slot_type& s, U&& u)
0237     : slot_(s),
0238       target_(static_cast<U&&>(u))
0239   {
0240   }
0241 
0242   /// Copy constructor.
0243   cancellation_slot_binder(const cancellation_slot_binder& other)
0244     : slot_(other.get_cancellation_slot()),
0245       target_(other.get())
0246   {
0247   }
0248 
0249   /// Construct a copy, but specify a different cancellation slot.
0250   cancellation_slot_binder(const cancellation_slot_type& s,
0251       const cancellation_slot_binder& other)
0252     : slot_(s),
0253       target_(other.get())
0254   {
0255   }
0256 
0257   /// Construct a copy of a different cancellation slot wrapper type.
0258   /**
0259    * This constructor is only valid if the @c CancellationSlot type is
0260    * constructible from type @c OtherCancellationSlot, and the type @c T is
0261    * constructible from type @c U.
0262    */
0263   template <typename U, typename OtherCancellationSlot>
0264   cancellation_slot_binder(
0265       const cancellation_slot_binder<U, OtherCancellationSlot>& other,
0266       constraint_t<is_constructible<CancellationSlot,
0267         OtherCancellationSlot>::value> = 0,
0268       constraint_t<is_constructible<T, U>::value> = 0)
0269     : slot_(other.get_cancellation_slot()),
0270       target_(other.get())
0271   {
0272   }
0273 
0274   /// Construct a copy of a different cancellation slot wrapper type, but
0275   /// specify a different cancellation slot.
0276   /**
0277    * This constructor is only valid if the type @c T is constructible from type
0278    * @c U.
0279    */
0280   template <typename U, typename OtherCancellationSlot>
0281   cancellation_slot_binder(const cancellation_slot_type& s,
0282       const cancellation_slot_binder<U, OtherCancellationSlot>& other,
0283       constraint_t<is_constructible<T, U>::value> = 0)
0284     : slot_(s),
0285       target_(other.get())
0286   {
0287   }
0288 
0289   /// Move constructor.
0290   cancellation_slot_binder(cancellation_slot_binder&& other)
0291     : slot_(static_cast<cancellation_slot_type&&>(
0292           other.get_cancellation_slot())),
0293       target_(static_cast<T&&>(other.get()))
0294   {
0295   }
0296 
0297   /// Move construct the target object, but specify a different cancellation
0298   /// slot.
0299   cancellation_slot_binder(const cancellation_slot_type& s,
0300       cancellation_slot_binder&& other)
0301     : slot_(s),
0302       target_(static_cast<T&&>(other.get()))
0303   {
0304   }
0305 
0306   /// Move construct from a different cancellation slot wrapper type.
0307   template <typename U, typename OtherCancellationSlot>
0308   cancellation_slot_binder(
0309       cancellation_slot_binder<U, OtherCancellationSlot>&& other,
0310       constraint_t<is_constructible<CancellationSlot,
0311         OtherCancellationSlot>::value> = 0,
0312       constraint_t<is_constructible<T, U>::value> = 0)
0313     : slot_(static_cast<OtherCancellationSlot&&>(
0314           other.get_cancellation_slot())),
0315       target_(static_cast<U&&>(other.get()))
0316   {
0317   }
0318 
0319   /// Move construct from a different cancellation slot wrapper type, but
0320   /// specify a different cancellation slot.
0321   template <typename U, typename OtherCancellationSlot>
0322   cancellation_slot_binder(const cancellation_slot_type& s,
0323       cancellation_slot_binder<U, OtherCancellationSlot>&& other,
0324       constraint_t<is_constructible<T, U>::value> = 0)
0325     : slot_(s),
0326       target_(static_cast<U&&>(other.get()))
0327   {
0328   }
0329 
0330   /// Destructor.
0331   ~cancellation_slot_binder()
0332   {
0333   }
0334 
0335   /// Obtain a reference to the target object.
0336   target_type& get() noexcept
0337   {
0338     return target_;
0339   }
0340 
0341   /// Obtain a reference to the target object.
0342   const target_type& get() const noexcept
0343   {
0344     return target_;
0345   }
0346 
0347   /// Obtain the associated cancellation slot.
0348   cancellation_slot_type get_cancellation_slot() const noexcept
0349   {
0350     return slot_;
0351   }
0352 
0353   /// Forwarding function call operator.
0354   template <typename... Args>
0355   result_of_t<T(Args...)> operator()(Args&&... args) &
0356   {
0357     return target_(static_cast<Args&&>(args)...);
0358   }
0359 
0360   /// Forwarding function call operator.
0361   template <typename... Args>
0362   result_of_t<T(Args...)> operator()(Args&&... args) &&
0363   {
0364     return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);
0365   }
0366 
0367   /// Forwarding function call operator.
0368   template <typename... Args>
0369   result_of_t<T(Args...)> operator()(Args&&... args) const&
0370   {
0371     return target_(static_cast<Args&&>(args)...);
0372   }
0373 
0374 private:
0375   CancellationSlot slot_;
0376   T target_;
0377 };
0378 
0379 /// A function object type that adapts a @ref completion_token to specify that
0380 /// the completion handler should have the supplied cancellation slot as its
0381 /// associated cancellation slot.
0382 /**
0383  * May also be used directly as a completion token, in which case it adapts the
0384  * asynchronous operation's default completion token (or boost::asio::deferred
0385  * if no default is available).
0386  */
0387 template <typename CancellationSlot>
0388 struct partial_cancellation_slot_binder
0389 {
0390   /// Constructor that specifies associated cancellation slot.
0391   explicit partial_cancellation_slot_binder(const CancellationSlot& ex)
0392     : cancellation_slot_(ex)
0393   {
0394   }
0395 
0396   /// Adapt a @ref completion_token to specify that the completion handler
0397   /// should have the cancellation slot as its associated cancellation slot.
0398   template <typename CompletionToken>
0399   BOOST_ASIO_NODISCARD inline
0400   constexpr cancellation_slot_binder<decay_t<CompletionToken>, CancellationSlot>
0401   operator()(CompletionToken&& completion_token) const
0402   {
0403     return cancellation_slot_binder<decay_t<CompletionToken>, CancellationSlot>(
0404         static_cast<CompletionToken&&>(completion_token), cancellation_slot_);
0405   }
0406 
0407 //private:
0408   CancellationSlot cancellation_slot_;
0409 };
0410 
0411 /// Create a partial completion token that associates a cancellation slot.
0412 template <typename CancellationSlot>
0413 BOOST_ASIO_NODISCARD inline partial_cancellation_slot_binder<CancellationSlot>
0414 bind_cancellation_slot(const CancellationSlot& ex)
0415 {
0416   return partial_cancellation_slot_binder<CancellationSlot>(ex);
0417 }
0418 
0419 /// Associate an object of type @c T with a cancellation slot of type
0420 /// @c CancellationSlot.
0421 template <typename CancellationSlot, typename T>
0422 BOOST_ASIO_NODISCARD inline
0423 cancellation_slot_binder<decay_t<T>, CancellationSlot>
0424 bind_cancellation_slot(const CancellationSlot& s, T&& t)
0425 {
0426   return cancellation_slot_binder<decay_t<T>, CancellationSlot>(
0427       s, static_cast<T&&>(t));
0428 }
0429 
0430 #if !defined(GENERATING_DOCUMENTATION)
0431 
0432 namespace detail {
0433 
0434 template <typename TargetAsyncResult,
0435     typename CancellationSlot, typename = void>
0436 class cancellation_slot_binder_completion_handler_async_result
0437 {
0438 public:
0439   template <typename T>
0440   explicit cancellation_slot_binder_completion_handler_async_result(T&)
0441   {
0442   }
0443 };
0444 
0445 template <typename TargetAsyncResult, typename CancellationSlot>
0446 class cancellation_slot_binder_completion_handler_async_result<
0447     TargetAsyncResult, CancellationSlot,
0448     void_t<typename TargetAsyncResult::completion_handler_type>>
0449 {
0450 private:
0451   TargetAsyncResult target_;
0452 
0453 public:
0454   typedef cancellation_slot_binder<
0455     typename TargetAsyncResult::completion_handler_type, CancellationSlot>
0456       completion_handler_type;
0457 
0458   explicit cancellation_slot_binder_completion_handler_async_result(
0459       typename TargetAsyncResult::completion_handler_type& handler)
0460     : target_(handler)
0461   {
0462   }
0463 
0464   auto get() -> decltype(target_.get())
0465   {
0466     return target_.get();
0467   }
0468 };
0469 
0470 template <typename TargetAsyncResult, typename = void>
0471 struct cancellation_slot_binder_async_result_return_type
0472 {
0473 };
0474 
0475 template <typename TargetAsyncResult>
0476 struct cancellation_slot_binder_async_result_return_type<
0477     TargetAsyncResult, void_t<typename TargetAsyncResult::return_type>>
0478 {
0479   typedef typename TargetAsyncResult::return_type return_type;
0480 };
0481 
0482 } // namespace detail
0483 
0484 template <typename T, typename CancellationSlot, typename Signature>
0485 class async_result<cancellation_slot_binder<T, CancellationSlot>, Signature> :
0486   public detail::cancellation_slot_binder_completion_handler_async_result<
0487       async_result<T, Signature>, CancellationSlot>,
0488   public detail::cancellation_slot_binder_async_result_return_type<
0489       async_result<T, Signature>>
0490 {
0491 public:
0492   explicit async_result(cancellation_slot_binder<T, CancellationSlot>& b)
0493     : detail::cancellation_slot_binder_completion_handler_async_result<
0494         async_result<T, Signature>, CancellationSlot>(b.get())
0495   {
0496   }
0497 
0498   template <typename Initiation>
0499   struct init_wrapper : detail::initiation_base<Initiation>
0500   {
0501     using detail::initiation_base<Initiation>::initiation_base;
0502 
0503     template <typename Handler, typename... Args>
0504     void operator()(Handler&& handler,
0505         const CancellationSlot& slot, Args&&... args) &&
0506     {
0507       static_cast<Initiation&&>(*this)(
0508           cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(
0509               slot, static_cast<Handler&&>(handler)),
0510           static_cast<Args&&>(args)...);
0511     }
0512 
0513     template <typename Handler, typename... Args>
0514     void operator()(Handler&& handler,
0515         const CancellationSlot& slot, Args&&... args) const &
0516     {
0517       static_cast<const Initiation&>(*this)(
0518           cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(
0519               slot, static_cast<Handler&&>(handler)),
0520           static_cast<Args&&>(args)...);
0521     }
0522   };
0523 
0524   template <typename Initiation, typename RawCompletionToken, typename... Args>
0525   static auto initiate(Initiation&& initiation,
0526       RawCompletionToken&& token, Args&&... args)
0527     -> decltype(
0528       async_initiate<
0529         conditional_t<
0530           is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,
0531         Signature>(
0532         declval<init_wrapper<decay_t<Initiation>>>(),
0533         token.get(), token.get_cancellation_slot(),
0534         static_cast<Args&&>(args)...))
0535   {
0536     return async_initiate<
0537       conditional_t<
0538         is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,
0539       Signature>(
0540         init_wrapper<decay_t<Initiation>>(
0541           static_cast<Initiation&&>(initiation)),
0542         token.get(), token.get_cancellation_slot(),
0543         static_cast<Args&&>(args)...);
0544   }
0545 
0546 private:
0547   async_result(const async_result&) = delete;
0548   async_result& operator=(const async_result&) = delete;
0549 
0550   async_result<T, Signature> target_;
0551 };
0552 
0553 template <typename CancellationSlot, typename... Signatures>
0554 struct async_result<partial_cancellation_slot_binder<CancellationSlot>,
0555     Signatures...>
0556 {
0557   template <typename Initiation, typename RawCompletionToken, typename... Args>
0558   static auto initiate(Initiation&& initiation,
0559       RawCompletionToken&& token, Args&&... args)
0560     -> decltype(
0561       async_initiate<Signatures...>(
0562         static_cast<Initiation&&>(initiation),
0563         cancellation_slot_binder<
0564           default_completion_token_t<associated_executor_t<Initiation>>,
0565           CancellationSlot>(token.cancellation_slot_,
0566             default_completion_token_t<associated_executor_t<Initiation>>{}),
0567         static_cast<Args&&>(args)...))
0568   {
0569     return async_initiate<Signatures...>(
0570         static_cast<Initiation&&>(initiation),
0571         cancellation_slot_binder<
0572           default_completion_token_t<associated_executor_t<Initiation>>,
0573           CancellationSlot>(token.cancellation_slot_,
0574             default_completion_token_t<associated_executor_t<Initiation>>{}),
0575         static_cast<Args&&>(args)...);
0576   }
0577 };
0578 
0579 template <template <typename, typename> class Associator,
0580     typename T, typename CancellationSlot, typename DefaultCandidate>
0581 struct associator<Associator,
0582     cancellation_slot_binder<T, CancellationSlot>,
0583     DefaultCandidate>
0584   : Associator<T, DefaultCandidate>
0585 {
0586   static typename Associator<T, DefaultCandidate>::type get(
0587       const cancellation_slot_binder<T, CancellationSlot>& b) noexcept
0588   {
0589     return Associator<T, DefaultCandidate>::get(b.get());
0590   }
0591 
0592   static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,
0593       const DefaultCandidate& c) noexcept
0594     -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))
0595   {
0596     return Associator<T, DefaultCandidate>::get(b.get(), c);
0597   }
0598 };
0599 
0600 template <typename T, typename CancellationSlot, typename CancellationSlot1>
0601 struct associated_cancellation_slot<
0602     cancellation_slot_binder<T, CancellationSlot>,
0603     CancellationSlot1>
0604 {
0605   typedef CancellationSlot type;
0606 
0607   static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,
0608       const CancellationSlot1& = CancellationSlot1()) noexcept
0609     -> decltype(b.get_cancellation_slot())
0610   {
0611     return b.get_cancellation_slot();
0612   }
0613 };
0614 
0615 #endif // !defined(GENERATING_DOCUMENTATION)
0616 
0617 } // namespace asio
0618 } // namespace boost
0619 
0620 #include <boost/asio/detail/pop_options.hpp>
0621 
0622 #endif // BOOST_ASIO_BIND_CANCELLATION_SLOT_HPP