// <experimental/executor> -*- C++ -*-

// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file experimental/executor
 *  This is a TS C++ Library header.
 *  @ingroup networking-ts
 */

#ifndef _GLIBCXX_EXPERIMENTAL_EXECUTOR
#define _GLIBCXX_EXPERIMENTAL_EXECUTOR 1

#pragma GCC system_header

#if __cplusplus >= 201402L

#include <algorithm>
#include <condition_variable>
#include <functional>
#include <future>
#include <list>
#include <queue>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <experimental/netfwd>
#include <bits/unique_ptr.h>
#include <experimental/bits/net.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace experimental
{
namespace net
{
inline namespace v1
{

  /** @addtogroup networking-ts
   *  @{
   */

  /// Customization point for asynchronous operations.
  template<typename _CompletionToken, typename _Signature, typename = void>
    class async_result;

  /// Convenience utility to help implement asynchronous operations.
  template<typename _CompletionToken, typename _Signature>
    class async_completion;

  template<typename _Tp, typename _ProtoAlloc, typename = __void_t<>>
    struct __associated_allocator_impl
    {
      using type = _ProtoAlloc;

      static type
      _S_get(const _Tp&, const _ProtoAlloc& __a) noexcept { return __a; }
    };

  template<typename _Tp, typename _ProtoAlloc>
    struct __associated_allocator_impl<_Tp, _ProtoAlloc,
				       __void_t<typename _Tp::allocator_type>>
    {
      using type = typename _Tp::allocator_type;

      static type
      _S_get(const _Tp& __t, const _ProtoAlloc&) noexcept
      { return __t.get_allocator(); }
    };

  /// Helper to associate an allocator with a type.
  template<typename _Tp, typename _ProtoAllocator = allocator<void>>
    struct associated_allocator
    : __associated_allocator_impl<_Tp, _ProtoAllocator>
    {
      static auto
      get(const _Tp& __t,
	  const _ProtoAllocator& __a = _ProtoAllocator()) noexcept
      {
	using _Impl = __associated_allocator_impl<_Tp, _ProtoAllocator>;
	return _Impl::_S_get(__t, __a);
      }
    };

  /// Alias template for associated_allocator.
  template<typename _Tp, typename _ProtoAllocator = allocator<void>>
    using associated_allocator_t
      = typename associated_allocator<_Tp, _ProtoAllocator>::type;

  // get_associated_allocator:

  template<typename _Tp>
    inline associated_allocator_t<_Tp>
    get_associated_allocator(const _Tp& __t) noexcept
    { return associated_allocator<_Tp>::get(__t); }

  template<typename _Tp, typename _ProtoAllocator>
    inline associated_allocator_t<_Tp, _ProtoAllocator>
    get_associated_allocator(const _Tp& __t,
			     const _ProtoAllocator& __a) noexcept
    { return associated_allocator<_Tp, _ProtoAllocator>::get(__t, __a); }

  enum class fork_event { prepare, parent, child };

  /// An extensible, type-safe, polymorphic set of services.
  class execution_context;

  class service_already_exists : public logic_error
  {
  public:
    // _GLIBCXX_RESOLVE_LIB_DEFECTS
    // 3414. service_already_exists has no usable constructors
    service_already_exists() : logic_error("service already exists") { }
  };

  template<typename _Tp> struct is_executor;

  struct executor_arg_t { };

  constexpr executor_arg_t executor_arg = executor_arg_t();

  /// Trait for determining whether to construct an object with an executor.
  template<typename _Tp, typename _Executor> struct uses_executor;

  template<typename _Tp, typename _Executor, typename = __void_t<>>
    struct __associated_executor_impl
    {
      using type = _Executor;

      static type
      _S_get(const _Tp&, const _Executor& __e) noexcept { return __e; }
    };

  template<typename _Tp, typename _Executor>
    struct __associated_executor_impl<_Tp, _Executor,
				       __void_t<typename _Tp::executor_type>>
    {
      using type = typename _Tp::executor_type;

      static type
      _S_get(const _Tp& __t, const _Executor&) noexcept
      { return __t.get_executor(); }
    };

  /// Helper to associate an executor with a type.
  template<typename _Tp, typename _Executor = system_executor>
    struct associated_executor
    : __associated_executor_impl<_Tp, _Executor>
    {
      static auto
      get(const _Tp& __t, const _Executor& __e = _Executor()) noexcept
      { return __associated_executor_impl<_Tp, _Executor>::_S_get(__t, __e); }
    };


  template<typename _Tp, typename _Executor = system_executor>
    using associated_executor_t
      = typename associated_executor<_Tp, _Executor>::type;

  template<typename _ExecutionContext>
    using __is_exec_context
      = is_convertible<_ExecutionContext&, execution_context&>;

  template<typename _Tp>
    using __executor_t = typename _Tp::executor_type;

  // get_associated_executor:

  template<typename _Tp>
    inline associated_executor_t<_Tp>
    get_associated_executor(const _Tp& __t) noexcept
    { return associated_executor<_Tp>::get(__t); }

  template<typename _Tp, typename _Executor>
    inline
    enable_if_t<is_executor<_Executor>::value,
		associated_executor_t<_Tp, _Executor>>
    get_associated_executor(const _Tp& __t, const _Executor& __ex)
    { return associated_executor<_Tp, _Executor>::get(__t, __ex); }

  template<typename _Tp, typename _ExecutionContext>
    inline
    enable_if_t<__is_exec_context<_ExecutionContext>::value,
		associated_executor_t<_Tp, __executor_t<_ExecutionContext>>>
    get_associated_executor(const _Tp& __t, _ExecutionContext& __ctx) noexcept
    { return net::get_associated_executor(__t, __ctx.get_executor()); }


  /// Helper to bind an executor to an object or function.
  template<typename _Tp, typename _Executor>
    class executor_binder;

  template<typename _Tp, typename _Executor, typename _Signature>
    class async_result<executor_binder<_Tp, _Executor>, _Signature>;

  template<typename _Tp, typename _Executor, typename _ProtoAllocator>
    struct associated_allocator<executor_binder<_Tp, _Executor>,
				_ProtoAllocator>;

  template<typename _Tp, typename _Executor, typename _Executor1>
    struct associated_executor<executor_binder<_Tp, _Executor>, _Executor1>;

  // bind_executor:

  template<typename _Executor, typename _Tp>
    inline
    enable_if_t<is_executor<_Executor>::value,
		executor_binder<decay_t<_Tp>, _Executor>>
    bind_executor(const _Executor& __ex, _Tp&& __t)
    { return { std::forward<_Tp>(__t), __ex }; }

  template<typename _ExecutionContext, typename _Tp>
    inline
    enable_if_t<__is_exec_context<_ExecutionContext>::value,
		executor_binder<decay_t<_Tp>, __executor_t<_ExecutionContext>>>
    bind_executor(_ExecutionContext& __ctx, _Tp&& __t)
    { return { __ctx.get_executor(), forward<_Tp>(__t) }; }


  /// A scope-guard type to record when work is started and finished.
  template<typename _Executor>
    class executor_work_guard;

  // make_work_guard:

  template<typename _Executor>
    inline
    enable_if_t<is_executor<_Executor>::value, executor_work_guard<_Executor>>
    make_work_guard(const _Executor& __ex)
    { return executor_work_guard<_Executor>(__ex); }

  template<typename _ExecutionContext>
    inline
    enable_if_t<__is_exec_context<_ExecutionContext>::value,
		executor_work_guard<__executor_t<_ExecutionContext>>>
    make_work_guard(_ExecutionContext& __ctx)
    { return net::make_work_guard(__ctx.get_executor()); }

  template<typename _Tp>
    inline
    enable_if_t<__not_<__or_<is_executor<_Tp>, __is_exec_context<_Tp>>>::value,
		executor_work_guard<associated_executor_t<_Tp>>>
    make_work_guard(const _Tp& __t)
    { return net::get_associated_executor(__t); }

  template<typename _Tp, typename _Up>
    auto
    make_work_guard(const _Tp& __t, _Up&& __u)
    -> decltype(net::make_work_guard(
	  net::get_associated_executor(__t, forward<_Up>(__u))))
    {
      return net::make_work_guard(
	  net::get_associated_executor(__t, forward<_Up>(__u)));
    }

  /// Allows function objects to execute on any thread.
  class system_executor;

  /// The execution context associated with system_executor objects.
  class system_context;

  inline bool
  operator==(const system_executor&, const system_executor&) { return true; }

  inline bool
  operator!=(const system_executor&, const system_executor&) { return false; }

  /// Exception thrown by empty executors.
  class bad_executor;

  /// Polymorphic wrapper for types satisfying the Executor requirements.
  class executor;

  bool
  operator==(const executor&, const executor&) noexcept;

  bool
  operator==(const executor&, nullptr_t) noexcept;

  bool
  operator==(nullptr_t, const executor&) noexcept;

  bool
  operator!=(const executor&, const executor&) noexcept;

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

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

  void swap(executor&, executor&) noexcept;

  // dispatch:

  template<typename _CompletionToken>
    __deduced_t<_CompletionToken, void()>
    dispatch(_CompletionToken&& __token);

  template<typename _Executor, typename _CompletionToken>
    __deduced_t<_CompletionToken, void()>
    dispatch(const _Executor& __ex, _CompletionToken&& __token);

  template<typename _ExecutionContext, typename _CompletionToken>
    __deduced_t<_CompletionToken, void()>
    dispatch(_ExecutionContext& __ctx, _CompletionToken&& __token);

  // post:

  template<typename _CompletionToken>
    __deduced_t<_CompletionToken, void()>
    post(_CompletionToken&& __token);
  template<typename _Executor, typename _CompletionToken>
    enable_if_t<is_executor<_Executor>::value,
		__deduced_t<_CompletionToken, void()>>
    post(const _Executor& __ex, _CompletionToken&& __token);
  template<typename _ExecutionContext, typename _CompletionToken>
    enable_if_t<__is_exec_context<_ExecutionContext>::value,
		__deduced_t<_CompletionToken, void()>>
    post(_ExecutionContext& __ctx, _CompletionToken&& __token);

  // defer:

  template<typename _CompletionToken>
    __deduced_t<_CompletionToken, void()>
    defer(_CompletionToken&& __token);
  template<typename _Executor, typename _CompletionToken>
    __deduced_t<_CompletionToken, void()>
    defer(const _Executor& __ex, _CompletionToken&& __token);
  template<typename _ExecutionContext, typename _CompletionToken>
    __deduced_t<_CompletionToken, void()>
    defer(_ExecutionContext& __ctx, _CompletionToken&& __token);

  template<typename _Executor>
    class strand;

  template<typename _Executor>
    bool
    operator==(const strand<_Executor>& __a, const strand<_Executor>& __b);

  template<typename _Executor>
    bool
    operator!=(const strand<_Executor>& __a, const strand<_Executor>& __b)
    { return !(__a == __b); }

  template<typename _CompletionToken, typename _Signature, typename>
    class async_result
    {
    public:
      typedef _CompletionToken completion_handler_type;
      typedef void return_type;

      explicit async_result(completion_handler_type&) {}
      async_result(const async_result&) = delete;
      async_result& operator=(const async_result&) = delete;

      return_type get() {}
    };

  template<typename _CompletionToken, typename _Signature>
    class async_completion
    {
      using __result_type
	= async_result<decay_t<_CompletionToken>, _Signature>;

    public:
      using completion_handler_type
	= typename __result_type::completion_handler_type;

    private:
      using __handler_type = conditional_t<
	is_same<_CompletionToken, completion_handler_type>::value,
	completion_handler_type&,
	completion_handler_type>;

    public:
      explicit
      async_completion(_CompletionToken& __t)
      : completion_handler(std::forward<__handler_type>(__t)),
	result(completion_handler)
      { }

      async_completion(const async_completion&) = delete;
      async_completion& operator=(const async_completion&) = delete;

      __handler_type	completion_handler;
      __result_type	result;
    };


  class execution_context
  {
  public:
    class service
    {
    protected:
      // construct / copy / destroy:

      explicit
      service(execution_context& __owner) : _M_context(__owner) { }

      service(const service&) = delete;
      service& operator=(const service&) = delete;

      virtual ~service() { } // TODO should not be inline

      // service observers:

      execution_context& context() const noexcept { return _M_context; }

    private:
      // service operations:

      virtual void shutdown() noexcept = 0;
      virtual void notify_fork(fork_event) { }

      friend class execution_context;
      execution_context& _M_context;
    };

    // construct / copy / destroy:

    execution_context() { }

    execution_context(const execution_context&) = delete;
    execution_context& operator=(const execution_context&) = delete;

    virtual ~execution_context()
    {
      shutdown();
      destroy();
    }

    // execution context operations:

    void
    notify_fork(fork_event __e)
    {
      auto __l = [=](auto& __svc) { __svc._M_ptr->notify_fork(__e); };
      if (__e == fork_event::prepare)
	std::for_each(_M_services.rbegin(), _M_services.rend(), __l);
      else
	std::for_each(_M_services.begin(), _M_services.end(), __l);
    }

  protected:
    // execution context protected operations:

    void
    shutdown()
    {
      std::for_each(_M_services.rbegin(), _M_services.rend(),
	  [=](auto& __svc) {
	    if (__svc._M_active)
	      {
	        __svc._M_ptr->shutdown();
		__svc._M_active = false;
	      }
	  });
    }

    void
    destroy()
    {
      while (_M_services.size())
	_M_services.pop_back();
      _M_keys.clear();
    }

  protected:

    template<typename _Service>
      static void
      _S_deleter(service* __svc) { delete static_cast<_Service*>(__svc); }

    struct _ServicePtr
    {
      template<typename _Service>
	explicit
	_ServicePtr(_Service* __svc)
	: _M_ptr(__svc, &_S_deleter<_Service>), _M_active(true) { }

      std::unique_ptr<service, void(*)(service*)> _M_ptr;
      bool _M_active;
    };

    mutable std::mutex _M_mutex;

    // Sorted in order of beginning of service object lifetime.
    std::list<_ServicePtr> _M_services;

    template<typename _Service, typename... _Args>
      service*
      _M_add_svc(_Args&&... __args)
      {
	_M_services.push_back(
	    _ServicePtr{new _Service{*this, std::forward<_Args>(__args)...}} );
	return _M_services.back()._M_ptr.get();
      }

    using __key_type = void(*)();

    template<typename _Key>
      static __key_type
      _S_key() { return reinterpret_cast<__key_type>(&_S_key<_Key>); }

    std::unordered_map<__key_type, service*> _M_keys;

    template<typename _Service>
      friend typename _Service::key_type&
      use_service(execution_context&);

    template<typename _Service, typename... _Args>
      friend _Service&
      make_service(execution_context&, _Args&&...);

    template<typename _Service>
      friend bool
      has_service(const execution_context&) noexcept;
  };

  // service access:

  template<typename _Service>
    typename _Service::key_type&
    use_service(execution_context& __ctx)
    {
      using _Key = typename _Service::key_type;
      static_assert(is_base_of<execution_context::service, _Key>::value,
	  "a service type must derive from execution_context::service");
      static_assert(is_base_of<_Key, _Service>::value,
	  "a service type must match or derive from its key_type");
      auto __key = execution_context::_S_key<_Key>();
      std::lock_guard<std::mutex> __lock(__ctx._M_mutex);
      auto& __svc = __ctx._M_keys[__key];
      if (__svc == nullptr)
	{
	  __try {
	    __svc = __ctx._M_add_svc<_Service>();
	  } __catch(...) {
	    __ctx._M_keys.erase(__key);
	    __throw_exception_again;
	  }
	}
      return static_cast<_Key&>(*__svc);
    }

  template<typename _Service, typename... _Args>
    _Service&
    make_service(execution_context& __ctx, _Args&&... __args)
    {
      using _Key = typename _Service::key_type;
      static_assert(is_base_of<execution_context::service, _Key>::value,
	  "a service type must derive from execution_context::service");
      static_assert(is_base_of<_Key, _Service>::value,
	  "a service type must match or derive from its key_type");
      auto __key = execution_context::_S_key<_Key>();
      std::lock_guard<std::mutex> __lock(__ctx._M_mutex);
      auto& __svc = __ctx._M_keys[__key];
      if (__svc != nullptr)
	throw service_already_exists();
      __try {
	__svc = __ctx._M_add_svc<_Service>(std::forward<_Args>(__args)...);
      } __catch(...) {
	__ctx._M_keys.erase(__key);
	__throw_exception_again;
      }
      return static_cast<_Service&>(*__svc);
    }

  template<typename _Service>
    inline bool
    has_service(const execution_context& __ctx) noexcept
    {
      using _Key = typename _Service::key_type;
      static_assert(is_base_of<execution_context::service, _Key>::value,
	  "a service type must derive from execution_context::service");
      static_assert(is_base_of<_Key, _Service>::value,
	  "a service type must match or derive from its key_type");
      std::lock_guard<std::mutex> __lock(__ctx._M_mutex);
      return __ctx._M_keys.count(execution_context::_S_key<_Key>());
    }

  template<typename _Tp, typename = __void_t<>>
    struct __is_executor_impl : false_type
    { };

  // Check Executor requirements.
  template<typename _Tp, typename _Up = remove_const_t<_Tp>>
    auto
    __executor_reqs(_Up* __x = 0, const _Up* __cx = 0, void(*__f)() = 0,
		    const allocator<int>& __a = {})
    -> enable_if_t<__is_value_constructible<_Tp>::value, __void_t<
      decltype(*__cx == *__cx),
      decltype(*__cx != *__cx),
      decltype(__x->context()),
      decltype(__x->on_work_started()),
      decltype(__x->on_work_finished()),
      decltype(__x->dispatch(std::move(__f), __a)),
      decltype(__x->post(std::move(__f), __a)),
      decltype(__x->defer(std::move(__f), __a))
    >>;

  template<typename _Tp>
    struct __is_executor_impl<_Tp, decltype(__executor_reqs<_Tp>())>
    : true_type
    { };

  template<typename _Tp>
    struct is_executor : __is_executor_impl<_Tp>
    { };

  template<typename _Tp>
    constexpr bool is_executor_v = is_executor<_Tp>::value;

  template<typename _Tp, typename _Executor, typename = __void_t<>>
    struct __uses_executor_impl : false_type
    { };

  template<typename _Tp, typename _Executor>
    struct __uses_executor_impl<_Tp, _Executor,
				__void_t<typename _Tp::executor_type>>
    : is_convertible<_Executor, typename _Tp::executor_type>
    { };

  template<typename _Tp, typename _Executor>
    struct uses_executor : __uses_executor_impl<_Tp, _Executor>::type
    { };

  template<typename _Tp, typename _Executor>
    constexpr bool uses_executor_v = uses_executor<_Tp, _Executor>::value;

  template<typename _Tp, typename _Executor>
    class executor_binder
    {
      struct __use_exec { };

    public:
      // types:

      typedef _Tp target_type;
      typedef _Executor executor_type;

      // construct / copy / destroy:

      executor_binder(_Tp __t, const _Executor& __ex)
      : executor_binder(__use_exec{}, std::move(__t), __ex)
      { }

      executor_binder(const executor_binder&) = default;
      executor_binder(executor_binder&&) = default;

      template<typename _Up, typename _OtherExecutor>
	executor_binder(const executor_binder<_Up, _OtherExecutor>& __other)
	: executor_binder(__use_exec{}, __other.get(), __other.get_executor())
	{ }

      template<typename _Up, typename _OtherExecutor>
	executor_binder(executor_binder<_Up, _OtherExecutor>&& __other)
	: executor_binder(__use_exec{}, std::move(__other.get()),
			  __other.get_executor())
	{ }

      template<typename _Up, typename _OtherExecutor>
	executor_binder(executor_arg_t, const _Executor& __ex,
			const executor_binder<_Up, _OtherExecutor>& __other)
	: executor_binder(__use_exec{}, __other.get(), __ex)
	{ }

      template<typename _Up, typename _OtherExecutor>
	executor_binder(executor_arg_t, const _Executor& __ex,
			executor_binder<_Up, _OtherExecutor>&& __other)
	: executor_binder(__use_exec{}, std::move(__other.get()), __ex)
	{ }

      ~executor_binder();

      // executor binder access:

      _Tp& get() noexcept { return _M_target; }
      const _Tp& get() const noexcept { return _M_target; }
      executor_type get_executor() const noexcept { return _M_ex; }

      // executor binder invocation:

      template<class... _Args>
	result_of_t<_Tp&(_Args&&...)>
	operator()(_Args&&... __args)
	{ return std::__invoke(get(), std::forward<_Args>(__args)...); }

      template<class... _Args>
	result_of_t<const _Tp&(_Args&&...)>
	operator()(_Args&&... __args) const
	{ return std::__invoke(get(), std::forward<_Args>(__args)...); }

    private:
      template<typename _Up>
	using __use_exec_cond
	  = __and_<uses_executor<_Tp, _Executor>,
		   is_constructible<_Tp, executor_arg_t, _Executor, _Up>>;

      template<typename _Up, typename _Exec, typename =
	       enable_if_t<__use_exec_cond<_Up>::value>>
	executor_binder(__use_exec, _Up&& __u, _Exec&& __ex)
	: _M_ex(std::forward<_Exec>(__ex)),
	  _M_target(executor_arg, _M_ex, std::forward<_Up>(__u))
	{ }

      template<typename _Up, typename _Exec, typename =
	       enable_if_t<!__use_exec_cond<_Up>::value>>
	executor_binder(__use_exec, _Up&& __u, const _Exec& __ex)
	: _M_ex(std::forward<_Exec>(__ex)),
	  _M_target(std::forward<_Up>(__u))
	{ }

      _Executor	_M_ex;
      _Tp	_M_target;
    };

  template<typename _Tp, typename _Executor, typename _Signature>
    class async_result<executor_binder<_Tp, _Executor>, _Signature>
    {
      using __inner = async_result<_Tp, _Signature>;

    public:
      using completion_handler_type =
	executor_binder<typename __inner::completion_handler_type, _Executor>;

      using return_type = typename __inner::return_type;

      explicit
      async_result(completion_handler_type& __h)
      : _M_target(__h.get()) { }

      async_result(const async_result&) = delete;
      async_result& operator=(const async_result&) = delete;

      return_type get() { return _M_target.get(); }

    private:
      __inner _M_target;
    };

  template<typename _Tp, typename _Executor, typename _ProtoAlloc>
    struct associated_allocator<executor_binder<_Tp, _Executor>, _ProtoAlloc>
    {
      typedef associated_allocator_t<_Tp, _ProtoAlloc> type;

      static type
      get(const executor_binder<_Tp, _Executor>& __b,
	  const _ProtoAlloc& __a = _ProtoAlloc()) noexcept
      { return associated_allocator<_Tp, _ProtoAlloc>::get(__b.get(), __a); }
    };

  template<typename _Tp, typename _Executor, typename _Executor1>
    struct associated_executor<executor_binder<_Tp, _Executor>, _Executor1>
    {
      typedef _Executor type;

      static type
      get(const executor_binder<_Tp, _Executor>& __b,
	  const _Executor1& = _Executor1()) noexcept
      { return __b.get_executor(); }
    };

  template<typename _Executor>
    class executor_work_guard
    {
    public:
      // types:

      typedef _Executor executor_type;

      // construct / copy / destroy:

      explicit
      executor_work_guard(const executor_type& __ex) noexcept
      : _M_ex(__ex), _M_owns(true)
      { _M_ex.on_work_started(); }

      executor_work_guard(const executor_work_guard& __other) noexcept
      : _M_ex(__other._M_ex), _M_owns(__other._M_owns)
      {
	if (_M_owns)
	  _M_ex.on_work_started();
      }

      executor_work_guard(executor_work_guard&& __other) noexcept
      : _M_ex(__other._M_ex), _M_owns(__other._M_owns)
      { __other._M_owns = false; }

      executor_work_guard& operator=(const executor_work_guard&) = delete;

      ~executor_work_guard()
      {
	if (_M_owns)
	  _M_ex.on_work_finished();
      }

      // executor work guard observers:

      executor_type get_executor() const noexcept { return _M_ex; }

      bool owns_work() const noexcept { return _M_owns; }

      // executor work guard modifiers:

      void reset() noexcept
      {
	if (_M_owns)
	  _M_ex.on_work_finished();
	_M_owns = false;
      }

    private:
      _Executor	_M_ex;
      bool	_M_owns;
    };


  class system_context : public execution_context
  {
  public:
    // types:

    typedef system_executor executor_type;

    // construct / copy / destroy:

    system_context() = delete;
    system_context(const system_context&) = delete;
    system_context& operator=(const system_context&) = delete;

    ~system_context()
    {
      stop();
      join();
    }

    // system_context operations:

    executor_type get_executor() noexcept;

    void stop()
    {
      lock_guard<mutex> __lock(_M_mtx);
      _M_stopped = true;
      _M_cv.notify_all();
    }

    bool stopped() const noexcept
    {
      lock_guard<mutex> __lock(_M_mtx);
      return _M_stopped;
    }

    void join()
    {
      _M_thread.join();
    }

  private:
    friend system_executor;

    struct __tag { };
    system_context(__tag) { }

    thread			_M_thread;
    mutable mutex		_M_mtx;
    condition_variable		_M_cv;
    queue<function<void()>>	_M_tasks;
    bool			_M_stopped = false;

    void
    _M_run()
    {
      while (true)
	{
	  function<void()> __f;
	  {
	    unique_lock<mutex> __lock(_M_mtx);
	    _M_cv.wait(__lock,
		       [this]{ return !_M_stopped && !_M_tasks.empty(); });
	    if (_M_stopped)
	      return;
	    __f = std::move(_M_tasks.front());
	    _M_tasks.pop();
	  }
	  __f();
	}
    }

    void
    _M_post(std::function<void()> __f)
    {
      lock_guard<mutex> __lock(_M_mtx);
      if (_M_stopped)
	return;
      if (!_M_thread.joinable())
	_M_thread = std::thread(&system_context::_M_run, this);
      _M_tasks.push(std::move(__f)); // XXX allocator not used
      _M_cv.notify_one();
    }

    static system_context&
    _S_get() noexcept
    {
      static system_context __sc(__tag{});
      return __sc;
    }
  };

  class system_executor
  {
  public:
    // executor operations:

    system_executor() { }

    system_context&
    context() const noexcept { return system_context::_S_get(); }

    void on_work_started() const noexcept { }
    void on_work_finished() const noexcept { }

    template<typename _Func, typename _ProtoAlloc>
      void
      dispatch(_Func&& __f, const _ProtoAlloc& __a) const
      { decay_t<_Func>{std::forward<_Func>(__f)}(); }

    template<typename _Func, typename _ProtoAlloc>
      void
      post(_Func&& __f, const _ProtoAlloc&) const // XXX allocator not used
      {
	system_context::_S_get()._M_post(std::forward<_Func>(__f));
      }

    template<typename _Func, typename _ProtoAlloc>
      void
      defer(_Func&& __f, const _ProtoAlloc& __a) const
      { post(std::forward<_Func>(__f), __a); }
  };

  inline system_executor
  system_context::get_executor() noexcept
  { return {}; }

  class bad_executor : public std::exception
  {
    virtual const char* what() const noexcept { return "bad executor"; }
  };

  inline void __throw_bad_executor() // TODO make non-inline
  {
#if __cpp_exceptions
    throw bad_executor();
#else
    __builtin_abort();
#endif
  }

  class executor
  {
  public:
    // construct / copy / destroy:

    executor() noexcept = default;

    executor(nullptr_t) noexcept { }
    executor(const executor&) noexcept = default;
    executor(executor&&) noexcept = default;

    template<typename _Executor>
      executor(_Executor __e)
      : _M_target(make_shared<_Tgt1<_Executor>>(std::move(__e)))
      { }

    template<typename _Executor, typename _ProtoAlloc>
      executor(allocator_arg_t, const _ProtoAlloc& __a, _Executor __e)
      : _M_target(allocate_shared<_Tgt2<_Executor, _ProtoAlloc>>(__a,
	    std::move(__e), __a))
      { }

    executor& operator=(const executor&) noexcept = default;
    executor& operator=(executor&&) noexcept = default;

    executor&
    operator=(nullptr_t) noexcept
    {
      _M_target = nullptr;
      return *this;
    }

    template<typename _Executor>
      executor&
      operator=(_Executor __e)
      {
	executor(std::move(__e)).swap(*this);
	return *this;
      }

    ~executor() = default;

    // executor modifiers:

    void
    swap(executor& __other) noexcept
    { _M_target.swap(__other._M_target); }

    template<typename _Executor, typename _Alloc>
      void
      assign(_Executor __e, const _Alloc& __a)
      { executor(allocator_arg, __a, std::move(__e)).swap(*this); }

    // executor operations:

    execution_context&
    context() const noexcept
    {
      __glibcxx_assert( _M_target );
      return _M_target->context();
    }

    void
    on_work_started() const noexcept
    {
      __glibcxx_assert( _M_target );
      return _M_target->on_work_started();
    }

    void
    on_work_finished() const noexcept
    {
      __glibcxx_assert( _M_target );
      return _M_target->on_work_finished();
    }

    template<typename _Func, typename _Alloc>
      void
      dispatch(_Func&& __f, const _Alloc& __a) const
      {
	if (!_M_target)
	  __throw_bad_executor();
	// _M_target->dispatch({allocator_arg, __a, std::forward<_Func>(__f)});
	_M_target->dispatch(std::forward<_Func>(__f));
      }

    template<typename _Func, typename _Alloc>
      void
      post(_Func&& __f, const _Alloc& __a) const
      {
	if (!_M_target)
	  __throw_bad_executor();
	// _M_target->post({allocator_arg, __a, std::forward<_Func>(__f)});
	_M_target->post(std::forward<_Func>(__f));
      }

    template<typename _Func, typename _Alloc>
      void
      defer(_Func&& __f, const _Alloc& __a) const
      {
	if (!_M_target)
	  __throw_bad_executor();
	// _M_target->defer({allocator_arg, __a, std::forward<_Func>(__f)});
	_M_target->defer(std::forward<_Func>(__f));
      }

    // executor capacity:

    explicit operator bool() const noexcept
    { return static_cast<bool>(_M_target); }

    // executor target access:

#if __cpp_rtti
    const type_info&
    target_type() const noexcept
    {
      if (_M_target)
	return *static_cast<const type_info*>(_M_target->target_type());
      return typeid(void);
    }
#endif

    template<typename _Executor>
      _Executor*
      target() noexcept
      {
	void* __p = nullptr;
	if (_M_target)
	  {
	    if (_M_target->_M_func == &_Tgt1<remove_cv_t<_Executor>>::_S_func)
	      __p = _M_target->_M_func(_M_target.get(), nullptr);
#if __cpp_rtti
	    else
	      __p = _M_target->target(&typeid(_Executor));
#endif
	  }
	return static_cast<_Executor*>(__p);
      }

    template<typename _Executor>
      const _Executor*
      target() const noexcept
      {
	const void* __p = nullptr;
	if (_M_target)
	  {
	    if (_M_target->_M_func == &_Tgt1<remove_cv_t<_Executor>>::_S_func)
	      return (_Executor*)_M_target->_M_func(_M_target.get(), nullptr);
#if __cpp_rtti
	    else
	      __p = _M_target->target(&typeid(_Executor));
#endif
	  }
	return static_cast<const _Executor*>(__p);
      }

  private:
    struct _Tgt
    {
      virtual void on_work_started() const noexcept = 0;
      virtual void on_work_finished() const noexcept = 0;
      virtual execution_context& context() const noexcept = 0;
      virtual void dispatch(std::function<void()>) const = 0;
      virtual void post(std::function<void()>) const = 0;
      virtual void defer(std::function<void()>) const = 0;
      virtual const void* target_type() const noexcept = 0;
      virtual void* target(const void*) noexcept = 0;
      virtual bool _M_equals(_Tgt*) const noexcept = 0;

      using _Func = void* (_Tgt*, const _Tgt*);
      _Func* _M_func; // Provides access to target without RTTI
    };

    template<typename _Ex>
      struct _Tgt1 : _Tgt
      {
	explicit
	_Tgt1(_Ex&& __ex)
	: _M_ex(std::move(__ex))
	{ this->_M_func = &_S_func; }

	void
	on_work_started() const noexcept override
	{ _M_ex.on_work_started(); }

	void
	on_work_finished() const noexcept override
	{ _M_ex.on_work_finished(); }

	execution_context&
	context() const noexcept override
	{ return _M_ex.context(); }

	void
	dispatch(std::function<void()> __f) const override
	{ _M_ex.dispatch(std::move(__f), allocator<void>()); }

	void
	post(std::function<void()> __f) const override
	{ _M_ex.post(std::move(__f), allocator<void>()); }

	void
	defer(std::function<void()> __f) const override
	{ _M_ex.defer(std::move(__f), allocator<void>()); }

	const void*
	target_type() const noexcept override
	{
#if __cpp_rtti
	  return &typeid(_Ex);
#else
	  return nullptr;
#endif
	}

	void*
	target(const void* __ti) noexcept override
	{
#if __cpp_rtti
	  if (*static_cast<const type_info*>(__ti) == typeid(_Ex))
	    return std::__addressof(_M_ex);
#endif
	  return nullptr;
	}

	bool
	_M_equals(_Tgt* __tgt) const noexcept override
	{
#if __cpp_rtti
	  if (const void* __p = __tgt->target(&typeid(_Ex)))
	    return *static_cast<const _Ex*>(__p) == _M_ex;
#endif
	  return false;
	}

	_Ex _M_ex [[__no_unique_address__]];

	static void*
	_S_func(_Tgt* __p, const _Tgt* __q) noexcept
	{
	  auto& __ex = static_cast<_Tgt1*>(__p)->_M_ex;
	  if (__q)
	    {
	      if (__ex == static_cast<const _Tgt1*>(__q)->_M_ex)
		return __p;
	      else
		return nullptr;
	    }
	  else
	    return std::__addressof(__ex);
	}
      };

    template<typename _Ex, typename _Alloc>
      struct _Tgt2 : _Tgt1<_Ex>
      {
	explicit
	_Tgt2(_Ex&& __ex, const _Alloc& __a)
	: _Tgt1<_Ex>(std::move(__ex)), _M_alloc(__a) { }

	void
	dispatch(std::function<void()> __f) const override
	{ this->_M_ex.dispatch(std::move(__f), _M_alloc); }

	void
	post(std::function<void()> __f) const override
	{ this->_M_ex.post(std::move(__f), _M_alloc); }

	void
	defer(std::function<void()> __f) const override
	{ this->_M_ex.defer(std::move(__f), _M_alloc); }

	_Alloc _M_alloc [[__no_unique_address__]];
      };

    // Partial specialization for std::allocator<T>.
    // Don't store the allocator.
    template<typename _Ex, typename _Tp>
      struct _Tgt2<_Ex, std::allocator<_Tp>> : _Tgt1<_Ex>
      { };

    friend bool
    operator==(const executor& __a, const executor& __b) noexcept
    {
      _Tgt* __ta = __a._M_target.get();
      _Tgt* __tb = __b._M_target.get();
      if (__ta == __tb)
	return true;
      if (!__ta || !__tb)
	return false;
      if (__ta->_M_func == __tb->_M_func)
	return __ta->_M_func(__ta, __tb);
      return __ta->_M_equals(__tb);
    }

    shared_ptr<_Tgt> _M_target;
  };

  template<> struct is_executor<executor> : true_type { };

  /// executor comparisons
  inline bool
  operator==(const executor& __e, nullptr_t) noexcept
  { return !__e; }

  inline bool
  operator==(nullptr_t, const executor& __e) noexcept
  { return !__e; }

  inline bool
  operator!=(const executor& __a, const executor& __b) noexcept
  { return !(__a == __b); }

  inline bool
  operator!=(const executor& __e, nullptr_t) noexcept
  { return (bool)__e; }

  inline bool
  operator!=(nullptr_t, const executor& __e) noexcept
  { return (bool)__e; }

  /// Swap two executor objects.
  inline void swap(executor& __a, executor& __b) noexcept { __a.swap(__b); }


  template<typename _CompletionHandler>
    struct __dispatcher
    {
      explicit
      __dispatcher(_CompletionHandler& __h)
      : _M_h(std::move(__h)), _M_w(net::make_work_guard(_M_h))
      { }

      void operator()()
      {
	auto __alloc = net::get_associated_allocator(_M_h);
	_M_w.get_executor().dispatch(std::move(_M_h), __alloc);
	_M_w.reset();
      }

      _CompletionHandler _M_h;
      decltype(net::make_work_guard(_M_h)) _M_w;
    };

  template<typename _CompletionHandler>
    inline __dispatcher<_CompletionHandler>
    __make_dispatcher(_CompletionHandler& __h)
    { return __dispatcher<_CompletionHandler>{__h}; }



  // dispatch:

  template<typename _CompletionToken>
    inline __deduced_t<_CompletionToken, void()>
    dispatch(_CompletionToken&& __token)
    {
      async_completion<_CompletionToken, void()> __cmpl{__token};
      auto __ex = net::get_associated_executor(__cmpl.completion_handler);
      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
      __ex.dispatch(std::move(__cmpl.completion_handler), __alloc);
      return __cmpl.result.get();
    }

  template<typename _Executor, typename _CompletionToken>
    inline
    enable_if_t<is_executor<_Executor>::value,
		__deduced_t<_CompletionToken, void()>>
    dispatch(const _Executor& __ex, _CompletionToken&& __token)
    {
      async_completion<_CompletionToken, void()> __cmpl{__token};
      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
      __ex.dispatch(net::__make_dispatcher(__cmpl.completion_handler),
		    __alloc);
      return __cmpl.result.get();
    }

  template<typename _ExecutionContext, typename _CompletionToken>
    inline
    enable_if_t<__is_exec_context<_ExecutionContext>::value,
		__deduced_t<_CompletionToken, void()>>
    dispatch(_ExecutionContext& __ctx, _CompletionToken&& __token)
    {
      return net::dispatch(__ctx.get_executor(),
			   forward<_CompletionToken>(__token));
    }

  // post:

  template<typename _CompletionToken>
    inline __deduced_t<_CompletionToken, void()>
    post(_CompletionToken&& __token)
    {
      async_completion<_CompletionToken, void()> __cmpl{__token};
      auto __ex = net::get_associated_executor(__cmpl.completion_handler);
      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
      __ex.post(std::move(__cmpl.completion_handler), __alloc);
      return __cmpl.result.get();
    }

  template<typename _Executor, typename _CompletionToken>
    inline
    enable_if_t<is_executor<_Executor>::value,
		__deduced_t<_CompletionToken, void()>>
    post(const _Executor& __ex, _CompletionToken&& __token)
    {
      async_completion<_CompletionToken, void()> __cmpl{__token};
      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
      __ex.post(net::__make_dispatcher(__cmpl.completion_handler), __alloc);
      return __cmpl.result.get();
    }

  template<typename _ExecutionContext, typename _CompletionToken>
    inline
    enable_if_t<__is_exec_context<_ExecutionContext>::value,
		__deduced_t<_CompletionToken, void()>>
    post(_ExecutionContext& __ctx, _CompletionToken&& __token)
    {
      return net::post(__ctx.get_executor(),
		       forward<_CompletionToken>(__token));
    }

  // defer:

  template<typename _CompletionToken>
    inline __deduced_t<_CompletionToken, void()>
    defer(_CompletionToken&& __token)
    {
      async_completion<_CompletionToken, void()> __cmpl{__token};
      auto __ex = net::get_associated_executor(__cmpl.completion_handler);
      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
      __ex.defer(std::move(__cmpl.completion_handler), __alloc);
      return __cmpl.result.get();
    }

  template<typename _Executor, typename _CompletionToken>
    inline
    enable_if_t<is_executor<_Executor>::value,
		__deduced_t<_CompletionToken, void()>>
    defer(const _Executor& __ex, _CompletionToken&& __token)
    {
      async_completion<_CompletionToken, void()> __cmpl{__token};
      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
      __ex.defer(net::__make_dispatcher(__cmpl.completion_handler), __alloc);
      return __cmpl.result.get();
    }

  template<typename _ExecutionContext, typename _CompletionToken>
    inline
    enable_if_t<__is_exec_context<_ExecutionContext>::value,
		__deduced_t<_CompletionToken, void()>>
    defer(_ExecutionContext& __ctx, _CompletionToken&& __token)
    {
      return net::defer(__ctx.get_executor(),
			forward<_CompletionToken>(__token));
    }


  template<typename _Executor>
    class strand
    {
    public:
      // types:

      typedef _Executor inner_executor_type;

      // construct / copy / destroy:

      strand(); // TODO make state

      explicit strand(_Executor __ex) : _M_inner_ex(__ex) { } // TODO make state

      template<typename _Alloc>
	strand(allocator_arg_t, const _Alloc& __a, _Executor __ex)
	: _M_inner_ex(__ex) { } // TODO make state

      strand(const strand& __other) noexcept
      : _M_state(__other._M_state), _M_inner_ex(__other._M_inner_ex) { }

      strand(strand&& __other) noexcept
      : _M_state(std::move(__other._M_state)),
	_M_inner_ex(std::move(__other._M_inner_ex)) { }

      template<typename _OtherExecutor>
	strand(const strand<_OtherExecutor>& __other) noexcept
	: _M_state(__other._M_state), _M_inner_ex(__other._M_inner_ex) { }

      template<typename _OtherExecutor>
	strand(strand<_OtherExecutor>&& __other) noexcept
	: _M_state(std::move(__other._M_state)),
	  _M_inner_ex(std::move(__other._M_inner_ex)) { }

      strand&
      operator=(const strand& __other) noexcept
      {
	static_assert(is_copy_assignable<_Executor>::value,
		      "inner executor type must be CopyAssignable");

	// TODO lock __other
	// TODO copy state
	_M_inner_ex = __other._M_inner_ex;
	return *this;
      }

      strand&
      operator=(strand&& __other) noexcept
      {
	static_assert(is_move_assignable<_Executor>::value,
		      "inner executor type must be MoveAssignable");

	// TODO move state
	_M_inner_ex = std::move(__other._M_inner_ex);
	return *this;
      }

      template<typename _OtherExecutor>
	strand&
	operator=(const strand<_OtherExecutor>& __other) noexcept
	{
	  static_assert(is_convertible<_OtherExecutor, _Executor>::value,
			"inner executor type must be compatible");

	  // TODO lock __other
	  // TODO copy state
	  _M_inner_ex = __other._M_inner_ex;
	  return *this;
	}

      template<typename _OtherExecutor>
	strand&
	operator=(strand<_OtherExecutor>&& __other) noexcept
	{
	  static_assert(is_convertible<_OtherExecutor, _Executor>::value,
			"inner executor type must be compatible");

	  // TODO move state
	  _M_inner_ex = std::move(__other._M_inner_ex);
	  return *this;
	}

      ~strand()
      {
	// the task queue outlives this object if non-empty
	// TODO create circular ref in queue?
      }

      // strand operations:

      inner_executor_type
      get_inner_executor() const noexcept
      { return _M_inner_ex; }

      bool
      running_in_this_thread() const noexcept
      { return std::this_thread::get_id() == _M_state->_M_running_on; }

      execution_context&
      context() const noexcept
      { return _M_inner_ex.context(); }

      void on_work_started() const noexcept { _M_inner_ex.on_work_started(); }
      void on_work_finished() const noexcept { _M_inner_ex.on_work_finished(); }

      template<typename _Func, typename _Alloc>
	void
	dispatch(_Func&& __f, const _Alloc& __a) const
	{
	  if (running_in_this_thread())
	    decay_t<_Func>{std::forward<_Func>(__f)}();
	  else
	    post(std::forward<_Func>(__f), __a);
	}

      template<typename _Func, typename _Alloc>
	void
	post(_Func&& __f, const _Alloc& __a) const; // TODO

      template<typename _Func, typename _Alloc>
	void
	defer(_Func&& __f, const _Alloc& __a) const
	{ post(std::forward<_Func>(__f), __a); }

    private:
      friend bool
      operator==(const strand& __a, const strand& __b)
      { return __a._M_state == __b._M_state; }

      // TODO add synchronised queue
      struct _State
      {
	std::thread::id _M_running_on;
      };
      shared_ptr<_State> _M_state;
      _Executor _M_inner_ex;
    };

#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)

  // Completion token for asynchronous operations initiated with use_future.
  template<typename _Func, typename _Alloc>
    struct __use_future_ct
    {
      std::tuple<_Func, _Alloc> _M_t;
    };

  template<typename _Func, typename _Tp>
    struct __use_future_ct<_Func, std::allocator<_Tp>>
    {
      _Func _M_f;
    };

  template<typename _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(is_nothrow_default_constructible<_ProtoAllocator>::value)
      : _M_alloc() { }

      explicit
      use_future_t(const _ProtoAllocator& __a) noexcept : _M_alloc(__a) { }

      template<typename _OtherAllocator>
	use_future_t<_OtherAllocator>
	rebind(const _OtherAllocator& __a) const noexcept
	{ return use_future_t<_OtherAllocator>(__a); }

      allocator_type get_allocator() const noexcept { return _M_alloc; }

      template<typename _Func>
	auto
	operator()(_Func&& __f) const
	{
	  using _Token = __use_future_ct<decay_t<_Func>, _ProtoAllocator>;
	  return _Token{ {std::forward<_Func>(__f), _M_alloc} };
	}

    private:
      _ProtoAllocator _M_alloc;
    };

  template<typename _Tp>
    class use_future_t<std::allocator<_Tp>>
    {
    public:
      // use_future_t types:
      using allocator_type = std::allocator<_Tp>;

      // use_future_t members:
      constexpr use_future_t() noexcept = default;

      explicit
      use_future_t(const allocator_type& __a) noexcept { }

      template<class _Up>
	use_future_t<std::allocator<_Up>>
	rebind(const std::allocator<_Up>& __a) const noexcept
	{ return use_future_t<std::allocator<_Up>>(__a); }

      allocator_type get_allocator() const noexcept { return {}; }

      template<typename _Func>
	auto
	operator()(_Func&& __f) const
	{
	  using _Token = __use_future_ct<decay_t<_Func>, allocator_type>;
	  return _Token{std::forward<_Func>(__f)};
	}
    };

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

  template<typename _Func, typename _Alloc, typename _Res, typename... _Args>
    class async_result<__use_future_ct<_Func, _Alloc>, _Res(_Args...)>;

  template<typename _Result, typename _Executor>
    struct __use_future_ex;

  // Completion handler for asynchronous operations initiated with use_future.
  template<typename _Func, typename... _Args>
    struct __use_future_ch
    {
      template<typename _Alloc>
	explicit
	__use_future_ch(__use_future_ct<_Func, _Alloc>&& __token)
	: _M_f{ std::move(std::get<0>(__token._M_t)) },
	  _M_promise{ std::get<1>(__token._M_t) }
	{ }

      template<typename _Tp>
	explicit
	__use_future_ch(__use_future_ct<_Func, std::allocator<_Tp>>&& __token)
	: _M_f{ std::move(__token._M_f) }
	{ }

      void
      operator()(_Args&&... __args)
      {
	__try
	  {
	    _M_promise.set_value(_M_f(std::forward<_Args>(__args)...));
	  }
	__catch(__cxxabiv1::__forced_unwind&)
	  {
	    __throw_exception_again;
	  }
	__catch(...)
	  {
	    _M_promise.set_exception(std::current_exception());
	  }
      }

      using __result = result_of_t<_Func(decay_t<_Args>...)>;

      future<__result> get_future() { return _M_promise.get_future(); }

    private:
      template<typename _Result, typename _Executor>
	friend struct __use_future_ex;

      _Func _M_f;
      mutable promise<__result> _M_promise;
    };

  // Specialization of async_result for operations initiated with use_future.
  template<typename _Func, typename _Alloc, typename _Res, typename... _Args>
    class async_result<__use_future_ct<_Func, _Alloc>, _Res(_Args...)>
    {
    public:
      using completion_handler_type = __use_future_ch<_Func, _Args...>;
      using return_type = future<typename completion_handler_type::__result>;

      explicit
      async_result(completion_handler_type& __h)
      : _M_future(__h.get_future())
      { }

      async_result(const async_result&) = delete;
      async_result& operator=(const async_result&) = delete;

      return_type get() { return std::move(_M_future); }

    private:
      return_type _M_future;
    };

  template<typename _Result, typename _Executor>
    struct __use_future_ex
    {
      template<typename _Handler>
      __use_future_ex(const _Handler& __h, _Executor __ex)
      : _M_t(__h._M_promise, __ex)
      { }

      template<typename _Fn, typename _Alloc>
	void
	dispatch(_Fn&& __fn)
	{
	  __try
	    {
	      std::get<1>(_M_t).dispatch(std::forward<_Fn>(__fn));
	    }
	  __catch(__cxxabiv1::__forced_unwind&)
	    {
	      __throw_exception_again;
	    }
	  __catch(...)
	    {
	      std::get<0>(_M_t).set_exception(std::current_exception());
	    }
	}

      template<typename _Fn, typename _Alloc>
	void
	post(_Fn&& __fn)
	{
	  __try
	    {
	      std::get<1>(_M_t).post(std::forward<_Fn>(__fn));
	    }
	  __catch(__cxxabiv1::__forced_unwind&)
	    {
	      __throw_exception_again;
	    }
	  __catch(...)
	    {
	      std::get<0>(_M_t).set_exception(std::current_exception());
	    }
	}

      template<typename _Fn, typename _Alloc>
	void
	defer(_Fn&& __fn)
	{
	  __try
	    {
	      std::get<1>(_M_t).defer(std::forward<_Fn>(__fn));
	    }
	  __catch(__cxxabiv1::__forced_unwind&)
	    {
	      __throw_exception_again;
	    }
	  __catch(...)
	    {
	      std::get<0>(_M_t).set_exception(std::current_exception());
	    }
	}

    private:
      tuple<promise<_Result>&, _Executor> _M_t;
    };

  template<typename _Func, typename... _Args, typename _Executor>
    struct associated_executor<__use_future_ch<_Func, _Args...>, _Executor>
    {
    private:
      using __handler = __use_future_ch<_Func, _Args...>;

      using type = __use_future_ex<typename __handler::__result, _Executor>;

      static type
      get(const __handler& __h, const _Executor& __ex)
      { return { __h, __ex }; }
    };

#if 0

  // [async.use.future.traits]
  template<typename _Allocator, typename _Ret, typename... _Args>
    class handler_type<use_future_t<_Allocator>, _Ret(_Args...)> // TODO uglify name
    {
      template<typename... _Args>
	struct __is_error_result : false_type { };

      template<typename... _Args>
	struct __is_error_result<error_code, _Args...> : true_type { };

      template<typename... _Args>
	struct __is_error_result<exception_ptr, _Args...> : true_type { };

      static exception_ptr
      _S_exptr(exception_ptr& __ex)
      { return std::move(__ex); }

      static exception_ptr
      _S_exptr(const error_code& __ec)
      { return make_exception_ptr(system_error(__ec)); }

      template<bool _IsError, typename... _UArgs>
	struct _Type;

      // N == 0
      template<bool _IsError>
	struct _Type<_IsError>
	{
	  std::promise<void> _M_promise;

	  void
	  operator()()
	  {
	    _M_promise.set_value();
	  }
	};

      // N == 1, U0 is error_code or exception_ptr
      template<typename _UArg0>
	struct _Type<true, _UArg0>
	{
	  std::promise<void> _M_promise;

	  template<typename _Arg0>
	    void
	    operator()(_Arg0&& __a0)
	    {
	      if (__a0)
		_M_promise.set_exception(_S_exptr(__a0));
	      else
		_M_promise.set_value();
	    }
	};

      // N == 1, U0 is not error_code or exception_ptr
      template<typename _UArg0>
	struct _Type<false, _UArg0>
	{
	  std::promise<_UArg0> _M_promise;

	  template<typename _Arg0>
	    void
	    operator()(_Arg0&& __a0)
	    {
	      _M_promise.set_value(std::forward<_Arg0>(__a0));
	    }
	};

      // N == 2, U0 is error_code or exception_ptr
      template<typename _UArg0, typename _UArg1>
	struct _Type<true, _UArg0, _UArg1>
	{
	  std::promise<_UArg1> _M_promise;

	  template<typename _Arg0, typename _Arg1>
	    void
	    operator()(_Arg0&& __a0, _Arg1&& __a1)
	    {
	      if (__a0)
		_M_promise.set_exception(_S_exptr(__a0));
	      else
		_M_promise.set_value(std::forward<_Arg1>(__a1));
	    }
	};

      // N >= 2, U0 is not error_code or exception_ptr
      template<typename... _UArgs>
	struct _Type<false, _UArgs...>
	{
	  static_assert(sizeof...(_UArgs) > 1, "wrong partial specialization");

	  std::promise<tuple<_UArgs...>> _M_promise;

	  template<typename... _Args>
	    void
	    operator()(_Args&&... __args)
	    {
	      _M_promise.set_value(
		  std::forward_as_tuple(std::forward<_Args>(__args)...));
	    }
	};

      // N > 2, U0 is error_code or exception_ptr
      template<typename _UArg0, typename... _UArgs>
	struct _Type<true, _UArg0, _UArgs...>
	{
	  static_assert(sizeof...(_UArgs) > 1, "wrong partial specialization");

	  std::promise<tuple<_UArgs...>> _M_promise;

	  template<typename _Arg0, typename... _Args>
	    void
	    operator()(_Arg0&& __a0, _Args&&... __args)
	    {
	      if (__a0)
		_M_promise.set_exception(_S_exptr(__a0));
	      else
		_M_promise.set_value(
		    std::forward_as_tuple(std::forward<_Args>(__args)...));
	    }
	};

    public:
      using type =
	_Type<__is_error_result<_Args...>::value, decay_t<_Args>...>;
    };


  template<typename _Alloc, typename _Ret, typename... _Args>
    struct async_result<use_future_t<_Alloc>, _Ret(_Args...)>
    {
      using completion_handler_type
	= typename handler_type<use_future_t<_Alloc>, _Ret(_Args...)>::type;

      using return_type = void; // XXX TODO ???;

      explicit
      async_result(completion_handler_type& __h) : _M_handler(__h) { }

      auto get() { return _M_handler._M_provider.get_future(); }

      async_result(const async_result&) = delete;
      async_result& operator=(const async_result&) = delete;

      return_type get() { return _M_handler._M_promise.get_future(); }

    private:
      completion_handler_type& _M_handler;
    };

  // TODO specialize associated_executor for
  // async_result<use_future_t<A>, Sig>::completion_handler_type
  // to use a __use_future_ex
  // (probably need to move _Type outside of handler_type so we don't have
  // a non-deduced context)


#endif

  // [async.packaged.task.specializations]
  template<typename _Ret, typename... _Args, typename _Signature>
    class async_result<packaged_task<_Ret(_Args...)>, _Signature>
    {
    public:
      using completion_handler_type = packaged_task<_Ret(_Args...)>;
      using return_type = future<_Ret>;

      explicit
      async_result(completion_handler_type& __h)
      : _M_future(__h.get_future()) { }

      async_result(const async_result&) = delete;
      async_result& operator=(const async_result&) = delete;

      return_type get() { return std::move(_M_future); }

    private:
      return_type _M_future;
    };

#endif

  /// @}

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

  template<typename _Alloc>
    struct uses_allocator<experimental::net::executor, _Alloc>
    : true_type {};

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_EXECUTOR
