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