| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582 | //// bind_executor.hpp// ~~~~~~~~~~~~~~~~~//// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//#ifndef BOOST_ASIO_BIND_EXECUTOR_HPP#define BOOST_ASIO_BIND_EXECUTOR_HPP#if defined(_MSC_VER) && (_MSC_VER >= 1200)# pragma once#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)#include <boost/asio/detail/config.hpp>#include <boost/asio/detail/type_traits.hpp>#include <boost/asio/detail/variadic_templates.hpp>#include <boost/asio/associated_executor.hpp>#include <boost/asio/associated_allocator.hpp>#include <boost/asio/async_result.hpp>#include <boost/asio/execution_context.hpp>#include <boost/asio/is_executor.hpp>#include <boost/asio/uses_executor.hpp>#include <boost/asio/detail/push_options.hpp>namespace boost {namespace asio {namespace detail {template <typename T>struct executor_binder_check{  typedef void type;};// Helper to automatically define nested typedef result_type.template <typename T, typename = void>struct executor_binder_result_type{protected:  typedef void result_type_or_void;};template <typename T>struct executor_binder_result_type<T,  typename executor_binder_check<typename T::result_type>::type>{  typedef typename T::result_type result_type;protected:  typedef result_type result_type_or_void;};template <typename R>struct executor_binder_result_type<R(*)()>{  typedef R result_type;protected:  typedef result_type result_type_or_void;};template <typename R>struct executor_binder_result_type<R(&)()>{  typedef R result_type;protected:  typedef result_type result_type_or_void;};template <typename R, typename A1>struct executor_binder_result_type<R(*)(A1)>{  typedef R result_type;protected:  typedef result_type result_type_or_void;};template <typename R, typename A1>struct executor_binder_result_type<R(&)(A1)>{  typedef R result_type;protected:  typedef result_type result_type_or_void;};template <typename R, typename A1, typename A2>struct executor_binder_result_type<R(*)(A1, A2)>{  typedef R result_type;protected:  typedef result_type result_type_or_void;};template <typename R, typename A1, typename A2>struct executor_binder_result_type<R(&)(A1, A2)>{  typedef R result_type;protected:  typedef result_type result_type_or_void;};// Helper to automatically define nested typedef argument_type.template <typename T, typename = void>struct executor_binder_argument_type {};template <typename T>struct executor_binder_argument_type<T,  typename executor_binder_check<typename T::argument_type>::type>{  typedef typename T::argument_type argument_type;};template <typename R, typename A1>struct executor_binder_argument_type<R(*)(A1)>{  typedef A1 argument_type;};template <typename R, typename A1>struct executor_binder_argument_type<R(&)(A1)>{  typedef A1 argument_type;};// Helper to automatically define nested typedefs first_argument_type and// second_argument_type.template <typename T, typename = void>struct executor_binder_argument_types {};template <typename T>struct executor_binder_argument_types<T,  typename executor_binder_check<typename T::first_argument_type>::type>{  typedef typename T::first_argument_type first_argument_type;  typedef typename T::second_argument_type second_argument_type;};template <typename R, typename A1, typename A2>struct executor_binder_argument_type<R(*)(A1, A2)>{  typedef A1 first_argument_type;  typedef A2 second_argument_type;};template <typename R, typename A1, typename A2>struct executor_binder_argument_type<R(&)(A1, A2)>{  typedef A1 first_argument_type;  typedef A2 second_argument_type;};// Helper to:// - Apply the empty base optimisation to the executor.// - Perform uses_executor construction of the target type, if required.template <typename T, typename Executor, bool UsesExecutor>class executor_binder_base;template <typename T, typename Executor>class executor_binder_base<T, Executor, true>  : protected Executor{protected:  template <typename E, typename U>  executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)    : executor_(BOOST_ASIO_MOVE_CAST(E)(e)),      target_(executor_arg_t(), executor_, BOOST_ASIO_MOVE_CAST(U)(u))  {  }  Executor executor_;  T target_;};template <typename T, typename Executor>class executor_binder_base<T, Executor, false>{protected:  template <typename E, typename U>  executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)    : executor_(BOOST_ASIO_MOVE_CAST(E)(e)),      target_(BOOST_ASIO_MOVE_CAST(U)(u))  {  }  Executor executor_;  T target_;};// Helper to enable SFINAE on zero-argument operator() below.template <typename T, typename = void>struct executor_binder_result_of0{  typedef void type;};template <typename T>struct executor_binder_result_of0<T,  typename executor_binder_check<typename result_of<T()>::type>::type>{  typedef typename result_of<T()>::type type;};} // namespace detail/// A call wrapper type to bind an executor of type @c Executor to an object of/// type @c T.template <typename T, typename Executor>class executor_binder#if !defined(GENERATING_DOCUMENTATION)  : public detail::executor_binder_result_type<T>,    public detail::executor_binder_argument_type<T>,    public detail::executor_binder_argument_types<T>,    private detail::executor_binder_base<      T, Executor, uses_executor<T, Executor>::value>#endif // !defined(GENERATING_DOCUMENTATION){public:  /// The type of the target object.  typedef T target_type;  /// The type of the associated executor.  typedef Executor executor_type;#if defined(GENERATING_DOCUMENTATION)  /// The return type if a function.  /**   * The type of @c result_type is based on the type @c T of the wrapper's   * target object:   *   * @li if @c T is a pointer to function type, @c result_type is a synonym for   * the return type of @c T;   *   * @li if @c T is a class type with a member type @c result_type, then @c   * result_type is a synonym for @c T::result_type;   *   * @li otherwise @c result_type is not defined.   */  typedef see_below result_type;  /// The type of the function's argument.  /**   * The type of @c argument_type is based on the type @c T of the wrapper's   * target object:   *   * @li if @c T is a pointer to a function type accepting a single argument,   * @c argument_type is a synonym for the return type of @c T;   *   * @li if @c T is a class type with a member type @c argument_type, then @c   * argument_type is a synonym for @c T::argument_type;   *   * @li otherwise @c argument_type is not defined.   */  typedef see_below argument_type;  /// The type of the function's first argument.  /**   * The type of @c first_argument_type is based on the type @c T of the   * wrapper's target object:   *   * @li if @c T is a pointer to a function type accepting two arguments, @c   * first_argument_type is a synonym for the return type of @c T;   *   * @li if @c T is a class type with a member type @c first_argument_type,   * then @c first_argument_type is a synonym for @c T::first_argument_type;   *   * @li otherwise @c first_argument_type is not defined.   */  typedef see_below first_argument_type;  /// The type of the function's second argument.  /**   * The type of @c second_argument_type is based on the type @c T of the   * wrapper's target object:   *   * @li if @c T is a pointer to a function type accepting two arguments, @c   * second_argument_type is a synonym for the return type of @c T;   *   * @li if @c T is a class type with a member type @c first_argument_type,   * then @c second_argument_type is a synonym for @c T::second_argument_type;   *   * @li otherwise @c second_argument_type is not defined.   */  typedef see_below second_argument_type;#endif // defined(GENERATING_DOCUMENTATION)  /// Construct an executor wrapper for the specified object.  /**   * This constructor is only valid if the type @c T is constructible from type   * @c U.   */  template <typename U>  executor_binder(executor_arg_t, const executor_type& e,      BOOST_ASIO_MOVE_ARG(U) u)    : base_type(e, BOOST_ASIO_MOVE_CAST(U)(u))  {  }  /// Copy constructor.  executor_binder(const executor_binder& other)    : base_type(other.get_executor(), other.get())  {  }  /// Construct a copy, but specify a different executor.  executor_binder(executor_arg_t, const executor_type& e,      const executor_binder& other)    : base_type(e, other.get())  {  }  /// Construct a copy of a different executor wrapper type.  /**   * This constructor is only valid if the @c Executor type is constructible   * from type @c OtherExecutor, and the type @c T is constructible from type   * @c U.   */  template <typename U, typename OtherExecutor>  executor_binder(const executor_binder<U, OtherExecutor>& other)    : base_type(other.get_executor(), other.get())  {  }  /// Construct a copy of a different executor wrapper type, but specify a  /// different executor.  /**   * This constructor is only valid if the type @c T is constructible from type   * @c U.   */  template <typename U, typename OtherExecutor>  executor_binder(executor_arg_t, const executor_type& e,      const executor_binder<U, OtherExecutor>& other)    : base_type(e, other.get())  {  }#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  /// Move constructor.  executor_binder(executor_binder&& other)    : base_type(BOOST_ASIO_MOVE_CAST(executor_type)(other.get_executor()),        BOOST_ASIO_MOVE_CAST(T)(other.get()))  {  }  /// Move construct the target object, but specify a different executor.  executor_binder(executor_arg_t, const executor_type& e,      executor_binder&& other)    : base_type(e, BOOST_ASIO_MOVE_CAST(T)(other.get()))  {  }  /// Move construct from a different executor wrapper type.  template <typename U, typename OtherExecutor>  executor_binder(executor_binder<U, OtherExecutor>&& other)    : base_type(BOOST_ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()),        BOOST_ASIO_MOVE_CAST(U)(other.get()))  {  }  /// Move construct from a different executor wrapper type, but specify a  /// different executor.  template <typename U, typename OtherExecutor>  executor_binder(executor_arg_t, const executor_type& e,      executor_binder<U, OtherExecutor>&& other)    : base_type(e, BOOST_ASIO_MOVE_CAST(U)(other.get()))  {  }#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  /// Destructor.  ~executor_binder()  {  }  /// Obtain a reference to the target object.  target_type& get() BOOST_ASIO_NOEXCEPT  {    return this->target_;  }  /// Obtain a reference to the target object.  const target_type& get() const BOOST_ASIO_NOEXCEPT  {    return this->target_;  }  /// Obtain the associated executor.  executor_type get_executor() const BOOST_ASIO_NOEXCEPT  {    return this->executor_;  }#if defined(GENERATING_DOCUMENTATION)  template <typename... Args> auto operator()(Args&& ...);  template <typename... Args> auto operator()(Args&& ...) const;#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)  /// Forwarding function call operator.  template <typename... Args>  typename result_of<T(Args...)>::type operator()(      BOOST_ASIO_MOVE_ARG(Args)... args)  {    return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);  }  /// Forwarding function call operator.  template <typename... Args>  typename result_of<T(Args...)>::type operator()(      BOOST_ASIO_MOVE_ARG(Args)... args) const  {    return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);  }#elif defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)  typename detail::executor_binder_result_of0<T>::type operator()()  {    return this->target_();  }  typename detail::executor_binder_result_of0<T>::type operator()() const  {    return this->target_();  }#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \  typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \  { \    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \  } \  \  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \  typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \  { \    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \  } \  /**/  BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF#else // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)  typedef typename detail::executor_binder_result_type<T>::result_type_or_void    result_type_or_void;  result_type_or_void operator()()  {    return this->target_();  }  result_type_or_void operator()() const  {    return this->target_();  }#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \  result_type_or_void operator()( \      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \  { \    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \  } \  \  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \  result_type_or_void operator()( \      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \  { \    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \  } \  /**/  BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF#endif // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)private:  typedef detail::executor_binder_base<T, Executor,    uses_executor<T, Executor>::value> base_type;};/// Associate an object of type @c T with an executor of type @c Executor.template <typename Executor, typename T>inline executor_binder<typename decay<T>::type, Executor>bind_executor(const Executor& ex, BOOST_ASIO_MOVE_ARG(T) t,    typename enable_if<is_executor<Executor>::value>::type* = 0){  return executor_binder<typename decay<T>::type, Executor>(      executor_arg_t(), ex, BOOST_ASIO_MOVE_CAST(T)(t));}/// Associate an object of type @c T with an execution context's executor.template <typename ExecutionContext, typename T>inline executor_binder<typename decay<T>::type,  typename ExecutionContext::executor_type>bind_executor(ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(T) t,    typename enable_if<is_convertible<      ExecutionContext&, execution_context&>::value>::type* = 0){  return executor_binder<typename decay<T>::type,    typename ExecutionContext::executor_type>(      executor_arg_t(), ctx.get_executor(), BOOST_ASIO_MOVE_CAST(T)(t));}#if !defined(GENERATING_DOCUMENTATION)template <typename T, typename Executor>struct uses_executor<executor_binder<T, Executor>, Executor>  : true_type {};template <typename T, typename Executor, typename Signature>class async_result<executor_binder<T, Executor>, Signature>{public:  typedef executor_binder<    typename async_result<T, Signature>::completion_handler_type, Executor>      completion_handler_type;  typedef typename async_result<T, Signature>::return_type return_type;  explicit async_result(executor_binder<T, Executor>& b)    : target_(b.get())  {  }  return_type get()  {    return target_.get();  }private:  async_result(const async_result&) BOOST_ASIO_DELETED;  async_result& operator=(const async_result&) BOOST_ASIO_DELETED;  async_result<T, Signature> target_;};template <typename T, typename Executor, typename Allocator>struct associated_allocator<executor_binder<T, Executor>, Allocator>{  typedef typename associated_allocator<T, Allocator>::type type;  static type get(const executor_binder<T, Executor>& b,      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT  {    return associated_allocator<T, Allocator>::get(b.get(), a);  }};template <typename T, typename Executor, typename Executor1>struct associated_executor<executor_binder<T, Executor>, Executor1>{  typedef Executor type;  static type get(const executor_binder<T, Executor>& b,      const Executor1& = Executor1()) BOOST_ASIO_NOEXCEPT  {    return b.get_executor();  }};#endif // !defined(GENERATING_DOCUMENTATION)} // namespace asio} // namespace boost#include <boost/asio/detail/pop_options.hpp>#endif // BOOST_ASIO_BIND_EXECUTOR_HPP
 |