blob: f6896a3a0fcee8d2f02b70b141943d5d0dd01282 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:161// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:014// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:165//
Howard Hinnantb64f8b02010-11-16 22:09:026// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:168//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
22 broken_promise,
23 future_already_retrieved,
24 promise_already_satisfied,
25 no_state
26};
27
28enum class launch
29{
Howard Hinnant66895642010-11-23 18:33:5430 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:1633};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
43error_code make_error_code(future_errc e);
44error_condition make_error_condition(future_errc e);
45
46const error_category& future_category();
47
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
54 const error_code& code() const throw();
55 const char* what() const throw();
56};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
65 promise(promise&& rhs);
66 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
70 promise& operator=(promise&& rhs);
71 promise& operator=(const promise& rhs) = delete;
72 void swap(promise& other);
73
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
95 promise(promise&& rhs);
96 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
100 promise& operator=(promise&& rhs);
101 promise& operator=(const promise& rhs) = delete;
102 void swap(promise& other);
103
104 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19105 future<R&> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
123 promise(promise&& rhs);
124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
128 promise& operator=(promise&& rhs);
129 promise& operator=(const promise& rhs) = delete;
130 void swap(promise& other);
131
132 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19133 future<void> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
144template <class R> void swap(promise<R>& x, promise<R>& y);
145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
153 future();
154 future(future&&);
155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
158 future& operator=(future&&);
Howard Hinnant7de47902010-11-30 20:23:32159 shared_future<R> share() &&;
Howard Hinnantbc8d3f92010-05-11 19:42:16160
161 // retrieving the value
162 R get();
163
164 // functions to check state
165 bool valid() const;
166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
180 future();
181 future(future&&);
182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
185 future& operator=(future&&);
Howard Hinnant7de47902010-11-30 20:23:32186 shared_future<R&> share() &&;
Howard Hinnantbc8d3f92010-05-11 19:42:16187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
192 bool valid() const;
193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
207 future();
208 future(future&&);
209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
212 future& operator=(future&&);
Howard Hinnant7de47902010-11-30 20:23:32213 shared_future<void> share() &&;
Howard Hinnantbc8d3f92010-05-11 19:42:16214
215 // retrieving the value
216 void get();
217
218 // functions to check state
219 bool valid() const;
220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
234 shared_future();
235 shared_future(const shared_future& rhs);
236 shared_future(future<R>&&);
237 shared_future(shared_future&& rhs);
238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
240 shared_future& operator=(shared_future&& rhs);
241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
246 bool valid() const;
247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
261 shared_future();
262 shared_future(const shared_future& rhs);
Howard Hinnant99be8232010-09-03 18:39:25263 shared_future(future<R&>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16264 shared_future(shared_future&& rhs);
265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
267 shared_future& operator=(shared_future&& rhs);
268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
273 bool valid() const;
274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
288 shared_future();
289 shared_future(const shared_future& rhs);
Howard Hinnant99be8232010-09-03 18:39:25290 shared_future(future<void>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16291 shared_future(shared_future&& rhs);
292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
294 shared_future& operator=(shared_future&& rhs);
295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
300 bool valid() const;
301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantbc8d3f92010-05-11 19:42:16311template <class F, class... Args>
312 future<typename result_of<F(Args...)>::type>
313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
316 future<typename result_of<F(Args...)>::type>
317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantf5256e12010-05-11 21:36:01319template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
325 typedef R result_type;
326
327 // construction and destruction
328 packaged_task();
329 template <class F>
Howard Hinnantbc8d3f92010-05-11 19:42:16330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
332 explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333 ~packaged_task();
334
335 // no copy
336 packaged_task(packaged_task&) = delete;
337 packaged_task& operator=(packaged_task&) = delete;
338
339 // move support
340 packaged_task(packaged_task&& other);
341 packaged_task& operator=(packaged_task&& other);
342 void swap(packaged_task& other);
343
Howard Hinnant7de47902010-11-30 20:23:32344 bool valid() const;
Howard Hinnantbc8d3f92010-05-11 19:42:16345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&);
358
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant47499b12010-08-27 20:10:19367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37370#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19371#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16372
Howard Hinnant08e17472011-10-17 20:05:10373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16374#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10375#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16376
377_LIBCPP_BEGIN_NAMESPACE_STD
378
379//enum class future_errc
Howard Hinnant8c6cbb22010-09-22 14:16:26380struct _LIBCPP_VISIBLE future_errc
Howard Hinnantbc8d3f92010-05-11 19:42:16381{
382enum _ {
383 broken_promise,
384 future_already_retrieved,
385 promise_already_satisfied,
386 no_state
387};
388
389 _ __v_;
390
Howard Hinnant8c6cbb22010-09-22 14:16:26391 _LIBCPP_INLINE_VISIBILITY future_errc(_ __v) : __v_(__v) {}
392 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16393
394};
395
Howard Hinnant8c6cbb22010-09-22 14:16:26396template <>
397struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05398
Howard Hinnantbc8d3f92010-05-11 19:42:16399//enum class launch
Howard Hinnant8c6cbb22010-09-22 14:16:26400struct _LIBCPP_VISIBLE launch
Howard Hinnantbc8d3f92010-05-11 19:42:16401{
402enum _ {
Howard Hinnant66895642010-11-23 18:33:54403 async = 1,
404 deferred = 2,
405 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16406};
407
408 _ __v_;
409
Howard Hinnant8c6cbb22010-09-22 14:16:26410 _LIBCPP_INLINE_VISIBILITY launch(_ __v) : __v_(__v) {}
411 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16412
413};
414
415//enum class future_status
Howard Hinnant8c6cbb22010-09-22 14:16:26416struct _LIBCPP_VISIBLE future_status
Howard Hinnantbc8d3f92010-05-11 19:42:16417{
418enum _ {
419 ready,
420 timeout,
421 deferred
422};
423
424 _ __v_;
425
Howard Hinnant8c6cbb22010-09-22 14:16:26426 _LIBCPP_INLINE_VISIBILITY future_status(_ __v) : __v_(__v) {}
427 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16428
429};
430
Howard Hinnant8c6cbb22010-09-22 14:16:26431_LIBCPP_VISIBLE
Howard Hinnanta6521722010-08-25 17:32:05432const error_category& future_category();
433
434inline _LIBCPP_INLINE_VISIBILITY
435error_code
436make_error_code(future_errc __e)
437{
438 return error_code(static_cast<int>(__e), future_category());
439}
440
441inline _LIBCPP_INLINE_VISIBILITY
442error_condition
443make_error_condition(future_errc __e)
444{
445 return error_condition(static_cast<int>(__e), future_category());
446}
447
Howard Hinnant8c6cbb22010-09-22 14:16:26448class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05449 : public logic_error
450{
451 error_code __ec_;
452public:
453 future_error(error_code __ec);
454
Howard Hinnant8c6cbb22010-09-22 14:16:26455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta6521722010-08-25 17:32:05456 const error_code& code() const throw() {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52457
458 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05459};
460
Howard Hinnant47499b12010-08-27 20:10:19461class __assoc_sub_state
462 : public __shared_count
463{
464protected:
465 exception_ptr __exception_;
466 mutable mutex __mut_;
467 mutable condition_variable __cv_;
468 unsigned __state_;
469
Howard Hinnant1694d232011-05-28 14:41:13470 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21471 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19472public:
473 enum
474 {
475 __constructed = 1,
476 __future_attached = 2,
477 ready = 4,
478 deferred = 8
479 };
480
Howard Hinnant8c6cbb22010-09-22 14:16:26481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19482 __assoc_sub_state() : __state_(0) {}
483
Howard Hinnant8c6cbb22010-09-22 14:16:26484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19485 bool __has_value() const
486 {return (__state_ & __constructed) || (__exception_ != nullptr);}
487
Howard Hinnant8c6cbb22010-09-22 14:16:26488 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19489 void __set_future_attached() {__state_ |= __future_attached;}
Howard Hinnant8c6cbb22010-09-22 14:16:26490 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19491 bool __has_future_attached() const {return __state_ & __future_attached;}
492
Howard Hinnant8c6cbb22010-09-22 14:16:26493 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21494 void __set_deferred() {__state_ |= deferred;}
495
Howard Hinnant47499b12010-08-27 20:10:19496 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26497 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19498 bool __is_ready() const {return __state_ & ready;}
499
500 void set_value();
501 void set_value_at_thread_exit();
502
503 void set_exception(exception_ptr __p);
504 void set_exception_at_thread_exit(exception_ptr __p);
505
506 void copy();
507
Howard Hinnant54da3382010-08-30 18:46:21508 void wait();
Howard Hinnant47499b12010-08-27 20:10:19509 template <class _Rep, class _Period>
510 future_status
511 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
512 template <class _Clock, class _Duration>
513 future_status
514 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21515
516 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19517};
518
Howard Hinnantf39daa82010-08-28 21:01:06519template <class _Clock, class _Duration>
520future_status
521__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
522{
523 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21524 if (__state_ & deferred)
525 return future_status::deferred;
526 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06527 __cv_.wait_until(__lk, __abs_time);
528 if (__state_ & ready)
529 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06530 return future_status::timeout;
531}
532
533template <class _Rep, class _Period>
534inline _LIBCPP_INLINE_VISIBILITY
535future_status
536__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
537{
Howard Hinnantf8f85212010-11-20 19:16:30538 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06539}
540
Howard Hinnant47499b12010-08-27 20:10:19541template <class _R>
542class __assoc_state
543 : public __assoc_sub_state
544{
545 typedef __assoc_sub_state base;
546 typedef typename aligned_storage<sizeof(_R), alignment_of<_R>::value>::type _U;
547protected:
548 _U __value_;
549
Howard Hinnant1694d232011-05-28 14:41:13550 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19551public:
552
553 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19554#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19555 void set_value(_Arg&& __arg);
556#else
557 void set_value(_Arg& __arg);
558#endif
559
560 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19561#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19562 void set_value_at_thread_exit(_Arg&& __arg);
563#else
564 void set_value_at_thread_exit(_Arg& __arg);
565#endif
566
567 _R move();
568 typename add_lvalue_reference<_R>::type copy();
569};
570
571template <class _R>
572void
Howard Hinnant1694d232011-05-28 14:41:13573__assoc_state<_R>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19574{
575 if (this->__state_ & base::__constructed)
576 reinterpret_cast<_R*>(&__value_)->~_R();
577 delete this;
578}
579
580template <class _R>
581template <class _Arg>
582void
Howard Hinnant73d21a42010-09-04 23:28:19583#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19584__assoc_state<_R>::set_value(_Arg&& __arg)
585#else
586__assoc_state<_R>::set_value(_Arg& __arg)
587#endif
588{
589 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50590#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19591 if (this->__has_value())
592 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50593#endif
Howard Hinnant0949eed2011-06-30 21:18:19594 ::new(&__value_) _R(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19595 this->__state_ |= base::__constructed | base::ready;
596 __lk.unlock();
597 __cv_.notify_all();
598}
599
600template <class _R>
601template <class _Arg>
602void
Howard Hinnant73d21a42010-09-04 23:28:19603#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19604__assoc_state<_R>::set_value_at_thread_exit(_Arg&& __arg)
605#else
606__assoc_state<_R>::set_value_at_thread_exit(_Arg& __arg)
607#endif
608{
609 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50610#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19611 if (this->__has_value())
612 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50613#endif
Howard Hinnant0949eed2011-06-30 21:18:19614 ::new(&__value_) _R(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19615 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04616 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19617 __lk.unlock();
618}
619
620template <class _R>
621_R
622__assoc_state<_R>::move()
623{
624 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21625 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19626 if (this->__exception_ != nullptr)
627 rethrow_exception(this->__exception_);
Howard Hinnant0949eed2011-06-30 21:18:19628 return _VSTD::move(*reinterpret_cast<_R*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19629}
630
631template <class _R>
632typename add_lvalue_reference<_R>::type
633__assoc_state<_R>::copy()
634{
635 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21636 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19637 if (this->__exception_ != nullptr)
638 rethrow_exception(this->__exception_);
639 return *reinterpret_cast<_R*>(&__value_);
640}
641
Howard Hinnantf39daa82010-08-28 21:01:06642template <class _R>
643class __assoc_state<_R&>
644 : public __assoc_sub_state
645{
646 typedef __assoc_sub_state base;
647 typedef _R* _U;
648protected:
649 _U __value_;
650
Howard Hinnant1694d232011-05-28 14:41:13651 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06652public:
653
654 void set_value(_R& __arg);
655 void set_value_at_thread_exit(_R& __arg);
656
657 _R& copy();
658};
659
660template <class _R>
661void
Howard Hinnant1694d232011-05-28 14:41:13662__assoc_state<_R&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06663{
664 delete this;
665}
666
667template <class _R>
668void
669__assoc_state<_R&>::set_value(_R& __arg)
670{
671 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50672#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06673 if (this->__has_value())
674 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50675#endif
Howard Hinnantf39daa82010-08-28 21:01:06676 __value_ = &__arg;
677 this->__state_ |= base::__constructed | base::ready;
678 __lk.unlock();
679 __cv_.notify_all();
680}
681
682template <class _R>
683void
684__assoc_state<_R&>::set_value_at_thread_exit(_R& __arg)
685{
686 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50687#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06688 if (this->__has_value())
689 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50690#endif
Howard Hinnantf39daa82010-08-28 21:01:06691 __value_ = &__arg;
692 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04693 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06694 __lk.unlock();
695}
696
697template <class _R>
698_R&
699__assoc_state<_R&>::copy()
700{
701 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21702 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06703 if (this->__exception_ != nullptr)
704 rethrow_exception(this->__exception_);
705 return *__value_;
706}
707
Howard Hinnant47499b12010-08-27 20:10:19708template <class _R, class _Alloc>
709class __assoc_state_alloc
710 : public __assoc_state<_R>
711{
712 typedef __assoc_state<_R> base;
713 _Alloc __alloc_;
714
Howard Hinnant1694d232011-05-28 14:41:13715 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19716public:
Howard Hinnant8c6cbb22010-09-22 14:16:26717 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19718 explicit __assoc_state_alloc(const _Alloc& __a)
719 : __alloc_(__a) {}
720};
721
722template <class _R, class _Alloc>
723void
Howard Hinnant1694d232011-05-28 14:41:13724__assoc_state_alloc<_R, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19725{
726 if (this->__state_ & base::__constructed)
727 reinterpret_cast<_R*>(&this->__value_)->~_R();
728 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
729 this->~__assoc_state_alloc();
730 __a.deallocate(this, 1);
731}
732
Howard Hinnantf39daa82010-08-28 21:01:06733template <class _R, class _Alloc>
734class __assoc_state_alloc<_R&, _Alloc>
735 : public __assoc_state<_R&>
736{
737 typedef __assoc_state<_R&> base;
738 _Alloc __alloc_;
739
Howard Hinnant1694d232011-05-28 14:41:13740 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06741public:
Howard Hinnant8c6cbb22010-09-22 14:16:26742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06743 explicit __assoc_state_alloc(const _Alloc& __a)
744 : __alloc_(__a) {}
745};
746
747template <class _R, class _Alloc>
748void
Howard Hinnant1694d232011-05-28 14:41:13749__assoc_state_alloc<_R&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06750{
751 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
752 this->~__assoc_state_alloc();
753 __a.deallocate(this, 1);
754}
755
Howard Hinnant47499b12010-08-27 20:10:19756template <class _Alloc>
757class __assoc_sub_state_alloc
758 : public __assoc_sub_state
759{
760 typedef __assoc_sub_state base;
761 _Alloc __alloc_;
762
Howard Hinnant1694d232011-05-28 14:41:13763 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19764public:
Howard Hinnant8c6cbb22010-09-22 14:16:26765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19766 explicit __assoc_sub_state_alloc(const _Alloc& __a)
767 : __alloc_(__a) {}
768};
769
770template <class _Alloc>
771void
Howard Hinnant1694d232011-05-28 14:41:13772__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19773{
774 this->~base();
Howard Hinnantf39daa82010-08-28 21:01:06775 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19776 this->~__assoc_sub_state_alloc();
777 __a.deallocate(this, 1);
778}
779
Howard Hinnant54da3382010-08-30 18:46:21780template <class _R, class _F>
781class __deferred_assoc_state
782 : public __assoc_state<_R>
783{
784 typedef __assoc_state<_R> base;
785
786 _F __func_;
787
788public:
Howard Hinnant73d21a42010-09-04 23:28:19789#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21790 explicit __deferred_assoc_state(_F&& __f);
791#endif
792
793 virtual void __execute();
794};
795
Howard Hinnant73d21a42010-09-04 23:28:19796#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21797
798template <class _R, class _F>
799inline _LIBCPP_INLINE_VISIBILITY
800__deferred_assoc_state<_R, _F>::__deferred_assoc_state(_F&& __f)
Howard Hinnant0949eed2011-06-30 21:18:19801 : __func_(_VSTD::forward<_F>(__f))
Howard Hinnant54da3382010-08-30 18:46:21802{
803 this->__set_deferred();
804}
805
Howard Hinnant73d21a42010-09-04 23:28:19806#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21807
808template <class _R, class _F>
809void
810__deferred_assoc_state<_R, _F>::__execute()
811{
812#ifndef _LIBCPP_NO_EXCEPTIONS
813 try
814 {
815#endif // _LIBCPP_NO_EXCEPTIONS
816 this->set_value(__func_());
817#ifndef _LIBCPP_NO_EXCEPTIONS
818 }
819 catch (...)
820 {
821 this->set_exception(current_exception());
822 }
823#endif // _LIBCPP_NO_EXCEPTIONS
824}
825
826template <class _F>
827class __deferred_assoc_state<void, _F>
828 : public __assoc_sub_state
829{
830 typedef __assoc_sub_state base;
831
832 _F __func_;
833
834public:
Howard Hinnant73d21a42010-09-04 23:28:19835#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21836 explicit __deferred_assoc_state(_F&& __f);
837#endif
838
839 virtual void __execute();
840};
841
Howard Hinnant73d21a42010-09-04 23:28:19842#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21843
844template <class _F>
845inline _LIBCPP_INLINE_VISIBILITY
846__deferred_assoc_state<void, _F>::__deferred_assoc_state(_F&& __f)
Howard Hinnant0949eed2011-06-30 21:18:19847 : __func_(_VSTD::forward<_F>(__f))
Howard Hinnant54da3382010-08-30 18:46:21848{
849 this->__set_deferred();
850}
851
Howard Hinnant73d21a42010-09-04 23:28:19852#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21853
854template <class _F>
855void
856__deferred_assoc_state<void, _F>::__execute()
857{
858#ifndef _LIBCPP_NO_EXCEPTIONS
859 try
860 {
861#endif // _LIBCPP_NO_EXCEPTIONS
862 __func_();
863 this->set_value();
864#ifndef _LIBCPP_NO_EXCEPTIONS
865 }
866 catch (...)
867 {
868 this->set_exception(current_exception());
869 }
870#endif // _LIBCPP_NO_EXCEPTIONS
871}
872
Howard Hinnant57cff292011-05-19 15:05:04873template <class _R, class _F>
874class __async_assoc_state
875 : public __assoc_state<_R>
876{
877 typedef __assoc_state<_R> base;
878
879 _F __func_;
880
Howard Hinnant1694d232011-05-28 14:41:13881 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04882public:
883#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
884 explicit __async_assoc_state(_F&& __f);
885#endif
886
887 virtual void __execute();
888};
889
890#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
891
892template <class _R, class _F>
893inline _LIBCPP_INLINE_VISIBILITY
894__async_assoc_state<_R, _F>::__async_assoc_state(_F&& __f)
Howard Hinnant0949eed2011-06-30 21:18:19895 : __func_(_VSTD::forward<_F>(__f))
Howard Hinnant57cff292011-05-19 15:05:04896{
897}
898
899#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
900
901template <class _R, class _F>
902void
903__async_assoc_state<_R, _F>::__execute()
904{
905#ifndef _LIBCPP_NO_EXCEPTIONS
906 try
907 {
908#endif // _LIBCPP_NO_EXCEPTIONS
909 this->set_value(__func_());
910#ifndef _LIBCPP_NO_EXCEPTIONS
911 }
912 catch (...)
913 {
914 this->set_exception(current_exception());
915 }
916#endif // _LIBCPP_NO_EXCEPTIONS
917}
918
919template <class _R, class _F>
920void
Howard Hinnant1694d232011-05-28 14:41:13921__async_assoc_state<_R, _F>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04922{
923 this->wait();
924 base::__on_zero_shared();
925}
926
927template <class _F>
928class __async_assoc_state<void, _F>
929 : public __assoc_sub_state
930{
931 typedef __assoc_sub_state base;
932
933 _F __func_;
934
Howard Hinnant1694d232011-05-28 14:41:13935 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04936public:
937#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
938 explicit __async_assoc_state(_F&& __f);
939#endif
940
941 virtual void __execute();
942};
943
944#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
945
946template <class _F>
947inline _LIBCPP_INLINE_VISIBILITY
948__async_assoc_state<void, _F>::__async_assoc_state(_F&& __f)
Howard Hinnant0949eed2011-06-30 21:18:19949 : __func_(_VSTD::forward<_F>(__f))
Howard Hinnant57cff292011-05-19 15:05:04950{
951}
952
953#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
954
955template <class _F>
956void
957__async_assoc_state<void, _F>::__execute()
958{
959#ifndef _LIBCPP_NO_EXCEPTIONS
960 try
961 {
962#endif // _LIBCPP_NO_EXCEPTIONS
963 __func_();
964 this->set_value();
965#ifndef _LIBCPP_NO_EXCEPTIONS
966 }
967 catch (...)
968 {
969 this->set_exception(current_exception());
970 }
971#endif // _LIBCPP_NO_EXCEPTIONS
972}
973
974template <class _F>
975void
Howard Hinnant1694d232011-05-28 14:41:13976__async_assoc_state<void, _F>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04977{
978 this->wait();
979 base::__on_zero_shared();
980}
981
Howard Hinnant2b1b2d42011-06-14 19:58:17982template <class _R> class promise;
983template <class _R> class shared_future;
Howard Hinnant47499b12010-08-27 20:10:19984
985// future
986
Howard Hinnant54da3382010-08-30 18:46:21987template <class _R> class future;
988
989template <class _R, class _F>
990future<_R>
Howard Hinnant73d21a42010-09-04 23:28:19991#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21992__make_deferred_assoc_state(_F&& __f);
993#else
994__make_deferred_assoc_state(_F __f);
995#endif
996
Howard Hinnant57cff292011-05-19 15:05:04997template <class _R, class _F>
998future<_R>
999#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1000__make_async_assoc_state(_F&& __f);
1001#else
1002__make_async_assoc_state(_F __f);
1003#endif
1004
Howard Hinnant47499b12010-08-27 20:10:191005template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:261006class _LIBCPP_VISIBLE future
Howard Hinnant47499b12010-08-27 20:10:191007{
1008 __assoc_state<_R>* __state_;
1009
1010 explicit future(__assoc_state<_R>* __state);
1011
1012 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:251013 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:211014
Howard Hinnant73d21a42010-09-04 23:28:191015#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant57cff292011-05-19 15:05:041016 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:211017 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
Howard Hinnant57cff292011-05-19 15:05:041018 template <class _R1, class _F>
1019 friend future<_R1> __make_async_assoc_state(_F&& __f);
Howard Hinnant54da3382010-08-30 18:46:211020#else
Howard Hinnant57cff292011-05-19 15:05:041021 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:211022 friend future<_R1> __make_deferred_assoc_state(_F __f);
Howard Hinnant57cff292011-05-19 15:05:041023 template <class _R1, class _F>
1024 friend future<_R1> __make_async_assoc_state(_F __f);
Howard Hinnant54da3382010-08-30 18:46:211025#endif
1026
Howard Hinnant47499b12010-08-27 20:10:191027public:
Howard Hinnant8c6cbb22010-09-22 14:16:261028 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191029 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:191030#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261031 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191032 future(future&& __rhs)
1033 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1034 future(const future&) = delete;
1035 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:261036 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191037 future& operator=(future&& __rhs)
1038 {
1039 future(std::move(__rhs)).swap(*this);
1040 return *this;
1041 }
Howard Hinnant73d21a42010-09-04 23:28:191042#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191043private:
1044 future(const future&);
1045 future& operator=(const future&);
1046public:
Howard Hinnant73d21a42010-09-04 23:28:191047#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191048 ~future();
Howard Hinnant7de47902010-11-30 20:23:321049 shared_future<_R> share();
Howard Hinnant47499b12010-08-27 20:10:191050
1051 // retrieving the value
1052 _R get();
1053
Howard Hinnant8c6cbb22010-09-22 14:16:261054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191055 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191056
1057 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:261058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191059 bool valid() const {return __state_ != nullptr;}
1060
Howard Hinnant8c6cbb22010-09-22 14:16:261061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191062 void wait() const {__state_->wait();}
1063 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:261064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191065 future_status
1066 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1067 {return __state_->wait_for(__rel_time);}
1068 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:261069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191070 future_status
1071 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1072 {return __state_->wait_until(__abs_time);}
1073};
1074
1075template <class _R>
1076future<_R>::future(__assoc_state<_R>* __state)
1077 : __state_(__state)
1078{
Howard Hinnant22ba71b2011-07-13 16:00:501079#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191080 if (__state_->__has_future_attached())
1081 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:501082#endif
Howard Hinnant47499b12010-08-27 20:10:191083 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:211084 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:191085}
1086
Howard Hinnant54da3382010-08-30 18:46:211087struct __release_shared_count
1088{
1089 void operator()(__shared_count* p) {p->__release_shared();}
1090};
1091
Howard Hinnant47499b12010-08-27 20:10:191092template <class _R>
1093future<_R>::~future()
1094{
1095 if (__state_)
1096 __state_->__release_shared();
1097}
1098
1099template <class _R>
1100_R
1101future<_R>::get()
1102{
Howard Hinnant54da3382010-08-30 18:46:211103 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant47499b12010-08-27 20:10:191104 __assoc_state<_R>* __s = __state_;
1105 __state_ = nullptr;
1106 return __s->move();
1107}
1108
1109template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:261110class _LIBCPP_VISIBLE future<_R&>
Howard Hinnant47499b12010-08-27 20:10:191111{
1112 __assoc_state<_R&>* __state_;
1113
1114 explicit future(__assoc_state<_R&>* __state);
1115
1116 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:251117 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:211118
Howard Hinnant73d21a42010-09-04 23:28:191119#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant57cff292011-05-19 15:05:041120 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:211121 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
Howard Hinnant57cff292011-05-19 15:05:041122 template <class _R1, class _F>
1123 friend future<_R1> __make_async_assoc_state(_F&& __f);
Howard Hinnant54da3382010-08-30 18:46:211124#else
Howard Hinnant57cff292011-05-19 15:05:041125 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:211126 friend future<_R1> __make_deferred_assoc_state(_F __f);
Howard Hinnant57cff292011-05-19 15:05:041127 template <class _R1, class _F>
1128 friend future<_R1> __make_async_assoc_state(_F __f);
Howard Hinnant54da3382010-08-30 18:46:211129#endif
1130
Howard Hinnant47499b12010-08-27 20:10:191131public:
Howard Hinnant8c6cbb22010-09-22 14:16:261132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191133 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:191134#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191136 future(future&& __rhs)
1137 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1138 future(const future&) = delete;
1139 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:261140 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191141 future& operator=(future&& __rhs)
1142 {
1143 future(std::move(__rhs)).swap(*this);
1144 return *this;
1145 }
Howard Hinnant73d21a42010-09-04 23:28:191146#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191147private:
1148 future(const future&);
1149 future& operator=(const future&);
1150public:
Howard Hinnant73d21a42010-09-04 23:28:191151#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191152 ~future();
Howard Hinnant7de47902010-11-30 20:23:321153 shared_future<_R&> share();
Howard Hinnant47499b12010-08-27 20:10:191154
1155 // retrieving the value
1156 _R& get();
1157
Howard Hinnant8c6cbb22010-09-22 14:16:261158 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191159 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191160
1161 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:261162 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191163 bool valid() const {return __state_ != nullptr;}
1164
Howard Hinnant8c6cbb22010-09-22 14:16:261165 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191166 void wait() const {__state_->wait();}
1167 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:261168 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191169 future_status
1170 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1171 {return __state_->wait_for(__rel_time);}
1172 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:261173 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191174 future_status
1175 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1176 {return __state_->wait_until(__abs_time);}
1177};
1178
1179template <class _R>
1180future<_R&>::future(__assoc_state<_R&>* __state)
1181 : __state_(__state)
1182{
Howard Hinnant22ba71b2011-07-13 16:00:501183#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191184 if (__state_->__has_future_attached())
1185 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:501186#endif
Howard Hinnant47499b12010-08-27 20:10:191187 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:211188 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:191189}
1190
1191template <class _R>
1192future<_R&>::~future()
1193{
1194 if (__state_)
1195 __state_->__release_shared();
1196}
1197
1198template <class _R>
1199_R&
1200future<_R&>::get()
1201{
Howard Hinnant54da3382010-08-30 18:46:211202 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantf39daa82010-08-28 21:01:061203 __assoc_state<_R&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:191204 __state_ = nullptr;
1205 return __s->copy();
1206}
1207
1208template <>
Howard Hinnant8c6cbb22010-09-22 14:16:261209class _LIBCPP_VISIBLE future<void>
Howard Hinnant47499b12010-08-27 20:10:191210{
1211 __assoc_sub_state* __state_;
1212
1213 explicit future(__assoc_sub_state* __state);
1214
1215 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:251216 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:211217
Howard Hinnant73d21a42010-09-04 23:28:191218#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant57cff292011-05-19 15:05:041219 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:211220 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
Howard Hinnant57cff292011-05-19 15:05:041221 template <class _R1, class _F>
1222 friend future<_R1> __make_async_assoc_state(_F&& __f);
Howard Hinnant54da3382010-08-30 18:46:211223#else
Howard Hinnant57cff292011-05-19 15:05:041224 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:211225 friend future<_R1> __make_deferred_assoc_state(_F __f);
Howard Hinnant57cff292011-05-19 15:05:041226 template <class _R1, class _F>
1227 friend future<_R1> __make_async_assoc_state(_F __f);
Howard Hinnant54da3382010-08-30 18:46:211228#endif
1229
Howard Hinnant47499b12010-08-27 20:10:191230public:
Howard Hinnant8c6cbb22010-09-22 14:16:261231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191232 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:191233#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191235 future(future&& __rhs)
1236 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1237 future(const future&) = delete;
1238 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:261239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191240 future& operator=(future&& __rhs)
1241 {
1242 future(std::move(__rhs)).swap(*this);
1243 return *this;
1244 }
Howard Hinnant73d21a42010-09-04 23:28:191245#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191246private:
1247 future(const future&);
1248 future& operator=(const future&);
1249public:
Howard Hinnant73d21a42010-09-04 23:28:191250#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191251 ~future();
Howard Hinnant7de47902010-11-30 20:23:321252 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:191253
1254 // retrieving the value
1255 void get();
1256
Howard Hinnant8c6cbb22010-09-22 14:16:261257 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191258 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191259
1260 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:261261 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191262 bool valid() const {return __state_ != nullptr;}
1263
Howard Hinnant8c6cbb22010-09-22 14:16:261264 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191265 void wait() const {__state_->wait();}
1266 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:261267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191268 future_status
1269 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1270 {return __state_->wait_for(__rel_time);}
1271 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:261272 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191273 future_status
1274 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1275 {return __state_->wait_until(__abs_time);}
1276};
1277
Howard Hinnant99be8232010-09-03 18:39:251278template <class _R>
1279inline _LIBCPP_INLINE_VISIBILITY
1280void
1281swap(future<_R>& __x, future<_R>& __y)
1282{
1283 __x.swap(__y);
1284}
1285
Howard Hinnant47499b12010-08-27 20:10:191286// promise<R>
1287
Howard Hinnant2b1b2d42011-06-14 19:58:171288template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:211289
Howard Hinnant47499b12010-08-27 20:10:191290template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:261291class _LIBCPP_VISIBLE promise
Howard Hinnant47499b12010-08-27 20:10:191292{
1293 __assoc_state<_R>* __state_;
Howard Hinnant54da3382010-08-30 18:46:211294
Howard Hinnant8c6cbb22010-09-22 14:16:261295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211296 explicit promise(nullptr_t) : __state_(nullptr) {}
1297
1298 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:191299public:
1300 promise();
1301 template <class _Alloc>
1302 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:191303#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191305 promise(promise&& __rhs)
1306 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1307 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191308#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191309private:
1310 promise(const promise& __rhs);
1311public:
Howard Hinnant73d21a42010-09-04 23:28:191312#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191313 ~promise();
1314
1315 // assignment
Howard Hinnant73d21a42010-09-04 23:28:191316#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191318 promise& operator=(promise&& __rhs)
1319 {
1320 promise(std::move(__rhs)).swap(*this);
1321 return *this;
1322 }
1323 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191324#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191325private:
1326 promise& operator=(const promise& __rhs);
1327public:
Howard Hinnant73d21a42010-09-04 23:28:191328#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191330 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191331
1332 // retrieving the result
1333 future<_R> get_future();
1334
1335 // setting the result
1336 void set_value(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:191337#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191338 void set_value(_R&& __r);
1339#endif
1340 void set_exception(exception_ptr __p);
1341
1342 // setting the result with deferred notification
1343 void set_value_at_thread_exit(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:191344#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191345 void set_value_at_thread_exit(_R&& __r);
1346#endif
1347 void set_exception_at_thread_exit(exception_ptr __p);
1348};
1349
1350template <class _R>
1351promise<_R>::promise()
1352 : __state_(new __assoc_state<_R>)
1353{
1354}
1355
1356template <class _R>
1357template <class _Alloc>
1358promise<_R>::promise(allocator_arg_t, const _Alloc& __a0)
1359{
1360 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R, _Alloc> >::other _A2;
1361 typedef __allocator_destructor<_A2> _D2;
1362 _A2 __a(__a0);
1363 unique_ptr<__assoc_state_alloc<_R, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1364 ::new(__hold.get()) __assoc_state_alloc<_R, _Alloc>(__a0);
1365 __state_ = __hold.release();
1366}
1367
1368template <class _R>
1369promise<_R>::~promise()
1370{
1371 if (__state_)
1372 {
1373 if (!__state_->__has_value() && __state_->use_count() > 1)
1374 __state_->set_exception(make_exception_ptr(
1375 future_error(make_error_code(future_errc::broken_promise))
1376 ));
1377 __state_->__release_shared();
1378 }
1379}
1380
1381template <class _R>
1382future<_R>
1383promise<_R>::get_future()
1384{
Howard Hinnant22ba71b2011-07-13 16:00:501385#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191386 if (__state_ == nullptr)
1387 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501388#endif
Howard Hinnant47499b12010-08-27 20:10:191389 return future<_R>(__state_);
1390}
1391
1392template <class _R>
1393void
1394promise<_R>::set_value(const _R& __r)
1395{
Howard Hinnant22ba71b2011-07-13 16:00:501396#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191397 if (__state_ == nullptr)
1398 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501399#endif
Howard Hinnant47499b12010-08-27 20:10:191400 __state_->set_value(__r);
1401}
1402
Howard Hinnant73d21a42010-09-04 23:28:191403#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191404
1405template <class _R>
1406void
1407promise<_R>::set_value(_R&& __r)
1408{
Howard Hinnant22ba71b2011-07-13 16:00:501409#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191410 if (__state_ == nullptr)
1411 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501412#endif
Howard Hinnant0949eed2011-06-30 21:18:191413 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:191414}
1415
Howard Hinnant73d21a42010-09-04 23:28:191416#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191417
1418template <class _R>
1419void
1420promise<_R>::set_exception(exception_ptr __p)
1421{
Howard Hinnant22ba71b2011-07-13 16:00:501422#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191423 if (__state_ == nullptr)
1424 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501425#endif
Howard Hinnant47499b12010-08-27 20:10:191426 __state_->set_exception(__p);
1427}
1428
1429template <class _R>
1430void
1431promise<_R>::set_value_at_thread_exit(const _R& __r)
1432{
Howard Hinnant22ba71b2011-07-13 16:00:501433#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191434 if (__state_ == nullptr)
1435 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501436#endif
Howard Hinnant47499b12010-08-27 20:10:191437 __state_->set_value_at_thread_exit(__r);
1438}
1439
Howard Hinnant73d21a42010-09-04 23:28:191440#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191441
1442template <class _R>
1443void
1444promise<_R>::set_value_at_thread_exit(_R&& __r)
1445{
Howard Hinnant22ba71b2011-07-13 16:00:501446#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191447 if (__state_ == nullptr)
1448 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501449#endif
Howard Hinnant0949eed2011-06-30 21:18:191450 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:191451}
1452
Howard Hinnant73d21a42010-09-04 23:28:191453#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191454
1455template <class _R>
1456void
1457promise<_R>::set_exception_at_thread_exit(exception_ptr __p)
1458{
Howard Hinnant22ba71b2011-07-13 16:00:501459#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191460 if (__state_ == nullptr)
1461 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501462#endif
Howard Hinnant47499b12010-08-27 20:10:191463 __state_->set_exception_at_thread_exit(__p);
1464}
1465
1466// promise<R&>
1467
1468template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:261469class _LIBCPP_VISIBLE promise<_R&>
Howard Hinnant47499b12010-08-27 20:10:191470{
1471 __assoc_state<_R&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:211472
Howard Hinnant8c6cbb22010-09-22 14:16:261473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211474 explicit promise(nullptr_t) : __state_(nullptr) {}
1475
1476 template <class> friend class packaged_task;
1477
Howard Hinnant47499b12010-08-27 20:10:191478public:
1479 promise();
1480 template <class _Allocator>
1481 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:191482#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191484 promise(promise&& __rhs)
1485 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1486 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191487#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191488private:
1489 promise(const promise& __rhs);
1490public:
Howard Hinnant73d21a42010-09-04 23:28:191491#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191492 ~promise();
1493
1494 // assignment
Howard Hinnant73d21a42010-09-04 23:28:191495#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261496 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191497 promise& operator=(promise&& __rhs)
1498 {
1499 promise(std::move(__rhs)).swap(*this);
1500 return *this;
1501 }
1502 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191503#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191504private:
1505 promise& operator=(const promise& __rhs);
1506public:
Howard Hinnant73d21a42010-09-04 23:28:191507#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261508 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191509 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191510
1511 // retrieving the result
1512 future<_R&> get_future();
1513
1514 // setting the result
1515 void set_value(_R& __r);
1516 void set_exception(exception_ptr __p);
1517
1518 // setting the result with deferred notification
1519 void set_value_at_thread_exit(_R&);
1520 void set_exception_at_thread_exit(exception_ptr __p);
1521};
1522
1523template <class _R>
1524promise<_R&>::promise()
1525 : __state_(new __assoc_state<_R&>)
1526{
1527}
1528
1529template <class _R>
1530template <class _Alloc>
1531promise<_R&>::promise(allocator_arg_t, const _Alloc& __a0)
1532{
1533 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R&, _Alloc> >::other _A2;
1534 typedef __allocator_destructor<_A2> _D2;
1535 _A2 __a(__a0);
1536 unique_ptr<__assoc_state_alloc<_R&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1537 ::new(__hold.get()) __assoc_state_alloc<_R&, _Alloc>(__a0);
1538 __state_ = __hold.release();
1539}
1540
1541template <class _R>
1542promise<_R&>::~promise()
1543{
1544 if (__state_)
1545 {
1546 if (!__state_->__has_value() && __state_->use_count() > 1)
1547 __state_->set_exception(make_exception_ptr(
1548 future_error(make_error_code(future_errc::broken_promise))
1549 ));
1550 __state_->__release_shared();
1551 }
1552}
1553
1554template <class _R>
1555future<_R&>
1556promise<_R&>::get_future()
1557{
Howard Hinnant22ba71b2011-07-13 16:00:501558#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191559 if (__state_ == nullptr)
1560 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501561#endif
Howard Hinnant47499b12010-08-27 20:10:191562 return future<_R&>(__state_);
1563}
1564
1565template <class _R>
1566void
1567promise<_R&>::set_value(_R& __r)
1568{
Howard Hinnant22ba71b2011-07-13 16:00:501569#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191570 if (__state_ == nullptr)
1571 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501572#endif
Howard Hinnant47499b12010-08-27 20:10:191573 __state_->set_value(__r);
1574}
1575
1576template <class _R>
1577void
1578promise<_R&>::set_exception(exception_ptr __p)
1579{
Howard Hinnant22ba71b2011-07-13 16:00:501580#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191581 if (__state_ == nullptr)
1582 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501583#endif
Howard Hinnant47499b12010-08-27 20:10:191584 __state_->set_exception(__p);
1585}
1586
1587template <class _R>
1588void
1589promise<_R&>::set_value_at_thread_exit(_R& __r)
1590{
Howard Hinnant22ba71b2011-07-13 16:00:501591#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191592 if (__state_ == nullptr)
1593 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501594#endif
Howard Hinnant47499b12010-08-27 20:10:191595 __state_->set_value_at_thread_exit(__r);
1596}
1597
1598template <class _R>
1599void
1600promise<_R&>::set_exception_at_thread_exit(exception_ptr __p)
1601{
Howard Hinnant22ba71b2011-07-13 16:00:501602#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191603 if (__state_ == nullptr)
1604 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501605#endif
Howard Hinnant47499b12010-08-27 20:10:191606 __state_->set_exception_at_thread_exit(__p);
1607}
1608
1609// promise<void>
1610
1611template <>
Howard Hinnant8c6cbb22010-09-22 14:16:261612class _LIBCPP_VISIBLE promise<void>
Howard Hinnant47499b12010-08-27 20:10:191613{
1614 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:211615
Howard Hinnant8c6cbb22010-09-22 14:16:261616 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211617 explicit promise(nullptr_t) : __state_(nullptr) {}
1618
1619 template <class> friend class packaged_task;
1620
Howard Hinnant47499b12010-08-27 20:10:191621public:
1622 promise();
1623 template <class _Allocator>
1624 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:191625#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261626 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191627 promise(promise&& __rhs)
1628 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1629 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191630#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191631private:
1632 promise(const promise& __rhs);
1633public:
Howard Hinnant73d21a42010-09-04 23:28:191634#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191635 ~promise();
1636
1637 // assignment
Howard Hinnant73d21a42010-09-04 23:28:191638#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261639 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191640 promise& operator=(promise&& __rhs)
1641 {
1642 promise(std::move(__rhs)).swap(*this);
1643 return *this;
1644 }
1645 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191646#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191647private:
1648 promise& operator=(const promise& __rhs);
1649public:
Howard Hinnant73d21a42010-09-04 23:28:191650#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261651 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191652 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191653
1654 // retrieving the result
1655 future<void> get_future();
1656
1657 // setting the result
1658 void set_value();
1659 void set_exception(exception_ptr __p);
1660
1661 // setting the result with deferred notification
1662 void set_value_at_thread_exit();
1663 void set_exception_at_thread_exit(exception_ptr __p);
1664};
1665
1666template <class _Alloc>
1667promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1668{
1669 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1670 typedef __allocator_destructor<_A2> _D2;
1671 _A2 __a(__a0);
1672 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1673 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1674 __state_ = __hold.release();
1675}
1676
1677template <class _R>
1678inline _LIBCPP_INLINE_VISIBILITY
1679void
1680swap(promise<_R>& __x, promise<_R>& __y)
1681{
1682 __x.swap(__y);
1683}
1684
1685template <class _R, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:261686 struct _LIBCPP_VISIBLE uses_allocator<promise<_R>, _Alloc>
1687 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:191688
Howard Hinnant54da3382010-08-30 18:46:211689#ifndef _LIBCPP_HAS_NO_VARIADICS
1690
1691// packaged_task
1692
1693template<class _Fp> class __packaged_task_base;
1694
1695template<class _R, class ..._ArgTypes>
1696class __packaged_task_base<_R(_ArgTypes...)>
1697{
1698 __packaged_task_base(const __packaged_task_base&);
1699 __packaged_task_base& operator=(const __packaged_task_base&);
1700public:
Howard Hinnant8c6cbb22010-09-22 14:16:261701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211702 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:261703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211704 virtual ~__packaged_task_base() {}
1705 virtual void __move_to(__packaged_task_base*) = 0;
1706 virtual void destroy() = 0;
1707 virtual void destroy_deallocate() = 0;
1708 virtual _R operator()(_ArgTypes&& ...) = 0;
1709};
1710
1711template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1712
1713template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1714class __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>
1715 : public __packaged_task_base<_R(_ArgTypes...)>
1716{
1717 __compressed_pair<_F, _Alloc> __f_;
1718public:
Howard Hinnant8c6cbb22010-09-22 14:16:261719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211720 explicit __packaged_task_func(const _F& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191722 explicit __packaged_task_func(_F&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211724 __packaged_task_func(const _F& __f, const _Alloc& __a)
1725 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211727 __packaged_task_func(_F&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:191728 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant54da3382010-08-30 18:46:211729 virtual void __move_to(__packaged_task_base<_R(_ArgTypes...)>*);
1730 virtual void destroy();
1731 virtual void destroy_deallocate();
1732 virtual _R operator()(_ArgTypes&& ... __args);
1733};
1734
1735template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1736void
1737__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::__move_to(
1738 __packaged_task_base<_R(_ArgTypes...)>* __p)
1739{
Howard Hinnant0949eed2011-06-30 21:18:191740 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:211741}
1742
1743template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1744void
1745__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy()
1746{
1747 __f_.~__compressed_pair<_F, _Alloc>();
1748}
1749
1750template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1751void
1752__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy_deallocate()
1753{
1754 typedef typename _Alloc::template rebind<__packaged_task_func>::other _A;
1755 _A __a(__f_.second());
1756 __f_.~__compressed_pair<_F, _Alloc>();
1757 __a.deallocate(this, 1);
1758}
1759
1760template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1761_R
1762__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1763{
Howard Hinnant0949eed2011-06-30 21:18:191764 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:211765}
1766
Howard Hinnant2b1b2d42011-06-14 19:58:171767template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:211768
1769template<class _R, class ..._ArgTypes>
1770class __packaged_task_function<_R(_ArgTypes...)>
1771{
1772 typedef __packaged_task_base<_R(_ArgTypes...)> __base;
1773 aligned_storage<3*sizeof(void*)>::type __buf_;
1774 __base* __f_;
1775
1776public:
1777 typedef _R result_type;
1778
1779 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:261780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211781 __packaged_task_function() : __f_(nullptr) {}
1782 template<class _F>
1783 __packaged_task_function(_F&& __f);
1784 template<class _F, class _Alloc>
1785 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _F&& __f);
1786
1787 __packaged_task_function(__packaged_task_function&&);
1788 __packaged_task_function& operator=(__packaged_task_function&&);
1789
1790 __packaged_task_function(const __packaged_task_function&) = delete;
1791 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1792
1793 ~__packaged_task_function();
1794
1795 void swap(__packaged_task_function&);
1796
1797 _R operator()(_ArgTypes...) const;
1798};
1799
1800template<class _R, class ..._ArgTypes>
1801__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f)
1802{
1803 if (__f.__f_ == nullptr)
1804 __f_ = nullptr;
1805 else if (__f.__f_ == (__base*)&__f.__buf_)
1806 {
1807 __f_ = (__base*)&__buf_;
1808 __f.__f_->__move_to(__f_);
1809 }
1810 else
1811 {
1812 __f_ = __f.__f_;
1813 __f.__f_ = nullptr;
1814 }
1815}
1816
1817template<class _R, class ..._ArgTypes>
1818template <class _F>
1819__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(_F&& __f)
1820 : __f_(nullptr)
1821{
1822 typedef typename remove_reference<_F>::type _FR;
1823 typedef __packaged_task_func<_FR, allocator<_FR>, _R(_ArgTypes...)> _FF;
1824 if (sizeof(_FF) <= sizeof(__buf_))
1825 {
1826 __f_ = (__base*)&__buf_;
Howard Hinnant0949eed2011-06-30 21:18:191827 ::new (__f_) _FF(_VSTD::forward<_F>(__f));
Howard Hinnant54da3382010-08-30 18:46:211828 }
1829 else
1830 {
1831 typedef allocator<_FF> _A;
1832 _A __a;
1833 typedef __allocator_destructor<_A> _D;
1834 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:191835 ::new (__hold.get()) _FF(_VSTD::forward<_F>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:211836 __f_ = __hold.release();
1837 }
1838}
1839
1840template<class _R, class ..._ArgTypes>
1841template <class _F, class _Alloc>
1842__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(
1843 allocator_arg_t, const _Alloc& __a0, _F&& __f)
1844 : __f_(nullptr)
1845{
1846 typedef allocator_traits<_Alloc> __alloc_traits;
1847 typedef typename remove_reference<_F>::type _FR;
1848 typedef __packaged_task_func<_FR, _Alloc, _R(_ArgTypes...)> _FF;
1849 if (sizeof(_FF) <= sizeof(__buf_))
1850 {
1851 __f_ = (__base*)&__buf_;
Howard Hinnant0949eed2011-06-30 21:18:191852 ::new (__f_) _FF(_VSTD::forward<_F>(__f));
Howard Hinnant54da3382010-08-30 18:46:211853 }
1854 else
1855 {
1856 typedef typename __alloc_traits::template
1857#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1858 rebind_alloc<_FF>
1859#else
1860 rebind_alloc<_FF>::other
1861#endif
1862 _A;
1863 _A __a(__a0);
1864 typedef __allocator_destructor<_A> _D;
1865 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:191866 ::new (__hold.get()) _FF(_VSTD::forward<_F>(__f), _Alloc(__a));
Howard Hinnant54da3382010-08-30 18:46:211867 __f_ = __hold.release();
1868 }
1869}
1870
1871template<class _R, class ..._ArgTypes>
1872__packaged_task_function<_R(_ArgTypes...)>&
1873__packaged_task_function<_R(_ArgTypes...)>::operator=(__packaged_task_function&& __f)
1874{
1875 if (__f_ == (__base*)&__buf_)
1876 __f_->destroy();
1877 else if (__f_)
1878 __f_->destroy_deallocate();
1879 __f_ = nullptr;
1880 if (__f.__f_ == nullptr)
1881 __f_ = nullptr;
1882 else if (__f.__f_ == (__base*)&__f.__buf_)
1883 {
1884 __f_ = (__base*)&__buf_;
1885 __f.__f_->__move_to(__f_);
1886 }
1887 else
1888 {
1889 __f_ = __f.__f_;
1890 __f.__f_ = nullptr;
1891 }
1892}
1893
1894template<class _R, class ..._ArgTypes>
1895__packaged_task_function<_R(_ArgTypes...)>::~__packaged_task_function()
1896{
1897 if (__f_ == (__base*)&__buf_)
1898 __f_->destroy();
1899 else if (__f_)
1900 __f_->destroy_deallocate();
1901}
1902
1903template<class _R, class ..._ArgTypes>
1904void
1905__packaged_task_function<_R(_ArgTypes...)>::swap(__packaged_task_function& __f)
1906{
1907 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1908 {
1909 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1910 __base* __t = (__base*)&__tempbuf;
1911 __f_->__move_to(__t);
1912 __f_->destroy();
1913 __f_ = nullptr;
1914 __f.__f_->__move_to((__base*)&__buf_);
1915 __f.__f_->destroy();
1916 __f.__f_ = nullptr;
1917 __f_ = (__base*)&__buf_;
1918 __t->__move_to((__base*)&__f.__buf_);
1919 __t->destroy();
1920 __f.__f_ = (__base*)&__f.__buf_;
1921 }
1922 else if (__f_ == (__base*)&__buf_)
1923 {
1924 __f_->__move_to((__base*)&__f.__buf_);
1925 __f_->destroy();
1926 __f_ = __f.__f_;
1927 __f.__f_ = (__base*)&__f.__buf_;
1928 }
1929 else if (__f.__f_ == (__base*)&__f.__buf_)
1930 {
1931 __f.__f_->__move_to((__base*)&__buf_);
1932 __f.__f_->destroy();
1933 __f.__f_ = __f_;
1934 __f_ = (__base*)&__buf_;
1935 }
1936 else
Howard Hinnant0949eed2011-06-30 21:18:191937 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:211938}
1939
1940template<class _R, class ..._ArgTypes>
1941inline _LIBCPP_INLINE_VISIBILITY
1942_R
1943__packaged_task_function<_R(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1944{
Howard Hinnant0949eed2011-06-30 21:18:191945 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:211946}
1947
1948template<class _R, class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:261949class _LIBCPP_VISIBLE packaged_task<_R(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:211950{
1951public:
1952 typedef _R result_type;
1953
1954private:
1955 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1956 promise<result_type> __p_;
1957
1958public:
1959 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:261960 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211961 packaged_task() : __p_(nullptr) {}
1962 template <class _F>
Howard Hinnant8c6cbb22010-09-22 14:16:261963 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:191964 explicit packaged_task(_F&& __f) : __f_(_VSTD::forward<_F>(__f)) {}
Howard Hinnant54da3382010-08-30 18:46:211965 template <class _F, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:261966 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211967 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
Howard Hinnant0949eed2011-06-30 21:18:191968 : __f_(allocator_arg, __a, _VSTD::forward<_F>(__f)),
Howard Hinnant54da3382010-08-30 18:46:211969 __p_(allocator_arg, __a) {}
1970 // ~packaged_task() = default;
1971
1972 // no copy
1973 packaged_task(packaged_task&) = delete;
1974 packaged_task& operator=(packaged_task&) = delete;
1975
1976 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:261977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211978 packaged_task(packaged_task&& __other)
Howard Hinnant0949eed2011-06-30 21:18:191979 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261980 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211981 packaged_task& operator=(packaged_task&& __other)
1982 {
Howard Hinnant0949eed2011-06-30 21:18:191983 __f_ = _VSTD::move(__other.__f_);
1984 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:211985 return *this;
1986 }
Howard Hinnant8c6cbb22010-09-22 14:16:261987 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211988 void swap(packaged_task& __other)
1989 {
1990 __f_.swap(__other.__f_);
1991 __p_.swap(__other.__p_);
1992 }
1993
Howard Hinnant8c6cbb22010-09-22 14:16:261994 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:321995 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:211996
1997 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:261998 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211999 future<result_type> get_future() {return __p_.get_future();}
2000
2001 // execution
2002 void operator()(_ArgTypes... __args);
2003 void make_ready_at_thread_exit(_ArgTypes... __args);
2004
2005 void reset();
2006};
2007
2008template<class _R, class ..._ArgTypes>
2009void
2010packaged_task<_R(_ArgTypes...)>::operator()(_ArgTypes... __args)
2011{
2012#ifndef _LIBCPP_NO_EXCEPTIONS
2013 if (__p_.__state_ == nullptr)
2014 throw future_error(make_error_code(future_errc::no_state));
2015 if (__p_.__state_->__has_value())
2016 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2017 try
2018 {
2019#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192020 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:212021#ifndef _LIBCPP_NO_EXCEPTIONS
2022 }
2023 catch (...)
2024 {
2025 __p_.set_exception(current_exception());
2026 }
2027#endif // _LIBCPP_NO_EXCEPTIONS
2028}
2029
2030template<class _R, class ..._ArgTypes>
2031void
2032packaged_task<_R(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2033{
2034#ifndef _LIBCPP_NO_EXCEPTIONS
2035 if (__p_.__state_ == nullptr)
2036 throw future_error(make_error_code(future_errc::no_state));
2037 if (__p_.__state_->__has_value())
2038 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2039 try
2040 {
2041#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192042 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:212043#ifndef _LIBCPP_NO_EXCEPTIONS
2044 }
2045 catch (...)
2046 {
2047 __p_.set_exception_at_thread_exit(current_exception());
2048 }
2049#endif // _LIBCPP_NO_EXCEPTIONS
2050}
2051
2052template<class _R, class ..._ArgTypes>
2053void
2054packaged_task<_R(_ArgTypes...)>::reset()
2055{
2056#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:322057 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:212058 throw future_error(make_error_code(future_errc::no_state));
2059#endif // _LIBCPP_NO_EXCEPTIONS
2060 __p_ = promise<result_type>();
2061}
2062
2063template<class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:262064class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:212065{
2066public:
2067 typedef void result_type;
2068
2069private:
2070 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2071 promise<result_type> __p_;
2072
2073public:
2074 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:262075 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:212076 packaged_task() : __p_(nullptr) {}
2077 template <class _F>
Howard Hinnant8c6cbb22010-09-22 14:16:262078 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:192079 explicit packaged_task(_F&& __f) : __f_(_VSTD::forward<_F>(__f)) {}
Howard Hinnant54da3382010-08-30 18:46:212080 template <class _F, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:262081 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:212082 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
Howard Hinnant0949eed2011-06-30 21:18:192083 : __f_(allocator_arg, __a, _VSTD::forward<_F>(__f)),
Howard Hinnant54da3382010-08-30 18:46:212084 __p_(allocator_arg, __a) {}
2085 // ~packaged_task() = default;
2086
2087 // no copy
2088 packaged_task(packaged_task&) = delete;
2089 packaged_task& operator=(packaged_task&) = delete;
2090
2091 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:262092 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:212093 packaged_task(packaged_task&& __other)
Howard Hinnant0949eed2011-06-30 21:18:192094 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262095 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:212096 packaged_task& operator=(packaged_task&& __other)
2097 {
Howard Hinnant0949eed2011-06-30 21:18:192098 __f_ = _VSTD::move(__other.__f_);
2099 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:212100 return *this;
2101 }
Howard Hinnant8c6cbb22010-09-22 14:16:262102 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:212103 void swap(packaged_task& __other)
2104 {
2105 __f_.swap(__other.__f_);
2106 __p_.swap(__other.__p_);
2107 }
2108
Howard Hinnant8c6cbb22010-09-22 14:16:262109 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:322110 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:212111
2112 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:262113 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:212114 future<result_type> get_future() {return __p_.get_future();}
2115
2116 // execution
2117 void operator()(_ArgTypes... __args);
2118 void make_ready_at_thread_exit(_ArgTypes... __args);
2119
2120 void reset();
2121};
2122
2123template<class ..._ArgTypes>
2124void
2125packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2126{
2127#ifndef _LIBCPP_NO_EXCEPTIONS
2128 if (__p_.__state_ == nullptr)
2129 throw future_error(make_error_code(future_errc::no_state));
2130 if (__p_.__state_->__has_value())
2131 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2132 try
2133 {
2134#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192135 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:212136 __p_.set_value();
2137#ifndef _LIBCPP_NO_EXCEPTIONS
2138 }
2139 catch (...)
2140 {
2141 __p_.set_exception(current_exception());
2142 }
2143#endif // _LIBCPP_NO_EXCEPTIONS
2144}
2145
2146template<class ..._ArgTypes>
2147void
2148packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2149{
2150#ifndef _LIBCPP_NO_EXCEPTIONS
2151 if (__p_.__state_ == nullptr)
2152 throw future_error(make_error_code(future_errc::no_state));
2153 if (__p_.__state_->__has_value())
2154 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2155 try
2156 {
2157#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192158 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:212159 __p_.set_value_at_thread_exit();
2160#ifndef _LIBCPP_NO_EXCEPTIONS
2161 }
2162 catch (...)
2163 {
2164 __p_.set_exception_at_thread_exit(current_exception());
2165 }
2166#endif // _LIBCPP_NO_EXCEPTIONS
2167}
2168
2169template<class ..._ArgTypes>
2170void
2171packaged_task<void(_ArgTypes...)>::reset()
2172{
2173#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:322174 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:212175 throw future_error(make_error_code(future_errc::no_state));
2176#endif // _LIBCPP_NO_EXCEPTIONS
2177 __p_ = promise<result_type>();
2178}
2179
2180template <class _Callable>
2181inline _LIBCPP_INLINE_VISIBILITY
2182void
2183swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y)
2184{
2185 __x.swap(__y);
2186}
2187
2188template <class _Callable, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:262189struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2190 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:212191
2192template <class _R, class _F>
2193future<_R>
Howard Hinnant73d21a42010-09-04 23:28:192194#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:212195__make_deferred_assoc_state(_F&& __f)
2196#else
2197__make_deferred_assoc_state(_F __f)
2198#endif
2199{
2200 unique_ptr<__deferred_assoc_state<_R, _F>, __release_shared_count>
Howard Hinnant0949eed2011-06-30 21:18:192201 __h(new __deferred_assoc_state<_R, _F>(_VSTD::forward<_F>(__f)));
Howard Hinnant54da3382010-08-30 18:46:212202 return future<_R>(__h.get());
2203}
2204
Howard Hinnant57cff292011-05-19 15:05:042205template <class _R, class _F>
2206future<_R>
2207#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2208__make_async_assoc_state(_F&& __f)
2209#else
2210__make_async_assoc_state(_F __f)
2211#endif
2212{
2213 unique_ptr<__async_assoc_state<_R, _F>, __release_shared_count>
Howard Hinnant0949eed2011-06-30 21:18:192214 __h(new __async_assoc_state<_R, _F>(_VSTD::forward<_F>(__f)));
2215 _VSTD::thread(&__async_assoc_state<_R, _F>::__execute, __h.get()).detach();
Howard Hinnant57cff292011-05-19 15:05:042216 return future<_R>(__h.get());
2217}
2218
Howard Hinnant54da3382010-08-30 18:46:212219template <class _F, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:042220class __async_func
2221{
2222 tuple<_F, _Args...> __f_;
2223
2224public:
2225 typedef typename __invoke_of<_F, _Args...>::type _R;
2226
2227 _LIBCPP_INLINE_VISIBILITY
2228 explicit __async_func(_F&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:192229 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:042230
2231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:192232 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:042233
2234 _R operator()()
2235 {
2236 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2237 return __execute(_Index());
2238 }
2239private:
2240 template <size_t ..._Indices>
2241 _R
2242 __execute(__tuple_indices<_Indices...>)
2243 {
Howard Hinnant0949eed2011-06-30 21:18:192244 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:042245 }
2246};
2247
2248template <class _F, class... _Args>
2249future<typename __invoke_of<typename decay<_F>::type, typename decay<_Args>::type...>::type>
Howard Hinnant54da3382010-08-30 18:46:212250async(launch __policy, _F&& __f, _Args&&... __args)
2251{
Howard Hinnant57cff292011-05-19 15:05:042252 typedef __async_func<typename decay<_F>::type, typename decay<_Args>::type...> _BF;
2253 typedef typename _BF::_R _R;
Howard Hinnant54da3382010-08-30 18:46:212254 future<_R> __r;
Howard Hinnant66895642010-11-23 18:33:542255 if (__policy & launch::async)
Howard Hinnant0949eed2011-06-30 21:18:192256 __r = _VSTD::__make_async_assoc_state<_R>(_BF(__decay_copy(_VSTD::forward<_F>(__f)),
2257 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant66895642010-11-23 18:33:542258 else if (__policy & launch::deferred)
Howard Hinnant0949eed2011-06-30 21:18:192259 __r = _VSTD::__make_deferred_assoc_state<_R>(_BF(__decay_copy(_VSTD::forward<_F>(__f)),
2260 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:212261 return __r;
2262}
2263
2264template <class _F, class... _Args>
2265inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant57cff292011-05-19 15:05:042266future<typename __invoke_of<typename decay<_F>::type, typename decay<_Args>::type...>::type>
Howard Hinnant54da3382010-08-30 18:46:212267async(_F&& __f, _Args&&... __args)
2268{
Howard Hinnant0949eed2011-06-30 21:18:192269 return _VSTD::async(launch::any, _VSTD::forward<_F>(__f),
2270 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:212271}
2272
2273#endif // _LIBCPP_HAS_NO_VARIADICS
2274
Howard Hinnante6e4d012010-09-03 21:46:372275// shared_future
2276
Howard Hinnant99be8232010-09-03 18:39:252277template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:262278class _LIBCPP_VISIBLE shared_future
Howard Hinnant99be8232010-09-03 18:39:252279{
2280 __assoc_state<_R>* __state_;
2281
2282public:
Howard Hinnant8c6cbb22010-09-22 14:16:262283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252284 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252286 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2287 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:192288#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262289 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252290 shared_future(future<_R>&& __f) : __state_(__f.__state_)
2291 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:262292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252293 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2294 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:192295#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252296 ~shared_future();
2297 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:192298#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252300 shared_future& operator=(shared_future&& __rhs)
2301 {
2302 shared_future(std::move(__rhs)).swap(*this);
2303 return *this;
2304 }
Howard Hinnant73d21a42010-09-04 23:28:192305#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252306
2307 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:262308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252309 const _R& get() const {return __state_->copy();}
2310
Howard Hinnant8c6cbb22010-09-22 14:16:262311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:192312 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:252313
2314 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:262315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252316 bool valid() const {return __state_ != nullptr;}
2317
Howard Hinnant8c6cbb22010-09-22 14:16:262318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252319 void wait() const {__state_->wait();}
2320 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:262321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252322 future_status
2323 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2324 {return __state_->wait_for(__rel_time);}
2325 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:262326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252327 future_status
2328 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2329 {return __state_->wait_until(__abs_time);}
2330};
2331
2332template <class _R>
2333shared_future<_R>::~shared_future()
2334{
2335 if (__state_)
2336 __state_->__release_shared();
2337}
2338
2339template <class _R>
2340shared_future<_R>&
2341shared_future<_R>::operator=(const shared_future& __rhs)
2342{
2343 if (__rhs.__state_)
2344 __rhs.__state_->__add_shared();
2345 if (__state_)
2346 __state_->__release_shared();
2347 __state_ = __rhs.__state_;
2348 return *this;
2349}
2350
2351template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:262352class _LIBCPP_VISIBLE shared_future<_R&>
Howard Hinnant99be8232010-09-03 18:39:252353{
2354 __assoc_state<_R&>* __state_;
2355
2356public:
Howard Hinnant8c6cbb22010-09-22 14:16:262357 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252358 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262359 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252360 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2361 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:192362#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262363 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252364 shared_future(future<_R&>&& __f) : __state_(__f.__state_)
2365 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:262366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252367 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2368 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:192369#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252370 ~shared_future();
2371 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:192372#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262373 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252374 shared_future& operator=(shared_future&& __rhs)
2375 {
2376 shared_future(std::move(__rhs)).swap(*this);
2377 return *this;
2378 }
Howard Hinnant73d21a42010-09-04 23:28:192379#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252380
2381 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:262382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252383 _R& get() const {return __state_->copy();}
2384
Howard Hinnant8c6cbb22010-09-22 14:16:262385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:192386 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:252387
2388 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:262389 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252390 bool valid() const {return __state_ != nullptr;}
2391
Howard Hinnant8c6cbb22010-09-22 14:16:262392 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252393 void wait() const {__state_->wait();}
2394 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:262395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252396 future_status
2397 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2398 {return __state_->wait_for(__rel_time);}
2399 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:262400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252401 future_status
2402 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2403 {return __state_->wait_until(__abs_time);}
2404};
2405
2406template <class _R>
2407shared_future<_R&>::~shared_future()
2408{
2409 if (__state_)
2410 __state_->__release_shared();
2411}
2412
2413template <class _R>
2414shared_future<_R&>&
2415shared_future<_R&>::operator=(const shared_future& __rhs)
2416{
2417 if (__rhs.__state_)
2418 __rhs.__state_->__add_shared();
2419 if (__state_)
2420 __state_->__release_shared();
2421 __state_ = __rhs.__state_;
2422 return *this;
2423}
2424
2425template <>
Howard Hinnant8c6cbb22010-09-22 14:16:262426class _LIBCPP_VISIBLE shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:252427{
2428 __assoc_sub_state* __state_;
2429
2430public:
Howard Hinnant8c6cbb22010-09-22 14:16:262431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252432 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252434 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2435 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:192436#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262437 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252438 shared_future(future<void>&& __f) : __state_(__f.__state_)
2439 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:262440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252441 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2442 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:192443#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252444 ~shared_future();
2445 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:192446#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252448 shared_future& operator=(shared_future&& __rhs)
2449 {
2450 shared_future(std::move(__rhs)).swap(*this);
2451 return *this;
2452 }
Howard Hinnant73d21a42010-09-04 23:28:192453#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252454
2455 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:262456 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252457 void get() const {__state_->copy();}
2458
Howard Hinnant8c6cbb22010-09-22 14:16:262459 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:192460 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:252461
2462 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:262463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252464 bool valid() const {return __state_ != nullptr;}
2465
Howard Hinnant8c6cbb22010-09-22 14:16:262466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252467 void wait() const {__state_->wait();}
2468 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:262469 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252470 future_status
2471 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2472 {return __state_->wait_for(__rel_time);}
2473 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:262474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252475 future_status
2476 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2477 {return __state_->wait_until(__abs_time);}
2478};
2479
2480template <class _R>
2481inline _LIBCPP_INLINE_VISIBILITY
2482void
2483swap(shared_future<_R>& __x, shared_future<_R>& __y)
2484{
2485 __x.swap(__y);
2486}
2487
Howard Hinnante6e4d012010-09-03 21:46:372488template <class _R>
Howard Hinnant7de47902010-11-30 20:23:322489inline _LIBCPP_INLINE_VISIBILITY
2490shared_future<_R>
2491future<_R>::share()
Howard Hinnante6e4d012010-09-03 21:46:372492{
Howard Hinnant0949eed2011-06-30 21:18:192493 return shared_future<_R>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:372494}
2495
2496template <class _R>
Howard Hinnante6e4d012010-09-03 21:46:372497inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:322498shared_future<_R&>
2499future<_R&>::share()
Howard Hinnante6e4d012010-09-03 21:46:372500{
Howard Hinnant0949eed2011-06-30 21:18:192501 return shared_future<_R&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:322502}
2503
Howard Hinnanta4451512010-12-02 16:45:212504#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2505
Howard Hinnant7de47902010-11-30 20:23:322506inline _LIBCPP_INLINE_VISIBILITY
2507shared_future<void>
2508future<void>::share()
2509{
Howard Hinnant0949eed2011-06-30 21:18:192510 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:372511}
2512
Howard Hinnanta4451512010-12-02 16:45:212513#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2514
Howard Hinnantbc8d3f92010-05-11 19:42:162515_LIBCPP_END_NAMESPACE_STD
2516
2517#endif // _LIBCPP_FUTURE