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