13 Asynchronous model [async]

13.26 Class template use_future_t [async.use.future]

The class template use_future_t defines a set of types that, when passed as a completion token ([async.reqmts.async.token]) to an asynchronous operation's initiating function, cause the result of the asynchronous operation to be delivered via a future (C++ 2014 [futures.uniquefuture]).

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

  template<class ProtoAllocator = allocator<void>>
  class use_future_t
  {
  public:
    // use_future_t types:
    using allocator_type = ProtoAllocator;

    // use_future_t members:
    constexpr use_future_t() noexcept(noexcept(allocator_type()));
    explicit use_future_t(const allocator_type& a) noexcept;
    template<class OtherProtoAllocator> use_future_t<OtherProtoAllocator>
      rebind(const OtherProtoAllocator& a) const noexcept;
    allocator_type get_allocator() const noexcept;
    template <class F> unspecified operator()(F&& f) const;
  };

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

13.26.1 use_future_t constructors [async.use.future.cons]

constexpr use_future_t() noexcept(noexcept(allocator_type()));

Effects: Constructs a use_future_t with a default-constructed allocator.

explicit use_future_t(const allocator_type& a) noexcept;

Postconditions: get_allocator() == a.

13.26.2 use_future_t members [async.use.future.members]

template<class OtherProtoAllocator> use_future_t<OtherProtoAllocator> rebind(const OtherProtoAllocator& a) const noexcept;

Returns: A use_future_t object where get_allocator() == a.

allocator_type get_allocator() const noexcept;

Returns: The associated allocator object.

template <class F> unspecified operator()(F&& f) const;

Let T be a completion token type. Let H be a completion handler type and let h be an object of type H. Let FD be the type decay_t<F> and let fd be an lvalue of type FD constructed with std::forward<F>(f). Let R(Args...) be the completion signature of an asynchronous operation using H and let N be sizeof...(Args). Let i be in the range [0, N) and let Ai be the ith type in Args. Let ai be the argument associated with Ai.

Returns: A completion token t of type T.

Remarks: The return type T satisfies the Destructible (C++ 2014 [destructible]) and MoveConstructible (C++ 2014 [moveconstructible]) requirements.

The object h of type H is an asynchronous provider with an associated shared state (C++ 2014 [futures.state]). The effect of h(a0, ..., aN-1) is to atomically store the result of INVOKE(fd, forward<A0>(a0), ..., forward<AN-1>(aN-1)) (C++ 2014 [func.require]) in the shared state and make the shared state ready. If fd exits via an exception then that exception is atomically stored in the shared state and the shared state is made ready.

The implementation provides a partial specialization template <class Result, class... Args> async_result<T, Result(Args...)> such that:

  • the nested type completion_handler_type is a type H;

  • the nested type return_type is future<result_of_t<FD(decay_t<Args>...)>>; and

  • when an object r1 of type async_result<T, Result(Args...)> is constructed from h, the expression r1.get() returns a future with the same shared state as h.

For any executor type E, the associated object for the associator associated_executor<H, E> is an executor where, for function objects executed using the executor's dispatch(), post() or defer() functions, any exception thrown is caught by a function object and stored in the associated shared state.

13.26.3 Partial class template specialization async_result for use_future_t [async.use.future.result]

template<class ProtoAllocator, class Result, class... Args>
class async_result<use_future_t<ProtoAllocator>, Result(Args...)>{
  using completion_handler_type = see below;
  using return_type =  see below;

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

  return_type get();
};

Let R be the type async_result<use_future_t<ProtoAllocator>, Result(Args...)>. Let F be the nested function object type R::completion_handler_type.

An object t1 of type F is an asynchronous provider with an associated shared state (C++ 2014 [futures.state]). The type F provides F::operator() such that the expression t1(declval<Args>()...) is well formed.

The implementation specializes associated_executor for F. For function objects executed using the associated executor's dispatch(), post() or defer() functions, any exception thrown is caught by the executor and stored in the associated shared state.

For any executor type E, the associated object for the associator associated_executor<F, E> is an executor where, for function objects executed using the executor's dispatch(), post() or defer() functions, any exception thrown by a function object is caught by the executor and stored in the associated shared state.

When an object r1 of type R is constructed from t1, the expression r1.get() returns a future with the same shared state as t1.

The type of R::return_type and the effects of F::operator() are defined in Table [tab:async.use.future.result.requirements]. After establishing these effects, F::operator() makes the shared state ready. In this table, N is the value of sizeof...(Args); let i be in the range [0, N) and let Ti be the ith type in Args; let Ui be decay_t<Ti> for each type Ti in Args; let Ai be the deduced type of the ith argument to F::operator(); and let ai be the ith argument to F::operator().

Table 10async_result<use_future_t<ProtoAllocator>, Result(Args...)> semantics
NU0R::return_typeF::operator() effects
0 future<void> None.
1 error_code future<void> If a0 evaluates to true, atomically stores the exception pointer produced by make_exception_ptr(system_error(a0)) in the shared state.
1 exception_ptr future<void> If a0 is non-null, atomically stores the exception pointer a0 in the shared state.
1 all other types future<U0> Atomically stores forward<A0>(a0) in the shared state.
2 error_code future<U1> If a0 evaluates to true, atomically stores the exception pointer produced by make_exception_ptr(system_error(a0)) in the shared state; otherwise, atomically stores forward<A1>(a1) in the shared state.
2 exception_ptr future<U1> If a0 is non-null, atomically stores the exception pointer in the shared state; otherwise, atomically stores forward<A1>(a1) in the shared state.
2 all other types future<tuple<U0, U1>> Atomically stores forward_as_tuple(
forward<A0>(a0), forward<A1>(a1))
in the shared state.
>2 error_code future<tuple<U1, , UN-1>> If a0 evaluates to true, atomically stores the exception pointer produced by make_exception_ptr(system_error(a0)) in the shared state; otherwise, atomically stores forward_as_tuple(forward<A1>(a1), , forward<AN-1>(aN-1)) in the shared state.
>2 exception_ptr future<tuple<U1, , UN-1>> If a0 is non-null, atomically stores the exception pointer in the shared state; otherwise, atomically stores forward_as_tuple(forward<A1>(a1), , forward<AN-1>(aN-1)) in the shared state.
>2 all other types future<tuple<U0, , UN-1>> Atomically stores forward_as_tuple(
forward<A0>(a0), , forward<AN-1>(aN-1))
in the shared state.