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

// Copyright (C) 2009, 2010, 2011 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

#ifndef __GXX_EXPERIMENTAL_CXX0X__
# include <bits/c++0x_warning.h>
#else

#include <functional>
#include <memory>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <system_error>
#include <exception>
#include <atomic>
#include <bits/functexcept.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
  {
    broken_promise,
    future_already_retrieved,
    promise_already_satisfied,
    no_state
  };

  /// 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();

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

  /// Overload for make_error_condition.
  inline error_condition 
  make_error_condition(future_errc __errc)
  { 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() throw();

    virtual const char* 
    what() const throw();

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

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

  template<typename _Res>
    class shared_future;

  template<typename _Res>
    class atomic_future;

  template<typename _Signature> 
    class packaged_task;

  template<typename _Res>
    class promise;

  /// Launch code for futures
  enum class launch 
  { 
    any, 
    async, 
    sync 
  };

  /// 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 _FnCheck, typename _Fn, typename... _Args>
    struct __async_sfinae_helper
    {
      typedef future<typename result_of<_Fn(_Args...)>::type> type;
    };

  template<typename _Fn, typename... _Args>
    struct __async_sfinae_helper<launch, _Fn, _Args...>
    { };

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

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

  /// 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:
	_Result() : _M_initialized() { }
	
	~_Result()
	{
	  if (_M_initialized)
	    _M_value().~_Res();
	}

	// Return lvalue, future will add const or rvalue-reference
	_Res& 
	_M_value() { 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() { return static_cast<void*>(&_M_storage); }
    };

    // TODO: use template alias when available
    /*
      template<typename _Res>
      using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;
    */
    /// A unique_ptr based on the instantiating type.
    template<typename _Res>
      struct _Ptr
      {
	typedef unique_ptr<_Res, _Result_base::_Deleter> type;
      };

    /// Result_alloc.
    template<typename _Res, typename _Alloc>
      struct _Result_alloc : _Result<_Res>, _Alloc
      {
        typedef typename _Alloc::template rebind<_Result_alloc>::other
          __allocator_type;

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

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


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

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

    public:
      _State_base() : _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);
	if (!_M_ready())
	  _M_cond.wait(__lock, std::bind<bool>(&_State_base::_M_ready, this));
	return *_M_result;
      }

      template<typename _Rep, typename _Period>
        bool
        wait_for(const chrono::duration<_Rep, _Period>& __rel)
        {
	  unique_lock<mutex> __lock(_M_mutex);
	  auto __bound = std::bind<bool>(&_State_base::_M_ready, this);
	  return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound);
	}

      template<typename _Clock, typename _Duration>
        bool
        wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
        {
	  unique_lock<mutex> __lock(_M_mutex);
	  auto __bound = std::bind<bool>(&_State_base::_M_ready, this);
	  return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound);
	}

      void
      _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false)
      {
        bool __set = __ignore_failure;
        // 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)
          __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 bool
        _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);
        }
        _M_cond.notify_all();
        __set = true;
      }

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

      virtual void _M_run_deferred() { }
    };

    template<typename _Res>
      class _Deferred_state;

    template<typename _Res>
      class _Async_state;

    template<typename _Signature>
      class _Task_state;

    template<typename _StateT, typename _Res = typename _StateT::_Res_type>
      struct _Task_setter;
  };

  /// Partial specialization for reference types.
  template<typename _Res>
    struct __future_base::_Result<_Res&> : __future_base::_Result_base
    {
      _Result() : _M_value_ptr() { }

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

      _Res& _M_get() { 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
    {
    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 { return static_cast<bool>(_M_state); }

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

      template<typename _Rep, typename _Period>
        bool
        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>
        bool
        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()
      {
        _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)
      {
        _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>&);

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

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

      constexpr __basic_future() : _M_state() { }

      struct _Reset
      {
        explicit _Reset(__basic_future& __fut) : _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() : _Base_type() { }

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

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

      future& operator=(future&& __fut)
      {
        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());
      }
    };
 
  /// 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() : _Base_type() { }

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

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

      future& operator=(future&& __fut)
      {
        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();
      }
    };

  /// 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() : _Base_type() { }

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

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

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

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


  /// 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() : _Base_type() { }

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

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

      /// Construct from a shared_future rvalue
      shared_future(shared_future&& __sf)
      : _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)
      {
        shared_future(std::move(__sf))._M_swap(*this);
        return *this;
      }

      /// Retrieving the value
      const _Res&
      get()
      {
	typename _Base_type::__result_type __r = this->_M_get_result();
	_Res& __rs(__r._M_value());
	return __rs;
      }
    };
 
  /// 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() : _Base_type() { }

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

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

      /// Construct from a shared_future rvalue
      shared_future(shared_future&& __sf)
      : _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)
      {
        shared_future(std::move(__sf))._M_swap(*this);
        return *this;
      }

      /// Retrieving the value
      _Res& 
      get() { 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() : _Base_type() { }

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

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

      /// Construct from a shared_future rvalue
      shared_future(shared_future&& __sf)
      : _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)
      {
        shared_future(std::move(__sf))._M_swap(*this);
        return *this;
      }

      // Retrieving the value
      void 
      get() { 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)
    : _M_state(__sf._M_state)
    { }

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

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


  /// Primary template for promise
  template<typename _Res>
    class promise
    {
      typedef __future_base::_State_base 			_State;
      typedef __future_base::_Result<_Res>			_Res_type;
      typedef typename __future_base::_Ptr<_Res_type>::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)
      : _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))
        { }

      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)
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

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

      void
      swap(promise& __rhs)
      {
        _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 __setter = _State::__setter(this, __r);
        _M_future->_M_set_result(std::move(__setter));
      }

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

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

  template<typename _Res>
    inline void
    swap(promise<_Res>& __x, promise<_Res>& __y)
    { __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 typename __future_base::_Ptr<_Res_type>::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)
      : _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))
        { }

      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)
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

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

      void
      swap(promise& __rhs)
      {
        _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 __setter = _State::__setter(this, __r);
        _M_future->_M_set_result(std::move(__setter));
      }

      void
      set_exception(exception_ptr __p)
      {
        auto __setter = _State::__setter(__p, this);
        _M_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 typename __future_base::_Ptr<_Res_type>::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)
      : _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))
        { }

      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)
      {
        promise(std::move(__rhs)).swap(*this);
        return *this;
      }

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

      void
      swap(promise& __rhs)
      {
        _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 __setter = _State::__setter(__p, this);
        _M_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 __setter = _State::__setter(this);
    _M_future->_M_set_result(std::move(__setter));
  }


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

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

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

      _Task_state(std::function<_Res(_Args...)> __task)
      : _M_result(new _Result<_Res>()), _M_task(std::move(__task))
      { }

      template<typename _Func, typename _Alloc>
        _Task_state(_Func&& __task, const _Alloc& __a)
        : _M_result(_S_allocate_result<_Res>(__a)),
	  _M_task(allocator_arg, __a, std::move(__task))
        { }

      void
      _M_run(_Args... __args)
      {
        // bound arguments decay so wrap lvalue references
        auto __bound = std::bind<_Res>(std::ref(_M_task),
            _S_maybe_wrap_ref(std::forward<_Args>(__args))...);
        _Task_setter<_Task_state> __setter{ this, std::move(__bound) };
        _M_set_result(std::move(__setter));
      }

      template<typename, typename> friend class _Task_setter;
      typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type;
      _Ptr_type _M_result;
      std::function<_Res(_Args...)> _M_task;

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

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

    public:
      typedef _Res result_type;

      // Construction and destruction
      packaged_task() { }

      template<typename _Fn>
        explicit
        packaged_task(const _Fn& __fn)
        : _M_state(std::make_shared<_State_type>(__fn))
        { }

      template<typename _Fn>
        explicit
        packaged_task(_Fn&& __fn)
        : _M_state(std::make_shared<_State_type>(std::move(__fn)))
        { }

      explicit
      packaged_task(_Res(*__fn)(_ArgTypes...))
      : _M_state(std::make_shared<_State_type>(__fn))
      { }

      template<typename _Fn, typename _Allocator>
        explicit
        packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn __fn)
        : _M_state(std::allocate_shared<_State_type>(__a, std::move(__fn)))
        { }

      ~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(packaged_task&) = delete;
      packaged_task& operator=(packaged_task&) = delete;

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

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

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

      bool
      valid() const
      { 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);
        _M_state->_M_run(std::forward<_ArgTypes>(__args)...);
      }

      void
      reset()
      {
        __future_base::_State_base::_S_check(_M_state);
        packaged_task(std::move(_M_state->_M_task)).swap(*this);
      }
    };

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

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


  template<typename _Res>
    class __future_base::_Deferred_state : public __future_base::_State_base
    {
    public:
      typedef _Res _Res_type;

      explicit
      _Deferred_state(std::function<_Res()>&& __fn)
      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
      { }

    private:
      template<typename, typename> friend class _Task_setter;
      typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type;
      _Ptr_type _M_result;
      std::function<_Res()> _M_fn;

      virtual void
      _M_run_deferred()
      {
        _Task_setter<_Deferred_state> __setter{ this, _M_fn };
        // safe to call multiple times so ignore failure
        _M_set_result(std::move(__setter), true);
      }
    };

  template<typename _Res>
    class __future_base::_Async_state : public __future_base::_State_base
    {
    public:
      typedef _Res _Res_type;

      explicit 
      _Async_state(std::function<_Res()>&& __fn)
      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)),
	_M_thread(mem_fn(&_Async_state::_M_do_run), this)
      { }

      ~_Async_state() { _M_thread.join(); }

    private:
      void _M_do_run()
      {
        _Task_setter<_Async_state> __setter{ this, std::move(_M_fn) };
        _M_set_result(std::move(__setter));
      }

      template<typename, typename> friend class _Task_setter;
      typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type;
      _Ptr_type _M_result;
      std::function<_Res()> _M_fn;
      thread _M_thread;
    };

  /// 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)
	{
	  typedef typename __future_base::_Async_state<result_type> _State;
	  __state = std::make_shared<_State>(std::bind<result_type>(
              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
	}
      else
	{
	  typedef typename __future_base::_Deferred_state<result_type> _State;
	  __state = std::make_shared<_State>(std::bind<result_type>(
              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
	}
      return future<result_type>(__state);
    }

  /// async, potential overload
  template<typename _Fn, typename... _Args>
    inline typename
    __async_sfinae_helper<typename decay<_Fn>::type, _Fn, _Args...>::type
    async(_Fn&& __fn, _Args&&... __args)
    {
      return async(launch::any, std::forward<_Fn>(__fn),
		   std::forward<_Args>(__args)...);
    }

#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
       // && _GLIBCXX_ATOMIC_BUILTINS_4

  // @} group futures
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif // __GXX_EXPERIMENTAL_CXX0X__

#endif // _GLIBCXX_FUTURE
