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