]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/future
Use shared_ptr<T>::element_type in hash specializations
[thirdparty/gcc.git] / libstdc++-v3 / include / std / future
CommitLineData
c910ceff
JW
1// <future> -*- C++ -*-
2
818ab71a 3// Copyright (C) 2009-2016 Free Software Foundation, Inc.
c910ceff
JW
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
f910786b 25/** @file include/future
c910ceff
JW
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_FUTURE
30#define _GLIBCXX_FUTURE 1
31
32#pragma GCC system_header
33
734f5023 34#if __cplusplus < 201103L
ab65a4c7 35# include <bits/c++0x_warning.h>
c910ceff
JW
36#else
37
c910ceff 38#include <mutex>
b3eed6fe 39#include <thread>
c910ceff
JW
40#include <condition_variable>
41#include <system_error>
afd88205 42#include <atomic>
eae801ba 43#include <bits/atomic_futex.h>
abcd7e08 44#include <bits/functexcept.h>
5579170b 45#include <bits/invoke.h>
6e48db73
JW
46#include <bits/unique_ptr.h>
47#include <bits/shared_ptr.h>
c05986b9 48#include <bits/std_function.h>
6e48db73 49#include <bits/uses_allocator.h>
b925bf59 50#include <bits/allocated_ptr.h>
f2e2de5f 51#include <ext/aligned_buffer.h>
c910ceff 52
12ffa228
BK
53namespace std _GLIBCXX_VISIBILITY(default)
54{
55_GLIBCXX_BEGIN_NAMESPACE_VERSION
53dc5044 56
c910ceff
JW
57 /**
58 * @defgroup futures Futures
59 * @ingroup concurrency
60 *
61 * Classes for futures support.
62 * @{
63 */
64
65 /// Error code for futures
66 enum class future_errc
b3eed6fe 67 {
7e98765e 68 future_already_retrieved = 1,
b3eed6fe 69 promise_already_satisfied,
7e98765e
JW
70 no_state,
71 broken_promise
b3eed6fe 72 };
c910ceff 73
94a86be0 74 /// Specialization.
c910ceff
JW
75 template<>
76 struct is_error_code_enum<future_errc> : public true_type { };
77
78 /// Points to a statically-allocated object derived from error_category.
94a86be0 79 const error_category&
84b63c01 80 future_category() noexcept;
c910ceff 81
94a86be0 82 /// Overload for make_error_code.
faa00511 83 inline error_code
84b63c01 84 make_error_code(future_errc __errc) noexcept
94a86be0 85 { return error_code(static_cast<int>(__errc), future_category()); }
c910ceff 86
94a86be0 87 /// Overload for make_error_condition.
faa00511 88 inline error_condition
84b63c01 89 make_error_condition(future_errc __errc) noexcept
94a86be0 90 { return error_condition(static_cast<int>(__errc), future_category()); }
c910ceff 91
8d1b99e2
BK
92 /**
93 * @brief Exception type thrown by futures.
94 * @ingroup exceptions
95 */
c910ceff
JW
96 class future_error : public logic_error
97 {
c36abf03 98 error_code _M_code;
8d1b99e2 99
c910ceff 100 public:
b3eed6fe 101 explicit future_error(error_code __ec)
664e99ea 102 : logic_error("std::future_error: " + __ec.message()), _M_code(__ec)
c910ceff
JW
103 { }
104
84b63c01 105 virtual ~future_error() noexcept;
c910ceff 106
faa00511 107 virtual const char*
84b63c01 108 what() const noexcept;
c910ceff 109
faa00511 110 const error_code&
84b63c01 111 code() const noexcept { return _M_code; }
c910ceff
JW
112 };
113
3259554a 114 // Forward declarations.
c36abf03 115 template<typename _Res>
b3eed6fe 116 class future;
3259554a 117
c36abf03 118 template<typename _Res>
3259554a
BK
119 class shared_future;
120
faa00511 121 template<typename _Signature>
3259554a
BK
122 class packaged_task;
123
c36abf03 124 template<typename _Res>
3259554a
BK
125 class promise;
126
94a86be0 127 /// Launch code for futures
faa00511
JW
128 enum class launch
129 {
130 async = 1,
131 deferred = 2
94a86be0
BK
132 };
133
a4eeb822 134 constexpr launch operator&(launch __x, launch __y)
faa00511
JW
135 {
136 return static_cast<launch>(
137 static_cast<int>(__x) & static_cast<int>(__y));
138 }
139
a4eeb822 140 constexpr launch operator|(launch __x, launch __y)
faa00511
JW
141 {
142 return static_cast<launch>(
143 static_cast<int>(__x) | static_cast<int>(__y));
144 }
145
a4eeb822 146 constexpr launch operator^(launch __x, launch __y)
faa00511
JW
147 {
148 return static_cast<launch>(
149 static_cast<int>(__x) ^ static_cast<int>(__y));
150 }
151
a4eeb822 152 constexpr launch operator~(launch __x)
faa00511
JW
153 { return static_cast<launch>(~static_cast<int>(__x)); }
154
155 inline launch& operator&=(launch& __x, launch __y)
156 { return __x = __x & __y; }
157
158 inline launch& operator|=(launch& __x, launch __y)
159 { return __x = __x | __y; }
160
161 inline launch& operator^=(launch& __x, launch __y)
162 { return __x = __x ^ __y; }
163
94a86be0 164 /// Status code for futures
faa00511 165 enum class future_status
94a86be0
BK
166 {
167 ready,
168 timeout,
169 deferred
170 };
b3eed6fe 171
75eb6443
JW
172 // _GLIBCXX_RESOLVE_LIB_DEFECTS
173 // 2021. Further incorrect usages of result_of
b3eed6fe 174 template<typename _Fn, typename... _Args>
75eb6443
JW
175 using __async_result_of = typename result_of<
176 typename decay<_Fn>::type(typename decay<_Args>::type...)>::type;
177
178 template<typename _Fn, typename... _Args>
179 future<__async_result_of<_Fn, _Args...>>
b3eed6fe
JW
180 async(launch __policy, _Fn&& __fn, _Args&&... __args);
181
be7f7822 182 template<typename _Fn, typename... _Args>
75eb6443 183 future<__async_result_of<_Fn, _Args...>>
b3eed6fe
JW
184 async(_Fn&& __fn, _Args&&... __args);
185
41ca4246 186#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
a152e96f 187 && (ATOMIC_INT_LOCK_FREE > 1)
41ca4246 188
c36abf03
BK
189 /// Base class and enclosing scope.
190 struct __future_base
c910ceff 191 {
c36abf03
BK
192 /// Base class for results.
193 struct _Result_base
194 {
195 exception_ptr _M_error;
c910ceff 196
c36abf03
BK
197 _Result_base(const _Result_base&) = delete;
198 _Result_base& operator=(const _Result_base&) = delete;
c910ceff 199
b3eed6fe 200 // _M_destroy() allows derived classes to control deallocation
c36abf03 201 virtual void _M_destroy() = 0;
c910ceff 202
c36abf03
BK
203 struct _Deleter
204 {
205 void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
206 };
c910ceff 207
c36abf03 208 protected:
e9599233
BK
209 _Result_base();
210 virtual ~_Result_base();
c36abf03 211 };
20f2653e 212
9db7c931
JW
213 /// A unique_ptr for result objects.
214 template<typename _Res>
215 using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;
216
217 /// A result object that has storage for an object of type _Res.
c36abf03
BK
218 template<typename _Res>
219 struct _Result : _Result_base
220 {
221 private:
f2e2de5f
JW
222 __gnu_cxx::__aligned_buffer<_Res> _M_storage;
223 bool _M_initialized;
c36abf03
BK
224
225 public:
aaad548e
JW
226 typedef _Res result_type;
227
84b63c01 228 _Result() noexcept : _M_initialized() { }
33ac58d5 229
c36abf03
BK
230 ~_Result()
231 {
232 if (_M_initialized)
233 _M_value().~_Res();
234 }
235
236 // Return lvalue, future will add const or rvalue-reference
faa00511 237 _Res&
f2e2de5f 238 _M_value() noexcept { return *_M_storage._M_ptr(); }
c36abf03
BK
239
240 void
241 _M_set(const _Res& __res)
242 {
f2e2de5f 243 ::new (_M_storage._M_addr()) _Res(__res);
c36abf03
BK
244 _M_initialized = true;
245 }
246
247 void
248 _M_set(_Res&& __res)
249 {
f2e2de5f 250 ::new (_M_storage._M_addr()) _Res(std::move(__res));
c36abf03
BK
251 _M_initialized = true;
252 }
253
254 private:
255 void _M_destroy() { delete this; }
c910ceff
JW
256 };
257
9db7c931 258 /// A result object that uses an allocator.
b3eed6fe 259 template<typename _Res, typename _Alloc>
a58a38b3 260 struct _Result_alloc final : _Result<_Res>, _Alloc
b3eed6fe 261 {
b925bf59 262 using __allocator_type = __alloc_rebind<_Alloc, _Result_alloc>;
b3eed6fe
JW
263
264 explicit
0fd76d8e 265 _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a)
b925bf59 266 { }
33ac58d5 267
b3eed6fe
JW
268 private:
269 void _M_destroy()
b925bf59
JW
270 {
271 __allocator_type __a(*this);
272 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
273 this->~_Result_alloc();
274 }
135a0d0a 275 };
b3eed6fe 276
9db7c931 277 // Create a result object that uses an allocator.
b3eed6fe 278 template<typename _Res, typename _Allocator>
c4d9f419 279 static _Ptr<_Result_alloc<_Res, _Allocator>>
b3eed6fe
JW
280 _S_allocate_result(const _Allocator& __a)
281 {
b925bf59
JW
282 using __result_type = _Result_alloc<_Res, _Allocator>;
283 typename __result_type::__allocator_type __a2(__a);
284 auto __guard = std::__allocate_guarded(__a2);
285 __result_type* __p = ::new((void*)__guard.get()) __result_type{__a};
286 __guard = nullptr;
287 return _Ptr<__result_type>(__p);
b3eed6fe 288 }
b3eed6fe 289
9db7c931 290 // Keep it simple for std::allocator.
aaad548e
JW
291 template<typename _Res, typename _Tp>
292 static _Ptr<_Result<_Res>>
293 _S_allocate_result(const std::allocator<_Tp>& __a)
294 {
295 return _Ptr<_Result<_Res>>(new _Result<_Res>);
296 }
c910ceff 297
9db7c931
JW
298 // Base class for various types of shared state created by an
299 // asynchronous provider (such as a std::promise) and shared with one
300 // or more associated futures.
f2f08be7 301 class _State_baseV2
c910ceff 302 {
c4d9f419 303 typedef _Ptr<_Result_base> _Ptr_type;
c910ceff 304
eae801ba
TR
305 enum _Status : unsigned {
306 __not_ready,
307 __ready
308 };
309
c36abf03 310 _Ptr_type _M_result;
eae801ba
TR
311 __atomic_futex_unsigned<> _M_status;
312 atomic_flag _M_retrieved = ATOMIC_FLAG_INIT;
b3eed6fe 313 once_flag _M_once;
c910ceff 314
c36abf03 315 public:
eae801ba
TR
316 _State_baseV2() noexcept : _M_result(), _M_status(_Status::__not_ready)
317 { }
f2f08be7
JW
318 _State_baseV2(const _State_baseV2&) = delete;
319 _State_baseV2& operator=(const _State_baseV2&) = delete;
320 virtual ~_State_baseV2() = default;
c910ceff 321
c36abf03
BK
322 _Result_base&
323 wait()
c910ceff 324 {
9db7c931 325 // Run any deferred function or join any asynchronous thread:
f2f08be7 326 _M_complete_async();
eae801ba
TR
327 // Acquire MO makes sure this synchronizes with the thread that made
328 // the future ready.
329 _M_status._M_load_when_equal(_Status::__ready, memory_order_acquire);
c36abf03 330 return *_M_result;
c910ceff 331 }
c910ceff 332
c36abf03 333 template<typename _Rep, typename _Period>
488b3e65 334 future_status
c36abf03
BK
335 wait_for(const chrono::duration<_Rep, _Period>& __rel)
336 {
eae801ba
TR
337 // First, check if the future has been made ready. Use acquire MO
338 // to synchronize with the thread that made it ready.
339 if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
488b3e65 340 return future_status::ready;
eae801ba 341 if (_M_is_deferred_future())
f2f08be7 342 return future_status::deferred;
eae801ba
TR
343 if (_M_status._M_load_when_equal_for(_Status::__ready,
344 memory_order_acquire, __rel))
f2f08be7
JW
345 {
346 // _GLIBCXX_RESOLVE_LIB_DEFECTS
347 // 2100. timed waiting functions must also join
9db7c931
JW
348 // This call is a no-op by default except on an async future,
349 // in which case the async thread is joined. It's also not a
350 // no-op for a deferred future, but such a future will never
351 // reach this point because it returns future_status::deferred
352 // instead of waiting for the future to become ready (see
353 // above). Async futures synchronize in this call, so we need
354 // no further synchronization here.
f2f08be7 355 _M_complete_async();
9db7c931 356
f2f08be7
JW
357 return future_status::ready;
358 }
488b3e65 359 return future_status::timeout;
c36abf03 360 }
c910ceff 361
c36abf03 362 template<typename _Clock, typename _Duration>
488b3e65 363 future_status
c36abf03
BK
364 wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
365 {
eae801ba
TR
366 // First, check if the future has been made ready. Use acquire MO
367 // to synchronize with the thread that made it ready.
368 if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
488b3e65 369 return future_status::ready;
eae801ba 370 if (_M_is_deferred_future())
f2f08be7 371 return future_status::deferred;
eae801ba
TR
372 if (_M_status._M_load_when_equal_until(_Status::__ready,
373 memory_order_acquire, __abs))
f2f08be7
JW
374 {
375 // _GLIBCXX_RESOLVE_LIB_DEFECTS
376 // 2100. timed waiting functions must also join
9db7c931 377 // See wait_for(...) above.
f2f08be7 378 _M_complete_async();
9db7c931 379
f2f08be7
JW
380 return future_status::ready;
381 }
488b3e65 382 return future_status::timeout;
c36abf03 383 }
c910ceff 384
9db7c931 385 // Provide a result to the shared state and make it ready.
eae801ba 386 // Calls at most once: _M_result = __res();
c36abf03 387 void
b3eed6fe 388 _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false)
c910ceff 389 {
eae801ba 390 bool __did_set = false;
b3eed6fe
JW
391 // all calls to this function are serialized,
392 // side-effects of invoking __res only happen once
a0eaa08c 393 call_once(_M_once, &_State_baseV2::_M_do_set, this,
eae801ba
TR
394 std::__addressof(__res), std::__addressof(__did_set));
395 if (__did_set)
396 // Use release MO to synchronize with observers of the ready state.
397 _M_status._M_store_notify_all(_Status::__ready,
398 memory_order_release);
a0eaa08c 399 else if (!__ignore_failure)
b3eed6fe 400 __throw_future_error(int(future_errc::promise_already_satisfied));
c910ceff
JW
401 }
402
9db7c931
JW
403 // Provide a result to the shared state but delay making it ready
404 // until the calling thread exits.
eae801ba 405 // Calls at most once: _M_result = __res();
9db7c931
JW
406 void
407 _M_set_delayed_result(function<_Ptr_type()> __res,
408 weak_ptr<_State_baseV2> __self)
409 {
eae801ba 410 bool __did_set = false;
9db7c931 411 unique_ptr<_Make_ready> __mr{new _Make_ready};
9db7c931
JW
412 // all calls to this function are serialized,
413 // side-effects of invoking __res only happen once
414 call_once(_M_once, &_State_baseV2::_M_do_set, this,
eae801ba
TR
415 std::__addressof(__res), std::__addressof(__did_set));
416 if (!__did_set)
9db7c931
JW
417 __throw_future_error(int(future_errc::promise_already_satisfied));
418 __mr->_M_shared_state = std::move(__self);
419 __mr->_M_set();
420 __mr.release();
421 }
422
423 // Abandon this shared state.
c910ceff 424 void
c36abf03 425 _M_break_promise(_Ptr_type __res)
c910ceff 426 {
c36abf03
BK
427 if (static_cast<bool>(__res))
428 {
b3eed6fe 429 error_code __ec(make_error_code(future_errc::broken_promise));
ec98d010 430 __res->_M_error = make_exception_ptr(future_error(__ec));
9db7c931
JW
431 // This function is only called when the last asynchronous result
432 // provider is abandoning this shared state, so noone can be
433 // trying to make the shared state ready at the same time, and
434 // we can access _M_result directly instead of through call_once.
eae801ba
TR
435 _M_result.swap(__res);
436 // Use release MO to synchronize with observers of the ready state.
437 _M_status._M_store_notify_all(_Status::__ready,
438 memory_order_release);
c36abf03 439 }
c910ceff
JW
440 }
441
9db7c931 442 // Called when this object is first passed to a future.
c910ceff 443 void
c36abf03 444 _M_set_retrieved_flag()
c910ceff 445 {
c36abf03
BK
446 if (_M_retrieved.test_and_set())
447 __throw_future_error(int(future_errc::future_already_retrieved));
c910ceff
JW
448 }
449
b3eed6fe
JW
450 template<typename _Res, typename _Arg>
451 struct _Setter;
452
453 // set lvalues
454 template<typename _Res, typename _Arg>
455 struct _Setter<_Res, _Arg&>
456 {
457 // check this is only used by promise<R>::set_value(const R&)
4e48c109 458 // or promise<R&>::set_value(R&)
b3eed6fe 459 static_assert(is_same<_Res, _Arg&>::value // promise<R&>
4e48c109 460 || is_same<const _Res, _Arg>::value, // promise<R>
b3eed6fe
JW
461 "Invalid specialisation");
462
9db7c931 463 // Used by std::promise to copy construct the result.
9131b509 464 typename promise<_Res>::_Ptr_type operator()() const
b3eed6fe 465 {
f2f08be7 466 _State_baseV2::_S_check(_M_promise->_M_future);
4e48c109 467 _M_promise->_M_storage->_M_set(*_M_arg);
b3eed6fe
JW
468 return std::move(_M_promise->_M_storage);
469 }
470 promise<_Res>* _M_promise;
4e48c109 471 _Arg* _M_arg;
b3eed6fe
JW
472 };
473
474 // set rvalues
475 template<typename _Res>
476 struct _Setter<_Res, _Res&&>
477 {
9db7c931 478 // Used by std::promise to move construct the result.
9131b509 479 typename promise<_Res>::_Ptr_type operator()() const
b3eed6fe 480 {
f2f08be7 481 _State_baseV2::_S_check(_M_promise->_M_future);
4e48c109 482 _M_promise->_M_storage->_M_set(std::move(*_M_arg));
b3eed6fe
JW
483 return std::move(_M_promise->_M_storage);
484 }
485 promise<_Res>* _M_promise;
4e48c109 486 _Res* _M_arg;
b3eed6fe
JW
487 };
488
489 struct __exception_ptr_tag { };
490
491 // set exceptions
492 template<typename _Res>
493 struct _Setter<_Res, __exception_ptr_tag>
494 {
9db7c931 495 // Used by std::promise to store an exception as the result.
9131b509 496 typename promise<_Res>::_Ptr_type operator()() const
b3eed6fe 497 {
f2f08be7 498 _State_baseV2::_S_check(_M_promise->_M_future);
4e48c109 499 _M_promise->_M_storage->_M_error = *_M_ex;
b3eed6fe
JW
500 return std::move(_M_promise->_M_storage);
501 }
502
503 promise<_Res>* _M_promise;
4e48c109 504 exception_ptr* _M_ex;
b3eed6fe
JW
505 };
506
507 template<typename _Res, typename _Arg>
508 static _Setter<_Res, _Arg&&>
509 __setter(promise<_Res>* __prom, _Arg&& __arg)
510 {
f885fa89 511 return _Setter<_Res, _Arg&&>{ __prom, std::__addressof(__arg) };
b3eed6fe
JW
512 }
513
514 template<typename _Res>
515 static _Setter<_Res, __exception_ptr_tag>
516 __setter(exception_ptr& __ex, promise<_Res>* __prom)
517 {
4e48c109 518 return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex };
b3eed6fe
JW
519 }
520
b3eed6fe 521 template<typename _Tp>
c93fa3ca 522 static void
b3eed6fe
JW
523 _S_check(const shared_ptr<_Tp>& __p)
524 {
525 if (!static_cast<bool>(__p))
526 __throw_future_error((int)future_errc::no_state);
527 }
528
c910ceff 529 private:
9db7c931 530 // The function invoked with std::call_once(_M_once, ...).
b3eed6fe 531 void
eae801ba 532 _M_do_set(function<_Ptr_type()>* __f, bool* __did_set)
c36abf03 533 {
eae801ba
TR
534 _Ptr_type __res = (*__f)();
535 // Notify the caller that we did try to set; if we do not throw an
536 // exception, the caller will be aware that it did set (e.g., see
537 // _M_set_result).
538 *__did_set = true;
539 _M_result.swap(__res); // nothrow
c36abf03 540 }
c910ceff 541
f2f08be7
JW
542 // Wait for completion of async function.
543 virtual void _M_complete_async() { }
544
9db7c931 545 // Return true if state corresponds to a deferred function.
eae801ba 546 virtual bool _M_is_deferred_future() const { return false; }
9db7c931
JW
547
548 struct _Make_ready final : __at_thread_exit_elt
549 {
550 weak_ptr<_State_baseV2> _M_shared_state;
551 static void _S_run(void*);
552 void _M_set();
553 };
c910ceff 554 };
b3eed6fe 555
f2f08be7
JW
556#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
557 class _State_base;
558 class _Async_state_common;
559#else
560 using _State_base = _State_baseV2;
561 class _Async_state_commonV2;
562#endif
563
a2284544
JW
564 template<typename _BoundFn,
565 typename _Res = decltype(std::declval<_BoundFn&>()())>
b3eed6fe
JW
566 class _Deferred_state;
567
a2284544
JW
568 template<typename _BoundFn,
569 typename _Res = decltype(std::declval<_BoundFn&>()())>
488b3e65 570 class _Async_state_impl;
b3eed6fe
JW
571
572 template<typename _Signature>
aaad548e
JW
573 class _Task_state_base;
574
575 template<typename _Fn, typename _Alloc, typename _Signature>
b3eed6fe
JW
576 class _Task_state;
577
4880236e
JW
578 template<typename _BoundFn>
579 static std::shared_ptr<_State_base>
580 _S_make_deferred_state(_BoundFn&& __fn);
581
582 template<typename _BoundFn>
583 static std::shared_ptr<_State_base>
584 _S_make_async_state(_BoundFn&& __fn);
585
4e48c109 586 template<typename _Res_ptr, typename _Fn,
aaad548e 587 typename _Res = typename _Res_ptr::element_type::result_type>
b3eed6fe 588 struct _Task_setter;
4880236e
JW
589
590 template<typename _Res_ptr, typename _BoundFn>
4e48c109
JW
591 static _Task_setter<_Res_ptr, _BoundFn>
592 _S_task_setter(_Res_ptr& __ptr, _BoundFn& __call)
4880236e 593 {
4e48c109 594 return { std::__addressof(__ptr), std::__addressof(__call) };
4880236e 595 }
c36abf03 596 };
c910ceff 597
c36abf03
BK
598 /// Partial specialization for reference types.
599 template<typename _Res>
600 struct __future_base::_Result<_Res&> : __future_base::_Result_base
601 {
aaad548e
JW
602 typedef _Res& result_type;
603
84b63c01 604 _Result() noexcept : _M_value_ptr() { }
c910ceff 605
9db7c931
JW
606 void
607 _M_set(_Res& __res) noexcept
608 { _M_value_ptr = std::addressof(__res); }
b3eed6fe 609
84b63c01 610 _Res& _M_get() noexcept { return *_M_value_ptr; }
b3eed6fe
JW
611
612 private:
c36abf03 613 _Res* _M_value_ptr;
faa00511 614
c910ceff
JW
615 void _M_destroy() { delete this; }
616 };
617
c36abf03 618 /// Explicit specialization for void.
c910ceff 619 template<>
c36abf03 620 struct __future_base::_Result<void> : __future_base::_Result_base
c910ceff 621 {
aaad548e
JW
622 typedef void result_type;
623
c36abf03 624 private:
c910ceff
JW
625 void _M_destroy() { delete this; }
626 };
627
db0b7db3
JW
628#ifndef _GLIBCXX_ASYNC_ABI_COMPAT
629
4e48c109
JW
630 // Allow _Setter objects to be stored locally in std::function
631 template<typename _Res, typename _Arg>
632 struct __is_location_invariant
633 <__future_base::_State_base::_Setter<_Res, _Arg>>
634 : true_type { };
635
636 // Allow _Task_setter objects to be stored locally in std::function
637 template<typename _Res_ptr, typename _Fn, typename _Res>
638 struct __is_location_invariant
639 <__future_base::_Task_setter<_Res_ptr, _Fn, _Res>>
640 : true_type { };
641
b3eed6fe 642 /// Common implementation for future and shared_future.
c36abf03
BK
643 template<typename _Res>
644 class __basic_future : public __future_base
c910ceff 645 {
c36abf03 646 protected:
e9599233 647 typedef shared_ptr<_State_base> __state_type;
c36abf03
BK
648 typedef __future_base::_Result<_Res>& __result_type;
649
650 private:
651 __state_type _M_state;
652
c910ceff 653 public:
c36abf03
BK
654 // Disable copying.
655 __basic_future(const __basic_future&) = delete;
656 __basic_future& operator=(const __basic_future&) = delete;
c910ceff 657
faa00511 658 bool
84b63c01 659 valid() const noexcept { return static_cast<bool>(_M_state); }
c910ceff 660
faa00511 661 void
5262c72a
JW
662 wait() const
663 {
e9599233 664 _State_base::_S_check(_M_state);
5262c72a
JW
665 _M_state->wait();
666 }
c910ceff
JW
667
668 template<typename _Rep, typename _Period>
488b3e65 669 future_status
c910ceff 670 wait_for(const chrono::duration<_Rep, _Period>& __rel) const
5262c72a 671 {
e9599233 672 _State_base::_S_check(_M_state);
5262c72a
JW
673 return _M_state->wait_for(__rel);
674 }
c910ceff
JW
675
676 template<typename _Clock, typename _Duration>
488b3e65 677 future_status
c910ceff 678 wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
5262c72a 679 {
e9599233 680 _State_base::_S_check(_M_state);
5262c72a
JW
681 return _M_state->wait_until(__abs);
682 }
c910ceff
JW
683
684 protected:
c36abf03
BK
685 /// Wait for the state to be ready and rethrow any stored exception
686 __result_type
c93fa3ca 687 _M_get_result() const
c910ceff 688 {
e9599233 689 _State_base::_S_check(_M_state);
b3eed6fe 690 _Result_base& __res = _M_state->wait();
c910ceff
JW
691 if (!(__res._M_error == 0))
692 rethrow_exception(__res._M_error);
c36abf03 693 return static_cast<__result_type>(__res);
c910ceff
JW
694 }
695
84b63c01 696 void _M_swap(__basic_future& __that) noexcept
b3eed6fe
JW
697 {
698 _M_state.swap(__that._M_state);
699 }
700
701 // Construction of a future by promise::get_future()
c910ceff 702 explicit
c36abf03 703 __basic_future(const __state_type& __state) : _M_state(__state)
c910ceff 704 {
e9599233 705 _State_base::_S_check(_M_state);
b3eed6fe 706 _M_state->_M_set_retrieved_flag();
c910ceff
JW
707 }
708
c36abf03 709 // Copy construction from a shared_future
c910ceff 710 explicit
84b63c01 711 __basic_future(const shared_future<_Res>&) noexcept;
c910ceff 712
b3eed6fe 713 // Move construction from a shared_future
c910ceff 714 explicit
84b63c01 715 __basic_future(shared_future<_Res>&&) noexcept;
b3eed6fe
JW
716
717 // Move construction from a future
718 explicit
84b63c01 719 __basic_future(future<_Res>&&) noexcept;
b3eed6fe 720
84b63c01 721 constexpr __basic_future() noexcept : _M_state() { }
b3eed6fe
JW
722
723 struct _Reset
724 {
84b63c01 725 explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { }
b3eed6fe
JW
726 ~_Reset() { _M_fut._M_state.reset(); }
727 __basic_future& _M_fut;
728 };
c910ceff
JW
729 };
730
c36abf03 731
b3eed6fe 732 /// Primary template for future.
c36abf03 733 template<typename _Res>
b3eed6fe 734 class future : public __basic_future<_Res>
c910ceff 735 {
c36abf03 736 friend class promise<_Res>;
b3eed6fe
JW
737 template<typename> friend class packaged_task;
738 template<typename _Fn, typename... _Args>
75eb6443 739 friend future<__async_result_of<_Fn, _Args...>>
b3eed6fe 740 async(launch, _Fn&&, _Args&&...);
c36abf03
BK
741
742 typedef __basic_future<_Res> _Base_type;
743 typedef typename _Base_type::__state_type __state_type;
c36abf03
BK
744
745 explicit
b3eed6fe 746 future(const __state_type& __state) : _Base_type(__state) { }
c910ceff
JW
747
748 public:
84b63c01 749 constexpr future() noexcept : _Base_type() { }
b3eed6fe 750
c910ceff 751 /// Move constructor
84b63c01 752 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
c910ceff 753
c36abf03 754 // Disable copying
b3eed6fe
JW
755 future(const future&) = delete;
756 future& operator=(const future&) = delete;
757
84b63c01 758 future& operator=(future&& __fut) noexcept
b3eed6fe
JW
759 {
760 future(std::move(__fut))._M_swap(*this);
761 return *this;
762 }
c910ceff 763
c36abf03 764 /// Retrieving the value
b3eed6fe 765 _Res
c910ceff 766 get()
b3eed6fe
JW
767 {
768 typename _Base_type::_Reset __reset(*this);
769 return std::move(this->_M_get_result()._M_value());
770 }
e3e08a1d
JW
771
772 shared_future<_Res> share();
c910ceff 773 };
faa00511 774
b3eed6fe 775 /// Partial specialization for future<R&>
c36abf03 776 template<typename _Res>
b3eed6fe 777 class future<_Res&> : public __basic_future<_Res&>
c910ceff 778 {
c36abf03 779 friend class promise<_Res&>;
b3eed6fe
JW
780 template<typename> friend class packaged_task;
781 template<typename _Fn, typename... _Args>
75eb6443 782 friend future<__async_result_of<_Fn, _Args...>>
b3eed6fe 783 async(launch, _Fn&&, _Args&&...);
c36abf03
BK
784
785 typedef __basic_future<_Res&> _Base_type;
786 typedef typename _Base_type::__state_type __state_type;
787
788 explicit
b3eed6fe 789 future(const __state_type& __state) : _Base_type(__state) { }
c36abf03 790
c910ceff 791 public:
84b63c01 792 constexpr future() noexcept : _Base_type() { }
b3eed6fe 793
c910ceff 794 /// Move constructor
84b63c01 795 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
c910ceff 796
c36abf03 797 // Disable copying
b3eed6fe
JW
798 future(const future&) = delete;
799 future& operator=(const future&) = delete;
800
84b63c01 801 future& operator=(future&& __fut) noexcept
b3eed6fe
JW
802 {
803 future(std::move(__fut))._M_swap(*this);
804 return *this;
805 }
c910ceff 806
c36abf03 807 /// Retrieving the value
faa00511 808 _Res&
b3eed6fe
JW
809 get()
810 {
811 typename _Base_type::_Reset __reset(*this);
812 return this->_M_get_result()._M_get();
813 }
e3e08a1d
JW
814
815 shared_future<_Res&> share();
c36abf03 816 };
c910ceff 817
b3eed6fe 818 /// Explicit specialization for future<void>
c36abf03 819 template<>
b3eed6fe 820 class future<void> : public __basic_future<void>
c36abf03
BK
821 {
822 friend class promise<void>;
b3eed6fe
JW
823 template<typename> friend class packaged_task;
824 template<typename _Fn, typename... _Args>
75eb6443 825 friend future<__async_result_of<_Fn, _Args...>>
b3eed6fe 826 async(launch, _Fn&&, _Args&&...);
c910ceff 827
c36abf03
BK
828 typedef __basic_future<void> _Base_type;
829 typedef typename _Base_type::__state_type __state_type;
c910ceff
JW
830
831 explicit
b3eed6fe 832 future(const __state_type& __state) : _Base_type(__state) { }
c910ceff 833
c910ceff 834 public:
84b63c01 835 constexpr future() noexcept : _Base_type() { }
b3eed6fe 836
c910ceff 837 /// Move constructor
84b63c01 838 future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
c910ceff 839
c36abf03 840 // Disable copying
b3eed6fe
JW
841 future(const future&) = delete;
842 future& operator=(const future&) = delete;
843
84b63c01 844 future& operator=(future&& __fut) noexcept
b3eed6fe
JW
845 {
846 future(std::move(__fut))._M_swap(*this);
847 return *this;
848 }
c910ceff 849
c36abf03 850 /// Retrieving the value
faa00511 851 void
b3eed6fe
JW
852 get()
853 {
854 typename _Base_type::_Reset __reset(*this);
855 this->_M_get_result();
856 }
e3e08a1d
JW
857
858 shared_future<void> share();
c910ceff
JW
859 };
860
c36abf03
BK
861
862 /// Primary template for shared_future.
863 template<typename _Res>
864 class shared_future : public __basic_future<_Res>
c910ceff 865 {
c36abf03
BK
866 typedef __basic_future<_Res> _Base_type;
867
c910ceff 868 public:
84b63c01 869 constexpr shared_future() noexcept : _Base_type() { }
b3eed6fe 870
c910ceff
JW
871 /// Copy constructor
872 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
873
b3eed6fe 874 /// Construct from a future rvalue
84b63c01 875 shared_future(future<_Res>&& __uf) noexcept
c910ceff
JW
876 : _Base_type(std::move(__uf))
877 { }
878
b3eed6fe 879 /// Construct from a shared_future rvalue
84b63c01 880 shared_future(shared_future&& __sf) noexcept
b3eed6fe
JW
881 : _Base_type(std::move(__sf))
882 { }
883
884 shared_future& operator=(const shared_future& __sf)
885 {
886 shared_future(__sf)._M_swap(*this);
887 return *this;
888 }
889
84b63c01 890 shared_future& operator=(shared_future&& __sf) noexcept
b3eed6fe
JW
891 {
892 shared_future(std::move(__sf))._M_swap(*this);
893 return *this;
894 }
c910ceff 895
c36abf03
BK
896 /// Retrieving the value
897 const _Res&
c93fa3ca 898 get() const { return this->_M_get_result()._M_value(); }
c910ceff 899 };
faa00511 900
c36abf03
BK
901 /// Partial specialization for shared_future<R&>
902 template<typename _Res>
903 class shared_future<_Res&> : public __basic_future<_Res&>
c910ceff 904 {
c36abf03
BK
905 typedef __basic_future<_Res&> _Base_type;
906
c910ceff 907 public:
84b63c01 908 constexpr shared_future() noexcept : _Base_type() { }
b3eed6fe 909
c910ceff
JW
910 /// Copy constructor
911 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
912
b3eed6fe 913 /// Construct from a future rvalue
84b63c01 914 shared_future(future<_Res&>&& __uf) noexcept
c910ceff
JW
915 : _Base_type(std::move(__uf))
916 { }
917
b3eed6fe 918 /// Construct from a shared_future rvalue
84b63c01 919 shared_future(shared_future&& __sf) noexcept
b3eed6fe
JW
920 : _Base_type(std::move(__sf))
921 { }
922
923 shared_future& operator=(const shared_future& __sf)
924 {
925 shared_future(__sf)._M_swap(*this);
926 return *this;
927 }
928
84b63c01 929 shared_future& operator=(shared_future&& __sf) noexcept
b3eed6fe
JW
930 {
931 shared_future(std::move(__sf))._M_swap(*this);
932 return *this;
933 }
c910ceff 934
c36abf03 935 /// Retrieving the value
faa00511 936 _Res&
c93fa3ca 937 get() const { return this->_M_get_result()._M_get(); }
c910ceff
JW
938 };
939
c36abf03 940 /// Explicit specialization for shared_future<void>
c910ceff 941 template<>
c36abf03 942 class shared_future<void> : public __basic_future<void>
c910ceff 943 {
c36abf03
BK
944 typedef __basic_future<void> _Base_type;
945
c910ceff 946 public:
84b63c01 947 constexpr shared_future() noexcept : _Base_type() { }
b3eed6fe 948
c910ceff
JW
949 /// Copy constructor
950 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
951
b3eed6fe 952 /// Construct from a future rvalue
84b63c01 953 shared_future(future<void>&& __uf) noexcept
c910ceff
JW
954 : _Base_type(std::move(__uf))
955 { }
956
b3eed6fe 957 /// Construct from a shared_future rvalue
84b63c01 958 shared_future(shared_future&& __sf) noexcept
b3eed6fe
JW
959 : _Base_type(std::move(__sf))
960 { }
961
962 shared_future& operator=(const shared_future& __sf)
963 {
964 shared_future(__sf)._M_swap(*this);
965 return *this;
966 }
967
84b63c01 968 shared_future& operator=(shared_future&& __sf) noexcept
b3eed6fe
JW
969 {
970 shared_future(std::move(__sf))._M_swap(*this);
971 return *this;
972 }
c910ceff 973
c36abf03 974 // Retrieving the value
faa00511 975 void
c93fa3ca 976 get() const { this->_M_get_result(); }
c910ceff
JW
977 };
978
c36abf03
BK
979 // Now we can define the protected __basic_future constructors.
980 template<typename _Res>
19501406 981 inline __basic_future<_Res>::
84b63c01 982 __basic_future(const shared_future<_Res>& __sf) noexcept
c910ceff
JW
983 : _M_state(__sf._M_state)
984 { }
985
c36abf03 986 template<typename _Res>
19501406 987 inline __basic_future<_Res>::
84b63c01 988 __basic_future(shared_future<_Res>&& __sf) noexcept
b3eed6fe
JW
989 : _M_state(std::move(__sf._M_state))
990 { }
991
992 template<typename _Res>
19501406 993 inline __basic_future<_Res>::
84b63c01 994 __basic_future(future<_Res>&& __uf) noexcept
c910ceff
JW
995 : _M_state(std::move(__uf._M_state))
996 { }
997
e3e08a1d
JW
998 template<typename _Res>
999 inline shared_future<_Res>
1000 future<_Res>::share()
1001 { return shared_future<_Res>(std::move(*this)); }
1002
1003 template<typename _Res>
1004 inline shared_future<_Res&>
1005 future<_Res&>::share()
1006 { return shared_future<_Res&>(std::move(*this)); }
1007
1008 inline shared_future<void>
1009 future<void>::share()
1010 { return shared_future<void>(std::move(*this)); }
c36abf03
BK
1011
1012 /// Primary template for promise
1013 template<typename _Res>
c910ceff
JW
1014 class promise
1015 {
c4d9f419
JW
1016 typedef __future_base::_State_base _State;
1017 typedef __future_base::_Result<_Res> _Res_type;
1018 typedef __future_base::_Ptr<_Res_type> _Ptr_type;
b3eed6fe 1019 template<typename, typename> friend class _State::_Setter;
faa00511 1020
c36abf03 1021 shared_ptr<_State> _M_future;
b3eed6fe 1022 _Ptr_type _M_storage;
c36abf03 1023
c910ceff
JW
1024 public:
1025 promise()
19501406
PC
1026 : _M_future(std::make_shared<_State>()),
1027 _M_storage(new _Res_type())
c910ceff
JW
1028 { }
1029
84b63c01 1030 promise(promise&& __rhs) noexcept
c910ceff 1031 : _M_future(std::move(__rhs._M_future)),
19501406 1032 _M_storage(std::move(__rhs._M_storage))
c910ceff
JW
1033 { }
1034
c910ceff 1035 template<typename _Allocator>
b3eed6fe
JW
1036 promise(allocator_arg_t, const _Allocator& __a)
1037 : _M_future(std::allocate_shared<_State>(__a)),
135a0d0a 1038 _M_storage(__future_base::_S_allocate_result<_Res>(__a))
b3eed6fe 1039 { }
c910ceff 1040
376d7c51
JW
1041 template<typename _Allocator>
1042 promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1043 : _M_future(std::move(__rhs._M_future)),
1044 _M_storage(std::move(__rhs._M_storage))
1045 { }
1046
c910ceff
JW
1047 promise(const promise&) = delete;
1048
1049 ~promise()
1050 {
1051 if (static_cast<bool>(_M_future) && !_M_future.unique())
1052 _M_future->_M_break_promise(std::move(_M_storage));
1053 }
1054
c36abf03 1055 // Assignment
c910ceff 1056 promise&
84b63c01 1057 operator=(promise&& __rhs) noexcept
c910ceff
JW
1058 {
1059 promise(std::move(__rhs)).swap(*this);
1060 return *this;
1061 }
1062
1063 promise& operator=(const promise&) = delete;
1064
1065 void
84b63c01 1066 swap(promise& __rhs) noexcept
c910ceff
JW
1067 {
1068 _M_future.swap(__rhs._M_future);
1069 _M_storage.swap(__rhs._M_storage);
1070 }
1071
c36abf03 1072 // Retrieving the result
b3eed6fe 1073 future<_Res>
c910ceff 1074 get_future()
b3eed6fe 1075 { return future<_Res>(_M_future); }
c910ceff 1076
c36abf03 1077 // Setting the result
c910ceff 1078 void
c36abf03 1079 set_value(const _Res& __r)
4e48c109 1080 { _M_future->_M_set_result(_State::__setter(this, __r)); }
c910ceff
JW
1081
1082 void
c36abf03 1083 set_value(_Res&& __r)
4e48c109 1084 { _M_future->_M_set_result(_State::__setter(this, std::move(__r))); }
c910ceff
JW
1085
1086 void
1087 set_exception(exception_ptr __p)
4e48c109 1088 { _M_future->_M_set_result(_State::__setter(__p, this)); }
9db7c931
JW
1089
1090 void
1091 set_value_at_thread_exit(const _Res& __r)
1092 {
1093 _M_future->_M_set_delayed_result(_State::__setter(this, __r),
1094 _M_future);
1095 }
1096
1097 void
1098 set_value_at_thread_exit(_Res&& __r)
1099 {
1100 _M_future->_M_set_delayed_result(
1101 _State::__setter(this, std::move(__r)), _M_future);
1102 }
1103
1104 void
1105 set_exception_at_thread_exit(exception_ptr __p)
1106 {
1107 _M_future->_M_set_delayed_result(_State::__setter(__p, this),
1108 _M_future);
1109 }
c910ceff
JW
1110 };
1111
19501406
PC
1112 template<typename _Res>
1113 inline void
84b63c01 1114 swap(promise<_Res>& __x, promise<_Res>& __y) noexcept
19501406
PC
1115 { __x.swap(__y); }
1116
135a0d0a
PC
1117 template<typename _Res, typename _Alloc>
1118 struct uses_allocator<promise<_Res>, _Alloc>
1119 : public true_type { };
1120
1121
c36abf03
BK
1122 /// Partial specialization for promise<R&>
1123 template<typename _Res>
1124 class promise<_Res&>
c910ceff 1125 {
c4d9f419
JW
1126 typedef __future_base::_State_base _State;
1127 typedef __future_base::_Result<_Res&> _Res_type;
1128 typedef __future_base::_Ptr<_Res_type> _Ptr_type;
b3eed6fe 1129 template<typename, typename> friend class _State::_Setter;
c36abf03
BK
1130
1131 shared_ptr<_State> _M_future;
b3eed6fe 1132 _Ptr_type _M_storage;
c36abf03 1133
c910ceff
JW
1134 public:
1135 promise()
19501406
PC
1136 : _M_future(std::make_shared<_State>()),
1137 _M_storage(new _Res_type())
c910ceff
JW
1138 { }
1139
84b63c01 1140 promise(promise&& __rhs) noexcept
faa00511 1141 : _M_future(std::move(__rhs._M_future)),
c36abf03 1142 _M_storage(std::move(__rhs._M_storage))
c910ceff
JW
1143 { }
1144
c910ceff 1145 template<typename _Allocator>
b3eed6fe
JW
1146 promise(allocator_arg_t, const _Allocator& __a)
1147 : _M_future(std::allocate_shared<_State>(__a)),
135a0d0a 1148 _M_storage(__future_base::_S_allocate_result<_Res&>(__a))
b3eed6fe 1149 { }
c910ceff 1150
376d7c51
JW
1151 template<typename _Allocator>
1152 promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1153 : _M_future(std::move(__rhs._M_future)),
1154 _M_storage(std::move(__rhs._M_storage))
1155 { }
1156
c910ceff
JW
1157 promise(const promise&) = delete;
1158
1159 ~promise()
1160 {
1161 if (static_cast<bool>(_M_future) && !_M_future.unique())
1162 _M_future->_M_break_promise(std::move(_M_storage));
1163 }
1164
c36abf03 1165 // Assignment
c910ceff 1166 promise&
84b63c01 1167 operator=(promise&& __rhs) noexcept
c910ceff
JW
1168 {
1169 promise(std::move(__rhs)).swap(*this);
1170 return *this;
1171 }
1172
1173 promise& operator=(const promise&) = delete;
1174
1175 void
84b63c01 1176 swap(promise& __rhs) noexcept
c910ceff
JW
1177 {
1178 _M_future.swap(__rhs._M_future);
1179 _M_storage.swap(__rhs._M_storage);
1180 }
1181
c36abf03 1182 // Retrieving the result
b3eed6fe 1183 future<_Res&>
c910ceff 1184 get_future()
b3eed6fe 1185 { return future<_Res&>(_M_future); }
c910ceff 1186
c36abf03 1187 // Setting the result
c910ceff 1188 void
c36abf03 1189 set_value(_Res& __r)
4e48c109 1190 { _M_future->_M_set_result(_State::__setter(this, __r)); }
c910ceff
JW
1191
1192 void
1193 set_exception(exception_ptr __p)
4e48c109 1194 { _M_future->_M_set_result(_State::__setter(__p, this)); }
9db7c931
JW
1195
1196 void
1197 set_value_at_thread_exit(_Res& __r)
1198 {
1199 _M_future->_M_set_delayed_result(_State::__setter(this, __r),
1200 _M_future);
1201 }
1202
1203 void
1204 set_exception_at_thread_exit(exception_ptr __p)
1205 {
1206 _M_future->_M_set_delayed_result(_State::__setter(__p, this),
1207 _M_future);
1208 }
c910ceff
JW
1209 };
1210
c36abf03 1211 /// Explicit specialization for promise<void>
c910ceff
JW
1212 template<>
1213 class promise<void>
1214 {
c4d9f419
JW
1215 typedef __future_base::_State_base _State;
1216 typedef __future_base::_Result<void> _Res_type;
1217 typedef __future_base::_Ptr<_Res_type> _Ptr_type;
b3eed6fe 1218 template<typename, typename> friend class _State::_Setter;
c36abf03 1219
b3eed6fe
JW
1220 shared_ptr<_State> _M_future;
1221 _Ptr_type _M_storage;
c36abf03 1222
c910ceff
JW
1223 public:
1224 promise()
c36abf03 1225 : _M_future(std::make_shared<_State>()),
b3eed6fe 1226 _M_storage(new _Res_type())
c910ceff
JW
1227 { }
1228
84b63c01 1229 promise(promise&& __rhs) noexcept
c910ceff 1230 : _M_future(std::move(__rhs._M_future)),
19501406 1231 _M_storage(std::move(__rhs._M_storage))
c910ceff
JW
1232 { }
1233
c910ceff 1234 template<typename _Allocator>
b3eed6fe
JW
1235 promise(allocator_arg_t, const _Allocator& __a)
1236 : _M_future(std::allocate_shared<_State>(__a)),
135a0d0a 1237 _M_storage(__future_base::_S_allocate_result<void>(__a))
b3eed6fe 1238 { }
c910ceff 1239
1b5dc776
JW
1240 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1241 // 2095. missing constructors needed for uses-allocator construction
376d7c51
JW
1242 template<typename _Allocator>
1243 promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1244 : _M_future(std::move(__rhs._M_future)),
1245 _M_storage(std::move(__rhs._M_storage))
1246 { }
1247
c910ceff
JW
1248 promise(const promise&) = delete;
1249
1250 ~promise()
1251 {
1252 if (static_cast<bool>(_M_future) && !_M_future.unique())
1253 _M_future->_M_break_promise(std::move(_M_storage));
1254 }
1255
c36abf03 1256 // Assignment
c910ceff 1257 promise&
84b63c01 1258 operator=(promise&& __rhs) noexcept
c910ceff
JW
1259 {
1260 promise(std::move(__rhs)).swap(*this);
1261 return *this;
1262 }
1263
1264 promise& operator=(const promise&) = delete;
1265
1266 void
84b63c01 1267 swap(promise& __rhs) noexcept
c910ceff
JW
1268 {
1269 _M_future.swap(__rhs._M_future);
1270 _M_storage.swap(__rhs._M_storage);
1271 }
1272
c36abf03 1273 // Retrieving the result
b3eed6fe 1274 future<void>
c910ceff 1275 get_future()
b3eed6fe 1276 { return future<void>(_M_future); }
c910ceff 1277
c36abf03 1278 // Setting the result
b3eed6fe
JW
1279 void set_value();
1280
c910ceff 1281 void
b3eed6fe 1282 set_exception(exception_ptr __p)
4e48c109 1283 { _M_future->_M_set_result(_State::__setter(__p, this)); }
9db7c931
JW
1284
1285 void
1286 set_value_at_thread_exit();
1287
1288 void
1289 set_exception_at_thread_exit(exception_ptr __p)
1290 {
1291 _M_future->_M_set_delayed_result(_State::__setter(__p, this),
1292 _M_future);
1293 }
b3eed6fe 1294 };
c910ceff 1295
b3eed6fe
JW
1296 // set void
1297 template<>
e9599233 1298 struct __future_base::_State_base::_Setter<void, void>
b3eed6fe 1299 {
9131b509 1300 promise<void>::_Ptr_type operator()() const
c910ceff 1301 {
e9599233 1302 _State_base::_S_check(_M_promise->_M_future);
b3eed6fe 1303 return std::move(_M_promise->_M_storage);
c910ceff
JW
1304 }
1305
b3eed6fe 1306 promise<void>* _M_promise;
c910ceff
JW
1307 };
1308
b3eed6fe
JW
1309 inline void
1310 promise<void>::set_value()
4e48c109 1311 { _M_future->_M_set_result(_State::_Setter<void, void>{ this }); }
b3eed6fe 1312
9db7c931
JW
1313 inline void
1314 promise<void>::set_value_at_thread_exit()
1315 {
1316 _M_future->_M_set_delayed_result(_State::_Setter<void, void>{this},
1317 _M_future);
1318 }
1319
4e48c109 1320 template<typename _Ptr_type, typename _Fn, typename _Res>
b3eed6fe 1321 struct __future_base::_Task_setter
c910ceff 1322 {
9db7c931 1323 // Invoke the function and provide the result to the caller.
9131b509 1324 _Ptr_type operator()() const
c910ceff 1325 {
aaad548e 1326 __try
19501406 1327 {
4e48c109 1328 (*_M_result)->_M_set((*_M_fn)());
19501406 1329 }
315eb4bb
JW
1330 __catch(const __cxxabiv1::__forced_unwind&)
1331 {
1332 __throw_exception_again; // will cause broken_promise
1333 }
19501406
PC
1334 __catch(...)
1335 {
4e48c109 1336 (*_M_result)->_M_error = current_exception();
19501406 1337 }
4e48c109 1338 return std::move(*_M_result);
c910ceff 1339 }
4e48c109
JW
1340 _Ptr_type* _M_result;
1341 _Fn* _M_fn;
c910ceff
JW
1342 };
1343
4e48c109
JW
1344 template<typename _Ptr_type, typename _Fn>
1345 struct __future_base::_Task_setter<_Ptr_type, _Fn, void>
c910ceff 1346 {
9131b509 1347 _Ptr_type operator()() const
c910ceff 1348 {
aaad548e 1349 __try
19501406 1350 {
4e48c109 1351 (*_M_fn)();
19501406 1352 }
315eb4bb
JW
1353 __catch(const __cxxabiv1::__forced_unwind&)
1354 {
1355 __throw_exception_again; // will cause broken_promise
1356 }
19501406
PC
1357 __catch(...)
1358 {
4e48c109 1359 (*_M_result)->_M_error = current_exception();
19501406 1360 }
4e48c109 1361 return std::move(*_M_result);
c910ceff 1362 }
4e48c109
JW
1363 _Ptr_type* _M_result;
1364 _Fn* _M_fn;
c910ceff
JW
1365 };
1366
9db7c931 1367 // Holds storage for a packaged_task's result.
b3eed6fe 1368 template<typename _Res, typename... _Args>
aaad548e 1369 struct __future_base::_Task_state_base<_Res(_Args...)>
e9599233 1370 : __future_base::_State_base
b3eed6fe
JW
1371 {
1372 typedef _Res _Res_type;
1373
aaad548e
JW
1374 template<typename _Alloc>
1375 _Task_state_base(const _Alloc& __a)
1376 : _M_result(_S_allocate_result<_Res>(__a))
1377 { }
b3eed6fe 1378
9db7c931 1379 // Invoke the stored task and make the state ready.
aaad548e 1380 virtual void
9db7c931
JW
1381 _M_run(_Args&&... __args) = 0;
1382
1383 // Invoke the stored task and make the state ready at thread exit.
1384 virtual void
1385 _M_run_delayed(_Args&&... __args, weak_ptr<_State_base>) = 0;
b3eed6fe 1386
aaad548e
JW
1387 virtual shared_ptr<_Task_state_base>
1388 _M_reset() = 0;
1389
1390 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1391 _Ptr_type _M_result;
1392 };
1393
9db7c931 1394 // Holds a packaged_task's stored task.
aaad548e
JW
1395 template<typename _Fn, typename _Alloc, typename _Res, typename... _Args>
1396 struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final
1397 : __future_base::_Task_state_base<_Res(_Args...)>
1398 {
f7e68d08
JW
1399 template<typename _Fn2>
1400 _Task_state(_Fn2&& __fn, const _Alloc& __a)
1401 : _Task_state_base<_Res(_Args...)>(__a),
1402 _M_impl(std::forward<_Fn2>(__fn), __a)
1403 { }
aaad548e
JW
1404
1405 private:
1406 virtual void
9db7c931 1407 _M_run(_Args&&... __args)
b3eed6fe 1408 {
5579170b
JW
1409 auto __boundfn = [&] () -> typename result_of<_Fn(_Args&&...)>::type {
1410 return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...);
1411 };
4e48c109 1412 this->_M_set_result(_S_task_setter(this->_M_result, __boundfn));
b3eed6fe
JW
1413 }
1414
9db7c931
JW
1415 virtual void
1416 _M_run_delayed(_Args&&... __args, weak_ptr<_State_base> __self)
1417 {
5579170b
JW
1418 auto __boundfn = [&] () -> typename result_of<_Fn(_Args&&...)>::type {
1419 return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...);
1420 };
9db7c931
JW
1421 this->_M_set_delayed_result(_S_task_setter(this->_M_result, __boundfn),
1422 std::move(__self));
1423 }
1424
aaad548e
JW
1425 virtual shared_ptr<_Task_state_base<_Res(_Args...)>>
1426 _M_reset();
b3eed6fe 1427
aaad548e
JW
1428 struct _Impl : _Alloc
1429 {
f7e68d08
JW
1430 template<typename _Fn2>
1431 _Impl(_Fn2&& __fn, const _Alloc& __a)
1432 : _Alloc(__a), _M_fn(std::forward<_Fn2>(__fn)) { }
aaad548e
JW
1433 _Fn _M_fn;
1434 } _M_impl;
b3eed6fe 1435 };
c36abf03 1436
f7e68d08
JW
1437 template<typename _Signature, typename _Fn, typename _Alloc>
1438 static shared_ptr<__future_base::_Task_state_base<_Signature>>
1439 __create_task_state(_Fn&& __fn, const _Alloc& __a)
1440 {
1441 typedef typename decay<_Fn>::type _Fn2;
1442 typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State;
1443 return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a);
1444 }
aaad548e
JW
1445
1446 template<typename _Fn, typename _Alloc, typename _Res, typename... _Args>
1447 shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>>
1448 __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset()
1449 {
1450 return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn),
1451 static_cast<_Alloc&>(_M_impl));
1452 }
1453
376d7c51 1454 template<typename _Task, typename _Fn, bool
aaad548e 1455 = is_same<_Task, typename decay<_Fn>::type>::value>
c4d9f419 1456 struct __constrain_pkgdtask
376d7c51
JW
1457 { typedef void __type; };
1458
1459 template<typename _Task, typename _Fn>
c4d9f419 1460 struct __constrain_pkgdtask<_Task, _Fn, true>
376d7c51
JW
1461 { };
1462
3259554a 1463 /// packaged_task
c36abf03
BK
1464 template<typename _Res, typename... _ArgTypes>
1465 class packaged_task<_Res(_ArgTypes...)>
c910ceff 1466 {
aaad548e 1467 typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type;
b3eed6fe 1468 shared_ptr<_State_type> _M_state;
c36abf03 1469
c910ceff 1470 public:
c36abf03 1471 // Construction and destruction
84b63c01 1472 packaged_task() noexcept { }
c910ceff 1473
1b5dc776
JW
1474 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1475 // 2095. missing constructors needed for uses-allocator construction
376d7c51 1476 template<typename _Allocator>
aaad548e
JW
1477 packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
1478 { }
376d7c51
JW
1479
1480 template<typename _Fn, typename = typename
aaad548e
JW
1481 __constrain_pkgdtask<packaged_task, _Fn>::__type>
1482 explicit
1483 packaged_task(_Fn&& __fn)
f7e68d08
JW
1484 : packaged_task(allocator_arg, std::allocator<int>(),
1485 std::forward<_Fn>(__fn))
aaad548e 1486 { }
c910ceff 1487
1b5dc776
JW
1488 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1489 // 2097. packaged_task constructors should be constrained
e6508eaf 1490 // 2407. [this constructor should not be] explicit
aaad548e
JW
1491 template<typename _Fn, typename _Alloc, typename = typename
1492 __constrain_pkgdtask<packaged_task, _Fn>::__type>
aaad548e
JW
1493 packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn)
1494 : _M_state(__create_task_state<_Res(_ArgTypes...)>(
1495 std::forward<_Fn>(__fn), __a))
1496 { }
c910ceff 1497
b3eed6fe
JW
1498 ~packaged_task()
1499 {
1500 if (static_cast<bool>(_M_state) && !_M_state.unique())
aaad548e 1501 _M_state->_M_break_promise(std::move(_M_state->_M_result));
b3eed6fe 1502 }
c910ceff 1503
c36abf03 1504 // No copy
376d7c51
JW
1505 packaged_task(const packaged_task&) = delete;
1506 packaged_task& operator=(const packaged_task&) = delete;
1507
1508 template<typename _Allocator>
aaad548e
JW
1509 packaged_task(allocator_arg_t, const _Allocator&,
1510 const packaged_task&) = delete;
c910ceff 1511
c36abf03 1512 // Move support
84b63c01 1513 packaged_task(packaged_task&& __other) noexcept
c910ceff
JW
1514 { this->swap(__other); }
1515
376d7c51 1516 template<typename _Allocator>
aaad548e
JW
1517 packaged_task(allocator_arg_t, const _Allocator&,
1518 packaged_task&& __other) noexcept
1519 { this->swap(__other); }
376d7c51 1520
84b63c01 1521 packaged_task& operator=(packaged_task&& __other) noexcept
c910ceff 1522 {
aaad548e
JW
1523 packaged_task(std::move(__other)).swap(*this);
1524 return *this;
c910ceff
JW
1525 }
1526
1527 void
84b63c01 1528 swap(packaged_task& __other) noexcept
b3eed6fe 1529 { _M_state.swap(__other._M_state); }
c910ceff 1530
7a0269de 1531 bool
84b63c01 1532 valid() const noexcept
7a0269de 1533 { return static_cast<bool>(_M_state); }
c910ceff 1534
c36abf03 1535 // Result retrieval
b3eed6fe 1536 future<_Res>
c910ceff 1537 get_future()
b3eed6fe 1538 { return future<_Res>(_M_state); }
c910ceff 1539
c36abf03 1540 // Execution
c910ceff
JW
1541 void
1542 operator()(_ArgTypes... __args)
1543 {
aaad548e
JW
1544 __future_base::_State_base::_S_check(_M_state);
1545 _M_state->_M_run(std::forward<_ArgTypes>(__args)...);
b3eed6fe 1546 }
8d1b99e2 1547
9db7c931
JW
1548 void
1549 make_ready_at_thread_exit(_ArgTypes... __args)
1550 {
1551 __future_base::_State_base::_S_check(_M_state);
1552 _M_state->_M_run_delayed(std::forward<_ArgTypes>(__args)..., _M_state);
1553 }
1554
b3eed6fe
JW
1555 void
1556 reset()
1557 {
aaad548e
JW
1558 __future_base::_State_base::_S_check(_M_state);
1559 packaged_task __tmp;
1560 __tmp._M_state = _M_state;
1561 _M_state = _M_state->_M_reset();
b3eed6fe
JW
1562 }
1563 };
1564
94a86be0 1565 /// swap
19501406 1566 template<typename _Res, typename... _ArgTypes>
4e4d27aa 1567 inline void
19501406 1568 swap(packaged_task<_Res(_ArgTypes...)>& __x,
84b63c01 1569 packaged_task<_Res(_ArgTypes...)>& __y) noexcept
19501406 1570 { __x.swap(__y); }
135a0d0a
PC
1571
1572 template<typename _Res, typename _Alloc>
1573 struct uses_allocator<packaged_task<_Res>, _Alloc>
1574 : public true_type { };
1575
1576
9db7c931
JW
1577 // Shared state created by std::async().
1578 // Holds a deferred function and storage for its result.
4880236e 1579 template<typename _BoundFn, typename _Res>
a58a38b3
JW
1580 class __future_base::_Deferred_state final
1581 : public __future_base::_State_base
b3eed6fe
JW
1582 {
1583 public:
b3eed6fe 1584 explicit
4880236e 1585 _Deferred_state(_BoundFn&& __fn)
b3eed6fe
JW
1586 : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
1587 { }
1588
1589 private:
c4d9f419 1590 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
b3eed6fe 1591 _Ptr_type _M_result;
4880236e 1592 _BoundFn _M_fn;
b3eed6fe 1593
f2f08be7 1594 // Run the deferred function.
b3eed6fe 1595 virtual void
f2f08be7 1596 _M_complete_async()
b3eed6fe 1597 {
9db7c931
JW
1598 // Multiple threads can call a waiting function on the future and
1599 // reach this point at the same time. The call_once in _M_set_result
1600 // ensures only the first one run the deferred function, stores the
1601 // result in _M_result, swaps that with the base _M_result and makes
1602 // the state ready. Tell _M_set_result to ignore failure so all later
1603 // calls do nothing.
4880236e 1604 _M_set_result(_S_task_setter(_M_result, _M_fn), true);
b3eed6fe 1605 }
f2f08be7 1606
9db7c931
JW
1607 // Caller should check whether the state is ready first, because this
1608 // function will return true even after the deferred function has run.
eae801ba 1609 virtual bool _M_is_deferred_future() const { return true; }
b3eed6fe
JW
1610 };
1611
9db7c931 1612 // Common functionality hoisted out of the _Async_state_impl template.
f2f08be7
JW
1613 class __future_base::_Async_state_commonV2
1614 : public __future_base::_State_base
488b3e65
JW
1615 {
1616 protected:
f2f08be7 1617 ~_Async_state_commonV2() = default;
488b3e65 1618
f2f08be7 1619 // Make waiting functions block until the thread completes, as if joined.
9db7c931
JW
1620 //
1621 // This function is used by wait() to satisfy the first requirement below
1622 // and by wait_for() / wait_until() to satisfy the second.
1623 //
1624 // [futures.async]:
1625 //
1626 // — a call to a waiting function on an asynchronous return object that
1627 // shares the shared state created by this async call shall block until
1628 // the associated thread has completed, as if joined, or else time out.
1629 //
1630 // — the associated thread completion synchronizes with the return from
1631 // the first function that successfully detects the ready status of the
1632 // shared state or with the return from the last function that releases
1633 // the shared state, whichever happens first.
f2f08be7 1634 virtual void _M_complete_async() { _M_join(); }
488b3e65 1635
93e95400 1636 void _M_join() { std::call_once(_M_once, &thread::join, &_M_thread); }
488b3e65
JW
1637
1638 thread _M_thread;
1639 once_flag _M_once;
1640 };
1641
9db7c931
JW
1642 // Shared state created by std::async().
1643 // Starts a new thread that runs a function and makes the shared state ready.
4880236e 1644 template<typename _BoundFn, typename _Res>
488b3e65 1645 class __future_base::_Async_state_impl final
f2f08be7 1646 : public __future_base::_Async_state_commonV2
b3eed6fe
JW
1647 {
1648 public:
faa00511 1649 explicit
488b3e65
JW
1650 _Async_state_impl(_BoundFn&& __fn)
1651 : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
b3eed6fe 1652 {
488b3e65 1653 _M_thread = std::thread{ [this] {
315eb4bb
JW
1654 __try
1655 {
1656 _M_set_result(_S_task_setter(_M_result, _M_fn));
1657 }
1658 __catch (const __cxxabiv1::__forced_unwind&)
1659 {
1660 // make the shared state ready on thread cancellation
1661 if (static_cast<bool>(_M_result))
1662 this->_M_break_promise(std::move(_M_result));
1663 __throw_exception_again;
1664 }
488b3e65 1665 } };
c910ceff
JW
1666 }
1667
9db7c931
JW
1668 // Must not destroy _M_result and _M_fn until the thread finishes.
1669 // Call join() directly rather than through _M_join() because no other
1670 // thread can be referring to this state if it is being destroyed.
1671 ~_Async_state_impl() { if (_M_thread.joinable()) _M_thread.join(); }
277f43d2 1672
488b3e65 1673 private:
c4d9f419 1674 typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
b3eed6fe 1675 _Ptr_type _M_result;
4880236e 1676 _BoundFn _M_fn;
c910ceff
JW
1677 };
1678
4880236e
JW
1679 template<typename _BoundFn>
1680 inline std::shared_ptr<__future_base::_State_base>
1681 __future_base::_S_make_deferred_state(_BoundFn&& __fn)
1682 {
1683 typedef typename remove_reference<_BoundFn>::type __fn_type;
1684 typedef _Deferred_state<__fn_type> __state_type;
1685 return std::make_shared<__state_type>(std::move(__fn));
1686 }
1687
1688 template<typename _BoundFn>
1689 inline std::shared_ptr<__future_base::_State_base>
1690 __future_base::_S_make_async_state(_BoundFn&& __fn)
1691 {
1692 typedef typename remove_reference<_BoundFn>::type __fn_type;
488b3e65 1693 typedef _Async_state_impl<__fn_type> __state_type;
4880236e
JW
1694 return std::make_shared<__state_type>(std::move(__fn));
1695 }
1696
1697
faa00511 1698 /// async
b3eed6fe 1699 template<typename _Fn, typename... _Args>
75eb6443 1700 future<__async_result_of<_Fn, _Args...>>
b3eed6fe
JW
1701 async(launch __policy, _Fn&& __fn, _Args&&... __args)
1702 {
e9599233 1703 std::shared_ptr<__future_base::_State_base> __state;
f6341d8d 1704 if ((__policy & launch::async) == launch::async)
19501406 1705 {
6fbd5984
JW
1706 __try
1707 {
5579170b
JW
1708 __state = __future_base::_S_make_async_state(
1709 std::thread::__make_invoker(std::forward<_Fn>(__fn),
1710 std::forward<_Args>(__args)...)
1711 );
6fbd5984
JW
1712 }
1713#if __cpp_exceptions
1714 catch(const system_error& __e)
1715 {
1716 if (__e.code() != errc::resource_unavailable_try_again
1717 || (__policy & launch::deferred) != launch::deferred)
1718 throw;
1719 }
1720#endif
19501406 1721 }
6fbd5984 1722 if (!__state)
19501406 1723 {
5579170b
JW
1724 __state = __future_base::_S_make_deferred_state(
1725 std::thread::__make_invoker(std::forward<_Fn>(__fn),
1726 std::forward<_Args>(__args)...));
19501406 1727 }
75eb6443 1728 return future<__async_result_of<_Fn, _Args...>>(__state);
b3eed6fe
JW
1729 }
1730
94a86be0 1731 /// async, potential overload
b3eed6fe 1732 template<typename _Fn, typename... _Args>
75eb6443 1733 inline future<__async_result_of<_Fn, _Args...>>
b3eed6fe
JW
1734 async(_Fn&& __fn, _Args&&... __args)
1735 {
75eb6443
JW
1736 return std::async(launch::async|launch::deferred,
1737 std::forward<_Fn>(__fn),
1738 std::forward<_Args>(__args)...);
b3eed6fe
JW
1739 }
1740
f2f08be7 1741#endif // _GLIBCXX_ASYNC_ABI_COMPAT
c910ceff 1742#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
a152e96f 1743 // && ATOMIC_INT_LOCK_FREE
c910ceff 1744
41ca4246 1745 // @} group futures
12ffa228
BK
1746_GLIBCXX_END_NAMESPACE_VERSION
1747} // namespace
41ca4246 1748
734f5023 1749#endif // C++11
c910ceff
JW
1750
1751#endif // _GLIBCXX_FUTURE