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

// Copyright (C) 2009, 2010 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 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
{
  /**
   * @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
  };

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

  /// Points to a statically-allocated object derived from error_category.
  extern const error_category* const future_category;

  // TODO: requires constexpr
  inline error_code make_error_code(future_errc __errc)
  { return error_code(static_cast<int>(__errc), *future_category); }

  // TODO: requires constexpr
  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;

  enum class launch { any, async, sync };

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

  template<typename _Fn, typename... _Args>
    typename
    enable_if<!is_same<typename decay<_Fn>::type, launch>::value,
              future<decltype(std::declval<_Fn>()(std::declval<_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() = default;
      _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();
    };

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

    // TODO: use when allocator_arg_t available
    /*
    /// Result_alloc.
    template<typename _Res, typename _Alloc>
      struct _Result_alloc : _Result<_Res>
      {
        typedef typename _Alloc::template rebind<_Result_alloc>::other
          __allocator_type;

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

        __allocator_type _M_alloc;
    };

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


    /// Shared state between a promise and one or more associated futures.
    class _State
    {
      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() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }

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

      _Result_base&
      wait()
      {
	_M_run_deferred();
	unique_lock<mutex> __lock(_M_mutex);
	if (!_M_ready())
	  _M_cond.wait(__lock, std::bind<bool>(&_State::_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::_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::_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, mem_fn(&_State::_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::_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::_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::_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;
  };

  inline __future_base::_Result_base::~_Result_base() = default;

  /// 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>		__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 { _M_state->wait(); }

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

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

    protected:
      /// Wait for the state to be ready and rethrow any stored exception
      __result_type
      _M_get_result()
      {
        _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::_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>&&);

      __basic_future() { }

      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:
      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:
      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:
      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:
      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:
      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:
      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 		_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))
      { }

      // TODO: needs allocator_arg_t
      /*
      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); }

  /// Partial specialization for promise<R&>
  template<typename _Res>
    class promise<_Res&>
    {
      typedef __future_base::_State 		_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))
      { }

      // TODO: needs allocator_arg_t
      /*
      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 		_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))
      { }


      // TODO: needs allocator_arg_t
      /*
      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::_Setter<void, void>
    {
      promise<void>::_Ptr_type operator()()
      {
        _State::_S_check(_M_promise->_M_future);
        return std::move(_M_promise->_M_storage);
      }

      promise<void>*    _M_promise;
    };

  inline __future_base::_State::_Setter<void, void>
  __future_base::_State::__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));
  }

  // TODO: needs allocators
  /*
  template<typename _Res, class Alloc>
    struct uses_allocator<promise<_Res>, Alloc> : true_type  { };
  */


  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
    {
      typedef _Res _Res_type;

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

      // TODO: needs allocator_arg_t
      /*
      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>(_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))
      { }

      // TODO: needs allocator_arg_t
      /*
      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); }

      explicit operator bool() 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::_S_check(_M_state);
        _M_state->_M_run(std::forward<_ArgTypes>(__args)...);
      }

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

  template<typename _Res, typename... _ArgTypes>
    inline void
    swap(packaged_task<_Res(_ArgTypes...)>& __x,
	 packaged_task<_Res(_ArgTypes...)>& __y)
    { __x.swap(__y); }
 
  template<typename _Res>
    class __future_base::_Deferred_state : public __future_base::_State
    {
    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
    {
    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;
    };

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

  template<typename _Fn, typename... _Args>
    inline typename
    enable_if<!is_same<typename decay<_Fn>::type, launch>::value,
              future<decltype(std::declval<_Fn>()(std::declval<_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
}

#endif // __GXX_EXPERIMENTAL_CXX0X__

#endif // _GLIBCXX_FUTURE
