13 Asynchronous model [async]

13.14 Class template executor_binder [async.exec.binder]

The class template executor_binder binds executors to objects. A specialization executor_binder<T, Executor> binds an executor of type Executor satisfying the Executor requirements ([async.reqmts.executor]) to an object or function of type T.

namespace std {
namespace experimental {
namespace net {
inline namespace v1 {

  template<class T, class Executor>
  class executor_binder
  {
  public:
    // types:

    using target_type = T;
    using executor_type = Executor;

    // [async.exec.binder.cons], construct / copy / destroy:

    executor_binder(T t, const Executor& ex);
    executor_binder(const executor_binder& other) = default;
    executor_binder(executor_binder&& other) = default;
    template<class U, class OtherExecutor>
      executor_binder(const executor_binder<U, OtherExecutor>& other);
    template<class U, class OtherExecutor>
      executor_binder(executor_binder<U, OtherExecutor>&& other);
    template<class U, class OtherExecutor>
      executor_binder(executor_arg_t, const Executor& ex,
        const executor_binder<U, OtherExecutor>& other);
    template<class U, class OtherExecutor>
      executor_binder(executor_arg_t, const Executor& ex,
        executor_binder<U, OtherExecutor>&& other);

    ~executor_binder();

    // [async.exec.binder.access], executor binder access:

    T& get() noexcept;
    const T& get() const noexcept;
    executor_type get_executor() const noexcept;

    // [async.exec.binder.invocation], executor binder invocation:

    template<class... Args>
      result_of_t<T&(Args&&...)> operator()(Args&&... args);
    template<class... Args>
      result_of_t<const T&(Args&&...)> operator()(Args&&... args) const;

  private:
    Executor ex_; // exposition only
    T target_; // exposition only
  };

  template<class T, class Executor, class Signature>
    class async_result<executor_binder<T, Executor>, Signature>;

  template<class T, class Executor, class ProtoAllocator>
    struct associated_allocator<executor_binder<T, Executor>, ProtoAllocator>;

  template<class T, class Executor, class Executor1>
    struct associated_executor<executor_binder<T, Executor>, Executor1>;

} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std

13.14.1 executor_binder constructors [async.exec.binder.cons]

executor_binder(T t, const Executor& ex);

Effects: Initializes ex_ with ex. Initializes target_ by performing uses-executor construction, using the constructor argument std::move(t) and the executor ex_.

template<class U, class OtherExecutor> executor_binder(const executor_binder<U, OtherExecutor>& other);

Requires: If U is not convertible to T, or if OtherExecutor is not convertible to Executor, the program is ill-formed.

Effects: Initializes ex_ with other.get_executor(). Initializes target_ by performing uses-executor construction, using the constructor argument other.get() and the executor ex_.

template<class U, class OtherExecutor> executor_binder(executor_binder<U, OtherExecutor>&& other);

Requires: If U is not convertible to T, or if OtherExecutor is not convertible to Executor, the program is ill-formed.

Effects: Initializes ex_ with other.get_executor(). Initializes target_ by performing uses-executor construction, using the constructor argument std::move(other.get()) and the executor ex_.

template<class U, class OtherExecutor> executor_binder(executor_arg_t, const Executor& ex, const executor_binder<U, OtherExecutor>& other);

Requires: If U is not convertible to T the program is ill-formed.

Effects: Initializes ex_ with ex. Initializes target_ by performing uses-executor construction, using the constructor argument other.get() and the executor ex_.

template<class U, class OtherExecutor> executor_binder(executor_arg_t, const Executor& ex, executor_binder<U, OtherExecutor>&& other);

Requires: U is T or convertible to T.

Effects: Initializes ex_ with ex. Initializes target_ by performing uses-executor construction, using the constructor argument std::move(other.get()) and the executor ex_.

13.14.2 executor_binder access [async.exec.binder.access]

T& get() noexcept; const T& get() const noexcept;

Returns: target_.

executor_type get_executor() const noexcept;

Returns: executor_.

13.14.3 executor_binder invocation [async.exec.binder.invocation]

template<class... Args> result_of_t<T&(Args&&...)> operator()(Args&&... args); template<class... Args> result_of_t<const T&(Args&&...)> operator()(Args&&... args) const;

Returns: INVOKE(get(), forward<Args>(args)...) (C++ 2014 [func.require]).

13.14.4 Class template partial specialization async_result [async.exec.binder.async.result]

namespace std {
namespace experimental {
namespace net {
inline namespace v1 {

  template<class T, class Executor, class Signature>
  class async_result<executor_binder<T, Executor>, Signature>
  {
  public:
    using completion_handler_type = executor_binder<
      typename async_result<T, Signature>::completion_handler_type,
        Executor>;
    using return_type = typename async_result<T, Signature>::return_type;

    explicit async_result(completion_handler_type& h);
    async_result(const async_result&) = delete;
    async_result& operator=(const async_result&) = delete;

    return_type get();

  private:
    async_result<T, Signature> target_; // exposition only
  };

} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std

explicit async_result(completion_handler_type& h);

Effects: Initializes target_ as target_(h.get()).

return_type get();

Returns: target_.get().

13.14.5 Class template partial specialization associated_allocator [async.exec.binder.assoc.alloc]

namespace std {
namespace experimental {
namespace net {
inline namespace v1 {

  template<class T, class Executor, class ProtoAllocator>
    struct associated_allocator<executor_binder<T, Executor>, ProtoAllocator>
  {
    using type = associated_allocator_t<T, ProtoAllocator>;

    static type get(const executor_binder<T, Executor>& b,
                    const ProtoAllocator& a = ProtoAllocator()) noexcept;
  };

} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std

static type get(const executor_binder<T, Executor>& b, const ProtoAllocator& a = ProtoAllocator()) noexcept;

Returns: associated_allocator<T, ProtoAllocator>::get(b.get(), a).

13.14.6 Class template partial specialization associated_executor [async.exec.binder.assoc.exec]

namespace std {
namespace experimental {
namespace net {
inline namespace v1 {

  template<class T, class Executor, class Executor1>
    struct associated_executor<executor_binder<T, Executor>, Executor1>
  {
    using type = Executor;

    static type get(const executor_binder<T, Executor>& b,
                    const Executor1& e = Executor1()) noexcept;
  };

} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std

static type get(const executor_binder<T, Executor>& b, const Executor1& e = Executor1()) noexcept;

Returns: b.get_executor().