// <future> -*- C++ -*-

// Copyright (C) 2009-2013 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 include/future
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_FUTURE
#define _GLIBCXX_FUTURE 1

#pragma GCC system_header

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else

#include <functional>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <system_error>
#include <atomic>
#include <bits/functexcept.h>
#include <bits/unique_ptr.h>
#include <bits/shared_ptr.h>
#include <bits/uses_allocator.h>
#include <bits/alloc_traits.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @defgroup futures Futures
   * @ingroup concurrency
   *
   * Classes for futures support.
   * @{
   */

  /// Error code for futures
  enum class future_errc
  {
    future_already_retrieved = 1,
    promise_already_satisfied,
    no_state,
    broken_promise
  };

  /// Specialization.
  template<>
    struct is_error_code_enum<future_errc> : public true_type { };

  /// Points to a statically-allocated object derived from error_category.
  const error_category&
  future_category() noexcept;

  /// Overload for make_error_code.
  inline error_code
  make_error_code(future_errc __errc) noexcept
  { return error_code(static_cast<int>(__errc), future_category()); }

  /// Overload for make_error_condition.
  inline error_condition
  make_error_condition(future_errc __errc) noexcept
  { return error_condition(static_cast<int>(__errc), future_category()); }

  /**
   *  @brief Exception type thrown by futures.
   *  @ingroup exceptions
   */
  class future_error : public logic_error
  {
    error_code 			_M_code;

  public:
    explicit future_error(error_code __ec)
    : logic_error("std::future_error"), _M_code(__ec)
    { }

    virtual ~future_error() noexcept;

    virtual const char*
    what() const noexcept;

    const error_code&
    code() const noexcept { return _M_code; }
  };

  // Forward declarations.
  template<typename _Res>
    class future;

  template<typename _Res>
    class shared_future;

  template<typename _Signature>
    class packaged_task;

  template<typename _Res>
    class promise;

  /// Launch code for futures
  enum class launch
  {
    async = 1,
    deferred = 2
  };

  constexpr launch operator&(launch __x, launch __y)
  {
    return static_cast<launch>(
	static_cast<int>(__x) & static_cast<int>(__y));
  }

  constexpr launch operator|(launch __x, launch __y)
  {
    return static_cast<launch>(
	static_cast<int>(__x) | static_cast<int>(__y));
  }

  constexpr launch operator^(launch __x, launch __y)
  {
    return static_cast<launch>(
	static_cast<int>(__x) ^ static_cast<int>(__y));
  }

  constexpr launch operator~(launch __x)
  { return static_cast<launch>(~static_cast<int>(__x)); }

  inline launch& operator&=(launch& __x, launch __y)
  { return __x = __x & __y; }

  inline launch& operator|=(launch& __x, launch __y)
  { return __x = __x | __y; }

  inline launch& operator^=(launch& __x, launch __y)
  { return __x = __x ^ __y; }

  /// Status code for futures
  enum class future_status
  {
    ready,
    timeout,
    deferred
  };

  template<typename _Fn, typename... _Args>
    future<typename result_of<_Fn(_Args...)>::type>
    async(launch __policy, _Fn&& __fn, _Args&&... __args);

  template<typename _Fn, typename... _Args>
    future<typename result_of<_Fn(_Args...)>::type>
    async(_Fn&& __fn, _Args&&... __args);

#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
  && (ATOMIC_INT_LOCK_FREE > 1)

  /// Base class and enclosing scope.
  struct __future_base
  {
    /// Base class for results.
    struct _Result_base
    {
      exception_ptr		_M_error;

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

      // _M_destroy() allows derived classes to control deallocation
      virtual void _M_destroy() = 0;

      struct _Deleter
      {
	void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
      };

    protected:
      _Result_base();
      virtual ~_Result_base();
    };

    /// Result.
    template<typename _Res>
      struct _Result : _Result_base
      {
      private:
	typedef alignment_of<_Res>				__a_of;
	typedef aligned_storage<sizeof(_Res), __a_of::value>	__align_storage;
	typedef typename __align_storage::type			__align_type;

	__align_type		_M_storage;
	bool 			_M_initialized;

      public:
	typedef _Res result_type;

	_Result() noexcept : _M_initialized() { }
	
	~_Result()
	{
	  if (_M_initialized)
	    _M_value().~_Res();
	}

	// Return lvalue, future will add const or rvalue-reference
	_Res&
	_M_value() noexcept { return *static_cast<_Res*>(_M_addr()); }

	void
	_M_set(const _Res& __res)
	{
	  ::new (_M_addr()) _Res(__res);
	  _M_initialized = true;
	}

	void
	_M_set(_Res&& __res)
	{
	  ::new (_M_addr()) _Res(std::move(__res));
	  _M_initialized = true;
	}

      private:
	void _M_destroy() { delete this; }

	void* _M_addr() noexcept { return static_cast<void*>(&_M_storage); }
    };

    /// A unique_ptr based on the instantiating type.
    template<typename _Res>
      using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;

    /// Result_alloc.
    template<typename _Res, typename _Alloc>
      struct _Result_alloc final : _Result<_Res>, _Alloc
      {
        typedef typename allocator_traits<_Alloc>::template
          rebind_alloc<_Result_alloc> __allocator_type;

        explicit
	_Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a)
        { }
	
      private:
	void _M_destroy()
        {
	  typedef allocator_traits<__allocator_type> __traits;
          __allocator_type __a(*this);
	  __traits::destroy(__a, this);
	  __traits::deallocate(__a, this, 1);
        }
      };

    template<typename _Res, typename _Allocator>
      static _Ptr<_Result_alloc<_Res, _Allocator>>
      _S_allocate_result(const _Allocator& __a)
      {
        typedef _Result_alloc<_Res, _Allocator>	__result_type;
	typedef allocator_traits<typename __result_type::__allocator_type>
	  __traits;
        typename __traits::allocator_type __a2(__a);
        __result_type* __p = __traits::allocate(__a2, 1);
        __try
	  {
	    __traits::construct(__a2, __p, __a);
	  }
        __catch(...)
	  {
	    __traits::deallocate(__a2, __p, 1);
	    __throw_exception_again;
	  }
        return _Ptr<__result_type>(__p);
      }

    template<typename _Res, typename _Tp>
      static _Ptr<_Result<_Res>>
      _S_allocate_result(const std::allocator<_Tp>& __a)
      {
	return _Ptr<_Result<_Res>>(new _Result<_Res>);
      }

    /// Base class for state between a promise and one or more
    /// associated futures.
    class _State_base
    {
      typedef _Ptr<_Result_base> _Ptr_type;

      _Ptr_type			_M_result;
      mutex               	_M_mutex;
      condition_variable  	_M_cond;
      atomic_flag         	_M_retrieved;
      once_flag			_M_once;

    public:
      _State_base() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
      _State_base(const _State_base&) = delete;
      _State_base& operator=(const _State_base&) = delete;
      virtual ~_State_base();

      _Result_base&
      wait()
      {
	_M_run_deferred();
	unique_lock<mutex> __lock(_M_mutex);
	_M_cond.wait(__lock, [&] { return _M_ready(); });
	return *_M_result;
      }

      template<typename _Rep, typename _Period>
        future_status
        wait_for(const chrono::duration<_Rep, _Period>& __rel)
        {
	  unique_lock<mutex> __lock(_M_mutex);
	  if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
	    return future_status::ready;
	  return future_status::timeout;
	}

      template<typename _Clock, typename _Duration>
        future_status
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
        {
	  unique_lock<mutex> __lock(_M_mutex);
	  if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
	    return future_status::ready;
	  return future_status::timeout;
	}

      void
      _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false)
      {
        bool __set = false;
        // all calls to this function are serialized,
        // side-effects of invoking __res only happen once
        call_once(_M_once, &_State_base::_M_do_set, this, ref(__res),
            ref(__set));
	if (__set)
	  _M_cond.notify_all();
	else if (!__ignore_failure)
          __throw_future_error(int(future_errc::promise_already_satisfied));
      }

      void
      _M_break_promise(_Ptr_type __res)
      {
	if (static_cast<bool>(__res))
	  {
	    error_code __ec(make_error_code(future_errc::broken_promise));
	    __res->_M_error = copy_exception(future_error(__ec));
	    {
	      lock_guard<mutex> __lock(_M_mutex);
	      _M_result.swap(__res);
	    }
	    _M_cond.notify_all();
	  }
      }

      // Called when this object is passed to a future.
      void
      _M_set_retrieved_flag()
      {
	if (_M_retrieved.test_and_set())
	  __throw_future_error(int(future_errc::future_already_retrieved));
      }

      template<typename _Res, typename _Arg>
        struct _Setter;

      // set lvalues
      template<typename _Res, typename _Arg>
        struct _Setter<_Res, _Arg&>
        {
          // check this is only used by promise<R>::set_value(const R&)
          // or promise<R>::set_value(R&)
          static_assert(is_same<_Res, _Arg&>::value  // promise<R&>
              || is_same<const _Res, _Arg>::value,  // promise<R>
              "Invalid specialisation");

          typename promise<_Res>::_Ptr_type operator()()
          {
            _State_base::_S_check(_M_promise->_M_future);
            _M_promise->_M_storage->_M_set(_M_arg);
            return std::move(_M_promise->_M_storage);
          }
          promise<_Res>*    _M_promise;
          _Arg&             _M_arg;
        };

      // set rvalues
      template<typename _Res>
        struct _Setter<_Res, _Res&&>
        {
          typename promise<_Res>::_Ptr_type operator()()
          {
            _State_base::_S_check(_M_promise->_M_future);
            _M_promise->_M_storage->_M_set(std::move(_M_arg));
            return std::move(_M_promise->_M_storage);
          }
          promise<_Res>*    _M_promise;
          _Res&             _M_arg;
        };

      struct __exception_ptr_tag { };

      // set exceptions
      template<typename _Res>
        struct _Setter<_Res, __exception_ptr_tag>
        {
          typename promise<_Res>::_Ptr_type operator()()
          {
            _State_base::_S_check(_M_promise->_M_future);
            _M_promise->_M_storage->_M_error = _M_ex;
            return std::move(_M_promise->_M_storage);
          }

          promise<_Res>*   _M_promise;
          exception_ptr&    _M_ex;
        };

      template<typename _Res, typename _Arg>
        static _Setter<_Res, _Arg&&>
        __setter(promise<_Res>* __prom, _Arg&& __arg)
        {
          return _Setter<_Res, _Arg&&>{ __prom, __arg };
        }

      template<typename _Res>
        static _Setter<_Res, __exception_ptr_tag>
        __setter(exception_ptr& __ex, promise<_Res>* __prom)
        {
          return _Setter<_Res, __exception_ptr_tag>{ __prom, __ex };
        }

      static _Setter<void, void>
      __setter(promise<void>* __prom);

      template<typename _Tp>
        static void
        _S_check(const shared_ptr<_Tp>& __p)
        {
          if (!static_cast<bool>(__p))
            __throw_future_error((int)future_errc::no_state);
        }

    private:
      void
      _M_do_set(function<_Ptr_type()>& __f, bool& __set)
      {
        _Ptr_type __res = __f();
        {
          lock_guard<mutex> __lock(_M_mutex);
          _M_result.swap(__res);
        }
        __set = true;
      }

      bool _M_ready() const noexcept { return static_cast<bool>(_M_result); }

      // Misnamed: waits for completion of async function.
      virtual void _M_run_deferred() { }
    };

    template<typename _BoundFn, typename = typename _BoundFn::result_type>
      class _Deferred_state;

    class _Async_state_common;

    template<typename _BoundFn, typename = typename _BoundFn::result_type>
      class _Async_state_impl;

    template<typename _Signature>
      class _Task_state_base;

    template<typename _Fn, typename _Alloc, typename _Signature>
      class _Task_state;

    template<typename _BoundFn>
      static std::shared_ptr<_State_base>
      _S_make_deferred_state(_BoundFn&& __fn);

    template<typename _BoundFn>
      static std::shared_ptr<_State_base>
      _S_make_async_state(_BoundFn&& __fn);

    template<typename _Res_ptr,
	     typename _Res = typename _Res_ptr::element_type::result_type>
      struct _Task_setter;

    template<typename _Res_ptr, typename _BoundFn>
      static _Task_setter<_Res_ptr>
      _S_task_setter(_Res_ptr& __ptr, _BoundFn&& __call)
      {
	return _Task_setter<_Res_ptr>{ __ptr, std::ref(__call) };
      }
  };

  /// Partial specialization for reference types.
  template<typename _Res>
    struct __future_base::_Result<_Res&> : __future_base::_Result_base
    {
      typedef _Res& result_type;

      _Result() noexcept : _M_value_ptr() { }

      void _M_set(_Res& __res) noexcept { _M_value_ptr = &__res; }

      _Res& _M_get() noexcept { return *_M_value_ptr; }

    private:
      _Res* 			_M_value_ptr;

      void _M_destroy() { delete this; }
    };

  /// Explicit specialization for void.
  template<>
    struct __future_base::_Result<void> : __future_base::_Result_base
    {
      typedef void result_type;

    private:
      void _M_destroy() { delete this; }
    };


  /// Common implementation for future and shared_future.
  template<typename _Res>
    class __basic_future : public __future_base
    {
    protected:
      typedef shared_ptr<_State_base>		__state_type;
      typedef __future_base::_Result<_Res>&	__result_type;

    private:
      __state_type 		_M_state;

    public:
      // Disable copying.
      __basic_future(const __basic_future&) = delete;
      __basic_future& operator=(const __basic_future&) = delete;

      bool
      valid() const noexcept { return static_cast<bool>(_M_state); }

      void
      wait() const
      {
        _State_base::_S_check(_M_state);
        _M_state->wait();
      }

      template<typename _Rep, typename _Period>
        future_status
        wait_for(const chrono::duration<_Rep, _Period>& __rel) const
        {
          _State_base::_S_check(_M_state);
          return _M_state->wait_for(__rel);
        }

      template<typename _Clock, typename _Duration>
        future_status
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
        {
          _State_base::_S_check(_M_state);
          return _M_state->wait_until(__abs);
        }

    protected:
      /// Wait for the state to be ready and rethrow any stored exception
      __result_type
      _M_get_result() const
      {
        _State_base::_S_check(_M_state);
        _Result_base& __res = _M_state->wait();
        if (!(__res._M_error == 0))
          rethrow_exception(__res._M_error);
        return static_cast<__result_type>(__res);
      }

      void _M_swap(__basic_future& __that) noexcept
      {
        _M_state.swap(__that._M_state);
      }

      // Construction of a future by promise::get_future()
      explicit
      __basic_future(const __state_type& __state) : _M_state(__state)
      {
        _State_base::_S_check(_M_state);
        _M_state->_M_set_retrieved_flag();
      }

      // Copy construction from a shared_future
      explicit
      __basic_future(const shared_future<_Res>&) noexcept;

      // Move construction from a shared_future
      explicit
      __basic_future(shared_future<_Res>&&) noexcept;

      // Move construction from a future
      explicit
      __basic_future(future<_Res>&&) noexcept;

      constexpr __basic_future() noexcept : _M_state() { }

      struct _Reset
      {
        explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { }
        ~_Reset() { _M_fut._M_state.reset(); }
        __basic_future& _M_fut;
      };
    };


  /// Primary template for future.
  template<typename _Res>
    class future : public __basic_future<_Res>
    {
      friend class promise<_Res>;
      template<typename> friend class packaged_task;
      template<typename _Fn, typename... _Args>
        friend future<typename result_of<_Fn(_Args...)>::type>
        async(launch, _Fn&&, _Args&&...);

      typedef __basic_future<_Res> _Base_type;
      typedef typename _Base_type::__state_type __state_type;

      explicit
      future(const __state_type& __state) : _Base_type(__state) { }

    public:
      constexpr future() noexcept : _Base_type() { }

      /// Move constructor
      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }

      // Disable copying
      future(const future&) = delete;
      future& operator=(const future&) = delete;

      future& operator=(future&& __fut) noexcept
      {
        future(std::move(__fut))._M_swap(*this);
        return *this;
      }

      /// Retrieving the value
      _Res
      get()
      {
        typename _Base_type::_Reset __reset(*this);
        return std::move(this->_M_get_result()._M_value());
      }

      shared_future<_Res> share();
    };

  /// Partial specialization for future<R&>
  template<typename _Res>
    class future<_Res&> : public __basic_future<_Res&>
    {
      friend class promise<_Res&>;
      template<typename> friend class packaged_task;
      template<typename _Fn, typename... _Args>
        friend future<typename result_of<_Fn(_Args...)>::type>
        async(launch, _Fn&&, _Args&&...);

      typedef __basic_future<_Res&> _Base_type;
      typedef typename _Base_type::__state_type __state_type;

      explicit
      future(const __state_type& __state) : _Base_type(__state) { }

    public:
      constexpr future() noexcept : _Base_type() { }

      /// Move constructor
      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }

      // Disable copying
      future(const future&) = delete;
      future& operator=(const future&) = delete;

      future& operator=(future&& __fut) noexcept
      {
        future(std::move(__fut))._M_swap(*this);
        return *this;
      }

      /// Retrieving the value
      _Res&
      get()
      {
        typename _Base_type::_Reset __reset(*this);
        return this->_M_get_result()._M_get();
      }

      shared_future<_Res&> share();
    };

  /// Explicit specialization for future<void>
  template<>
    class future<void> : public __basic_future<void>
    {
      friend class promise<void>;
      template<typename> friend class packaged_task;
      template<typename _Fn, typename... _Args>
        friend future<typename result_of<_Fn(_Args...)>::type>
        async(launch, _Fn&&, _Args&&...);

      typedef __basic_future<void> _Base_type;
      typedef typename _Base_type::__state_type __state_type;

      explicit
      future(const __state_type& __state) : _Base_type(__state) { }

    public:
      constexpr future() noexcept : _Base_type() { }

      /// Move constructor
      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }

      // Disable copying
      future(const future&) = delete;
      future& operator=(const future&) = delete;

      future& operator=(future&& __fut) noexcept
      {
        future(std::move(__fut))._M_swap(*this);
        return *this;
      }

      /// Retrieving the value
      void
      get()
      {
        typename _Base_type::_Reset __reset(*this);
        this->_M_get_result();
      }

      shared_future<void> share();
    };


  /// Primary template for shared_future.
  template<typename _Res>
    class shared_future : public __basic_future<_Res>
    {
      typedef __basic_future<_Res> _Base_type;

    public:
      constexpr shared_future() noexcept : _Base_type() { }

      /// Copy constructor
      shared_future(const shared_future& __sf) : _Base_type(__sf) { }

      /// Construct from a future rvalue
      shared_future(future<_Res>&& __uf) noexcept
      : _Base_type(std::move(__uf))
      { }

      /// Construct from a shared_future rvalue
      shared_future(shared_future&& __sf) noexcept
      : _Base_type(std::move(__sf))
      { }

      shared_future& operator=(const shared_future& __sf)
      {
        shared_future(__sf)._M_swap(*this);
        return *this;
      }

      shared_future& operator=(shared_future&& __sf) noexcept
      {
        shared_future(std::move(__sf))._M_swap(*this);
        return *this;
      }

      /// Retrieving the value
      const _Res&
      get() const { return this->_M_get_result()._M_value(); }
    };

  /// Partial specialization for shared_future<R&>
  template<typename _Res>
    class shared_future<_Res&> : public __basic_future<_Res&>
    {
      typedef __basic_future<_Res&>           _Base_type;

    public:
      constexpr shared_future() noexcept : _Base_type() { }

      /// Copy constructor
      shared_future(const shared_future& __sf) : _Base_type(__sf) { }

      /// Construct from a future rvalue
      shared_future(future<_Res&>&& __uf) noexcept
      : _Base_type(std::move(__uf))
      { }

      /// Construct from a shared_future rvalue
      shared_future(shared_future&& __sf) noexcept
      : _Base_type(std::move(__sf))
      { }

      shared_future& operator=(const shared_future& __sf)
      {
        shared_future(__sf)._M_swap(*this);
        return *this;
      }

      shared_future& operator=(shared_future&& __sf) noexcept
      {
        shared_future(std::move(__sf))._M_swap(*this);
        return *this;
      }

      /// Retrieving the value
      _Res&
      get() const { return this->_M_get_result()._M_get(); }
    };

  /// Explicit specialization for shared_future<void>
  template<>
    class shared_future<void> : public __basic_future<void>
    {
      typedef __basic_future<void> _Base_type;

    public:
      constexpr shared_future() noexcept : _Base_type() { }

      /// Copy constructor
      shared_future(const shared_future& __sf) : _Base_type(__sf) { }

      /// Construct from a future rvalue
      shared_future(future<void>&& __uf) noexcept
      : _Base_type(std::move(__uf))
      { }

      /// Construct from a shared_future rvalue
      shared_future(shared_future&& __sf) noexcept
      : _Base_type(std::move(__sf))
      { }

      shared_future& operator=(const shared_future& __sf)
      {
        shared_future(__sf)._M_swap(*this);
        return *this;
      }

      shared_future& operator=(shared_future&& __sf) noexcept
      {
        shared_future(std::move(__sf))._M_swap(*this);
        return *this;
      }

      // Retrieving the value
      void
      get() const { this->_M_get_result(); }
    };

  // Now we can define the protected __basic_future constructors.
  template<typename _Res>
    inline __basic_future<_Res>::
    __basic_future(const shared_future<_Res>& __sf) noexcept
    : _M_state(__sf._M_state)
    { }

  template<typename _Res>
    inline __basic_future<_Res>::
    __basic_future(shared_future<_Res>&& __sf) noexcept
    : _M_state(std::move(__sf._M_state))
    { }

  template<typename _Res>
    inline __basic_future<_Res>::
    __basic_future(future<_Res>&& __uf) noexcept
    : _M_state(std::move(__uf._M_state))
    { }

  template<typename _Res>
    inline shared_future<_Res>
    future<_Res>::share()
    { return shared_future<_Res>(std::move(*this)); }

  template<typename _Res>
    inline shared_future<_Res&>
    future<_Res&>::share()
    { return shared_future<_Res&>(std::move(*this)); }

  inline shared_future<void>
  future<void>::share()
  { return shared_future<void>(std::move(*this)); }

  /// Primary template for promise
  template<typename _Res>
    class promise
    {
      typedef __future_base::_State_base 	_State;
      typedef __future_base::_Result<_Res>	_Res_type;
      typedef __future_base::_Ptr<_Res_type>	_Ptr_type;
      template<typename, typename> friend class _State::_Setter;

      shared_ptr<_State>                        _M_future;
      _Ptr_type                                 _M_storage;

    public:
      promise()
      : _M_future(std::make_shared<_State>()),
	_M_storage(new _Res_type())
      { }

      promise(promise&& __rhs) noexcept
      : _M_future(std::move(__rhs._M_future)),
	_M_storage(std::move(__rhs._M_storage))
      { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator& __a)
        : _M_future(std::allocate_shared<_State>(__a)),
	  _M_storage(__future_base::_S_allocate_result<_Res>(__a))
        { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
        : _M_future(std::move(__rhs._M_future)),
	  _M_storage(std::move(__rhs._M_storage))
        { }

      promise(const promise&) = delete;

      ~promise()
      {
        if (static_cast<bool>(_M_future) && !_M_future.unique())
          _M_future->_M_break_promise(std::move(_M_storage));
      }

      // Assignment
      promise&
      operator=(promise&& __rhs) noexcept
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

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

      void
      swap(promise& __rhs) noexcept
      {
        _M_future.swap(__rhs._M_future);
        _M_storage.swap(__rhs._M_storage);
      }

      // Retrieving the result
      future<_Res>
      get_future()
      { return future<_Res>(_M_future); }

      // Setting the result
      void
      set_value(const _Res& __r)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(this, __r);
        __future->_M_set_result(std::move(__setter));
      }

      void
      set_value(_Res&& __r)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(this, std::move(__r));
        __future->_M_set_result(std::move(__setter));
      }

      void
      set_exception(exception_ptr __p)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(__p, this);
        __future->_M_set_result(std::move(__setter));
      }
    };

  template<typename _Res>
    inline void
    swap(promise<_Res>& __x, promise<_Res>& __y) noexcept
    { __x.swap(__y); }

  template<typename _Res, typename _Alloc>
    struct uses_allocator<promise<_Res>, _Alloc>
    : public true_type { };


  /// Partial specialization for promise<R&>
  template<typename _Res>
    class promise<_Res&>
    {
      typedef __future_base::_State_base	_State;
      typedef __future_base::_Result<_Res&>	_Res_type;
      typedef __future_base::_Ptr<_Res_type> 	_Ptr_type;
      template<typename, typename> friend class _State::_Setter;

      shared_ptr<_State>                        _M_future;
      _Ptr_type                                 _M_storage;

    public:
      promise()
      : _M_future(std::make_shared<_State>()),
	_M_storage(new _Res_type())
      { }

      promise(promise&& __rhs) noexcept
      : _M_future(std::move(__rhs._M_future)),
	_M_storage(std::move(__rhs._M_storage))
      { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator& __a)
        : _M_future(std::allocate_shared<_State>(__a)),
	  _M_storage(__future_base::_S_allocate_result<_Res&>(__a))
        { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
        : _M_future(std::move(__rhs._M_future)),
	  _M_storage(std::move(__rhs._M_storage))
        { }

      promise(const promise&) = delete;

      ~promise()
      {
        if (static_cast<bool>(_M_future) && !_M_future.unique())
          _M_future->_M_break_promise(std::move(_M_storage));
      }

      // Assignment
      promise&
      operator=(promise&& __rhs) noexcept
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

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

      void
      swap(promise& __rhs) noexcept
      {
        _M_future.swap(__rhs._M_future);
        _M_storage.swap(__rhs._M_storage);
      }

      // Retrieving the result
      future<_Res&>
      get_future()
      { return future<_Res&>(_M_future); }

      // Setting the result
      void
      set_value(_Res& __r)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(this, __r);
        __future->_M_set_result(std::move(__setter));
      }

      void
      set_exception(exception_ptr __p)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(__p, this);
        __future->_M_set_result(std::move(__setter));
      }
    };

  /// Explicit specialization for promise<void>
  template<>
    class promise<void>
    {
      typedef __future_base::_State_base	_State;
      typedef __future_base::_Result<void>	_Res_type;
      typedef __future_base::_Ptr<_Res_type> 	_Ptr_type;
      template<typename, typename> friend class _State::_Setter;

      shared_ptr<_State>                        _M_future;
      _Ptr_type                                 _M_storage;

    public:
      promise()
      : _M_future(std::make_shared<_State>()),
	_M_storage(new _Res_type())
      { }

      promise(promise&& __rhs) noexcept
      : _M_future(std::move(__rhs._M_future)),
	_M_storage(std::move(__rhs._M_storage))
      { }

      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator& __a)
        : _M_future(std::allocate_shared<_State>(__a)),
	  _M_storage(__future_base::_S_allocate_result<void>(__a))
        { }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2095.  missing constructors needed for uses-allocator construction
      template<typename _Allocator>
        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
        : _M_future(std::move(__rhs._M_future)),
	  _M_storage(std::move(__rhs._M_storage))
        { }

      promise(const promise&) = delete;

      ~promise()
      {
        if (static_cast<bool>(_M_future) && !_M_future.unique())
          _M_future->_M_break_promise(std::move(_M_storage));
      }

      // Assignment
      promise&
      operator=(promise&& __rhs) noexcept
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

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

      void
      swap(promise& __rhs) noexcept
      {
        _M_future.swap(__rhs._M_future);
        _M_storage.swap(__rhs._M_storage);
      }

      // Retrieving the result
      future<void>
      get_future()
      { return future<void>(_M_future); }

      // Setting the result
      void set_value();

      void
      set_exception(exception_ptr __p)
      {
	auto __future = _M_future;
        auto __setter = _State::__setter(__p, this);
        __future->_M_set_result(std::move(__setter));
      }
    };

  // set void
  template<>
    struct __future_base::_State_base::_Setter<void, void>
    {
      promise<void>::_Ptr_type operator()()
      {
        _State_base::_S_check(_M_promise->_M_future);
        return std::move(_M_promise->_M_storage);
      }

      promise<void>*    _M_promise;
    };

  inline __future_base::_State_base::_Setter<void, void>
  __future_base::_State_base::__setter(promise<void>* __prom)
  {
    return _Setter<void, void>{ __prom };
  }

  inline void
  promise<void>::set_value()
  {
    auto __future = _M_future;
    auto __setter = _State::__setter(this);
    __future->_M_set_result(std::move(__setter));
  }


  template<typename _Ptr_type, typename _Res>
    struct __future_base::_Task_setter
    {
      _Ptr_type operator()()
      {
	__try
	  {
	    _M_result->_M_set(_M_fn());
	  }
	__catch(...)
	  {
	    _M_result->_M_error = current_exception();
	  }
	return std::move(_M_result);
      }
      _Ptr_type&                _M_result;
      std::function<_Res()>     _M_fn;
    };

  template<typename _Ptr_type>
    struct __future_base::_Task_setter<_Ptr_type, void>
    {
      _Ptr_type operator()()
      {
	__try
	  {
	    _M_fn();
	  }
	__catch(...)
	  {
	    _M_result->_M_error = current_exception();
	  }
	return std::move(_M_result);
      }
      _Ptr_type&                _M_result;
      std::function<void()>     _M_fn;
    };

  template<typename _Res, typename... _Args>
    struct __future_base::_Task_state_base<_Res(_Args...)>
    : __future_base::_State_base
    {
      typedef _Res _Res_type;

      template<typename _Alloc>
	_Task_state_base(const _Alloc& __a)
	: _M_result(_S_allocate_result<_Res>(__a))
	{ }

      virtual void
      _M_run(_Args... __args) = 0;

      virtual shared_ptr<_Task_state_base>
      _M_reset() = 0;

      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
      _Ptr_type _M_result;
    };

  template<typename _Fn, typename _Alloc, typename _Res, typename... _Args>
    struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final
    : __future_base::_Task_state_base<_Res(_Args...)>
    {
      template<typename _Fn2>
	_Task_state(_Fn2&& __fn, const _Alloc& __a)
	: _Task_state_base<_Res(_Args...)>(__a),
	  _M_impl(std::forward<_Fn2>(__fn), __a)
	{ }

    private:
      virtual void
      _M_run(_Args... __args)
      {
	// bound arguments decay so wrap lvalue references
	auto __boundfn = std::__bind_simple(std::ref(_M_impl._M_fn),
	    _S_maybe_wrap_ref(std::forward<_Args>(__args))...);
	auto __setter = _S_task_setter(this->_M_result, std::move(__boundfn));
	this->_M_set_result(std::move(__setter));
      }

      virtual shared_ptr<_Task_state_base<_Res(_Args...)>>
      _M_reset();

      template<typename _Tp>
	static reference_wrapper<_Tp>
	_S_maybe_wrap_ref(_Tp& __t)
	{ return std::ref(__t); }

      template<typename _Tp>
	static
	typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp>::type&&
	_S_maybe_wrap_ref(_Tp&& __t)
	{ return std::forward<_Tp>(__t); }

      struct _Impl : _Alloc
      {
	template<typename _Fn2>
	  _Impl(_Fn2&& __fn, const _Alloc& __a)
	  : _Alloc(__a), _M_fn(std::forward<_Fn2>(__fn)) { }
	_Fn _M_fn;
      } _M_impl;
    };

  template<typename _Signature, typename _Fn, typename _Alloc>
    static shared_ptr<__future_base::_Task_state_base<_Signature>>
    __create_task_state(_Fn&& __fn, const _Alloc& __a)
    {
      typedef typename decay<_Fn>::type _Fn2;
      typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State;
      return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a);
    }

  template<typename _Fn, typename _Alloc, typename _Res, typename... _Args>
    shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>>
    __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset()
    {
      return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn),
						 static_cast<_Alloc&>(_M_impl));
    }

  template<typename _Task, typename _Fn, bool
	   = is_same<_Task, typename decay<_Fn>::type>::value>
    struct __constrain_pkgdtask
    { typedef void __type; };

  template<typename _Task, typename _Fn>
    struct __constrain_pkgdtask<_Task, _Fn, true>
    { };

  /// packaged_task
  template<typename _Res, typename... _ArgTypes>
    class packaged_task<_Res(_ArgTypes...)>
    {
      typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type;
      shared_ptr<_State_type>                   _M_state;

    public:
      // Construction and destruction
      packaged_task() noexcept { }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2095.  missing constructors needed for uses-allocator construction
      template<typename _Allocator>
	packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
	{ }

      template<typename _Fn, typename = typename
	       __constrain_pkgdtask<packaged_task, _Fn>::__type>
	explicit
	packaged_task(_Fn&& __fn)
	: packaged_task(allocator_arg, std::allocator<int>(),
			std::forward<_Fn>(__fn))
	{ }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 2097.  packaged_task constructors should be constrained
      template<typename _Fn, typename _Alloc, typename = typename
	       __constrain_pkgdtask<packaged_task, _Fn>::__type>
	explicit
	packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn)
	: _M_state(__create_task_state<_Res(_ArgTypes...)>(
		    std::forward<_Fn>(__fn), __a))
	{ }

      ~packaged_task()
      {
        if (static_cast<bool>(_M_state) && !_M_state.unique())
	  _M_state->_M_break_promise(std::move(_M_state->_M_result));
      }

      // No copy
      packaged_task(const packaged_task&) = delete;
      packaged_task& operator=(const packaged_task&) = delete;

      template<typename _Allocator>
	packaged_task(allocator_arg_t, const _Allocator&,
		      const packaged_task&) = delete;

      // Move support
      packaged_task(packaged_task&& __other) noexcept
      { this->swap(__other); }

      template<typename _Allocator>
	packaged_task(allocator_arg_t, const _Allocator&,
		      packaged_task&& __other) noexcept
	{ this->swap(__other); }

      packaged_task& operator=(packaged_task&& __other) noexcept
      {
	packaged_task(std::move(__other)).swap(*this);
	return *this;
      }

      void
      swap(packaged_task& __other) noexcept
      { _M_state.swap(__other._M_state); }

      bool
      valid() const noexcept
      { return static_cast<bool>(_M_state); }

      // Result retrieval
      future<_Res>
      get_future()
      { return future<_Res>(_M_state); }

      // Execution
      void
      operator()(_ArgTypes... __args)
      {
	__future_base::_State_base::_S_check(_M_state);
	auto __state = _M_state;
	__state->_M_run(std::forward<_ArgTypes>(__args)...);
      }

      void
      reset()
      {
	__future_base::_State_base::_S_check(_M_state);
	packaged_task __tmp;
	__tmp._M_state = _M_state;
	_M_state = _M_state->_M_reset();
      }
    };

  /// swap
  template<typename _Res, typename... _ArgTypes>
    inline void
    swap(packaged_task<_Res(_ArgTypes...)>& __x,
	 packaged_task<_Res(_ArgTypes...)>& __y) noexcept
    { __x.swap(__y); }

  template<typename _Res, typename _Alloc>
    struct uses_allocator<packaged_task<_Res>, _Alloc>
    : public true_type { };


  template<typename _BoundFn, typename _Res>
    class __future_base::_Deferred_state final
    : public __future_base::_State_base
    {
    public:
      explicit
      _Deferred_state(_BoundFn&& __fn)
      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
      { }

    private:
      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
      _Ptr_type _M_result;
      _BoundFn _M_fn;

      virtual void
      _M_run_deferred()
      {
        // safe to call multiple times so ignore failure
        _M_set_result(_S_task_setter(_M_result, _M_fn), true);
      }
    };

  class __future_base::_Async_state_common : public __future_base::_State_base
  {
  protected:
#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
    ~_Async_state_common();
#else
    ~_Async_state_common() = default;
#endif

    // Allow non-timed waiting functions to block until the thread completes,
    // as if joined.
    virtual void _M_run_deferred() { _M_join(); }

    void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); }

    thread _M_thread;
    once_flag _M_once;
  };

  template<typename _BoundFn, typename _Res>
    class __future_base::_Async_state_impl final
    : public __future_base::_Async_state_common
    {
    public:
      explicit
      _Async_state_impl(_BoundFn&& __fn)
      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
      {
	_M_thread = std::thread{ [this] {
	  _M_set_result(_S_task_setter(_M_result, _M_fn));
        } };
      }

      ~_Async_state_impl() { _M_join(); }

    private:
      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
      _Ptr_type _M_result;
      _BoundFn _M_fn;
    };

  template<typename _BoundFn>
    inline std::shared_ptr<__future_base::_State_base>
    __future_base::_S_make_deferred_state(_BoundFn&& __fn)
    {
      typedef typename remove_reference<_BoundFn>::type __fn_type;
      typedef _Deferred_state<__fn_type> __state_type;
      return std::make_shared<__state_type>(std::move(__fn));
    }

  template<typename _BoundFn>
    inline std::shared_ptr<__future_base::_State_base>
    __future_base::_S_make_async_state(_BoundFn&& __fn)
    {
      typedef typename remove_reference<_BoundFn>::type __fn_type;
      typedef _Async_state_impl<__fn_type> __state_type;
      return std::make_shared<__state_type>(std::move(__fn));
    }


  /// async
  template<typename _Fn, typename... _Args>
    future<typename result_of<_Fn(_Args...)>::type>
    async(launch __policy, _Fn&& __fn, _Args&&... __args)
    {
      typedef typename result_of<_Fn(_Args...)>::type result_type;
      std::shared_ptr<__future_base::_State_base> __state;
      if ((__policy & (launch::async|launch::deferred)) == launch::async)
	{
	  __state = __future_base::_S_make_async_state(std::__bind_simple(
              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
	}
      else
	{
	  __state = __future_base::_S_make_deferred_state(std::__bind_simple(
              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
	}
      return future<result_type>(__state);
    }

  /// async, potential overload
  template<typename _Fn, typename... _Args>
    inline future<typename result_of<_Fn(_Args...)>::type>
    async(_Fn&& __fn, _Args&&... __args)
    {
      return async(launch::async|launch::deferred, std::forward<_Fn>(__fn),
		   std::forward<_Args>(__args)...);
    }

#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
       // && ATOMIC_INT_LOCK_FREE

  // @} group futures
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif // C++11

#endif // _GLIBCXX_FUTURE
