]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/future
re PR rtl-optimization/42429 (Miscompilation of 2fish on s390)
[thirdparty/gcc.git] / libstdc++-v3 / include / std / future
CommitLineData
c910ceff
JW
1// <future> -*- C++ -*-
2
3// Copyright (C) 2009 Free Software Foundation, Inc.
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
25/** @file future
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
34#ifndef __GXX_EXPERIMENTAL_CXX0X__
35# include <c++0x_warning.h>
36#else
37
38#include <functional>
39#include <memory>
40#include <mutex>
41#include <condition_variable>
42#include <system_error>
43#include <exception>
44#include <cstdatomic>
abcd7e08 45#include <bits/functexcept.h>
c910ceff 46
c910ceff
JW
47namespace std
48{
49 /**
50 * @defgroup futures Futures
51 * @ingroup concurrency
52 *
53 * Classes for futures support.
54 * @{
55 */
56
57 /// Error code for futures
58 enum class future_errc
59 { broken_promise, future_already_retrieved, promise_already_satisfied };
60
61 // TODO: requires concepts
62 // concept_map ErrorCodeEnum<future_errc> { }
63 template<>
64 struct is_error_code_enum<future_errc> : public true_type { };
65
66 /// Points to a statically-allocated object derived from error_category.
67 extern const error_category* const future_category;
68
69 // TODO: requires constexpr
70 inline error_code make_error_code(future_errc __errc)
71 { return error_code(static_cast<int>(__errc), *future_category); }
72
73 // TODO: requires constexpr
74 inline error_condition make_error_condition(future_errc __errc)
75 { return error_condition(static_cast<int>(__errc), *future_category); }
76
8d1b99e2
BK
77 /**
78 * @brief Exception type thrown by futures.
79 * @ingroup exceptions
80 */
c910ceff
JW
81 class future_error : public logic_error
82 {
c36abf03 83 error_code _M_code;
8d1b99e2 84
c910ceff
JW
85 public:
86 explicit future_error(future_errc __ec)
87 : logic_error("std::future_error"), _M_code(make_error_code(__ec))
88 { }
89
8d1b99e2 90 virtual ~future_error() throw();
c910ceff 91
8d1b99e2
BK
92 virtual const char*
93 what() const throw();
c910ceff 94
8d1b99e2
BK
95 const error_code&
96 code() const throw() { return _M_code; }
c910ceff
JW
97 };
98
3259554a 99 // Forward declarations.
c36abf03 100 template<typename _Res>
3259554a
BK
101 class unique_future;
102
c36abf03 103 template<typename _Res>
3259554a
BK
104 class shared_future;
105
106 template<typename>
107 class packaged_task;
108
c36abf03 109 template<typename _Res>
3259554a
BK
110 class promise;
111
41ca4246
BK
112#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
113 && defined(_GLIBCXX_ATOMIC_BUILTINS_4)
114
c36abf03
BK
115 /// Base class and enclosing scope.
116 struct __future_base
c910ceff 117 {
c36abf03
BK
118 /// Base class for results.
119 struct _Result_base
120 {
121 exception_ptr _M_error;
c910ceff 122
c36abf03
BK
123 _Result_base() = default;
124 _Result_base(const _Result_base&) = delete;
125 _Result_base& operator=(const _Result_base&) = delete;
c910ceff 126
c36abf03
BK
127 // _M_destroy() allows derived classes to control deallocation,
128 // which will be needed when allocator support is added to promise.
129 // See http://gcc.gnu.org/ml/libstdc++/2009-06/msg00032.html
130 virtual void _M_destroy() = 0;
c910ceff 131
c36abf03
BK
132 struct _Deleter
133 {
134 void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
135 };
c910ceff 136
c36abf03
BK
137 protected:
138 ~_Result_base();
139 };
20f2653e 140
c36abf03
BK
141 /// Result.
142 template<typename _Res>
143 struct _Result : _Result_base
144 {
145 private:
146 typedef alignment_of<_Res> __a_of;
147 typedef aligned_storage<sizeof(_Res), __a_of::value> __align_storage;
148 typedef typename __align_storage::type __align_type;
149
150 __align_type _M_storage;
151 bool _M_initialized;
152
153 public:
154 _Result() : _M_initialized() { }
155
156 ~_Result()
157 {
158 if (_M_initialized)
159 _M_value().~_Res();
160 }
161
162 // Return lvalue, future will add const or rvalue-reference
163 _Res&
164 _M_value() { return *static_cast<_Res*>(_M_addr()); }
165
166 void
167 _M_set(const _Res& __res)
168 {
169 ::new (_M_addr()) _Res(__res);
170 _M_initialized = true;
171 }
172
173 void
174 _M_set(_Res&& __res)
175 {
abcd7e08 176 ::new (_M_addr()) _Res(std::move(__res));
c36abf03
BK
177 _M_initialized = true;
178 }
179
180 private:
181 void _M_destroy() { delete this; }
182
183 void* _M_addr() { return static_cast<void*>(&_M_storage); }
c910ceff
JW
184 };
185
c910ceff 186
c36abf03
BK
187 // TODO: use template alias when available
188 /*
189 template<typename _Res>
190 using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;
191 */
192 /// A unique_ptr based on the instantiating type.
193 template<typename _Res>
194 struct _Ptr
195 {
196 typedef unique_ptr<_Res, _Result_base::_Deleter> type;
197 };
c910ceff 198
c910ceff 199
c36abf03
BK
200 /// Shared state between a promise and one or more associated futures.
201 class _State
c910ceff 202 {
c36abf03 203 typedef _Ptr<_Result_base>::type _Ptr_type;
c910ceff 204
c36abf03
BK
205 _Ptr_type _M_result;
206 mutex _M_mutex;
207 condition_variable _M_cond;
208 atomic_flag _M_retrieved;
c910ceff 209
c36abf03
BK
210 public:
211 _State() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
212
213 _State(const _State&) = delete;
214 _State& operator=(const _State&) = delete;
c910ceff 215
c910ceff 216 bool
c36abf03
BK
217 is_ready()
218 { return _M_get() != 0; }
c910ceff 219
c910ceff 220 bool
c36abf03 221 has_exception()
c910ceff 222 {
c36abf03
BK
223 _Result_base* const __res = _M_get();
224 return __res && !(__res->_M_error == 0);
c910ceff
JW
225 }
226
c36abf03
BK
227 bool
228 has_value()
c910ceff 229 {
c36abf03
BK
230 _Result_base* const __res = _M_get();
231 return __res && (__res->_M_error == 0);
c910ceff 232 }
c910ceff 233
c36abf03
BK
234 _Result_base&
235 wait()
c910ceff 236 {
c36abf03
BK
237 unique_lock<mutex> __lock(_M_mutex);
238 if (!_M_ready())
239 _M_cond.wait(__lock, std::bind(&_State::_M_ready, this));
240 return *_M_result;
c910ceff 241 }
c910ceff 242
c36abf03
BK
243 template<typename _Rep, typename _Period>
244 bool
245 wait_for(const chrono::duration<_Rep, _Period>& __rel)
246 {
247 unique_lock<mutex> __lock(_M_mutex);
248 auto __bound = std::bind(&_State::_M_ready, this);
249 return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound);
250 }
c910ceff 251
c36abf03
BK
252 template<typename _Clock, typename _Duration>
253 bool
254 wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
255 {
256 unique_lock<mutex> __lock(_M_mutex);
257 auto __bound = std::bind(&_State::_M_ready, this);
258 return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound);
259 }
c910ceff 260
c36abf03
BK
261 void
262 _M_set_result(_Ptr_type __res)
c910ceff 263 {
c36abf03
BK
264 {
265 lock_guard<mutex> __lock(_M_mutex);
266 if (_M_ready())
267 __throw_future_error(int(future_errc::promise_already_satisfied));
268 _M_result.swap(__res);
269 }
270 _M_cond.notify_all();
c910ceff
JW
271 }
272
c910ceff 273 void
c36abf03 274 _M_break_promise(_Ptr_type __res)
c910ceff 275 {
c36abf03
BK
276 if (static_cast<bool>(__res))
277 {
278 future_errc __ec(future_errc::broken_promise); // XXX
279 __res->_M_error = copy_exception(future_error(__ec));
280 {
281 lock_guard<mutex> __lock(_M_mutex);
282 _M_result.swap(__res);
283 }
284 _M_cond.notify_all();
285 }
c910ceff
JW
286 }
287
c36abf03 288 // Called when this object is passed to a unique_future.
c910ceff 289 void
c36abf03 290 _M_set_retrieved_flag()
c910ceff 291 {
c36abf03
BK
292 if (_M_retrieved.test_and_set())
293 __throw_future_error(int(future_errc::future_already_retrieved));
c910ceff
JW
294 }
295
296 private:
c36abf03
BK
297 _Result_base*
298 _M_get()
299 {
300 lock_guard<mutex> __lock(_M_mutex);
301 return _M_result.get();
302 }
c910ceff 303
c36abf03 304 bool _M_ready() const { return static_cast<bool>(_M_result); }
c910ceff 305 };
c36abf03 306 };
c910ceff 307
c36abf03 308 inline __future_base::_Result_base::~_Result_base() = default;
c910ceff 309
c36abf03
BK
310 /// Partial specialization for reference types.
311 template<typename _Res>
312 struct __future_base::_Result<_Res&> : __future_base::_Result_base
313 {
314 _Result() : _M_value_ptr() { }
c910ceff 315
c36abf03
BK
316 _Res* _M_value_ptr;
317
318 private:
c910ceff
JW
319 void _M_destroy() { delete this; }
320 };
321
c36abf03 322 /// Explicit specialization for void.
c910ceff 323 template<>
c36abf03 324 struct __future_base::_Result<void> : __future_base::_Result_base
c910ceff 325 {
c36abf03 326 private:
c910ceff
JW
327 void _M_destroy() { delete this; }
328 };
329
c36abf03
BK
330
331 /// Common implementation for unique_future and shared_future.
332 template<typename _Res>
333 class __basic_future : public __future_base
c910ceff 334 {
c36abf03
BK
335 protected:
336 typedef shared_ptr<_State> __state_type;
337 typedef __future_base::_Result<_Res>& __result_type;
338
339 private:
340 __state_type _M_state;
341
c910ceff 342 public:
c36abf03
BK
343 // Disable copying.
344 __basic_future(const __basic_future&) = delete;
345 __basic_future& operator=(const __basic_future&) = delete;
c910ceff 346
c36abf03
BK
347 // Functions to check state and wait for ready.
348 bool
349 is_ready() const { return this->_M_state->is_ready(); }
c910ceff 350
c36abf03
BK
351 bool
352 has_exception() const { return this->_M_state->has_exception(); }
c910ceff 353
c36abf03
BK
354 bool
355 has_value() const { return this->_M_state->has_value(); }
c910ceff 356
c36abf03
BK
357 void
358 wait() const { this->_M_state->wait(); }
c910ceff
JW
359
360 template<typename _Rep, typename _Period>
361 bool
362 wait_for(const chrono::duration<_Rep, _Period>& __rel) const
363 { return this->_M_state->wait_for(__rel); }
364
365 template<typename _Clock, typename _Duration>
366 bool
367 wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
368 { return this->_M_state->wait_until(__abs); }
369
370 protected:
c36abf03
BK
371 /// Wait for the state to be ready and rethrow any stored exception
372 __result_type
c910ceff
JW
373 _M_get_result()
374 {
c36abf03 375 _Result_base& __res = this->_M_state->wait();
c910ceff
JW
376 if (!(__res._M_error == 0))
377 rethrow_exception(__res._M_error);
c36abf03 378 return static_cast<__result_type>(__res);
c910ceff
JW
379 }
380
c36abf03 381 // Construction of a unique_future by promise::get_future()
c910ceff 382 explicit
c36abf03 383 __basic_future(const __state_type& __state) : _M_state(__state)
c910ceff
JW
384 {
385 if (static_cast<bool>(this->_M_state))
386 this->_M_state->_M_set_retrieved_flag();
387 else
8d1b99e2 388 __throw_future_error(int(future_errc::future_already_retrieved));
c910ceff
JW
389 }
390
c36abf03 391 // Copy construction from a shared_future
c910ceff 392 explicit
c36abf03 393 __basic_future(const shared_future<_Res>&);
c910ceff 394
c36abf03 395 // Move construction from a unique_future
c910ceff 396 explicit
c36abf03 397 __basic_future(unique_future<_Res>&&);
c910ceff
JW
398 };
399
c36abf03
BK
400
401 /// Primary template for unique_future.
402 template<typename _Res>
403 class unique_future : public __basic_future<_Res>
c910ceff 404 {
c36abf03
BK
405 friend class promise<_Res>;
406
407 typedef __basic_future<_Res> _Base_type;
408 typedef typename _Base_type::__state_type __state_type;
c36abf03
BK
409
410 explicit
411 unique_future(const __state_type& __state) : _Base_type(__state) { }
c910ceff
JW
412
413 public:
414 /// Move constructor
415 unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
416
c36abf03 417 // Disable copying
c910ceff
JW
418 unique_future(const unique_future&) = delete;
419 unique_future& operator=(const unique_future&) = delete;
420
c36abf03 421 /// Retrieving the value
abcd7e08 422 _Res&&
c910ceff 423 get()
abcd7e08 424 { return std::move(this->_M_get_result()._M_value()); }
c910ceff
JW
425 };
426
c36abf03
BK
427 /// Partial specialization for unique_future<R&>
428 template<typename _Res>
429 class unique_future<_Res&> : public __basic_future<_Res&>
c910ceff 430 {
c36abf03
BK
431 friend class promise<_Res&>;
432
433 typedef __basic_future<_Res&> _Base_type;
434 typedef typename _Base_type::__state_type __state_type;
435
436 explicit
437 unique_future(const __state_type& __state) : _Base_type(__state) { }
438
c910ceff
JW
439 public:
440 /// Move constructor
441 unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
442
c36abf03 443 // Disable copying
c910ceff
JW
444 unique_future(const unique_future&) = delete;
445 unique_future& operator=(const unique_future&) = delete;
446
c36abf03
BK
447 /// Retrieving the value
448 _Res&
449 get() { return *this->_M_get_result()._M_value_ptr; }
450 };
c910ceff 451
c36abf03
BK
452 /// Explicit specialization for unique_future<void>
453 template<>
454 class unique_future<void> : public __basic_future<void>
455 {
456 friend class promise<void>;
c910ceff 457
c36abf03
BK
458 typedef __basic_future<void> _Base_type;
459 typedef typename _Base_type::__state_type __state_type;
c910ceff
JW
460
461 explicit
c36abf03 462 unique_future(const __state_type& __state) : _Base_type(__state) { }
c910ceff 463
c910ceff
JW
464 public:
465 /// Move constructor
466 unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
467
c36abf03 468 // Disable copying
c910ceff
JW
469 unique_future(const unique_future&) = delete;
470 unique_future& operator=(const unique_future&) = delete;
471
c36abf03
BK
472 /// Retrieving the value
473 void
474 get() { this->_M_get_result(); }
c910ceff
JW
475 };
476
c36abf03
BK
477
478 /// Primary template for shared_future.
479 template<typename _Res>
480 class shared_future : public __basic_future<_Res>
c910ceff 481 {
c36abf03
BK
482 typedef __basic_future<_Res> _Base_type;
483
c910ceff
JW
484 public:
485 /// Copy constructor
486 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
487
488 /// Construct from a unique_future rvalue
c36abf03 489 shared_future(unique_future<_Res>&& __uf)
c910ceff
JW
490 : _Base_type(std::move(__uf))
491 { }
492
493 shared_future& operator=(const shared_future&) = delete;
494
c36abf03
BK
495 /// Retrieving the value
496 const _Res&
c910ceff 497 get()
c36abf03
BK
498 {
499 typename _Base_type::__result_type __r = this->_M_get_result();
500 _Res& __rs(__r._M_value());
501 return __rs;
502 }
c910ceff
JW
503 };
504
c36abf03
BK
505 /// Partial specialization for shared_future<R&>
506 template<typename _Res>
507 class shared_future<_Res&> : public __basic_future<_Res&>
c910ceff 508 {
c36abf03
BK
509 typedef __basic_future<_Res&> _Base_type;
510
c910ceff
JW
511 public:
512 /// Copy constructor
513 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
514
515 /// Construct from a unique_future rvalue
c36abf03 516 shared_future(unique_future<_Res&>&& __uf)
c910ceff
JW
517 : _Base_type(std::move(__uf))
518 { }
519
520 shared_future& operator=(const shared_future&) = delete;
521
c36abf03
BK
522 /// Retrieving the value
523 _Res&
524 get() { return *this->_M_get_result()._M_value_ptr; }
c910ceff
JW
525 };
526
c36abf03 527 /// Explicit specialization for shared_future<void>
c910ceff 528 template<>
c36abf03 529 class shared_future<void> : public __basic_future<void>
c910ceff 530 {
c36abf03
BK
531 typedef __basic_future<void> _Base_type;
532
c910ceff
JW
533 public:
534 /// Copy constructor
535 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
536
537 /// Construct from a unique_future rvalue
538 shared_future(unique_future<void>&& __uf)
539 : _Base_type(std::move(__uf))
540 { }
541
542 shared_future& operator=(const shared_future&) = delete;
543
c36abf03
BK
544 // Retrieving the value
545 void
546 get() { this->_M_get_result(); }
c910ceff
JW
547 };
548
c36abf03
BK
549 // Now we can define the protected __basic_future constructors.
550 template<typename _Res>
551 __basic_future<_Res>::__basic_future(const shared_future<_Res>& __sf)
c910ceff
JW
552 : _M_state(__sf._M_state)
553 { }
554
c36abf03
BK
555 template<typename _Res>
556 __basic_future<_Res>::__basic_future(unique_future<_Res>&& __uf)
c910ceff
JW
557 : _M_state(std::move(__uf._M_state))
558 { }
559
c36abf03
BK
560
561 /// Primary template for promise
562 template<typename _Res>
c910ceff
JW
563 class promise
564 {
c36abf03
BK
565 template<typename> friend class packaged_task;
566
567 typedef __future_base::_State _State;
c36abf03
BK
568 typedef __future_base::_Result<_Res> result_type;
569
570 shared_ptr<_State> _M_future;
571 typename __future_base::_Ptr<result_type>::type _M_storage;
572
c910ceff
JW
573 public:
574 promise()
c36abf03 575 : _M_future(std::make_shared<_State>()), _M_storage(new result_type())
c910ceff
JW
576 { }
577
578 promise(promise&& __rhs)
579 : _M_future(std::move(__rhs._M_future)),
580 _M_storage(std::move(__rhs._M_storage))
581 { }
582
583 // TODO: requires allocator concepts
584 /*
585 template<typename _Allocator>
586 promise(allocator_arg_t, const _Allocator& __a);
587
588 template<typename _Allocator>
589 promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
590 */
591
592 promise(const promise&) = delete;
593
594 ~promise()
595 {
596 if (static_cast<bool>(_M_future) && !_M_future.unique())
597 _M_future->_M_break_promise(std::move(_M_storage));
598 }
599
c36abf03 600 // Assignment
c910ceff
JW
601 promise&
602 operator=(promise&& __rhs)
603 {
604 promise(std::move(__rhs)).swap(*this);
605 return *this;
606 }
607
608 promise& operator=(const promise&) = delete;
609
610 void
611 swap(promise& __rhs)
612 {
613 _M_future.swap(__rhs._M_future);
614 _M_storage.swap(__rhs._M_storage);
615 }
616
c36abf03
BK
617 // Retrieving the result
618 unique_future<_Res>
c910ceff 619 get_future()
c36abf03 620 { return unique_future<_Res>(_M_future); }
c910ceff 621
c36abf03 622 // Setting the result
c910ceff 623 void
c36abf03 624 set_value(const _Res& __r)
c910ceff
JW
625 {
626 if (!_M_satisfied())
627 _M_storage->_M_set(__r);
628 _M_future->_M_set_result(std::move(_M_storage));
629 }
630
631 void
c36abf03 632 set_value(_Res&& __r)
c910ceff
JW
633 {
634 if (!_M_satisfied())
abcd7e08 635 _M_storage->_M_set(std::move(__r));
c910ceff
JW
636 _M_future->_M_set_result(std::move(_M_storage));
637 }
638
639 void
640 set_exception(exception_ptr __p)
641 {
642 if (!_M_satisfied())
643 _M_storage->_M_error = __p;
644 _M_future->_M_set_result(std::move(_M_storage));
645 }
646
647 private:
c910ceff 648 bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
c910ceff
JW
649 };
650
c36abf03
BK
651 /// Partial specialization for promise<R&>
652 template<typename _Res>
653 class promise<_Res&>
c910ceff 654 {
c36abf03
BK
655 template<typename> friend class packaged_task;
656 typedef __future_base::_State _State;
657
658 typedef __future_base::_Result<_Res&> result_type;
659
660 shared_ptr<_State> _M_future;
661 typename __future_base::_Ptr<result_type>::type _M_storage;
662
c910ceff
JW
663 public:
664 promise()
c36abf03 665 : _M_future(std::make_shared<_State>()), _M_storage(new result_type())
c910ceff
JW
666 { }
667
668 promise(promise&& __rhs)
c36abf03
BK
669 : _M_future(std::move(__rhs._M_future)),
670 _M_storage(std::move(__rhs._M_storage))
c910ceff
JW
671 { }
672
673 // TODO: requires allocator concepts
674 /*
675 template<typename _Allocator>
676 promise(allocator_arg_t, const _Allocator& __a);
677
678 template<typename _Allocator>
679 promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
680 */
681
682 promise(const promise&) = delete;
683
684 ~promise()
685 {
686 if (static_cast<bool>(_M_future) && !_M_future.unique())
687 _M_future->_M_break_promise(std::move(_M_storage));
688 }
689
c36abf03 690 // Assignment
c910ceff
JW
691 promise&
692 operator=(promise&& __rhs)
693 {
694 promise(std::move(__rhs)).swap(*this);
695 return *this;
696 }
697
698 promise& operator=(const promise&) = delete;
699
700 void
701 swap(promise& __rhs)
702 {
703 _M_future.swap(__rhs._M_future);
704 _M_storage.swap(__rhs._M_storage);
705 }
706
c36abf03
BK
707 // Retrieving the result
708 unique_future<_Res&>
c910ceff 709 get_future()
c36abf03 710 { return unique_future<_Res&>(_M_future); }
c910ceff 711
c36abf03 712 // Setting the result
c910ceff 713 void
c36abf03 714 set_value(_Res& __r)
c910ceff
JW
715 {
716 if (!_M_satisfied())
717 _M_storage->_M_value_ptr = &__r;
718 _M_future->_M_set_result(std::move(_M_storage));
719 }
720
721 void
722 set_exception(exception_ptr __p)
723 {
724 if (!_M_satisfied())
725 _M_storage->_M_error = __p;
726 _M_future->_M_set_result(std::move(_M_storage));
727 }
728
729 private:
c910ceff 730 bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
c910ceff
JW
731 };
732
c36abf03 733 /// Explicit specialization for promise<void>
c910ceff
JW
734 template<>
735 class promise<void>
736 {
c36abf03
BK
737 template<typename> friend class packaged_task;
738 typedef __future_base::_State _State;
739 typedef __future_base::_Result<void> result_type;
740
741 shared_ptr<__future_base::_State> _M_future;
742 typename __future_base::_Ptr<result_type>::type _M_storage;
743
c910ceff
JW
744 public:
745 promise()
c36abf03
BK
746 : _M_future(std::make_shared<_State>()),
747 _M_storage(new result_type())
c910ceff
JW
748 { }
749
750 promise(promise&& __rhs)
751 : _M_future(std::move(__rhs._M_future)),
752 _M_storage(std::move(__rhs._M_storage))
753 { }
754
755 // TODO: requires allocator concepts
756 /*
757 template<typename _Allocator>
758 promise(allocator_arg_t, const _Allocator& __a);
759
760 template<typename _Allocator>
761 promise(allocator_arg_t, const _Allocator&, promise&& __rhs);
762 */
763
764 promise(const promise&) = delete;
765
766 ~promise()
767 {
768 if (static_cast<bool>(_M_future) && !_M_future.unique())
769 _M_future->_M_break_promise(std::move(_M_storage));
770 }
771
c36abf03 772 // Assignment
c910ceff
JW
773 promise&
774 operator=(promise&& __rhs)
775 {
776 promise(std::move(__rhs)).swap(*this);
777 return *this;
778 }
779
780 promise& operator=(const promise&) = delete;
781
782 void
783 swap(promise& __rhs)
784 {
785 _M_future.swap(__rhs._M_future);
786 _M_storage.swap(__rhs._M_storage);
787 }
788
c36abf03 789 // Retrieving the result
c910ceff
JW
790 unique_future<void>
791 get_future()
792 { return unique_future<void>(_M_future); }
793
c36abf03 794 // Setting the result
c910ceff
JW
795 void
796 set_value()
797 {
798 _M_future->_M_set_result(std::move(_M_storage));
799 }
800
801 void
802 set_exception(exception_ptr __p)
803 {
804 if (!_M_satisfied())
805 _M_storage->_M_error = __p;
806 _M_future->_M_set_result(std::move(_M_storage));
807 }
808
809 private:
c910ceff 810 bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
c910ceff
JW
811 };
812
813 // TODO: requires allocator concepts
814 /*
c36abf03
BK
815 template<typename _Res, class Alloc>
816 concept_map UsesAllocator<promise<_Res>, Alloc>
c910ceff
JW
817 {
818 typedef Alloc allocator_type;
819 }
820 */
c36abf03
BK
821 /// Primary template.
822 template<typename _Res, typename... _ArgTypes>
c910ceff
JW
823 struct _Run_task
824 {
825 static void
c36abf03
BK
826 _S_run(promise<_Res>& __p, function<_Res(_ArgTypes...)>& __f,
827 _ArgTypes... __args)
c910ceff
JW
828 {
829 __p.set_value(__f(std::forward<_ArgTypes>(__args)...));
830 }
831 };
832
c36abf03 833 /// Specialization used by packaged_task<void(...)>
c910ceff
JW
834 template<typename... _ArgTypes>
835 struct _Run_task<void, _ArgTypes...>
836 {
837 static void
838 _S_run(promise<void>& __p, function<void(_ArgTypes...)>& __f,
c36abf03 839 _ArgTypes... __args)
c910ceff
JW
840 {
841 __f(std::forward<_ArgTypes>(__args)...);
842 __p.set_value();
843 }
844 };
845
c36abf03 846
3259554a 847 /// packaged_task
c36abf03
BK
848 template<typename _Res, typename... _ArgTypes>
849 class packaged_task<_Res(_ArgTypes...)>
c910ceff 850 {
c36abf03
BK
851 function<_Res(_ArgTypes...)> _M_task;
852 promise<_Res> _M_promise;
853
c910ceff 854 public:
c36abf03 855 typedef _Res result_type;
c910ceff 856
c36abf03 857 // Construction and destruction
c910ceff
JW
858 packaged_task() { }
859
860 template<typename _Fn>
861 explicit
862 packaged_task(const _Fn& __fn) : _M_task(__fn) { }
863
864 template<typename _Fn>
865 explicit
866 packaged_task(_Fn&& __fn) : _M_task(std::move(__fn)) { }
867
868 explicit
c36abf03 869 packaged_task(_Res(*__fn)(_ArgTypes...)) : _M_task(__fn) { }
c910ceff
JW
870
871 // TODO: requires allocator concepts
872 /*
873 template<typename _Fn, typename _Allocator>
874 explicit
875 packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn __fn)
876 : _M_task(__tag, __a, __fn), _M_promise(__tag, __a)
877 { }
878
879 template<typename _Fn, typename _Allocator>
880 explicit
881 packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn&& __fn)
882 : _M_task(__tag, __a, std::move(__fn)), _M_promise(__tag, __a)
883 { }
884 */
885
886 ~packaged_task() = default;
887
c36abf03 888 // No copy
c910ceff
JW
889 packaged_task(packaged_task&) = delete;
890 packaged_task& operator=(packaged_task&) = delete;
891
c36abf03 892 // Move support
c910ceff
JW
893 packaged_task(packaged_task&& __other)
894 { this->swap(__other); }
895
896 packaged_task& operator=(packaged_task&& __other)
897 {
898 packaged_task(std::move(__other)).swap(*this);
899 return *this;
900 }
901
902 void
903 swap(packaged_task& __other)
904 {
905 _M_task.swap(__other._M_task);
906 _M_promise.swap(__other._M_promise);
907 }
908
909 explicit operator bool() const { return static_cast<bool>(_M_task); }
910
c36abf03
BK
911 // Result retrieval
912 unique_future<_Res>
c910ceff
JW
913 get_future()
914 {
8d1b99e2 915 __try
c910ceff
JW
916 {
917 return _M_promise.get_future();
918 }
8d1b99e2 919 __catch (const future_error& __e)
c910ceff
JW
920 {
921 if (__e.code() == future_errc::future_already_retrieved)
abcd7e08
JW
922 __throw_bad_function_call();
923 __throw_exception_again;
c910ceff
JW
924 }
925 }
926
c36abf03 927 // Execution
c910ceff
JW
928 void
929 operator()(_ArgTypes... __args)
930 {
931 if (!static_cast<bool>(_M_task) || _M_promise._M_satisfied())
abcd7e08 932 __throw_bad_function_call();
8d1b99e2
BK
933
934 __try
c910ceff 935 {
c36abf03 936 _Run_task<_Res, _ArgTypes...>::_S_run(_M_promise, _M_task,
c910ceff
JW
937 std::forward<_ArgTypes>(__args)...);
938 }
8d1b99e2 939 __catch (...)
c910ceff
JW
940 {
941 _M_promise.set_exception(current_exception());
942 }
943 }
944
c36abf03 945 void reset() { promise<_Res>().swap(_M_promise); }
c910ceff
JW
946 };
947
c910ceff
JW
948#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
949 // && _GLIBCXX_ATOMIC_BUILTINS_4
950
41ca4246
BK
951 // @} group futures
952}
953
c910ceff
JW
954#endif // __GXX_EXPERIMENTAL_CXX0X__
955
956#endif // _GLIBCXX_FUTURE