13 Asynchronous model [async]

13.1 Header <experimental/executor> synopsis [async.synop]

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

  template<class CompletionToken, class Signature>
    class async_result;

  template<class CompletionToken, class Signature>
    struct async_completion;

  template<class T, class ProtoAllocator = allocator<void>>
    struct associated_allocator;

  template<class T, class ProtoAllocator = allocator<void>>
    using associated_allocator_t = typename associated_allocator<T, ProtoAllocator>::type;

  // [async.assoc.alloc.get], get_associated_allocator:

  template<class T>
    associated_allocator_t<T> get_associated_allocator(const T& t) noexcept;
  template<class T, class ProtoAllocator>
    associated_allocator_t<T, ProtoAllocator>
      get_associated_allocator(const T& t, const ProtoAllocator& a) noexcept;

  enum class fork_event {
    prepare,
    parent,
    child
  };

  class execution_context;

  class service_already_exists;

  template<class Service> Service& use_service(execution_context& ctx);
  template<class Service, class... Args> Service&
    make_service(execution_context& ctx, Args&&... args);
  template<class Service> bool has_service(execution_context& ctx) noexcept;

  template<class T> struct is_executor;

  template<class T>
    constexpr bool is_executor_v = is_executor<T>::value;

  struct executor_arg_t { };
  constexpr executor_arg_t executor_arg = executor_arg_t();

  template<class T, class Executor> struct uses_executor;

  template<class T, class Executor>
    constexpr bool uses_executor_v = uses_executor<T, Executor>::value;

  template<class T, class Executor = system_executor>
    struct associated_executor;

  template<class T, class Executor = system_executor>
    using associated_executor_t = typename associated_executor<T, Executor>::type;

  // [async.assoc.exec.get], get_associated_executor:

  template<class T>
    associated_executor_t<T> get_associated_executor(const T& t) noexcept;
  template<class T, class Executor>
    associated_executor_t<T, Executor>
      get_associated_executor(const T& t, const Executor& ex) noexcept;
  template<class T, class ExecutionContext>
    associated_executor_t<T, typename ExecutionContext::executor_type>
      get_associated_executor(const T& t, ExecutionContext& ctx) noexcept;

  template<class T, class Executor>
    class executor_binder;

  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>;

  // [async.bind.executor], bind_executor:

  template<class Executor, class T>
    executor_binder<decay_t<T>, Executor>
      bind_executor(const Executor& ex, T&& t);
  template<class ExecutionContext, class T>
    executor_binder<decay_t<T>, typename ExecutionContext::executor_type>
      bind_executor(ExecutionContext& ctx, T&& t);

  template<class Executor>
    class executor_work_guard;

  // [async.make.work.guard], make_work_guard:

  template<class Executor>
    executor_work_guard<Executor>
      make_work_guard(const Executor& ex);
  template<class ExecutionContext>
    executor_work_guard<typename ExecutionContext::executor_type>
      make_work_guard(ExecutionContext& ctx);
  template<class T>
    executor_work_guard<associated_executor_t<T>>
      make_work_guard(const T& t);
  template<class T, class U>
    auto make_work_guard(const T& t, U&& u)
      -> decltype(make_work_guard(get_associated_executor(t, forward<U>(u))));

  class system_executor;
  class system_context;

  bool operator==(const system_executor&, const system_executor&);
  bool operator!=(const system_executor&, const system_executor&);

  class bad_executor;

  class executor;

  bool operator==(const executor& a, const executor& b) noexcept;
  bool operator==(const executor& e, nullptr_t) noexcept;
  bool operator==(nullptr_t, const executor& e) noexcept;
  bool operator!=(const executor& a, const executor& b) noexcept;
  bool operator!=(const executor& e, nullptr_t) noexcept;
  bool operator!=(nullptr_t, const executor& e) noexcept;

  // [async.dispatch], dispatch:

  template<class CompletionToken>
    DEDUCED dispatch(CompletionToken&& token);
  template<class Executor, class CompletionToken>
    DEDUCED dispatch(const Executor& ex, CompletionToken&& token);
  template<class ExecutionContext, class CompletionToken>
    DEDUCED dispatch(ExecutionContext& ctx, CompletionToken&& token);

  // [async.post], post:

  template<class CompletionToken>
    DEDUCED post(CompletionToken&& token);
  template<class Executor, class CompletionToken>
    DEDUCED post(const Executor& ex, CompletionToken&& token);
  template<class ExecutionContext, class CompletionToken>
    DEDUCED post(ExecutionContext& ctx, CompletionToken&& token);

  // [async.defer], defer:

  template<class CompletionToken>
    DEDUCED defer(CompletionToken&& token);
  template<class Executor, class CompletionToken>
    DEDUCED defer(const Executor& ex, CompletionToken&& token);
  template<class ExecutionContext, class CompletionToken>
    DEDUCED defer(ExecutionContext& ctx, CompletionToken&& token);

  template<class Executor>
    class strand;

  template<class Executor>
    bool operator==(const strand<Executor>& a, const strand<Executor>& b);
  template<class Executor>
    bool operator!=(const strand<Executor>& a, const strand<Executor>& b);

  template<class ProtoAllocator = allocator<void>>
    class use_future_t;

  constexpr use_future_t<> use_future = use_future_t<>();

  template<class ProtoAllocator, class Result, class... Args>
    class async_result<use_future_t<ProtoAllocator>, Result(Args...)>;

  template<class Result, class... Args, class Signature>
    class async_result<packaged_task<Result(Args...)>, Signature>;

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

  template<class Allocator>
    struct uses_allocator<experimental::net::v1::executor, Allocator>
      : true_type {};

} // namespace std