xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/std/future (revision 0a8dc9fc45f4d0b236341a473fac4a486375f60c)
1e4b17023SJohn Marino// <future> -*- C++ -*-
2e4b17023SJohn Marino
3*95d28233SJohn Marino// Copyright (C) 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4e4b17023SJohn Marino//
5e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library.  This library is free
6e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the
7e4b17023SJohn Marino// terms of the GNU General Public License as published by the
8e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option)
9e4b17023SJohn Marino// any later version.
10e4b17023SJohn Marino
11e4b17023SJohn Marino// This library is distributed in the hope that it will be useful,
12e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of
13e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e4b17023SJohn Marino// GNU General Public License for more details.
15e4b17023SJohn Marino
16e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional
17e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version
18e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation.
19e4b17023SJohn Marino
20e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and
21e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program;
22e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23e4b17023SJohn Marino// <http://www.gnu.org/licenses/>.
24e4b17023SJohn Marino
25e4b17023SJohn Marino/** @file include/future
26e4b17023SJohn Marino *  This is a Standard C++ Library header.
27e4b17023SJohn Marino */
28e4b17023SJohn Marino
29e4b17023SJohn Marino#ifndef _GLIBCXX_FUTURE
30e4b17023SJohn Marino#define _GLIBCXX_FUTURE 1
31e4b17023SJohn Marino
32e4b17023SJohn Marino#pragma GCC system_header
33e4b17023SJohn Marino
34e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__
35e4b17023SJohn Marino# include <bits/c++0x_warning.h>
36e4b17023SJohn Marino#else
37e4b17023SJohn Marino
38e4b17023SJohn Marino#include <functional>
39e4b17023SJohn Marino#include <memory>
40e4b17023SJohn Marino#include <mutex>
41e4b17023SJohn Marino#include <thread>
42e4b17023SJohn Marino#include <condition_variable>
43e4b17023SJohn Marino#include <system_error>
44e4b17023SJohn Marino#include <exception>
45e4b17023SJohn Marino#include <atomic>
46e4b17023SJohn Marino#include <bits/functexcept.h>
47e4b17023SJohn Marino
48e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default)
49e4b17023SJohn Marino{
50e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION
51e4b17023SJohn Marino
52e4b17023SJohn Marino  /**
53e4b17023SJohn Marino   * @defgroup futures Futures
54e4b17023SJohn Marino   * @ingroup concurrency
55e4b17023SJohn Marino   *
56e4b17023SJohn Marino   * Classes for futures support.
57e4b17023SJohn Marino   * @{
58e4b17023SJohn Marino   */
59e4b17023SJohn Marino
60e4b17023SJohn Marino  /// Error code for futures
61e4b17023SJohn Marino  enum class future_errc
62e4b17023SJohn Marino  {
63e4b17023SJohn Marino    future_already_retrieved = 1,
64e4b17023SJohn Marino    promise_already_satisfied,
65e4b17023SJohn Marino    no_state,
66e4b17023SJohn Marino    broken_promise
67e4b17023SJohn Marino  };
68e4b17023SJohn Marino
69e4b17023SJohn Marino  /// Specialization.
70e4b17023SJohn Marino  template<>
71e4b17023SJohn Marino    struct is_error_code_enum<future_errc> : public true_type { };
72e4b17023SJohn Marino
73e4b17023SJohn Marino  /// Points to a statically-allocated object derived from error_category.
74e4b17023SJohn Marino  const error_category&
75e4b17023SJohn Marino  future_category() noexcept;
76e4b17023SJohn Marino
77e4b17023SJohn Marino  /// Overload for make_error_code.
78e4b17023SJohn Marino  inline error_code
79e4b17023SJohn Marino  make_error_code(future_errc __errc) noexcept
80e4b17023SJohn Marino  { return error_code(static_cast<int>(__errc), future_category()); }
81e4b17023SJohn Marino
82e4b17023SJohn Marino  /// Overload for make_error_condition.
83e4b17023SJohn Marino  inline error_condition
84e4b17023SJohn Marino  make_error_condition(future_errc __errc) noexcept
85e4b17023SJohn Marino  { return error_condition(static_cast<int>(__errc), future_category()); }
86e4b17023SJohn Marino
87e4b17023SJohn Marino  /**
88e4b17023SJohn Marino   *  @brief Exception type thrown by futures.
89e4b17023SJohn Marino   *  @ingroup exceptions
90e4b17023SJohn Marino   */
91e4b17023SJohn Marino  class future_error : public logic_error
92e4b17023SJohn Marino  {
93e4b17023SJohn Marino    error_code 			_M_code;
94e4b17023SJohn Marino
95e4b17023SJohn Marino  public:
96e4b17023SJohn Marino    explicit future_error(error_code __ec)
97e4b17023SJohn Marino    : logic_error("std::future_error"), _M_code(__ec)
98e4b17023SJohn Marino    { }
99e4b17023SJohn Marino
100e4b17023SJohn Marino    virtual ~future_error() noexcept;
101e4b17023SJohn Marino
102e4b17023SJohn Marino    virtual const char*
103e4b17023SJohn Marino    what() const noexcept;
104e4b17023SJohn Marino
105e4b17023SJohn Marino    const error_code&
106e4b17023SJohn Marino    code() const noexcept { return _M_code; }
107e4b17023SJohn Marino  };
108e4b17023SJohn Marino
109e4b17023SJohn Marino  // Forward declarations.
110e4b17023SJohn Marino  template<typename _Res>
111e4b17023SJohn Marino    class future;
112e4b17023SJohn Marino
113e4b17023SJohn Marino  template<typename _Res>
114e4b17023SJohn Marino    class shared_future;
115e4b17023SJohn Marino
116e4b17023SJohn Marino  template<typename _Signature>
117e4b17023SJohn Marino    class packaged_task;
118e4b17023SJohn Marino
119e4b17023SJohn Marino  template<typename _Res>
120e4b17023SJohn Marino    class promise;
121e4b17023SJohn Marino
122e4b17023SJohn Marino  /// Launch code for futures
123e4b17023SJohn Marino  enum class launch
124e4b17023SJohn Marino  {
125e4b17023SJohn Marino    async = 1,
126e4b17023SJohn Marino    deferred = 2
127e4b17023SJohn Marino  };
128e4b17023SJohn Marino
129e4b17023SJohn Marino  constexpr launch operator&(launch __x, launch __y)
130e4b17023SJohn Marino  {
131e4b17023SJohn Marino    return static_cast<launch>(
132e4b17023SJohn Marino	static_cast<int>(__x) & static_cast<int>(__y));
133e4b17023SJohn Marino  }
134e4b17023SJohn Marino
135e4b17023SJohn Marino  constexpr launch operator|(launch __x, launch __y)
136e4b17023SJohn Marino  {
137e4b17023SJohn Marino    return static_cast<launch>(
138e4b17023SJohn Marino	static_cast<int>(__x) | static_cast<int>(__y));
139e4b17023SJohn Marino  }
140e4b17023SJohn Marino
141e4b17023SJohn Marino  constexpr launch operator^(launch __x, launch __y)
142e4b17023SJohn Marino  {
143e4b17023SJohn Marino    return static_cast<launch>(
144e4b17023SJohn Marino	static_cast<int>(__x) ^ static_cast<int>(__y));
145e4b17023SJohn Marino  }
146e4b17023SJohn Marino
147e4b17023SJohn Marino  constexpr launch operator~(launch __x)
148e4b17023SJohn Marino  { return static_cast<launch>(~static_cast<int>(__x)); }
149e4b17023SJohn Marino
150e4b17023SJohn Marino  inline launch& operator&=(launch& __x, launch __y)
151e4b17023SJohn Marino  { return __x = __x & __y; }
152e4b17023SJohn Marino
153e4b17023SJohn Marino  inline launch& operator|=(launch& __x, launch __y)
154e4b17023SJohn Marino  { return __x = __x | __y; }
155e4b17023SJohn Marino
156e4b17023SJohn Marino  inline launch& operator^=(launch& __x, launch __y)
157e4b17023SJohn Marino  { return __x = __x ^ __y; }
158e4b17023SJohn Marino
159e4b17023SJohn Marino  /// Status code for futures
160e4b17023SJohn Marino  enum class future_status
161e4b17023SJohn Marino  {
162e4b17023SJohn Marino    ready,
163e4b17023SJohn Marino    timeout,
164e4b17023SJohn Marino    deferred
165e4b17023SJohn Marino  };
166e4b17023SJohn Marino
167e4b17023SJohn Marino  template<typename _Fn, typename... _Args>
168e4b17023SJohn Marino    future<typename result_of<_Fn(_Args...)>::type>
169e4b17023SJohn Marino    async(launch __policy, _Fn&& __fn, _Args&&... __args);
170e4b17023SJohn Marino
171e4b17023SJohn Marino  template<typename _FnCheck, typename _Fn, typename... _Args>
172e4b17023SJohn Marino    struct __async_sfinae_helper
173e4b17023SJohn Marino    {
174e4b17023SJohn Marino      typedef future<typename result_of<_Fn(_Args...)>::type> type;
175e4b17023SJohn Marino    };
176e4b17023SJohn Marino
177e4b17023SJohn Marino  template<typename _Fn, typename... _Args>
178e4b17023SJohn Marino    struct __async_sfinae_helper<launch, _Fn, _Args...>
179e4b17023SJohn Marino    { };
180e4b17023SJohn Marino
181e4b17023SJohn Marino  template<typename _Fn, typename... _Args>
182e4b17023SJohn Marino    typename
183e4b17023SJohn Marino    __async_sfinae_helper<typename decay<_Fn>::type, _Fn, _Args...>::type
184e4b17023SJohn Marino    async(_Fn&& __fn, _Args&&... __args);
185e4b17023SJohn Marino
186e4b17023SJohn Marino#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
187e4b17023SJohn Marino  && (ATOMIC_INT_LOCK_FREE > 1)
188e4b17023SJohn Marino
189e4b17023SJohn Marino  /// Base class and enclosing scope.
190e4b17023SJohn Marino  struct __future_base
191e4b17023SJohn Marino  {
192e4b17023SJohn Marino    /// Base class for results.
193e4b17023SJohn Marino    struct _Result_base
194e4b17023SJohn Marino    {
195e4b17023SJohn Marino      exception_ptr		_M_error;
196e4b17023SJohn Marino
197e4b17023SJohn Marino      _Result_base(const _Result_base&) = delete;
198e4b17023SJohn Marino      _Result_base& operator=(const _Result_base&) = delete;
199e4b17023SJohn Marino
200e4b17023SJohn Marino      // _M_destroy() allows derived classes to control deallocation
201e4b17023SJohn Marino      virtual void _M_destroy() = 0;
202e4b17023SJohn Marino
203e4b17023SJohn Marino      struct _Deleter
204e4b17023SJohn Marino      {
205e4b17023SJohn Marino	void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
206e4b17023SJohn Marino      };
207e4b17023SJohn Marino
208e4b17023SJohn Marino    protected:
209e4b17023SJohn Marino      _Result_base();
210e4b17023SJohn Marino      virtual ~_Result_base();
211e4b17023SJohn Marino    };
212e4b17023SJohn Marino
213e4b17023SJohn Marino    /// Result.
214e4b17023SJohn Marino    template<typename _Res>
215e4b17023SJohn Marino      struct _Result : _Result_base
216e4b17023SJohn Marino      {
217e4b17023SJohn Marino      private:
218e4b17023SJohn Marino	typedef alignment_of<_Res>				__a_of;
219e4b17023SJohn Marino	typedef aligned_storage<sizeof(_Res), __a_of::value>	__align_storage;
220e4b17023SJohn Marino	typedef typename __align_storage::type			__align_type;
221e4b17023SJohn Marino
222e4b17023SJohn Marino	__align_type		_M_storage;
223e4b17023SJohn Marino	bool 			_M_initialized;
224e4b17023SJohn Marino
225e4b17023SJohn Marino      public:
226e4b17023SJohn Marino	_Result() noexcept : _M_initialized() { }
227e4b17023SJohn Marino
228e4b17023SJohn Marino	~_Result()
229e4b17023SJohn Marino	{
230e4b17023SJohn Marino	  if (_M_initialized)
231e4b17023SJohn Marino	    _M_value().~_Res();
232e4b17023SJohn Marino	}
233e4b17023SJohn Marino
234e4b17023SJohn Marino	// Return lvalue, future will add const or rvalue-reference
235e4b17023SJohn Marino	_Res&
236e4b17023SJohn Marino	_M_value() noexcept { return *static_cast<_Res*>(_M_addr()); }
237e4b17023SJohn Marino
238e4b17023SJohn Marino	void
239e4b17023SJohn Marino	_M_set(const _Res& __res)
240e4b17023SJohn Marino	{
241e4b17023SJohn Marino	  ::new (_M_addr()) _Res(__res);
242e4b17023SJohn Marino	  _M_initialized = true;
243e4b17023SJohn Marino	}
244e4b17023SJohn Marino
245e4b17023SJohn Marino	void
246e4b17023SJohn Marino	_M_set(_Res&& __res)
247e4b17023SJohn Marino	{
248e4b17023SJohn Marino	  ::new (_M_addr()) _Res(std::move(__res));
249e4b17023SJohn Marino	  _M_initialized = true;
250e4b17023SJohn Marino	}
251e4b17023SJohn Marino
252e4b17023SJohn Marino      private:
253e4b17023SJohn Marino	void _M_destroy() { delete this; }
254e4b17023SJohn Marino
255e4b17023SJohn Marino	void* _M_addr() noexcept { return static_cast<void*>(&_M_storage); }
256e4b17023SJohn Marino    };
257e4b17023SJohn Marino
258e4b17023SJohn Marino    /// A unique_ptr based on the instantiating type.
259e4b17023SJohn Marino    template<typename _Res>
260e4b17023SJohn Marino      using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;
261e4b17023SJohn Marino
262e4b17023SJohn Marino    /// Result_alloc.
263e4b17023SJohn Marino    template<typename _Res, typename _Alloc>
264e4b17023SJohn Marino      struct _Result_alloc final : _Result<_Res>, _Alloc
265e4b17023SJohn Marino      {
266e4b17023SJohn Marino        typedef typename allocator_traits<_Alloc>::template
267e4b17023SJohn Marino          rebind_alloc<_Result_alloc> __allocator_type;
268e4b17023SJohn Marino
269e4b17023SJohn Marino        explicit
270e4b17023SJohn Marino	_Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a)
271e4b17023SJohn Marino        { }
272e4b17023SJohn Marino
273e4b17023SJohn Marino      private:
274e4b17023SJohn Marino	void _M_destroy()
275e4b17023SJohn Marino        {
276e4b17023SJohn Marino	  typedef allocator_traits<__allocator_type> __traits;
277e4b17023SJohn Marino          __allocator_type __a(*this);
278e4b17023SJohn Marino	  __traits::destroy(__a, this);
279e4b17023SJohn Marino	  __traits::deallocate(__a, this, 1);
280e4b17023SJohn Marino        }
281e4b17023SJohn Marino      };
282e4b17023SJohn Marino
283e4b17023SJohn Marino    template<typename _Res, typename _Allocator>
284e4b17023SJohn Marino      static _Ptr<_Result_alloc<_Res, _Allocator>>
285e4b17023SJohn Marino      _S_allocate_result(const _Allocator& __a)
286e4b17023SJohn Marino      {
287e4b17023SJohn Marino        typedef _Result_alloc<_Res, _Allocator>	__result_type;
288e4b17023SJohn Marino	typedef allocator_traits<typename __result_type::__allocator_type>
289e4b17023SJohn Marino	  __traits;
290e4b17023SJohn Marino        typename __traits::allocator_type __a2(__a);
291e4b17023SJohn Marino        __result_type* __p = __traits::allocate(__a2, 1);
292e4b17023SJohn Marino        __try
293e4b17023SJohn Marino	{
294e4b17023SJohn Marino	  __traits::construct(__a2, __p, __a);
295e4b17023SJohn Marino        }
296e4b17023SJohn Marino        __catch(...)
297e4b17023SJohn Marino        {
298e4b17023SJohn Marino	  __traits::deallocate(__a2, __p, 1);
299e4b17023SJohn Marino          __throw_exception_again;
300e4b17023SJohn Marino        }
301e4b17023SJohn Marino        return _Ptr<__result_type>(__p);
302e4b17023SJohn Marino      }
303e4b17023SJohn Marino
304e4b17023SJohn Marino
305e4b17023SJohn Marino    /// Base class for state between a promise and one or more
306e4b17023SJohn Marino    /// associated futures.
307e4b17023SJohn Marino    class _State_base
308e4b17023SJohn Marino    {
309e4b17023SJohn Marino      typedef _Ptr<_Result_base> _Ptr_type;
310e4b17023SJohn Marino
311e4b17023SJohn Marino      _Ptr_type			_M_result;
312e4b17023SJohn Marino      mutex               	_M_mutex;
313e4b17023SJohn Marino      condition_variable  	_M_cond;
314e4b17023SJohn Marino      atomic_flag         	_M_retrieved;
315e4b17023SJohn Marino      once_flag			_M_once;
316e4b17023SJohn Marino
317e4b17023SJohn Marino    public:
318e4b17023SJohn Marino      _State_base() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
319e4b17023SJohn Marino      _State_base(const _State_base&) = delete;
320e4b17023SJohn Marino      _State_base& operator=(const _State_base&) = delete;
321e4b17023SJohn Marino      virtual ~_State_base();
322e4b17023SJohn Marino
323e4b17023SJohn Marino      _Result_base&
324e4b17023SJohn Marino      wait()
325e4b17023SJohn Marino      {
326e4b17023SJohn Marino	_M_run_deferred();
327e4b17023SJohn Marino	unique_lock<mutex> __lock(_M_mutex);
328e4b17023SJohn Marino	_M_cond.wait(__lock, [&] { return _M_ready(); });
329e4b17023SJohn Marino	return *_M_result;
330e4b17023SJohn Marino      }
331e4b17023SJohn Marino
332e4b17023SJohn Marino      template<typename _Rep, typename _Period>
333e4b17023SJohn Marino        future_status
334e4b17023SJohn Marino        wait_for(const chrono::duration<_Rep, _Period>& __rel)
335e4b17023SJohn Marino        {
336e4b17023SJohn Marino	  unique_lock<mutex> __lock(_M_mutex);
337e4b17023SJohn Marino	  if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
338e4b17023SJohn Marino	    return future_status::ready;
339e4b17023SJohn Marino	  return future_status::timeout;
340e4b17023SJohn Marino	}
341e4b17023SJohn Marino
342e4b17023SJohn Marino      template<typename _Clock, typename _Duration>
343e4b17023SJohn Marino        future_status
344e4b17023SJohn Marino        wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
345e4b17023SJohn Marino        {
346e4b17023SJohn Marino	  unique_lock<mutex> __lock(_M_mutex);
347e4b17023SJohn Marino	  if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
348e4b17023SJohn Marino	    return future_status::ready;
349e4b17023SJohn Marino	  return future_status::timeout;
350e4b17023SJohn Marino	}
351e4b17023SJohn Marino
352e4b17023SJohn Marino      void
353e4b17023SJohn Marino      _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false)
354e4b17023SJohn Marino      {
355e4b17023SJohn Marino        bool __set = __ignore_failure;
356e4b17023SJohn Marino        // all calls to this function are serialized,
357e4b17023SJohn Marino        // side-effects of invoking __res only happen once
358e4b17023SJohn Marino        call_once(_M_once, &_State_base::_M_do_set, this, ref(__res),
359e4b17023SJohn Marino            ref(__set));
360e4b17023SJohn Marino        if (!__set)
361e4b17023SJohn Marino          __throw_future_error(int(future_errc::promise_already_satisfied));
362e4b17023SJohn Marino      }
363e4b17023SJohn Marino
364e4b17023SJohn Marino      void
365e4b17023SJohn Marino      _M_break_promise(_Ptr_type __res)
366e4b17023SJohn Marino      {
367e4b17023SJohn Marino	if (static_cast<bool>(__res))
368e4b17023SJohn Marino	  {
369e4b17023SJohn Marino	    error_code __ec(make_error_code(future_errc::broken_promise));
370e4b17023SJohn Marino	    __res->_M_error = copy_exception(future_error(__ec));
371e4b17023SJohn Marino	    {
372e4b17023SJohn Marino	      lock_guard<mutex> __lock(_M_mutex);
373e4b17023SJohn Marino	      _M_result.swap(__res);
374e4b17023SJohn Marino	    }
375e4b17023SJohn Marino	    _M_cond.notify_all();
376e4b17023SJohn Marino	  }
377e4b17023SJohn Marino      }
378e4b17023SJohn Marino
379e4b17023SJohn Marino      // Called when this object is passed to a future.
380e4b17023SJohn Marino      void
381e4b17023SJohn Marino      _M_set_retrieved_flag()
382e4b17023SJohn Marino      {
383e4b17023SJohn Marino	if (_M_retrieved.test_and_set())
384e4b17023SJohn Marino	  __throw_future_error(int(future_errc::future_already_retrieved));
385e4b17023SJohn Marino      }
386e4b17023SJohn Marino
387e4b17023SJohn Marino      template<typename _Res, typename _Arg>
388e4b17023SJohn Marino        struct _Setter;
389e4b17023SJohn Marino
390e4b17023SJohn Marino      // set lvalues
391e4b17023SJohn Marino      template<typename _Res, typename _Arg>
392e4b17023SJohn Marino        struct _Setter<_Res, _Arg&>
393e4b17023SJohn Marino        {
394e4b17023SJohn Marino          // check this is only used by promise<R>::set_value(const R&)
395e4b17023SJohn Marino          // or promise<R>::set_value(R&)
396e4b17023SJohn Marino          static_assert(is_same<_Res, _Arg&>::value  // promise<R&>
397e4b17023SJohn Marino              || is_same<const _Res, _Arg>::value,  // promise<R>
398e4b17023SJohn Marino              "Invalid specialisation");
399e4b17023SJohn Marino
400e4b17023SJohn Marino          typename promise<_Res>::_Ptr_type operator()()
401e4b17023SJohn Marino          {
402e4b17023SJohn Marino            _State_base::_S_check(_M_promise->_M_future);
403e4b17023SJohn Marino            _M_promise->_M_storage->_M_set(_M_arg);
404e4b17023SJohn Marino            return std::move(_M_promise->_M_storage);
405e4b17023SJohn Marino          }
406e4b17023SJohn Marino          promise<_Res>*    _M_promise;
407e4b17023SJohn Marino          _Arg&             _M_arg;
408e4b17023SJohn Marino        };
409e4b17023SJohn Marino
410e4b17023SJohn Marino      // set rvalues
411e4b17023SJohn Marino      template<typename _Res>
412e4b17023SJohn Marino        struct _Setter<_Res, _Res&&>
413e4b17023SJohn Marino        {
414e4b17023SJohn Marino          typename promise<_Res>::_Ptr_type operator()()
415e4b17023SJohn Marino          {
416e4b17023SJohn Marino            _State_base::_S_check(_M_promise->_M_future);
417e4b17023SJohn Marino            _M_promise->_M_storage->_M_set(std::move(_M_arg));
418e4b17023SJohn Marino            return std::move(_M_promise->_M_storage);
419e4b17023SJohn Marino          }
420e4b17023SJohn Marino          promise<_Res>*    _M_promise;
421e4b17023SJohn Marino          _Res&             _M_arg;
422e4b17023SJohn Marino        };
423e4b17023SJohn Marino
424e4b17023SJohn Marino      struct __exception_ptr_tag { };
425e4b17023SJohn Marino
426e4b17023SJohn Marino      // set exceptions
427e4b17023SJohn Marino      template<typename _Res>
428e4b17023SJohn Marino        struct _Setter<_Res, __exception_ptr_tag>
429e4b17023SJohn Marino        {
430e4b17023SJohn Marino          typename promise<_Res>::_Ptr_type operator()()
431e4b17023SJohn Marino          {
432e4b17023SJohn Marino            _State_base::_S_check(_M_promise->_M_future);
433e4b17023SJohn Marino            _M_promise->_M_storage->_M_error = _M_ex;
434e4b17023SJohn Marino            return std::move(_M_promise->_M_storage);
435e4b17023SJohn Marino          }
436e4b17023SJohn Marino
437e4b17023SJohn Marino          promise<_Res>*   _M_promise;
438e4b17023SJohn Marino          exception_ptr&    _M_ex;
439e4b17023SJohn Marino        };
440e4b17023SJohn Marino
441e4b17023SJohn Marino      template<typename _Res, typename _Arg>
442e4b17023SJohn Marino        static _Setter<_Res, _Arg&&>
443e4b17023SJohn Marino        __setter(promise<_Res>* __prom, _Arg&& __arg)
444e4b17023SJohn Marino        {
445e4b17023SJohn Marino          return _Setter<_Res, _Arg&&>{ __prom, __arg };
446e4b17023SJohn Marino        }
447e4b17023SJohn Marino
448e4b17023SJohn Marino      template<typename _Res>
449e4b17023SJohn Marino        static _Setter<_Res, __exception_ptr_tag>
450e4b17023SJohn Marino        __setter(exception_ptr& __ex, promise<_Res>* __prom)
451e4b17023SJohn Marino        {
452e4b17023SJohn Marino          return _Setter<_Res, __exception_ptr_tag>{ __prom, __ex };
453e4b17023SJohn Marino        }
454e4b17023SJohn Marino
455e4b17023SJohn Marino      static _Setter<void, void>
456e4b17023SJohn Marino      __setter(promise<void>* __prom);
457e4b17023SJohn Marino
458e4b17023SJohn Marino      template<typename _Tp>
459*95d28233SJohn Marino        static void
460e4b17023SJohn Marino        _S_check(const shared_ptr<_Tp>& __p)
461e4b17023SJohn Marino        {
462e4b17023SJohn Marino          if (!static_cast<bool>(__p))
463e4b17023SJohn Marino            __throw_future_error((int)future_errc::no_state);
464e4b17023SJohn Marino        }
465e4b17023SJohn Marino
466e4b17023SJohn Marino    private:
467e4b17023SJohn Marino      void
468e4b17023SJohn Marino      _M_do_set(function<_Ptr_type()>& __f, bool& __set)
469e4b17023SJohn Marino      {
470e4b17023SJohn Marino        _Ptr_type __res = __f();
471e4b17023SJohn Marino        {
472e4b17023SJohn Marino          lock_guard<mutex> __lock(_M_mutex);
473e4b17023SJohn Marino          _M_result.swap(__res);
474e4b17023SJohn Marino        }
475e4b17023SJohn Marino        _M_cond.notify_all();
476e4b17023SJohn Marino        __set = true;
477e4b17023SJohn Marino      }
478e4b17023SJohn Marino
479e4b17023SJohn Marino      bool _M_ready() const noexcept { return static_cast<bool>(_M_result); }
480e4b17023SJohn Marino
481e4b17023SJohn Marino      // Misnamed: waits for completion of async function.
482e4b17023SJohn Marino      virtual void _M_run_deferred() { }
483e4b17023SJohn Marino    };
484e4b17023SJohn Marino
485e4b17023SJohn Marino    template<typename _BoundFn, typename = typename _BoundFn::result_type>
486e4b17023SJohn Marino      class _Deferred_state;
487e4b17023SJohn Marino
488e4b17023SJohn Marino    class _Async_state_common;
489e4b17023SJohn Marino
490e4b17023SJohn Marino    template<typename _BoundFn, typename = typename _BoundFn::result_type>
491e4b17023SJohn Marino      class _Async_state_impl;
492e4b17023SJohn Marino
493e4b17023SJohn Marino    template<typename _Signature>
494e4b17023SJohn Marino      class _Task_state;
495e4b17023SJohn Marino
496e4b17023SJohn Marino    template<typename _BoundFn>
497e4b17023SJohn Marino      static std::shared_ptr<_State_base>
498e4b17023SJohn Marino      _S_make_deferred_state(_BoundFn&& __fn);
499e4b17023SJohn Marino
500e4b17023SJohn Marino    template<typename _BoundFn>
501e4b17023SJohn Marino      static std::shared_ptr<_State_base>
502e4b17023SJohn Marino      _S_make_async_state(_BoundFn&& __fn);
503e4b17023SJohn Marino
504e4b17023SJohn Marino    template<typename _Res_ptr, typename _Res>
505e4b17023SJohn Marino      struct _Task_setter;
506e4b17023SJohn Marino
507e4b17023SJohn Marino    template<typename _Res_ptr, typename _BoundFn>
508e4b17023SJohn Marino      class _Task_setter_helper
509e4b17023SJohn Marino      {
510e4b17023SJohn Marino	typedef typename remove_reference<_BoundFn>::type::result_type __res;
511e4b17023SJohn Marino      public:
512e4b17023SJohn Marino	typedef _Task_setter<_Res_ptr, __res> __type;
513e4b17023SJohn Marino      };
514e4b17023SJohn Marino
515e4b17023SJohn Marino    template<typename _Res_ptr, typename _BoundFn>
516e4b17023SJohn Marino      static typename _Task_setter_helper<_Res_ptr, _BoundFn>::__type
517e4b17023SJohn Marino      _S_task_setter(_Res_ptr& __ptr, _BoundFn&& __call)
518e4b17023SJohn Marino      {
519e4b17023SJohn Marino	typedef _Task_setter_helper<_Res_ptr, _BoundFn> __helper_type;
520e4b17023SJohn Marino	typedef typename __helper_type::__type _Setter;
521e4b17023SJohn Marino	return _Setter{ __ptr, std::ref(__call) };
522e4b17023SJohn Marino      }
523e4b17023SJohn Marino  };
524e4b17023SJohn Marino
525e4b17023SJohn Marino  /// Partial specialization for reference types.
526e4b17023SJohn Marino  template<typename _Res>
527e4b17023SJohn Marino    struct __future_base::_Result<_Res&> : __future_base::_Result_base
528e4b17023SJohn Marino    {
529e4b17023SJohn Marino      _Result() noexcept : _M_value_ptr() { }
530e4b17023SJohn Marino
531e4b17023SJohn Marino      void _M_set(_Res& __res) noexcept { _M_value_ptr = &__res; }
532e4b17023SJohn Marino
533e4b17023SJohn Marino      _Res& _M_get() noexcept { return *_M_value_ptr; }
534e4b17023SJohn Marino
535e4b17023SJohn Marino    private:
536e4b17023SJohn Marino      _Res* 			_M_value_ptr;
537e4b17023SJohn Marino
538e4b17023SJohn Marino      void _M_destroy() { delete this; }
539e4b17023SJohn Marino    };
540e4b17023SJohn Marino
541e4b17023SJohn Marino  /// Explicit specialization for void.
542e4b17023SJohn Marino  template<>
543e4b17023SJohn Marino    struct __future_base::_Result<void> : __future_base::_Result_base
544e4b17023SJohn Marino    {
545e4b17023SJohn Marino    private:
546e4b17023SJohn Marino      void _M_destroy() { delete this; }
547e4b17023SJohn Marino    };
548e4b17023SJohn Marino
549e4b17023SJohn Marino
550e4b17023SJohn Marino  /// Common implementation for future and shared_future.
551e4b17023SJohn Marino  template<typename _Res>
552e4b17023SJohn Marino    class __basic_future : public __future_base
553e4b17023SJohn Marino    {
554e4b17023SJohn Marino    protected:
555e4b17023SJohn Marino      typedef shared_ptr<_State_base>		__state_type;
556e4b17023SJohn Marino      typedef __future_base::_Result<_Res>&	__result_type;
557e4b17023SJohn Marino
558e4b17023SJohn Marino    private:
559e4b17023SJohn Marino      __state_type 		_M_state;
560e4b17023SJohn Marino
561e4b17023SJohn Marino    public:
562e4b17023SJohn Marino      // Disable copying.
563e4b17023SJohn Marino      __basic_future(const __basic_future&) = delete;
564e4b17023SJohn Marino      __basic_future& operator=(const __basic_future&) = delete;
565e4b17023SJohn Marino
566e4b17023SJohn Marino      bool
567e4b17023SJohn Marino      valid() const noexcept { return static_cast<bool>(_M_state); }
568e4b17023SJohn Marino
569e4b17023SJohn Marino      void
570e4b17023SJohn Marino      wait() const
571e4b17023SJohn Marino      {
572e4b17023SJohn Marino        _State_base::_S_check(_M_state);
573e4b17023SJohn Marino        _M_state->wait();
574e4b17023SJohn Marino      }
575e4b17023SJohn Marino
576e4b17023SJohn Marino      template<typename _Rep, typename _Period>
577e4b17023SJohn Marino        future_status
578e4b17023SJohn Marino        wait_for(const chrono::duration<_Rep, _Period>& __rel) const
579e4b17023SJohn Marino        {
580e4b17023SJohn Marino          _State_base::_S_check(_M_state);
581e4b17023SJohn Marino          return _M_state->wait_for(__rel);
582e4b17023SJohn Marino        }
583e4b17023SJohn Marino
584e4b17023SJohn Marino      template<typename _Clock, typename _Duration>
585e4b17023SJohn Marino        future_status
586e4b17023SJohn Marino        wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
587e4b17023SJohn Marino        {
588e4b17023SJohn Marino          _State_base::_S_check(_M_state);
589e4b17023SJohn Marino          return _M_state->wait_until(__abs);
590e4b17023SJohn Marino        }
591e4b17023SJohn Marino
592e4b17023SJohn Marino    protected:
593e4b17023SJohn Marino      /// Wait for the state to be ready and rethrow any stored exception
594e4b17023SJohn Marino      __result_type
595e4b17023SJohn Marino      _M_get_result()
596e4b17023SJohn Marino      {
597e4b17023SJohn Marino        _State_base::_S_check(_M_state);
598e4b17023SJohn Marino        _Result_base& __res = _M_state->wait();
599e4b17023SJohn Marino        if (!(__res._M_error == 0))
600e4b17023SJohn Marino          rethrow_exception(__res._M_error);
601e4b17023SJohn Marino        return static_cast<__result_type>(__res);
602e4b17023SJohn Marino      }
603e4b17023SJohn Marino
604e4b17023SJohn Marino      void _M_swap(__basic_future& __that) noexcept
605e4b17023SJohn Marino      {
606e4b17023SJohn Marino        _M_state.swap(__that._M_state);
607e4b17023SJohn Marino      }
608e4b17023SJohn Marino
609e4b17023SJohn Marino      // Construction of a future by promise::get_future()
610e4b17023SJohn Marino      explicit
611e4b17023SJohn Marino      __basic_future(const __state_type& __state) : _M_state(__state)
612e4b17023SJohn Marino      {
613e4b17023SJohn Marino        _State_base::_S_check(_M_state);
614e4b17023SJohn Marino        _M_state->_M_set_retrieved_flag();
615e4b17023SJohn Marino      }
616e4b17023SJohn Marino
617e4b17023SJohn Marino      // Copy construction from a shared_future
618e4b17023SJohn Marino      explicit
619e4b17023SJohn Marino      __basic_future(const shared_future<_Res>&) noexcept;
620e4b17023SJohn Marino
621e4b17023SJohn Marino      // Move construction from a shared_future
622e4b17023SJohn Marino      explicit
623e4b17023SJohn Marino      __basic_future(shared_future<_Res>&&) noexcept;
624e4b17023SJohn Marino
625e4b17023SJohn Marino      // Move construction from a future
626e4b17023SJohn Marino      explicit
627e4b17023SJohn Marino      __basic_future(future<_Res>&&) noexcept;
628e4b17023SJohn Marino
629e4b17023SJohn Marino      constexpr __basic_future() noexcept : _M_state() { }
630e4b17023SJohn Marino
631e4b17023SJohn Marino      struct _Reset
632e4b17023SJohn Marino      {
633e4b17023SJohn Marino        explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { }
634e4b17023SJohn Marino        ~_Reset() { _M_fut._M_state.reset(); }
635e4b17023SJohn Marino        __basic_future& _M_fut;
636e4b17023SJohn Marino      };
637e4b17023SJohn Marino    };
638e4b17023SJohn Marino
639e4b17023SJohn Marino
640e4b17023SJohn Marino  /// Primary template for future.
641e4b17023SJohn Marino  template<typename _Res>
642e4b17023SJohn Marino    class future : public __basic_future<_Res>
643e4b17023SJohn Marino    {
644e4b17023SJohn Marino      friend class promise<_Res>;
645e4b17023SJohn Marino      template<typename> friend class packaged_task;
646e4b17023SJohn Marino      template<typename _Fn, typename... _Args>
647e4b17023SJohn Marino        friend future<typename result_of<_Fn(_Args...)>::type>
648e4b17023SJohn Marino        async(launch, _Fn&&, _Args&&...);
649e4b17023SJohn Marino
650e4b17023SJohn Marino      typedef __basic_future<_Res> _Base_type;
651e4b17023SJohn Marino      typedef typename _Base_type::__state_type __state_type;
652e4b17023SJohn Marino
653e4b17023SJohn Marino      explicit
654e4b17023SJohn Marino      future(const __state_type& __state) : _Base_type(__state) { }
655e4b17023SJohn Marino
656e4b17023SJohn Marino    public:
657e4b17023SJohn Marino      constexpr future() noexcept : _Base_type() { }
658e4b17023SJohn Marino
659e4b17023SJohn Marino      /// Move constructor
660e4b17023SJohn Marino      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
661e4b17023SJohn Marino
662e4b17023SJohn Marino      // Disable copying
663e4b17023SJohn Marino      future(const future&) = delete;
664e4b17023SJohn Marino      future& operator=(const future&) = delete;
665e4b17023SJohn Marino
666e4b17023SJohn Marino      future& operator=(future&& __fut) noexcept
667e4b17023SJohn Marino      {
668e4b17023SJohn Marino        future(std::move(__fut))._M_swap(*this);
669e4b17023SJohn Marino        return *this;
670e4b17023SJohn Marino      }
671e4b17023SJohn Marino
672e4b17023SJohn Marino      /// Retrieving the value
673e4b17023SJohn Marino      _Res
674e4b17023SJohn Marino      get()
675e4b17023SJohn Marino      {
676e4b17023SJohn Marino        typename _Base_type::_Reset __reset(*this);
677e4b17023SJohn Marino        return std::move(this->_M_get_result()._M_value());
678e4b17023SJohn Marino      }
679e4b17023SJohn Marino
680e4b17023SJohn Marino      shared_future<_Res> share();
681e4b17023SJohn Marino    };
682e4b17023SJohn Marino
683e4b17023SJohn Marino  /// Partial specialization for future<R&>
684e4b17023SJohn Marino  template<typename _Res>
685e4b17023SJohn Marino    class future<_Res&> : public __basic_future<_Res&>
686e4b17023SJohn Marino    {
687e4b17023SJohn Marino      friend class promise<_Res&>;
688e4b17023SJohn Marino      template<typename> friend class packaged_task;
689e4b17023SJohn Marino      template<typename _Fn, typename... _Args>
690e4b17023SJohn Marino        friend future<typename result_of<_Fn(_Args...)>::type>
691e4b17023SJohn Marino        async(launch, _Fn&&, _Args&&...);
692e4b17023SJohn Marino
693e4b17023SJohn Marino      typedef __basic_future<_Res&> _Base_type;
694e4b17023SJohn Marino      typedef typename _Base_type::__state_type __state_type;
695e4b17023SJohn Marino
696e4b17023SJohn Marino      explicit
697e4b17023SJohn Marino      future(const __state_type& __state) : _Base_type(__state) { }
698e4b17023SJohn Marino
699e4b17023SJohn Marino    public:
700e4b17023SJohn Marino      constexpr future() noexcept : _Base_type() { }
701e4b17023SJohn Marino
702e4b17023SJohn Marino      /// Move constructor
703e4b17023SJohn Marino      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
704e4b17023SJohn Marino
705e4b17023SJohn Marino      // Disable copying
706e4b17023SJohn Marino      future(const future&) = delete;
707e4b17023SJohn Marino      future& operator=(const future&) = delete;
708e4b17023SJohn Marino
709e4b17023SJohn Marino      future& operator=(future&& __fut) noexcept
710e4b17023SJohn Marino      {
711e4b17023SJohn Marino        future(std::move(__fut))._M_swap(*this);
712e4b17023SJohn Marino        return *this;
713e4b17023SJohn Marino      }
714e4b17023SJohn Marino
715e4b17023SJohn Marino      /// Retrieving the value
716e4b17023SJohn Marino      _Res&
717e4b17023SJohn Marino      get()
718e4b17023SJohn Marino      {
719e4b17023SJohn Marino        typename _Base_type::_Reset __reset(*this);
720e4b17023SJohn Marino        return this->_M_get_result()._M_get();
721e4b17023SJohn Marino      }
722e4b17023SJohn Marino
723e4b17023SJohn Marino      shared_future<_Res&> share();
724e4b17023SJohn Marino    };
725e4b17023SJohn Marino
726e4b17023SJohn Marino  /// Explicit specialization for future<void>
727e4b17023SJohn Marino  template<>
728e4b17023SJohn Marino    class future<void> : public __basic_future<void>
729e4b17023SJohn Marino    {
730e4b17023SJohn Marino      friend class promise<void>;
731e4b17023SJohn Marino      template<typename> friend class packaged_task;
732e4b17023SJohn Marino      template<typename _Fn, typename... _Args>
733e4b17023SJohn Marino        friend future<typename result_of<_Fn(_Args...)>::type>
734e4b17023SJohn Marino        async(launch, _Fn&&, _Args&&...);
735e4b17023SJohn Marino
736e4b17023SJohn Marino      typedef __basic_future<void> _Base_type;
737e4b17023SJohn Marino      typedef typename _Base_type::__state_type __state_type;
738e4b17023SJohn Marino
739e4b17023SJohn Marino      explicit
740e4b17023SJohn Marino      future(const __state_type& __state) : _Base_type(__state) { }
741e4b17023SJohn Marino
742e4b17023SJohn Marino    public:
743e4b17023SJohn Marino      constexpr future() noexcept : _Base_type() { }
744e4b17023SJohn Marino
745e4b17023SJohn Marino      /// Move constructor
746e4b17023SJohn Marino      future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
747e4b17023SJohn Marino
748e4b17023SJohn Marino      // Disable copying
749e4b17023SJohn Marino      future(const future&) = delete;
750e4b17023SJohn Marino      future& operator=(const future&) = delete;
751e4b17023SJohn Marino
752e4b17023SJohn Marino      future& operator=(future&& __fut) noexcept
753e4b17023SJohn Marino      {
754e4b17023SJohn Marino        future(std::move(__fut))._M_swap(*this);
755e4b17023SJohn Marino        return *this;
756e4b17023SJohn Marino      }
757e4b17023SJohn Marino
758e4b17023SJohn Marino      /// Retrieving the value
759e4b17023SJohn Marino      void
760e4b17023SJohn Marino      get()
761e4b17023SJohn Marino      {
762e4b17023SJohn Marino        typename _Base_type::_Reset __reset(*this);
763e4b17023SJohn Marino        this->_M_get_result();
764e4b17023SJohn Marino      }
765e4b17023SJohn Marino
766e4b17023SJohn Marino      shared_future<void> share();
767e4b17023SJohn Marino    };
768e4b17023SJohn Marino
769e4b17023SJohn Marino
770e4b17023SJohn Marino  /// Primary template for shared_future.
771e4b17023SJohn Marino  template<typename _Res>
772e4b17023SJohn Marino    class shared_future : public __basic_future<_Res>
773e4b17023SJohn Marino    {
774e4b17023SJohn Marino      typedef __basic_future<_Res> _Base_type;
775e4b17023SJohn Marino
776e4b17023SJohn Marino    public:
777e4b17023SJohn Marino      constexpr shared_future() noexcept : _Base_type() { }
778e4b17023SJohn Marino
779e4b17023SJohn Marino      /// Copy constructor
780e4b17023SJohn Marino      shared_future(const shared_future& __sf) : _Base_type(__sf) { }
781e4b17023SJohn Marino
782e4b17023SJohn Marino      /// Construct from a future rvalue
783e4b17023SJohn Marino      shared_future(future<_Res>&& __uf) noexcept
784e4b17023SJohn Marino      : _Base_type(std::move(__uf))
785e4b17023SJohn Marino      { }
786e4b17023SJohn Marino
787e4b17023SJohn Marino      /// Construct from a shared_future rvalue
788e4b17023SJohn Marino      shared_future(shared_future&& __sf) noexcept
789e4b17023SJohn Marino      : _Base_type(std::move(__sf))
790e4b17023SJohn Marino      { }
791e4b17023SJohn Marino
792e4b17023SJohn Marino      shared_future& operator=(const shared_future& __sf)
793e4b17023SJohn Marino      {
794e4b17023SJohn Marino        shared_future(__sf)._M_swap(*this);
795e4b17023SJohn Marino        return *this;
796e4b17023SJohn Marino      }
797e4b17023SJohn Marino
798e4b17023SJohn Marino      shared_future& operator=(shared_future&& __sf) noexcept
799e4b17023SJohn Marino      {
800e4b17023SJohn Marino        shared_future(std::move(__sf))._M_swap(*this);
801e4b17023SJohn Marino        return *this;
802e4b17023SJohn Marino      }
803e4b17023SJohn Marino
804e4b17023SJohn Marino      /// Retrieving the value
805e4b17023SJohn Marino      const _Res&
806e4b17023SJohn Marino      get()
807e4b17023SJohn Marino      {
808e4b17023SJohn Marino	typename _Base_type::__result_type __r = this->_M_get_result();
809e4b17023SJohn Marino	_Res& __rs(__r._M_value());
810e4b17023SJohn Marino	return __rs;
811e4b17023SJohn Marino      }
812e4b17023SJohn Marino    };
813e4b17023SJohn Marino
814e4b17023SJohn Marino  /// Partial specialization for shared_future<R&>
815e4b17023SJohn Marino  template<typename _Res>
816e4b17023SJohn Marino    class shared_future<_Res&> : public __basic_future<_Res&>
817e4b17023SJohn Marino    {
818e4b17023SJohn Marino      typedef __basic_future<_Res&>           _Base_type;
819e4b17023SJohn Marino
820e4b17023SJohn Marino    public:
821e4b17023SJohn Marino      constexpr shared_future() noexcept : _Base_type() { }
822e4b17023SJohn Marino
823e4b17023SJohn Marino      /// Copy constructor
824e4b17023SJohn Marino      shared_future(const shared_future& __sf) : _Base_type(__sf) { }
825e4b17023SJohn Marino
826e4b17023SJohn Marino      /// Construct from a future rvalue
827e4b17023SJohn Marino      shared_future(future<_Res&>&& __uf) noexcept
828e4b17023SJohn Marino      : _Base_type(std::move(__uf))
829e4b17023SJohn Marino      { }
830e4b17023SJohn Marino
831e4b17023SJohn Marino      /// Construct from a shared_future rvalue
832e4b17023SJohn Marino      shared_future(shared_future&& __sf) noexcept
833e4b17023SJohn Marino      : _Base_type(std::move(__sf))
834e4b17023SJohn Marino      { }
835e4b17023SJohn Marino
836e4b17023SJohn Marino      shared_future& operator=(const shared_future& __sf)
837e4b17023SJohn Marino      {
838e4b17023SJohn Marino        shared_future(__sf)._M_swap(*this);
839e4b17023SJohn Marino        return *this;
840e4b17023SJohn Marino      }
841e4b17023SJohn Marino
842e4b17023SJohn Marino      shared_future& operator=(shared_future&& __sf) noexcept
843e4b17023SJohn Marino      {
844e4b17023SJohn Marino        shared_future(std::move(__sf))._M_swap(*this);
845e4b17023SJohn Marino        return *this;
846e4b17023SJohn Marino      }
847e4b17023SJohn Marino
848e4b17023SJohn Marino      /// Retrieving the value
849e4b17023SJohn Marino      _Res&
850e4b17023SJohn Marino      get() { return this->_M_get_result()._M_get(); }
851e4b17023SJohn Marino    };
852e4b17023SJohn Marino
853e4b17023SJohn Marino  /// Explicit specialization for shared_future<void>
854e4b17023SJohn Marino  template<>
855e4b17023SJohn Marino    class shared_future<void> : public __basic_future<void>
856e4b17023SJohn Marino    {
857e4b17023SJohn Marino      typedef __basic_future<void> _Base_type;
858e4b17023SJohn Marino
859e4b17023SJohn Marino    public:
860e4b17023SJohn Marino      constexpr shared_future() noexcept : _Base_type() { }
861e4b17023SJohn Marino
862e4b17023SJohn Marino      /// Copy constructor
863e4b17023SJohn Marino      shared_future(const shared_future& __sf) : _Base_type(__sf) { }
864e4b17023SJohn Marino
865e4b17023SJohn Marino      /// Construct from a future rvalue
866e4b17023SJohn Marino      shared_future(future<void>&& __uf) noexcept
867e4b17023SJohn Marino      : _Base_type(std::move(__uf))
868e4b17023SJohn Marino      { }
869e4b17023SJohn Marino
870e4b17023SJohn Marino      /// Construct from a shared_future rvalue
871e4b17023SJohn Marino      shared_future(shared_future&& __sf) noexcept
872e4b17023SJohn Marino      : _Base_type(std::move(__sf))
873e4b17023SJohn Marino      { }
874e4b17023SJohn Marino
875e4b17023SJohn Marino      shared_future& operator=(const shared_future& __sf)
876e4b17023SJohn Marino      {
877e4b17023SJohn Marino        shared_future(__sf)._M_swap(*this);
878e4b17023SJohn Marino        return *this;
879e4b17023SJohn Marino      }
880e4b17023SJohn Marino
881e4b17023SJohn Marino      shared_future& operator=(shared_future&& __sf) noexcept
882e4b17023SJohn Marino      {
883e4b17023SJohn Marino        shared_future(std::move(__sf))._M_swap(*this);
884e4b17023SJohn Marino        return *this;
885e4b17023SJohn Marino      }
886e4b17023SJohn Marino
887e4b17023SJohn Marino      // Retrieving the value
888e4b17023SJohn Marino      void
889e4b17023SJohn Marino      get() { this->_M_get_result(); }
890e4b17023SJohn Marino    };
891e4b17023SJohn Marino
892e4b17023SJohn Marino  // Now we can define the protected __basic_future constructors.
893e4b17023SJohn Marino  template<typename _Res>
894e4b17023SJohn Marino    inline __basic_future<_Res>::
895e4b17023SJohn Marino    __basic_future(const shared_future<_Res>& __sf) noexcept
896e4b17023SJohn Marino    : _M_state(__sf._M_state)
897e4b17023SJohn Marino    { }
898e4b17023SJohn Marino
899e4b17023SJohn Marino  template<typename _Res>
900e4b17023SJohn Marino    inline __basic_future<_Res>::
901e4b17023SJohn Marino    __basic_future(shared_future<_Res>&& __sf) noexcept
902e4b17023SJohn Marino    : _M_state(std::move(__sf._M_state))
903e4b17023SJohn Marino    { }
904e4b17023SJohn Marino
905e4b17023SJohn Marino  template<typename _Res>
906e4b17023SJohn Marino    inline __basic_future<_Res>::
907e4b17023SJohn Marino    __basic_future(future<_Res>&& __uf) noexcept
908e4b17023SJohn Marino    : _M_state(std::move(__uf._M_state))
909e4b17023SJohn Marino    { }
910e4b17023SJohn Marino
911e4b17023SJohn Marino  template<typename _Res>
912e4b17023SJohn Marino    inline shared_future<_Res>
913e4b17023SJohn Marino    future<_Res>::share()
914e4b17023SJohn Marino    { return shared_future<_Res>(std::move(*this)); }
915e4b17023SJohn Marino
916e4b17023SJohn Marino  template<typename _Res>
917e4b17023SJohn Marino    inline shared_future<_Res&>
918e4b17023SJohn Marino    future<_Res&>::share()
919e4b17023SJohn Marino    { return shared_future<_Res&>(std::move(*this)); }
920e4b17023SJohn Marino
921e4b17023SJohn Marino  inline shared_future<void>
922e4b17023SJohn Marino  future<void>::share()
923e4b17023SJohn Marino  { return shared_future<void>(std::move(*this)); }
924e4b17023SJohn Marino
925e4b17023SJohn Marino  /// Primary template for promise
926e4b17023SJohn Marino  template<typename _Res>
927e4b17023SJohn Marino    class promise
928e4b17023SJohn Marino    {
929e4b17023SJohn Marino      typedef __future_base::_State_base 	_State;
930e4b17023SJohn Marino      typedef __future_base::_Result<_Res>	_Res_type;
931e4b17023SJohn Marino      typedef __future_base::_Ptr<_Res_type>	_Ptr_type;
932e4b17023SJohn Marino      template<typename, typename> friend class _State::_Setter;
933e4b17023SJohn Marino
934e4b17023SJohn Marino      shared_ptr<_State>                        _M_future;
935e4b17023SJohn Marino      _Ptr_type                                 _M_storage;
936e4b17023SJohn Marino
937e4b17023SJohn Marino    public:
938e4b17023SJohn Marino      promise()
939e4b17023SJohn Marino      : _M_future(std::make_shared<_State>()),
940e4b17023SJohn Marino	_M_storage(new _Res_type())
941e4b17023SJohn Marino      { }
942e4b17023SJohn Marino
943e4b17023SJohn Marino      promise(promise&& __rhs) noexcept
944e4b17023SJohn Marino      : _M_future(std::move(__rhs._M_future)),
945e4b17023SJohn Marino	_M_storage(std::move(__rhs._M_storage))
946e4b17023SJohn Marino      { }
947e4b17023SJohn Marino
948e4b17023SJohn Marino      template<typename _Allocator>
949e4b17023SJohn Marino        promise(allocator_arg_t, const _Allocator& __a)
950e4b17023SJohn Marino        : _M_future(std::allocate_shared<_State>(__a)),
951e4b17023SJohn Marino	  _M_storage(__future_base::_S_allocate_result<_Res>(__a))
952e4b17023SJohn Marino        { }
953e4b17023SJohn Marino
954e4b17023SJohn Marino      template<typename _Allocator>
955e4b17023SJohn Marino        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
956e4b17023SJohn Marino        : _M_future(std::move(__rhs._M_future)),
957e4b17023SJohn Marino	  _M_storage(std::move(__rhs._M_storage))
958e4b17023SJohn Marino        { }
959e4b17023SJohn Marino
960e4b17023SJohn Marino      promise(const promise&) = delete;
961e4b17023SJohn Marino
962e4b17023SJohn Marino      ~promise()
963e4b17023SJohn Marino      {
964e4b17023SJohn Marino        if (static_cast<bool>(_M_future) && !_M_future.unique())
965e4b17023SJohn Marino          _M_future->_M_break_promise(std::move(_M_storage));
966e4b17023SJohn Marino      }
967e4b17023SJohn Marino
968e4b17023SJohn Marino      // Assignment
969e4b17023SJohn Marino      promise&
970e4b17023SJohn Marino      operator=(promise&& __rhs) noexcept
971e4b17023SJohn Marino      {
972e4b17023SJohn Marino        promise(std::move(__rhs)).swap(*this);
973e4b17023SJohn Marino        return *this;
974e4b17023SJohn Marino      }
975e4b17023SJohn Marino
976e4b17023SJohn Marino      promise& operator=(const promise&) = delete;
977e4b17023SJohn Marino
978e4b17023SJohn Marino      void
979e4b17023SJohn Marino      swap(promise& __rhs) noexcept
980e4b17023SJohn Marino      {
981e4b17023SJohn Marino        _M_future.swap(__rhs._M_future);
982e4b17023SJohn Marino        _M_storage.swap(__rhs._M_storage);
983e4b17023SJohn Marino      }
984e4b17023SJohn Marino
985e4b17023SJohn Marino      // Retrieving the result
986e4b17023SJohn Marino      future<_Res>
987e4b17023SJohn Marino      get_future()
988e4b17023SJohn Marino      { return future<_Res>(_M_future); }
989e4b17023SJohn Marino
990e4b17023SJohn Marino      // Setting the result
991e4b17023SJohn Marino      void
992e4b17023SJohn Marino      set_value(const _Res& __r)
993e4b17023SJohn Marino      {
994e4b17023SJohn Marino        auto __setter = _State::__setter(this, __r);
995e4b17023SJohn Marino        _M_future->_M_set_result(std::move(__setter));
996e4b17023SJohn Marino      }
997e4b17023SJohn Marino
998e4b17023SJohn Marino      void
999e4b17023SJohn Marino      set_value(_Res&& __r)
1000e4b17023SJohn Marino      {
1001e4b17023SJohn Marino        auto __setter = _State::__setter(this, std::move(__r));
1002e4b17023SJohn Marino        _M_future->_M_set_result(std::move(__setter));
1003e4b17023SJohn Marino      }
1004e4b17023SJohn Marino
1005e4b17023SJohn Marino      void
1006e4b17023SJohn Marino      set_exception(exception_ptr __p)
1007e4b17023SJohn Marino      {
1008e4b17023SJohn Marino        auto __setter = _State::__setter(__p, this);
1009e4b17023SJohn Marino        _M_future->_M_set_result(std::move(__setter));
1010e4b17023SJohn Marino      }
1011e4b17023SJohn Marino    };
1012e4b17023SJohn Marino
1013e4b17023SJohn Marino  template<typename _Res>
1014e4b17023SJohn Marino    inline void
1015e4b17023SJohn Marino    swap(promise<_Res>& __x, promise<_Res>& __y) noexcept
1016e4b17023SJohn Marino    { __x.swap(__y); }
1017e4b17023SJohn Marino
1018e4b17023SJohn Marino  template<typename _Res, typename _Alloc>
1019e4b17023SJohn Marino    struct uses_allocator<promise<_Res>, _Alloc>
1020e4b17023SJohn Marino    : public true_type { };
1021e4b17023SJohn Marino
1022e4b17023SJohn Marino
1023e4b17023SJohn Marino  /// Partial specialization for promise<R&>
1024e4b17023SJohn Marino  template<typename _Res>
1025e4b17023SJohn Marino    class promise<_Res&>
1026e4b17023SJohn Marino    {
1027e4b17023SJohn Marino      typedef __future_base::_State_base	_State;
1028e4b17023SJohn Marino      typedef __future_base::_Result<_Res&>	_Res_type;
1029e4b17023SJohn Marino      typedef __future_base::_Ptr<_Res_type> 	_Ptr_type;
1030e4b17023SJohn Marino      template<typename, typename> friend class _State::_Setter;
1031e4b17023SJohn Marino
1032e4b17023SJohn Marino      shared_ptr<_State>                        _M_future;
1033e4b17023SJohn Marino      _Ptr_type                                 _M_storage;
1034e4b17023SJohn Marino
1035e4b17023SJohn Marino    public:
1036e4b17023SJohn Marino      promise()
1037e4b17023SJohn Marino      : _M_future(std::make_shared<_State>()),
1038e4b17023SJohn Marino	_M_storage(new _Res_type())
1039e4b17023SJohn Marino      { }
1040e4b17023SJohn Marino
1041e4b17023SJohn Marino      promise(promise&& __rhs) noexcept
1042e4b17023SJohn Marino      : _M_future(std::move(__rhs._M_future)),
1043e4b17023SJohn Marino	_M_storage(std::move(__rhs._M_storage))
1044e4b17023SJohn Marino      { }
1045e4b17023SJohn Marino
1046e4b17023SJohn Marino      template<typename _Allocator>
1047e4b17023SJohn Marino        promise(allocator_arg_t, const _Allocator& __a)
1048e4b17023SJohn Marino        : _M_future(std::allocate_shared<_State>(__a)),
1049e4b17023SJohn Marino	  _M_storage(__future_base::_S_allocate_result<_Res&>(__a))
1050e4b17023SJohn Marino        { }
1051e4b17023SJohn Marino
1052e4b17023SJohn Marino      template<typename _Allocator>
1053e4b17023SJohn Marino        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1054e4b17023SJohn Marino        : _M_future(std::move(__rhs._M_future)),
1055e4b17023SJohn Marino	  _M_storage(std::move(__rhs._M_storage))
1056e4b17023SJohn Marino        { }
1057e4b17023SJohn Marino
1058e4b17023SJohn Marino      promise(const promise&) = delete;
1059e4b17023SJohn Marino
1060e4b17023SJohn Marino      ~promise()
1061e4b17023SJohn Marino      {
1062e4b17023SJohn Marino        if (static_cast<bool>(_M_future) && !_M_future.unique())
1063e4b17023SJohn Marino          _M_future->_M_break_promise(std::move(_M_storage));
1064e4b17023SJohn Marino      }
1065e4b17023SJohn Marino
1066e4b17023SJohn Marino      // Assignment
1067e4b17023SJohn Marino      promise&
1068e4b17023SJohn Marino      operator=(promise&& __rhs) noexcept
1069e4b17023SJohn Marino      {
1070e4b17023SJohn Marino        promise(std::move(__rhs)).swap(*this);
1071e4b17023SJohn Marino        return *this;
1072e4b17023SJohn Marino      }
1073e4b17023SJohn Marino
1074e4b17023SJohn Marino      promise& operator=(const promise&) = delete;
1075e4b17023SJohn Marino
1076e4b17023SJohn Marino      void
1077e4b17023SJohn Marino      swap(promise& __rhs) noexcept
1078e4b17023SJohn Marino      {
1079e4b17023SJohn Marino        _M_future.swap(__rhs._M_future);
1080e4b17023SJohn Marino        _M_storage.swap(__rhs._M_storage);
1081e4b17023SJohn Marino      }
1082e4b17023SJohn Marino
1083e4b17023SJohn Marino      // Retrieving the result
1084e4b17023SJohn Marino      future<_Res&>
1085e4b17023SJohn Marino      get_future()
1086e4b17023SJohn Marino      { return future<_Res&>(_M_future); }
1087e4b17023SJohn Marino
1088e4b17023SJohn Marino      // Setting the result
1089e4b17023SJohn Marino      void
1090e4b17023SJohn Marino      set_value(_Res& __r)
1091e4b17023SJohn Marino      {
1092e4b17023SJohn Marino        auto __setter = _State::__setter(this, __r);
1093e4b17023SJohn Marino        _M_future->_M_set_result(std::move(__setter));
1094e4b17023SJohn Marino      }
1095e4b17023SJohn Marino
1096e4b17023SJohn Marino      void
1097e4b17023SJohn Marino      set_exception(exception_ptr __p)
1098e4b17023SJohn Marino      {
1099e4b17023SJohn Marino        auto __setter = _State::__setter(__p, this);
1100e4b17023SJohn Marino        _M_future->_M_set_result(std::move(__setter));
1101e4b17023SJohn Marino      }
1102e4b17023SJohn Marino    };
1103e4b17023SJohn Marino
1104e4b17023SJohn Marino  /// Explicit specialization for promise<void>
1105e4b17023SJohn Marino  template<>
1106e4b17023SJohn Marino    class promise<void>
1107e4b17023SJohn Marino    {
1108e4b17023SJohn Marino      typedef __future_base::_State_base	_State;
1109e4b17023SJohn Marino      typedef __future_base::_Result<void>	_Res_type;
1110e4b17023SJohn Marino      typedef __future_base::_Ptr<_Res_type> 	_Ptr_type;
1111e4b17023SJohn Marino      template<typename, typename> friend class _State::_Setter;
1112e4b17023SJohn Marino
1113e4b17023SJohn Marino      shared_ptr<_State>                        _M_future;
1114e4b17023SJohn Marino      _Ptr_type                                 _M_storage;
1115e4b17023SJohn Marino
1116e4b17023SJohn Marino    public:
1117e4b17023SJohn Marino      promise()
1118e4b17023SJohn Marino      : _M_future(std::make_shared<_State>()),
1119e4b17023SJohn Marino	_M_storage(new _Res_type())
1120e4b17023SJohn Marino      { }
1121e4b17023SJohn Marino
1122e4b17023SJohn Marino      promise(promise&& __rhs) noexcept
1123e4b17023SJohn Marino      : _M_future(std::move(__rhs._M_future)),
1124e4b17023SJohn Marino	_M_storage(std::move(__rhs._M_storage))
1125e4b17023SJohn Marino      { }
1126e4b17023SJohn Marino
1127e4b17023SJohn Marino      template<typename _Allocator>
1128e4b17023SJohn Marino        promise(allocator_arg_t, const _Allocator& __a)
1129e4b17023SJohn Marino        : _M_future(std::allocate_shared<_State>(__a)),
1130e4b17023SJohn Marino	  _M_storage(__future_base::_S_allocate_result<void>(__a))
1131e4b17023SJohn Marino        { }
1132e4b17023SJohn Marino
1133e4b17023SJohn Marino      template<typename _Allocator>
1134e4b17023SJohn Marino        promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1135e4b17023SJohn Marino        : _M_future(std::move(__rhs._M_future)),
1136e4b17023SJohn Marino	  _M_storage(std::move(__rhs._M_storage))
1137e4b17023SJohn Marino        { }
1138e4b17023SJohn Marino
1139e4b17023SJohn Marino      promise(const promise&) = delete;
1140e4b17023SJohn Marino
1141e4b17023SJohn Marino      ~promise()
1142e4b17023SJohn Marino      {
1143e4b17023SJohn Marino        if (static_cast<bool>(_M_future) && !_M_future.unique())
1144e4b17023SJohn Marino          _M_future->_M_break_promise(std::move(_M_storage));
1145e4b17023SJohn Marino      }
1146e4b17023SJohn Marino
1147e4b17023SJohn Marino      // Assignment
1148e4b17023SJohn Marino      promise&
1149e4b17023SJohn Marino      operator=(promise&& __rhs) noexcept
1150e4b17023SJohn Marino      {
1151e4b17023SJohn Marino        promise(std::move(__rhs)).swap(*this);
1152e4b17023SJohn Marino        return *this;
1153e4b17023SJohn Marino      }
1154e4b17023SJohn Marino
1155e4b17023SJohn Marino      promise& operator=(const promise&) = delete;
1156e4b17023SJohn Marino
1157e4b17023SJohn Marino      void
1158e4b17023SJohn Marino      swap(promise& __rhs) noexcept
1159e4b17023SJohn Marino      {
1160e4b17023SJohn Marino        _M_future.swap(__rhs._M_future);
1161e4b17023SJohn Marino        _M_storage.swap(__rhs._M_storage);
1162e4b17023SJohn Marino      }
1163e4b17023SJohn Marino
1164e4b17023SJohn Marino      // Retrieving the result
1165e4b17023SJohn Marino      future<void>
1166e4b17023SJohn Marino      get_future()
1167e4b17023SJohn Marino      { return future<void>(_M_future); }
1168e4b17023SJohn Marino
1169e4b17023SJohn Marino      // Setting the result
1170e4b17023SJohn Marino      void set_value();
1171e4b17023SJohn Marino
1172e4b17023SJohn Marino      void
1173e4b17023SJohn Marino      set_exception(exception_ptr __p)
1174e4b17023SJohn Marino      {
1175e4b17023SJohn Marino        auto __setter = _State::__setter(__p, this);
1176e4b17023SJohn Marino        _M_future->_M_set_result(std::move(__setter));
1177e4b17023SJohn Marino      }
1178e4b17023SJohn Marino    };
1179e4b17023SJohn Marino
1180e4b17023SJohn Marino  // set void
1181e4b17023SJohn Marino  template<>
1182e4b17023SJohn Marino    struct __future_base::_State_base::_Setter<void, void>
1183e4b17023SJohn Marino    {
1184e4b17023SJohn Marino      promise<void>::_Ptr_type operator()()
1185e4b17023SJohn Marino      {
1186e4b17023SJohn Marino        _State_base::_S_check(_M_promise->_M_future);
1187e4b17023SJohn Marino        return std::move(_M_promise->_M_storage);
1188e4b17023SJohn Marino      }
1189e4b17023SJohn Marino
1190e4b17023SJohn Marino      promise<void>*    _M_promise;
1191e4b17023SJohn Marino    };
1192e4b17023SJohn Marino
1193e4b17023SJohn Marino  inline __future_base::_State_base::_Setter<void, void>
1194e4b17023SJohn Marino  __future_base::_State_base::__setter(promise<void>* __prom)
1195e4b17023SJohn Marino  {
1196e4b17023SJohn Marino    return _Setter<void, void>{ __prom };
1197e4b17023SJohn Marino  }
1198e4b17023SJohn Marino
1199e4b17023SJohn Marino  inline void
1200e4b17023SJohn Marino  promise<void>::set_value()
1201e4b17023SJohn Marino  {
1202e4b17023SJohn Marino    auto __setter = _State::__setter(this);
1203e4b17023SJohn Marino    _M_future->_M_set_result(std::move(__setter));
1204e4b17023SJohn Marino  }
1205e4b17023SJohn Marino
1206e4b17023SJohn Marino
1207e4b17023SJohn Marino  template<typename _Ptr_type, typename _Res>
1208e4b17023SJohn Marino    struct __future_base::_Task_setter
1209e4b17023SJohn Marino    {
1210e4b17023SJohn Marino      _Ptr_type operator()()
1211e4b17023SJohn Marino      {
1212e4b17023SJohn Marino        __try
1213e4b17023SJohn Marino	  {
1214e4b17023SJohn Marino	    _M_result->_M_set(_M_fn());
1215e4b17023SJohn Marino	  }
1216e4b17023SJohn Marino	__catch(...)
1217e4b17023SJohn Marino	  {
1218e4b17023SJohn Marino	    _M_result->_M_error = current_exception();
1219e4b17023SJohn Marino	  }
1220e4b17023SJohn Marino        return std::move(_M_result);
1221e4b17023SJohn Marino      }
1222e4b17023SJohn Marino      _Ptr_type&                _M_result;
1223e4b17023SJohn Marino      std::function<_Res()>     _M_fn;
1224e4b17023SJohn Marino    };
1225e4b17023SJohn Marino
1226e4b17023SJohn Marino  template<typename _Ptr_type>
1227e4b17023SJohn Marino    struct __future_base::_Task_setter<_Ptr_type, void>
1228e4b17023SJohn Marino    {
1229e4b17023SJohn Marino      _Ptr_type operator()()
1230e4b17023SJohn Marino      {
1231e4b17023SJohn Marino        __try
1232e4b17023SJohn Marino	  {
1233e4b17023SJohn Marino	    _M_fn();
1234e4b17023SJohn Marino	  }
1235e4b17023SJohn Marino	__catch(...)
1236e4b17023SJohn Marino	  {
1237e4b17023SJohn Marino	    _M_result->_M_error = current_exception();
1238e4b17023SJohn Marino	  }
1239e4b17023SJohn Marino	return std::move(_M_result);
1240e4b17023SJohn Marino      }
1241e4b17023SJohn Marino      _Ptr_type&                _M_result;
1242e4b17023SJohn Marino      std::function<void()>     _M_fn;
1243e4b17023SJohn Marino    };
1244e4b17023SJohn Marino
1245e4b17023SJohn Marino  template<typename _Res, typename... _Args>
1246e4b17023SJohn Marino    struct __future_base::_Task_state<_Res(_Args...)> final
1247e4b17023SJohn Marino    : __future_base::_State_base
1248e4b17023SJohn Marino    {
1249e4b17023SJohn Marino      typedef _Res _Res_type;
1250e4b17023SJohn Marino
1251e4b17023SJohn Marino      _Task_state(std::function<_Res(_Args...)> __task)
1252e4b17023SJohn Marino      : _M_result(new _Result<_Res>()), _M_task(std::move(__task))
1253e4b17023SJohn Marino      { }
1254e4b17023SJohn Marino
1255e4b17023SJohn Marino      template<typename _Func, typename _Alloc>
1256e4b17023SJohn Marino        _Task_state(_Func&& __task, const _Alloc& __a)
1257e4b17023SJohn Marino        : _M_result(_S_allocate_result<_Res>(__a)),
1258e4b17023SJohn Marino	  _M_task(allocator_arg, __a, std::move(__task))
1259e4b17023SJohn Marino        { }
1260e4b17023SJohn Marino
1261e4b17023SJohn Marino      void
1262e4b17023SJohn Marino      _M_run(_Args... __args)
1263e4b17023SJohn Marino      {
1264e4b17023SJohn Marino        // bound arguments decay so wrap lvalue references
1265e4b17023SJohn Marino	auto __boundfn = std::__bind_simple(std::ref(_M_task),
1266e4b17023SJohn Marino	    _S_maybe_wrap_ref(std::forward<_Args>(__args))...);
1267e4b17023SJohn Marino        auto __setter = _S_task_setter(_M_result, std::move(__boundfn));
1268e4b17023SJohn Marino        _M_set_result(std::move(__setter));
1269e4b17023SJohn Marino      }
1270e4b17023SJohn Marino
1271e4b17023SJohn Marino      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1272e4b17023SJohn Marino      _Ptr_type _M_result;
1273e4b17023SJohn Marino      std::function<_Res(_Args...)> _M_task;
1274e4b17023SJohn Marino
1275e4b17023SJohn Marino      template<typename _Tp>
1276e4b17023SJohn Marino        static reference_wrapper<_Tp>
1277e4b17023SJohn Marino        _S_maybe_wrap_ref(_Tp& __t)
1278e4b17023SJohn Marino        { return std::ref(__t); }
1279e4b17023SJohn Marino
1280e4b17023SJohn Marino      template<typename _Tp>
1281e4b17023SJohn Marino        static typename enable_if<!is_lvalue_reference<_Tp>::value,
1282e4b17023SJohn Marino                        _Tp>::type&&
1283e4b17023SJohn Marino        _S_maybe_wrap_ref(_Tp&& __t)
1284e4b17023SJohn Marino        { return std::forward<_Tp>(__t); }
1285e4b17023SJohn Marino    };
1286e4b17023SJohn Marino
1287e4b17023SJohn Marino  template<typename _Task, typename _Fn, bool
1288e4b17023SJohn Marino           = is_same<_Task, typename decay<_Fn>::type>::value>
1289e4b17023SJohn Marino    struct __constrain_pkgdtask
1290e4b17023SJohn Marino    { typedef void __type; };
1291e4b17023SJohn Marino
1292e4b17023SJohn Marino  template<typename _Task, typename _Fn>
1293e4b17023SJohn Marino    struct __constrain_pkgdtask<_Task, _Fn, true>
1294e4b17023SJohn Marino    { };
1295e4b17023SJohn Marino
1296e4b17023SJohn Marino  /// packaged_task
1297e4b17023SJohn Marino  template<typename _Res, typename... _ArgTypes>
1298e4b17023SJohn Marino    class packaged_task<_Res(_ArgTypes...)>
1299e4b17023SJohn Marino    {
1300e4b17023SJohn Marino      typedef __future_base::_Task_state<_Res(_ArgTypes...)>  _State_type;
1301e4b17023SJohn Marino      shared_ptr<_State_type>                   _M_state;
1302e4b17023SJohn Marino
1303e4b17023SJohn Marino    public:
1304e4b17023SJohn Marino      // Construction and destruction
1305e4b17023SJohn Marino      packaged_task() noexcept { }
1306e4b17023SJohn Marino
1307e4b17023SJohn Marino      template<typename _Allocator>
1308e4b17023SJohn Marino        explicit
1309e4b17023SJohn Marino        packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
1310e4b17023SJohn Marino        { }
1311e4b17023SJohn Marino
1312e4b17023SJohn Marino      template<typename _Fn, typename = typename
1313e4b17023SJohn Marino               __constrain_pkgdtask<packaged_task, _Fn>::__type>
1314e4b17023SJohn Marino        explicit
1315e4b17023SJohn Marino        packaged_task(_Fn&& __fn)
1316e4b17023SJohn Marino        : _M_state(std::make_shared<_State_type>(std::forward<_Fn>(__fn)))
1317e4b17023SJohn Marino        { }
1318e4b17023SJohn Marino
1319e4b17023SJohn Marino      template<typename _Fn, typename _Allocator, typename = typename
1320e4b17023SJohn Marino               __constrain_pkgdtask<packaged_task, _Fn>::__type>
1321e4b17023SJohn Marino        explicit
1322e4b17023SJohn Marino        packaged_task(allocator_arg_t, const _Allocator& __a, _Fn&& __fn)
1323e4b17023SJohn Marino        : _M_state(std::allocate_shared<_State_type>(__a,
1324e4b17023SJohn Marino                                                     std::forward<_Fn>(__fn)))
1325e4b17023SJohn Marino        { }
1326e4b17023SJohn Marino
1327e4b17023SJohn Marino      ~packaged_task()
1328e4b17023SJohn Marino      {
1329e4b17023SJohn Marino        if (static_cast<bool>(_M_state) && !_M_state.unique())
1330e4b17023SJohn Marino          _M_state->_M_break_promise(std::move(_M_state->_M_result));
1331e4b17023SJohn Marino      }
1332e4b17023SJohn Marino
1333e4b17023SJohn Marino      // No copy
1334e4b17023SJohn Marino      packaged_task(const packaged_task&) = delete;
1335e4b17023SJohn Marino      packaged_task& operator=(const packaged_task&) = delete;
1336e4b17023SJohn Marino
1337e4b17023SJohn Marino      template<typename _Allocator>
1338e4b17023SJohn Marino        explicit
1339e4b17023SJohn Marino        packaged_task(allocator_arg_t, const _Allocator&,
1340e4b17023SJohn Marino                      const packaged_task&) = delete;
1341e4b17023SJohn Marino
1342e4b17023SJohn Marino      // Move support
1343e4b17023SJohn Marino      packaged_task(packaged_task&& __other) noexcept
1344e4b17023SJohn Marino      { this->swap(__other); }
1345e4b17023SJohn Marino
1346e4b17023SJohn Marino      template<typename _Allocator>
1347e4b17023SJohn Marino        explicit
1348e4b17023SJohn Marino        packaged_task(allocator_arg_t, const _Allocator&,
1349e4b17023SJohn Marino                      packaged_task&& __other) noexcept
1350e4b17023SJohn Marino        { this->swap(__other); }
1351e4b17023SJohn Marino
1352e4b17023SJohn Marino      packaged_task& operator=(packaged_task&& __other) noexcept
1353e4b17023SJohn Marino      {
1354e4b17023SJohn Marino        packaged_task(std::move(__other)).swap(*this);
1355e4b17023SJohn Marino        return *this;
1356e4b17023SJohn Marino      }
1357e4b17023SJohn Marino
1358e4b17023SJohn Marino      void
1359e4b17023SJohn Marino      swap(packaged_task& __other) noexcept
1360e4b17023SJohn Marino      { _M_state.swap(__other._M_state); }
1361e4b17023SJohn Marino
1362e4b17023SJohn Marino      bool
1363e4b17023SJohn Marino      valid() const noexcept
1364e4b17023SJohn Marino      { return static_cast<bool>(_M_state); }
1365e4b17023SJohn Marino
1366e4b17023SJohn Marino      // Result retrieval
1367e4b17023SJohn Marino      future<_Res>
1368e4b17023SJohn Marino      get_future()
1369e4b17023SJohn Marino      { return future<_Res>(_M_state); }
1370e4b17023SJohn Marino
1371e4b17023SJohn Marino      // Execution
1372e4b17023SJohn Marino      void
1373e4b17023SJohn Marino      operator()(_ArgTypes... __args)
1374e4b17023SJohn Marino      {
1375e4b17023SJohn Marino        __future_base::_State_base::_S_check(_M_state);
1376e4b17023SJohn Marino        _M_state->_M_run(std::forward<_ArgTypes>(__args)...);
1377e4b17023SJohn Marino      }
1378e4b17023SJohn Marino
1379e4b17023SJohn Marino      void
1380e4b17023SJohn Marino      reset()
1381e4b17023SJohn Marino      {
1382e4b17023SJohn Marino        __future_base::_State_base::_S_check(_M_state);
1383e4b17023SJohn Marino        packaged_task(std::move(_M_state->_M_task)).swap(*this);
1384e4b17023SJohn Marino      }
1385e4b17023SJohn Marino    };
1386e4b17023SJohn Marino
1387e4b17023SJohn Marino  /// swap
1388e4b17023SJohn Marino  template<typename _Res, typename... _ArgTypes>
1389e4b17023SJohn Marino    inline void
1390e4b17023SJohn Marino    swap(packaged_task<_Res(_ArgTypes...)>& __x,
1391e4b17023SJohn Marino	 packaged_task<_Res(_ArgTypes...)>& __y) noexcept
1392e4b17023SJohn Marino    { __x.swap(__y); }
1393e4b17023SJohn Marino
1394e4b17023SJohn Marino  template<typename _Res, typename _Alloc>
1395e4b17023SJohn Marino    struct uses_allocator<packaged_task<_Res>, _Alloc>
1396e4b17023SJohn Marino    : public true_type { };
1397e4b17023SJohn Marino
1398e4b17023SJohn Marino
1399e4b17023SJohn Marino  template<typename _BoundFn, typename _Res>
1400e4b17023SJohn Marino    class __future_base::_Deferred_state final
1401e4b17023SJohn Marino    : public __future_base::_State_base
1402e4b17023SJohn Marino    {
1403e4b17023SJohn Marino    public:
1404e4b17023SJohn Marino      explicit
1405e4b17023SJohn Marino      _Deferred_state(_BoundFn&& __fn)
1406e4b17023SJohn Marino      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
1407e4b17023SJohn Marino      { }
1408e4b17023SJohn Marino
1409e4b17023SJohn Marino    private:
1410e4b17023SJohn Marino      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1411e4b17023SJohn Marino      _Ptr_type _M_result;
1412e4b17023SJohn Marino      _BoundFn _M_fn;
1413e4b17023SJohn Marino
1414e4b17023SJohn Marino      virtual void
1415e4b17023SJohn Marino      _M_run_deferred()
1416e4b17023SJohn Marino      {
1417e4b17023SJohn Marino        // safe to call multiple times so ignore failure
1418e4b17023SJohn Marino        _M_set_result(_S_task_setter(_M_result, _M_fn), true);
1419e4b17023SJohn Marino      }
1420e4b17023SJohn Marino    };
1421e4b17023SJohn Marino
1422e4b17023SJohn Marino  class __future_base::_Async_state_common : public __future_base::_State_base
1423e4b17023SJohn Marino  {
1424e4b17023SJohn Marino  protected:
1425e4b17023SJohn Marino#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
1426e4b17023SJohn Marino    ~_Async_state_common();
1427e4b17023SJohn Marino#else
1428e4b17023SJohn Marino    ~_Async_state_common() = default;
1429e4b17023SJohn Marino#endif
1430e4b17023SJohn Marino
1431e4b17023SJohn Marino    // Allow non-timed waiting functions to block until the thread completes,
1432e4b17023SJohn Marino    // as if joined.
1433e4b17023SJohn Marino    virtual void _M_run_deferred() { _M_join(); }
1434e4b17023SJohn Marino
1435e4b17023SJohn Marino    void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); }
1436e4b17023SJohn Marino
1437e4b17023SJohn Marino    thread _M_thread;
1438e4b17023SJohn Marino    once_flag _M_once;
1439e4b17023SJohn Marino  };
1440e4b17023SJohn Marino
1441e4b17023SJohn Marino  template<typename _BoundFn, typename _Res>
1442e4b17023SJohn Marino    class __future_base::_Async_state_impl final
1443e4b17023SJohn Marino    : public __future_base::_Async_state_common
1444e4b17023SJohn Marino    {
1445e4b17023SJohn Marino    public:
1446e4b17023SJohn Marino      explicit
1447e4b17023SJohn Marino      _Async_state_impl(_BoundFn&& __fn)
1448e4b17023SJohn Marino      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
1449e4b17023SJohn Marino      {
1450e4b17023SJohn Marino	_M_thread = std::thread{ [this] {
1451e4b17023SJohn Marino	  _M_set_result(_S_task_setter(_M_result, _M_fn));
1452e4b17023SJohn Marino        } };
1453e4b17023SJohn Marino      }
1454e4b17023SJohn Marino
1455e4b17023SJohn Marino      ~_Async_state_impl() { _M_join(); }
1456e4b17023SJohn Marino
1457e4b17023SJohn Marino    private:
1458e4b17023SJohn Marino      typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1459e4b17023SJohn Marino      _Ptr_type _M_result;
1460e4b17023SJohn Marino      _BoundFn _M_fn;
1461e4b17023SJohn Marino    };
1462e4b17023SJohn Marino
1463e4b17023SJohn Marino  template<typename _BoundFn>
1464e4b17023SJohn Marino    inline std::shared_ptr<__future_base::_State_base>
1465e4b17023SJohn Marino    __future_base::_S_make_deferred_state(_BoundFn&& __fn)
1466e4b17023SJohn Marino    {
1467e4b17023SJohn Marino      typedef typename remove_reference<_BoundFn>::type __fn_type;
1468e4b17023SJohn Marino      typedef _Deferred_state<__fn_type> __state_type;
1469e4b17023SJohn Marino      return std::make_shared<__state_type>(std::move(__fn));
1470e4b17023SJohn Marino    }
1471e4b17023SJohn Marino
1472e4b17023SJohn Marino  template<typename _BoundFn>
1473e4b17023SJohn Marino    inline std::shared_ptr<__future_base::_State_base>
1474e4b17023SJohn Marino    __future_base::_S_make_async_state(_BoundFn&& __fn)
1475e4b17023SJohn Marino    {
1476e4b17023SJohn Marino      typedef typename remove_reference<_BoundFn>::type __fn_type;
1477e4b17023SJohn Marino      typedef _Async_state_impl<__fn_type> __state_type;
1478e4b17023SJohn Marino      return std::make_shared<__state_type>(std::move(__fn));
1479e4b17023SJohn Marino    }
1480e4b17023SJohn Marino
1481e4b17023SJohn Marino
1482e4b17023SJohn Marino  /// async
1483e4b17023SJohn Marino  template<typename _Fn, typename... _Args>
1484e4b17023SJohn Marino    future<typename result_of<_Fn(_Args...)>::type>
1485e4b17023SJohn Marino    async(launch __policy, _Fn&& __fn, _Args&&... __args)
1486e4b17023SJohn Marino    {
1487e4b17023SJohn Marino      typedef typename result_of<_Fn(_Args...)>::type result_type;
1488e4b17023SJohn Marino      std::shared_ptr<__future_base::_State_base> __state;
1489e4b17023SJohn Marino      if ((__policy & (launch::async|launch::deferred)) == launch::async)
1490e4b17023SJohn Marino	{
1491e4b17023SJohn Marino	  __state = __future_base::_S_make_async_state(std::__bind_simple(
1492e4b17023SJohn Marino              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
1493e4b17023SJohn Marino	}
1494e4b17023SJohn Marino      else
1495e4b17023SJohn Marino	{
1496e4b17023SJohn Marino	  __state = __future_base::_S_make_deferred_state(std::__bind_simple(
1497e4b17023SJohn Marino              std::forward<_Fn>(__fn), std::forward<_Args>(__args)...));
1498e4b17023SJohn Marino	}
1499e4b17023SJohn Marino      return future<result_type>(__state);
1500e4b17023SJohn Marino    }
1501e4b17023SJohn Marino
1502e4b17023SJohn Marino  /// async, potential overload
1503e4b17023SJohn Marino  template<typename _Fn, typename... _Args>
1504e4b17023SJohn Marino    inline typename
1505e4b17023SJohn Marino    __async_sfinae_helper<typename decay<_Fn>::type, _Fn, _Args...>::type
1506e4b17023SJohn Marino    async(_Fn&& __fn, _Args&&... __args)
1507e4b17023SJohn Marino    {
1508e4b17023SJohn Marino      return async(launch::async|launch::deferred, std::forward<_Fn>(__fn),
1509e4b17023SJohn Marino		   std::forward<_Args>(__args)...);
1510e4b17023SJohn Marino    }
1511e4b17023SJohn Marino
1512e4b17023SJohn Marino#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
1513e4b17023SJohn Marino       // && ATOMIC_INT_LOCK_FREE
1514e4b17023SJohn Marino
1515e4b17023SJohn Marino  // @} group futures
1516e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION
1517e4b17023SJohn Marino} // namespace
1518e4b17023SJohn Marino
1519e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__
1520e4b17023SJohn Marino
1521e4b17023SJohn Marino#endif // _GLIBCXX_FUTURE
1522