blob: 0e61869f2786fccb91eb71a7983359761e508759 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// 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:16 +00008//
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:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000033};
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:19 +0000105 future<R&> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000106
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:19 +0000133 future<void> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000134
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:32 +0000159 shared_future<R> share() &&;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160
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:32 +0000186 shared_future<R&> share() &&;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000187
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:32 +0000213 shared_future<void> share() &&;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000214
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:25 +0000263 shared_future(future<R&>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000264 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:25 +0000290 shared_future(future<void>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000291 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:16 +0000311template <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:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320
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:16 +0000330 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:32 +0000344 bool valid() const;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000345
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:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372
Howard Hinnant08e17472011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000375#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376
377_LIBCPP_BEGIN_NAMESPACE_STD
378
379//enum class future_errc
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000380struct _LIBCPP_VISIBLE future_errc
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381{
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:26 +0000391 _LIBCPP_INLINE_VISIBILITY future_errc(_ __v) : __v_(__v) {}
392 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000393
394};
395
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000396template <>
397struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000398
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000399//enum class launch
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000400struct _LIBCPP_VISIBLE launch
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401{
402enum _ {
Howard Hinnant66895642010-11-23 18:33:54 +0000403 async = 1,
404 deferred = 2,
405 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000406};
407
408 _ __v_;
409
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000410 _LIBCPP_INLINE_VISIBILITY launch(_ __v) : __v_(__v) {}
411 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000412
413};
414
415//enum class future_status
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000416struct _LIBCPP_VISIBLE future_status
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000417{
418enum _ {
419 ready,
420 timeout,
421 deferred
422};
423
424 _ __v_;
425
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000426 _LIBCPP_INLINE_VISIBILITY future_status(_ __v) : __v_(__v) {}
427 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000428
429};
430
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000431_LIBCPP_VISIBLE
Howard Hinnanta6521722010-08-25 17:32:05 +0000432const 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:26 +0000448class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000449 : public logic_error
450{
451 error_code __ec_;
452public:
453 future_error(error_code __ec);
454
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta6521722010-08-25 17:32:05 +0000456 const error_code& code() const throw() {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52 +0000457
458 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000459};
460
Howard Hinnant47499b12010-08-27 20:10:19 +0000461class __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:13 +0000470 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000471 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000472public:
473 enum
474 {
475 __constructed = 1,
476 __future_attached = 2,
477 ready = 4,
478 deferred = 8
479 };
480
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000482 __assoc_sub_state() : __state_(0) {}
483
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000485 bool __has_value() const
486 {return (__state_ & __constructed) || (__exception_ != nullptr);}
487
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000488 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000489 void __set_future_attached() {__state_ |= __future_attached;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000490 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000491 bool __has_future_attached() const {return __state_ & __future_attached;}
492
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000493 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000494 void __set_deferred() {__state_ |= deferred;}
495
Howard Hinnant47499b12010-08-27 20:10:19 +0000496 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000497 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000498 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:21 +0000508 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000509 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:21 +0000515
516 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000517};
518
Howard Hinnantf39daa82010-08-28 21:01:06 +0000519template <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:21 +0000524 if (__state_ & deferred)
525 return future_status::deferred;
526 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000527 __cv_.wait_until(__lk, __abs_time);
528 if (__state_ & ready)
529 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000530 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:30 +0000538 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000539}
540
Howard Hinnant99968442011-11-29 18:15:50 +0000541template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000542class __assoc_state
543 : public __assoc_sub_state
544{
545 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000546 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000547protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000548 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000549
Howard Hinnant1694d232011-05-28 14:41:13 +0000550 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000551public:
552
553 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000554#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000555 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:19 +0000561#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000562 void set_value_at_thread_exit(_Arg&& __arg);
563#else
564 void set_value_at_thread_exit(_Arg& __arg);
565#endif
566
Howard Hinnant99968442011-11-29 18:15:50 +0000567 _Rp move();
568 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000569};
570
Howard Hinnant99968442011-11-29 18:15:50 +0000571template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000572void
Howard Hinnant99968442011-11-29 18:15:50 +0000573__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000574{
575 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000576 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000577 delete this;
578}
579
Howard Hinnant99968442011-11-29 18:15:50 +0000580template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000581template <class _Arg>
582void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000583#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000584__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000585#else
Howard Hinnant99968442011-11-29 18:15:50 +0000586__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000587#endif
588{
589 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000590#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000591 if (this->__has_value())
592 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000593#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000594 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000595 this->__state_ |= base::__constructed | base::ready;
596 __lk.unlock();
597 __cv_.notify_all();
598}
599
Howard Hinnant99968442011-11-29 18:15:50 +0000600template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000601template <class _Arg>
602void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000603#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000604__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000605#else
Howard Hinnant99968442011-11-29 18:15:50 +0000606__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000607#endif
608{
609 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000610#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000611 if (this->__has_value())
612 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000613#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000614 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000615 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000616 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000617 __lk.unlock();
618}
619
Howard Hinnant99968442011-11-29 18:15:50 +0000620template <class _Rp>
621_Rp
622__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000623{
624 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000625 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000626 if (this->__exception_ != nullptr)
627 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000628 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000629}
630
Howard Hinnant99968442011-11-29 18:15:50 +0000631template <class _Rp>
632typename add_lvalue_reference<_Rp>::type
633__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000634{
635 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000636 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000637 if (this->__exception_ != nullptr)
638 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000639 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000640}
641
Howard Hinnant99968442011-11-29 18:15:50 +0000642template <class _Rp>
643class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000644 : public __assoc_sub_state
645{
646 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000647 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000648protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000649 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000650
Howard Hinnant1694d232011-05-28 14:41:13 +0000651 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000652public:
653
Howard Hinnant99968442011-11-29 18:15:50 +0000654 void set_value(_Rp& __arg);
655 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000656
Howard Hinnant99968442011-11-29 18:15:50 +0000657 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000658};
659
Howard Hinnant99968442011-11-29 18:15:50 +0000660template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000661void
Howard Hinnant99968442011-11-29 18:15:50 +0000662__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000663{
664 delete this;
665}
666
Howard Hinnant99968442011-11-29 18:15:50 +0000667template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000668void
Howard Hinnant99968442011-11-29 18:15:50 +0000669__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000670{
671 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000672#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000673 if (this->__has_value())
674 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000675#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000676 __value_ = &__arg;
677 this->__state_ |= base::__constructed | base::ready;
678 __lk.unlock();
679 __cv_.notify_all();
680}
681
Howard Hinnant99968442011-11-29 18:15:50 +0000682template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000683void
Howard Hinnant99968442011-11-29 18:15:50 +0000684__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000685{
686 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000687#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000688 if (this->__has_value())
689 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000690#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000691 __value_ = &__arg;
692 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000693 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000694 __lk.unlock();
695}
696
Howard Hinnant99968442011-11-29 18:15:50 +0000697template <class _Rp>
698_Rp&
699__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000700{
701 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000702 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000703 if (this->__exception_ != nullptr)
704 rethrow_exception(this->__exception_);
705 return *__value_;
706}
707
Howard Hinnant99968442011-11-29 18:15:50 +0000708template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000709class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000710 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000711{
Howard Hinnant99968442011-11-29 18:15:50 +0000712 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000713 _Alloc __alloc_;
714
Howard Hinnant1694d232011-05-28 14:41:13 +0000715 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000716public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000717 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000718 explicit __assoc_state_alloc(const _Alloc& __a)
719 : __alloc_(__a) {}
720};
721
Howard Hinnant99968442011-11-29 18:15:50 +0000722template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000723void
Howard Hinnant99968442011-11-29 18:15:50 +0000724__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000725{
726 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000727 reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000728 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
729 this->~__assoc_state_alloc();
730 __a.deallocate(this, 1);
731}
732
Howard Hinnant99968442011-11-29 18:15:50 +0000733template <class _Rp, class _Alloc>
734class __assoc_state_alloc<_Rp&, _Alloc>
735 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000736{
Howard Hinnant99968442011-11-29 18:15:50 +0000737 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000738 _Alloc __alloc_;
739
Howard Hinnant1694d232011-05-28 14:41:13 +0000740 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000741public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000743 explicit __assoc_state_alloc(const _Alloc& __a)
744 : __alloc_(__a) {}
745};
746
Howard Hinnant99968442011-11-29 18:15:50 +0000747template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000748void
Howard Hinnant99968442011-11-29 18:15:50 +0000749__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000750{
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:19 +0000756template <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:13 +0000763 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000764public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000766 explicit __assoc_sub_state_alloc(const _Alloc& __a)
767 : __alloc_(__a) {}
768};
769
770template <class _Alloc>
771void
Howard Hinnant1694d232011-05-28 14:41:13 +0000772__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000773{
774 this->~base();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000775 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000776 this->~__assoc_sub_state_alloc();
777 __a.deallocate(this, 1);
778}
779
Howard Hinnant99968442011-11-29 18:15:50 +0000780template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000781class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000782 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000783{
Howard Hinnant99968442011-11-29 18:15:50 +0000784 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000785
Howard Hinnant99968442011-11-29 18:15:50 +0000786 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000787
788public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000789#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000790 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000791#endif
792
793 virtual void __execute();
794};
795
Howard Hinnant73d21a42010-09-04 23:28:19 +0000796#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000797
Howard Hinnant99968442011-11-29 18:15:50 +0000798template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000799inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000800__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
801 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000802{
803 this->__set_deferred();
804}
805
Howard Hinnant73d21a42010-09-04 23:28:19 +0000806#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000807
Howard Hinnant99968442011-11-29 18:15:50 +0000808template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000809void
Howard Hinnant99968442011-11-29 18:15:50 +0000810__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000811{
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
Howard Hinnant99968442011-11-29 18:15:50 +0000826template <class _Fp>
827class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000828 : public __assoc_sub_state
829{
830 typedef __assoc_sub_state base;
831
Howard Hinnant99968442011-11-29 18:15:50 +0000832 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000833
834public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000835#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000836 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000837#endif
838
839 virtual void __execute();
840};
841
Howard Hinnant73d21a42010-09-04 23:28:19 +0000842#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000843
Howard Hinnant99968442011-11-29 18:15:50 +0000844template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000845inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000846__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
847 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000848{
849 this->__set_deferred();
850}
851
Howard Hinnant73d21a42010-09-04 23:28:19 +0000852#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000853
Howard Hinnant99968442011-11-29 18:15:50 +0000854template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000855void
Howard Hinnant99968442011-11-29 18:15:50 +0000856__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000857{
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 Hinnant99968442011-11-29 18:15:50 +0000873template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000874class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000875 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000876{
Howard Hinnant99968442011-11-29 18:15:50 +0000877 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000878
Howard Hinnant99968442011-11-29 18:15:50 +0000879 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000880
Howard Hinnant1694d232011-05-28 14:41:13 +0000881 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000882public:
883#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000884 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000885#endif
886
887 virtual void __execute();
888};
889
890#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
891
Howard Hinnant99968442011-11-29 18:15:50 +0000892template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000893inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000894__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
895 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000896{
897}
898
899#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
900
Howard Hinnant99968442011-11-29 18:15:50 +0000901template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000902void
Howard Hinnant99968442011-11-29 18:15:50 +0000903__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000904{
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
Howard Hinnant99968442011-11-29 18:15:50 +0000919template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000920void
Howard Hinnant99968442011-11-29 18:15:50 +0000921__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000922{
923 this->wait();
924 base::__on_zero_shared();
925}
926
Howard Hinnant99968442011-11-29 18:15:50 +0000927template <class _Fp>
928class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000929 : public __assoc_sub_state
930{
931 typedef __assoc_sub_state base;
932
Howard Hinnant99968442011-11-29 18:15:50 +0000933 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000934
Howard Hinnant1694d232011-05-28 14:41:13 +0000935 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000936public:
937#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000938 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000939#endif
940
941 virtual void __execute();
942};
943
944#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
945
Howard Hinnant99968442011-11-29 18:15:50 +0000946template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000947inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000948__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
949 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000950{
951}
952
953#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
954
Howard Hinnant99968442011-11-29 18:15:50 +0000955template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000956void
Howard Hinnant99968442011-11-29 18:15:50 +0000957__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000958{
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
Howard Hinnant99968442011-11-29 18:15:50 +0000974template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000975void
Howard Hinnant99968442011-11-29 18:15:50 +0000976__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000977{
978 this->wait();
979 base::__on_zero_shared();
980}
981
Howard Hinnant99968442011-11-29 18:15:50 +0000982template <class _Rp> class promise;
983template <class _Rp> class shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +0000984
985// future
986
Howard Hinnant99968442011-11-29 18:15:50 +0000987template <class _Rp> class future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000988
Howard Hinnant99968442011-11-29 18:15:50 +0000989template <class _Rp, class _Fp>
990future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000991#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000992__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000993#else
Howard Hinnant99968442011-11-29 18:15:50 +0000994__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000995#endif
996
Howard Hinnant99968442011-11-29 18:15:50 +0000997template <class _Rp, class _Fp>
998future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000999#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001000__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001001#else
Howard Hinnant99968442011-11-29 18:15:50 +00001002__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001003#endif
1004
Howard Hinnant99968442011-11-29 18:15:50 +00001005template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001006class _LIBCPP_VISIBLE future
Howard Hinnant47499b12010-08-27 20:10:19 +00001007{
Howard Hinnant99968442011-11-29 18:15:50 +00001008 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001009
Howard Hinnant99968442011-11-29 18:15:50 +00001010 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001011
1012 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001013 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001014
Howard Hinnant73d21a42010-09-04 23:28:19 +00001015#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001016 template <class _R1, class _Fp>
1017 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1018 template <class _R1, class _Fp>
1019 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001020#else
Howard Hinnant99968442011-11-29 18:15:50 +00001021 template <class _R1, class _Fp>
1022 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1023 template <class _R1, class _Fp>
1024 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001025#endif
1026
Howard Hinnant47499b12010-08-27 20:10:19 +00001027public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001028 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001029 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001030#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001031 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001032 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:26 +00001036 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001037 future& operator=(future&& __rhs)
1038 {
1039 future(std::move(__rhs)).swap(*this);
1040 return *this;
1041 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001042#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001043private:
1044 future(const future&);
1045 future& operator=(const future&);
1046public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001047#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001048 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001049 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001050
1051 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001052 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001053
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001055 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001056
1057 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001059 bool valid() const {return __state_ != nullptr;}
1060
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001062 void wait() const {__state_->wait();}
1063 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001065 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:26 +00001069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001070 future_status
1071 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1072 {return __state_->wait_until(__abs_time);}
1073};
1074
Howard Hinnant99968442011-11-29 18:15:50 +00001075template <class _Rp>
1076future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001077 : __state_(__state)
1078{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001079#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001080 if (__state_->__has_future_attached())
1081 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001082#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001083 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001084 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001085}
1086
Howard Hinnant54da3382010-08-30 18:46:21 +00001087struct __release_shared_count
1088{
1089 void operator()(__shared_count* p) {p->__release_shared();}
1090};
1091
Howard Hinnant99968442011-11-29 18:15:50 +00001092template <class _Rp>
1093future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001094{
1095 if (__state_)
1096 __state_->__release_shared();
1097}
1098
Howard Hinnant99968442011-11-29 18:15:50 +00001099template <class _Rp>
1100_Rp
1101future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001102{
Howard Hinnant54da3382010-08-30 18:46:21 +00001103 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001104 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001105 __state_ = nullptr;
1106 return __s->move();
1107}
1108
Howard Hinnant99968442011-11-29 18:15:50 +00001109template <class _Rp>
1110class _LIBCPP_VISIBLE future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001111{
Howard Hinnant99968442011-11-29 18:15:50 +00001112 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001113
Howard Hinnant99968442011-11-29 18:15:50 +00001114 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001115
1116 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001117 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001118
Howard Hinnant73d21a42010-09-04 23:28:19 +00001119#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001120 template <class _R1, class _Fp>
1121 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1122 template <class _R1, class _Fp>
1123 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001124#else
Howard Hinnant99968442011-11-29 18:15:50 +00001125 template <class _R1, class _Fp>
1126 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1127 template <class _R1, class _Fp>
1128 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001129#endif
1130
Howard Hinnant47499b12010-08-27 20:10:19 +00001131public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001133 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001134#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001136 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:26 +00001140 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001141 future& operator=(future&& __rhs)
1142 {
1143 future(std::move(__rhs)).swap(*this);
1144 return *this;
1145 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001146#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001147private:
1148 future(const future&);
1149 future& operator=(const future&);
1150public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001151#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001152 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001153 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001154
1155 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001156 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001157
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001158 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001159 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001160
1161 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001162 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001163 bool valid() const {return __state_ != nullptr;}
1164
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001165 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001166 void wait() const {__state_->wait();}
1167 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001168 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001169 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:26 +00001173 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001174 future_status
1175 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1176 {return __state_->wait_until(__abs_time);}
1177};
1178
Howard Hinnant99968442011-11-29 18:15:50 +00001179template <class _Rp>
1180future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001181 : __state_(__state)
1182{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001183#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001184 if (__state_->__has_future_attached())
1185 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001186#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001187 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001188 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001189}
1190
Howard Hinnant99968442011-11-29 18:15:50 +00001191template <class _Rp>
1192future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001193{
1194 if (__state_)
1195 __state_->__release_shared();
1196}
1197
Howard Hinnant99968442011-11-29 18:15:50 +00001198template <class _Rp>
1199_Rp&
1200future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001201{
Howard Hinnant54da3382010-08-30 18:46:21 +00001202 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001203 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001204 __state_ = nullptr;
1205 return __s->copy();
1206}
1207
1208template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001209class _LIBCPP_VISIBLE future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001210{
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:25 +00001216 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001217
Howard Hinnant73d21a42010-09-04 23:28:19 +00001218#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001219 template <class _R1, class _Fp>
1220 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1221 template <class _R1, class _Fp>
1222 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001223#else
Howard Hinnant99968442011-11-29 18:15:50 +00001224 template <class _R1, class _Fp>
1225 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1226 template <class _R1, class _Fp>
1227 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001228#endif
1229
Howard Hinnant47499b12010-08-27 20:10:19 +00001230public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001232 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001233#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001235 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:26 +00001239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001240 future& operator=(future&& __rhs)
1241 {
1242 future(std::move(__rhs)).swap(*this);
1243 return *this;
1244 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001245#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001246private:
1247 future(const future&);
1248 future& operator=(const future&);
1249public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001250#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001251 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001252 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001253
1254 // retrieving the value
1255 void get();
1256
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001257 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001258 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001259
1260 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001261 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001262 bool valid() const {return __state_ != nullptr;}
1263
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001264 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001265 void wait() const {__state_->wait();}
1266 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001268 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:26 +00001272 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001273 future_status
1274 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1275 {return __state_->wait_until(__abs_time);}
1276};
1277
Howard Hinnant99968442011-11-29 18:15:50 +00001278template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001279inline _LIBCPP_INLINE_VISIBILITY
1280void
Howard Hinnant99968442011-11-29 18:15:50 +00001281swap(future<_Rp>& __x, future<_Rp>& __y)
Howard Hinnant99be8232010-09-03 18:39:25 +00001282{
1283 __x.swap(__y);
1284}
1285
Howard Hinnant47499b12010-08-27 20:10:19 +00001286// promise<R>
1287
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001288template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001289
Howard Hinnant99968442011-11-29 18:15:50 +00001290template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001291class _LIBCPP_VISIBLE promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001292{
Howard Hinnant99968442011-11-29 18:15:50 +00001293 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001294
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001296 explicit promise(nullptr_t) : __state_(nullptr) {}
1297
1298 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001299public:
1300 promise();
1301 template <class _Alloc>
1302 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001303#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001305 promise(promise&& __rhs)
1306 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1307 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001308#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001309private:
1310 promise(const promise& __rhs);
1311public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001312#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001313 ~promise();
1314
1315 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001316#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001318 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:19 +00001324#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001325private:
1326 promise& operator=(const promise& __rhs);
1327public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001328#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001330 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001331
1332 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001333 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001334
1335 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001336 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001337#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001338 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001339#endif
1340 void set_exception(exception_ptr __p);
1341
1342 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001343 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001344#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001345 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001346#endif
1347 void set_exception_at_thread_exit(exception_ptr __p);
1348};
1349
Howard Hinnant99968442011-11-29 18:15:50 +00001350template <class _Rp>
1351promise<_Rp>::promise()
1352 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001353{
1354}
1355
Howard Hinnant99968442011-11-29 18:15:50 +00001356template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001357template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001358promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001359{
Howard Hinnant99968442011-11-29 18:15:50 +00001360 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001361 typedef __allocator_destructor<_A2> _D2;
1362 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001363 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1364 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001365 __state_ = __hold.release();
1366}
1367
Howard Hinnant99968442011-11-29 18:15:50 +00001368template <class _Rp>
1369promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001370{
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
Howard Hinnant99968442011-11-29 18:15:50 +00001381template <class _Rp>
1382future<_Rp>
1383promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001384{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001385#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001386 if (__state_ == nullptr)
1387 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001388#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001389 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001390}
1391
Howard Hinnant99968442011-11-29 18:15:50 +00001392template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001393void
Howard Hinnant99968442011-11-29 18:15:50 +00001394promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001395{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001396#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001397 if (__state_ == nullptr)
1398 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001399#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001400 __state_->set_value(__r);
1401}
1402
Howard Hinnant73d21a42010-09-04 23:28:19 +00001403#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001404
Howard Hinnant99968442011-11-29 18:15:50 +00001405template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001406void
Howard Hinnant99968442011-11-29 18:15:50 +00001407promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001408{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001409#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001410 if (__state_ == nullptr)
1411 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001412#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001413 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001414}
1415
Howard Hinnant73d21a42010-09-04 23:28:19 +00001416#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001417
Howard Hinnant99968442011-11-29 18:15:50 +00001418template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001419void
Howard Hinnant99968442011-11-29 18:15:50 +00001420promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001421{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001422#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001423 if (__state_ == nullptr)
1424 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001425#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001426 __state_->set_exception(__p);
1427}
1428
Howard Hinnant99968442011-11-29 18:15:50 +00001429template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001430void
Howard Hinnant99968442011-11-29 18:15:50 +00001431promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001432{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001433#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001434 if (__state_ == nullptr)
1435 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001436#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001437 __state_->set_value_at_thread_exit(__r);
1438}
1439
Howard Hinnant73d21a42010-09-04 23:28:19 +00001440#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001441
Howard Hinnant99968442011-11-29 18:15:50 +00001442template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001443void
Howard Hinnant99968442011-11-29 18:15:50 +00001444promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001445{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001446#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001447 if (__state_ == nullptr)
1448 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001449#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001450 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001451}
1452
Howard Hinnant73d21a42010-09-04 23:28:19 +00001453#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001454
Howard Hinnant99968442011-11-29 18:15:50 +00001455template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001456void
Howard Hinnant99968442011-11-29 18:15:50 +00001457promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001458{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001459#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001460 if (__state_ == nullptr)
1461 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001462#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001463 __state_->set_exception_at_thread_exit(__p);
1464}
1465
1466// promise<R&>
1467
Howard Hinnant99968442011-11-29 18:15:50 +00001468template <class _Rp>
1469class _LIBCPP_VISIBLE promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001470{
Howard Hinnant99968442011-11-29 18:15:50 +00001471 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001472
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001474 explicit promise(nullptr_t) : __state_(nullptr) {}
1475
1476 template <class> friend class packaged_task;
1477
Howard Hinnant47499b12010-08-27 20:10:19 +00001478public:
1479 promise();
1480 template <class _Allocator>
1481 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001482#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001484 promise(promise&& __rhs)
1485 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1486 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001487#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001488private:
1489 promise(const promise& __rhs);
1490public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001491#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001492 ~promise();
1493
1494 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001495#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001496 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001497 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:19 +00001503#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001504private:
1505 promise& operator=(const promise& __rhs);
1506public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001507#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001508 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001509 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001510
1511 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001512 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001513
1514 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001515 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001516 void set_exception(exception_ptr __p);
1517
1518 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001519 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001520 void set_exception_at_thread_exit(exception_ptr __p);
1521};
1522
Howard Hinnant99968442011-11-29 18:15:50 +00001523template <class _Rp>
1524promise<_Rp&>::promise()
1525 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001526{
1527}
1528
Howard Hinnant99968442011-11-29 18:15:50 +00001529template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001530template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001531promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001532{
Howard Hinnant99968442011-11-29 18:15:50 +00001533 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001534 typedef __allocator_destructor<_A2> _D2;
1535 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001536 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1537 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001538 __state_ = __hold.release();
1539}
1540
Howard Hinnant99968442011-11-29 18:15:50 +00001541template <class _Rp>
1542promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001543{
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
Howard Hinnant99968442011-11-29 18:15:50 +00001554template <class _Rp>
1555future<_Rp&>
1556promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001557{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001558#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001559 if (__state_ == nullptr)
1560 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001561#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001562 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001563}
1564
Howard Hinnant99968442011-11-29 18:15:50 +00001565template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001566void
Howard Hinnant99968442011-11-29 18:15:50 +00001567promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001568{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001569#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001570 if (__state_ == nullptr)
1571 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001572#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001573 __state_->set_value(__r);
1574}
1575
Howard Hinnant99968442011-11-29 18:15:50 +00001576template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001577void
Howard Hinnant99968442011-11-29 18:15:50 +00001578promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001579{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001580#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001581 if (__state_ == nullptr)
1582 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001583#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001584 __state_->set_exception(__p);
1585}
1586
Howard Hinnant99968442011-11-29 18:15:50 +00001587template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001588void
Howard Hinnant99968442011-11-29 18:15:50 +00001589promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001590{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001591#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001592 if (__state_ == nullptr)
1593 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001594#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001595 __state_->set_value_at_thread_exit(__r);
1596}
1597
Howard Hinnant99968442011-11-29 18:15:50 +00001598template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001599void
Howard Hinnant99968442011-11-29 18:15:50 +00001600promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001601{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001602#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001603 if (__state_ == nullptr)
1604 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001605#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001606 __state_->set_exception_at_thread_exit(__p);
1607}
1608
1609// promise<void>
1610
1611template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001612class _LIBCPP_VISIBLE promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001613{
1614 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001615
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001616 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001617 explicit promise(nullptr_t) : __state_(nullptr) {}
1618
1619 template <class> friend class packaged_task;
1620
Howard Hinnant47499b12010-08-27 20:10:19 +00001621public:
1622 promise();
1623 template <class _Allocator>
1624 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001625#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001626 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001627 promise(promise&& __rhs)
1628 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1629 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001630#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001631private:
1632 promise(const promise& __rhs);
1633public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001634#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001635 ~promise();
1636
1637 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001638#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001639 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001640 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:19 +00001646#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001647private:
1648 promise& operator=(const promise& __rhs);
1649public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001650#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001651 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001652 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001653
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
Howard Hinnant99968442011-11-29 18:15:50 +00001677template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001678inline _LIBCPP_INLINE_VISIBILITY
1679void
Howard Hinnant99968442011-11-29 18:15:50 +00001680swap(promise<_Rp>& __x, promise<_Rp>& __y)
Howard Hinnant47499b12010-08-27 20:10:19 +00001681{
1682 __x.swap(__y);
1683}
1684
Howard Hinnant99968442011-11-29 18:15:50 +00001685template <class _Rp, class _Alloc>
1686 struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001687 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001688
Howard Hinnant54da3382010-08-30 18:46:21 +00001689#ifndef _LIBCPP_HAS_NO_VARIADICS
1690
1691// packaged_task
1692
1693template<class _Fp> class __packaged_task_base;
1694
Howard Hinnant99968442011-11-29 18:15:50 +00001695template<class _Rp, class ..._ArgTypes>
1696class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001697{
1698 __packaged_task_base(const __packaged_task_base&);
1699 __packaged_task_base& operator=(const __packaged_task_base&);
1700public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001702 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001704 virtual ~__packaged_task_base() {}
1705 virtual void __move_to(__packaged_task_base*) = 0;
1706 virtual void destroy() = 0;
1707 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001708 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001709};
1710
1711template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1712
Howard Hinnant99968442011-11-29 18:15:50 +00001713template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1714class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1715 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001716{
Howard Hinnant99968442011-11-29 18:15:50 +00001717 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001718public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001720 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001722 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001724 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001725 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001727 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001728 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001729 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*);
Howard Hinnant54da3382010-08-30 18:46:21 +00001730 virtual void destroy();
1731 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001732 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001733};
1734
Howard Hinnant99968442011-11-29 18:15:50 +00001735template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001736void
Howard Hinnant99968442011-11-29 18:15:50 +00001737__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1738 __packaged_task_base<_Rp(_ArgTypes...)>* __p)
Howard Hinnant54da3382010-08-30 18:46:21 +00001739{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001740 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001741}
1742
Howard Hinnant99968442011-11-29 18:15:50 +00001743template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001744void
Howard Hinnant99968442011-11-29 18:15:50 +00001745__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001746{
Howard Hinnant99968442011-11-29 18:15:50 +00001747 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001748}
1749
Howard Hinnant99968442011-11-29 18:15:50 +00001750template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001751void
Howard Hinnant99968442011-11-29 18:15:50 +00001752__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001753{
Howard Hinnant99968442011-11-29 18:15:50 +00001754 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1755 _Ap __a(__f_.second());
1756 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001757 __a.deallocate(this, 1);
1758}
1759
Howard Hinnant99968442011-11-29 18:15:50 +00001760template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1761_Rp
1762__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001763{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001764 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001765}
1766
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001767template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001768
Howard Hinnant99968442011-11-29 18:15:50 +00001769template<class _Rp, class ..._ArgTypes>
1770class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001771{
Howard Hinnant99968442011-11-29 18:15:50 +00001772 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant54da3382010-08-30 18:46:21 +00001773 aligned_storage<3*sizeof(void*)>::type __buf_;
1774 __base* __f_;
1775
1776public:
Howard Hinnant99968442011-11-29 18:15:50 +00001777 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001778
1779 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001781 __packaged_task_function() : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001782 template<class _Fp>
1783 __packaged_task_function(_Fp&& __f);
1784 template<class _Fp, class _Alloc>
1785 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001786
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
Howard Hinnant99968442011-11-29 18:15:50 +00001797 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001798};
1799
Howard Hinnant99968442011-11-29 18:15:50 +00001800template<class _Rp, class ..._ArgTypes>
1801__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001802{
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
Howard Hinnant99968442011-11-29 18:15:50 +00001817template<class _Rp, class ..._ArgTypes>
1818template <class _Fp>
1819__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001820 : __f_(nullptr)
1821{
Howard Hinnant99968442011-11-29 18:15:50 +00001822 typedef typename remove_reference<_Fp>::type _FR;
1823 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001824 if (sizeof(_FF) <= sizeof(__buf_))
1825 {
1826 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001827 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001828 }
1829 else
1830 {
Howard Hinnant99968442011-11-29 18:15:50 +00001831 typedef allocator<_FF> _Ap;
1832 _Ap __a;
1833 typedef __allocator_destructor<_Ap> _Dp;
1834 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1835 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001836 __f_ = __hold.release();
1837 }
1838}
1839
Howard Hinnant99968442011-11-29 18:15:50 +00001840template<class _Rp, class ..._ArgTypes>
1841template <class _Fp, class _Alloc>
1842__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1843 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001844 : __f_(nullptr)
1845{
1846 typedef allocator_traits<_Alloc> __alloc_traits;
Howard Hinnant99968442011-11-29 18:15:50 +00001847 typedef typename remove_reference<_Fp>::type _FR;
1848 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001849 if (sizeof(_FF) <= sizeof(__buf_))
1850 {
1851 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001852 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001853 }
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
Howard Hinnant99968442011-11-29 18:15:50 +00001862 _Ap;
1863 _Ap __a(__a0);
1864 typedef __allocator_destructor<_Ap> _Dp;
1865 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1866 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001867 __f_ = __hold.release();
1868 }
1869}
1870
Howard Hinnant99968442011-11-29 18:15:50 +00001871template<class _Rp, class ..._ArgTypes>
1872__packaged_task_function<_Rp(_ArgTypes...)>&
1873__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001874{
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
Howard Hinnant99968442011-11-29 18:15:50 +00001894template<class _Rp, class ..._ArgTypes>
1895__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001896{
1897 if (__f_ == (__base*)&__buf_)
1898 __f_->destroy();
1899 else if (__f_)
1900 __f_->destroy_deallocate();
1901}
1902
Howard Hinnant99968442011-11-29 18:15:50 +00001903template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001904void
Howard Hinnant99968442011-11-29 18:15:50 +00001905__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001906{
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:19 +00001937 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001938}
1939
Howard Hinnant99968442011-11-29 18:15:50 +00001940template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001941inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001942_Rp
1943__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00001944{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001945 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001946}
1947
Howard Hinnant99968442011-11-29 18:15:50 +00001948template<class _Rp, class ..._ArgTypes>
1949class _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001950{
1951public:
Howard Hinnant99968442011-11-29 18:15:50 +00001952 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001953
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:26 +00001960 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001961 packaged_task() : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001962 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001963 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001964 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
1965 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001966 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001967 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1968 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00001969 __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:26 +00001977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001978 packaged_task(packaged_task&& __other)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001979 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001980 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001981 packaged_task& operator=(packaged_task&& __other)
1982 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001983 __f_ = _VSTD::move(__other.__f_);
1984 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001985 return *this;
1986 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001987 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001988 void swap(packaged_task& __other)
1989 {
1990 __f_.swap(__other.__f_);
1991 __p_.swap(__other.__p_);
1992 }
1993
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001994 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00001995 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00001996
1997 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001998 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001999 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
Howard Hinnant99968442011-11-29 18:15:50 +00002008template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002009void
Howard Hinnant99968442011-11-29 18:15:50 +00002010packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002011{
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:19 +00002020 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002021#ifndef _LIBCPP_NO_EXCEPTIONS
2022 }
2023 catch (...)
2024 {
2025 __p_.set_exception(current_exception());
2026 }
2027#endif // _LIBCPP_NO_EXCEPTIONS
2028}
2029
Howard Hinnant99968442011-11-29 18:15:50 +00002030template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002031void
Howard Hinnant99968442011-11-29 18:15:50 +00002032packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002033{
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:19 +00002042 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002043#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
Howard Hinnant99968442011-11-29 18:15:50 +00002052template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002053void
Howard Hinnant99968442011-11-29 18:15:50 +00002054packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002055{
2056#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002057 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002058 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:26 +00002064class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002065{
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:26 +00002075 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002076 packaged_task() : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00002077 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002078 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002079 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2080 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002081 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002082 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2083 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002084 __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:26 +00002092 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002093 packaged_task(packaged_task&& __other)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002094 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002095 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002096 packaged_task& operator=(packaged_task&& __other)
2097 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002098 __f_ = _VSTD::move(__other.__f_);
2099 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002100 return *this;
2101 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002102 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002103 void swap(packaged_task& __other)
2104 {
2105 __f_.swap(__other.__f_);
2106 __p_.swap(__other.__p_);
2107 }
2108
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002109 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00002110 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002111
2112 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002113 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002114 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:19 +00002135 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002136 __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:19 +00002158 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002159 __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:32 +00002174 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002175 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:26 +00002189struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2190 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002191
Howard Hinnant99968442011-11-29 18:15:50 +00002192template <class _Rp, class _Fp>
2193future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002194#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002195__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002196#else
Howard Hinnant99968442011-11-29 18:15:50 +00002197__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002198#endif
2199{
Howard Hinnant99968442011-11-29 18:15:50 +00002200 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2201 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2202 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002203}
2204
Howard Hinnant99968442011-11-29 18:15:50 +00002205template <class _Rp, class _Fp>
2206future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002207#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002208__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002209#else
Howard Hinnant99968442011-11-29 18:15:50 +00002210__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002211#endif
2212{
Howard Hinnant99968442011-11-29 18:15:50 +00002213 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2214 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2215 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2216 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002217}
2218
Howard Hinnant99968442011-11-29 18:15:50 +00002219template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002220class __async_func
2221{
Howard Hinnant99968442011-11-29 18:15:50 +00002222 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002223
2224public:
Howard Hinnant99968442011-11-29 18:15:50 +00002225 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002226
2227 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002228 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002229 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002230
2231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002232 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002233
Howard Hinnant99968442011-11-29 18:15:50 +00002234 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002235 {
2236 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2237 return __execute(_Index());
2238 }
2239private:
2240 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002241 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002242 __execute(__tuple_indices<_Indices...>)
2243 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002244 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002245 }
2246};
2247
Howard Hinnant99968442011-11-29 18:15:50 +00002248template <class _Fp, class... _Args>
2249future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2250async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002251{
Howard Hinnant99968442011-11-29 18:15:50 +00002252 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2253 typedef typename _BF::_Rp _Rp;
2254 future<_Rp> __r;
Howard Hinnant66895642010-11-23 18:33:54 +00002255 if (__policy & launch::async)
Howard Hinnant99968442011-11-29 18:15:50 +00002256 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002257 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant66895642010-11-23 18:33:54 +00002258 else if (__policy & launch::deferred)
Howard Hinnant99968442011-11-29 18:15:50 +00002259 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002260 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002261 return __r;
2262}
2263
Howard Hinnant99968442011-11-29 18:15:50 +00002264template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002265inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002266future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2267async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002268{
Howard Hinnant99968442011-11-29 18:15:50 +00002269 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002270 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002271}
2272
2273#endif // _LIBCPP_HAS_NO_VARIADICS
2274
Howard Hinnante6e4d012010-09-03 21:46:37 +00002275// shared_future
2276
Howard Hinnant99968442011-11-29 18:15:50 +00002277template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002278class _LIBCPP_VISIBLE shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002279{
Howard Hinnant99968442011-11-29 18:15:50 +00002280 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002281
2282public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002284 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002286 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2287 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002288#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002289 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002290 shared_future(future<_Rp>&& __f) : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002291 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002293 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2294 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002295#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002296 ~shared_future();
2297 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002298#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002300 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:19 +00002305#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002306
2307 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002309 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002310
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002312 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002313
2314 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002316 bool valid() const {return __state_ != nullptr;}
2317
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002319 void wait() const {__state_->wait();}
2320 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002322 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:26 +00002326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002327 future_status
2328 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2329 {return __state_->wait_until(__abs_time);}
2330};
2331
Howard Hinnant99968442011-11-29 18:15:50 +00002332template <class _Rp>
2333shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002334{
2335 if (__state_)
2336 __state_->__release_shared();
2337}
2338
Howard Hinnant99968442011-11-29 18:15:50 +00002339template <class _Rp>
2340shared_future<_Rp>&
2341shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002342{
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
Howard Hinnant99968442011-11-29 18:15:50 +00002351template <class _Rp>
2352class _LIBCPP_VISIBLE shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002353{
Howard Hinnant99968442011-11-29 18:15:50 +00002354 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002355
2356public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002357 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002358 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002359 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002360 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2361 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002362#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002363 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002364 shared_future(future<_Rp&>&& __f) : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002365 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002367 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2368 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002369#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002370 ~shared_future();
2371 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002372#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002373 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002374 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:19 +00002379#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002380
2381 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002383 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002384
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002386 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002387
2388 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002389 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002390 bool valid() const {return __state_ != nullptr;}
2391
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002392 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002393 void wait() const {__state_->wait();}
2394 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002396 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:26 +00002400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002401 future_status
2402 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2403 {return __state_->wait_until(__abs_time);}
2404};
2405
Howard Hinnant99968442011-11-29 18:15:50 +00002406template <class _Rp>
2407shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002408{
2409 if (__state_)
2410 __state_->__release_shared();
2411}
2412
Howard Hinnant99968442011-11-29 18:15:50 +00002413template <class _Rp>
2414shared_future<_Rp&>&
2415shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002416{
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:26 +00002426class _LIBCPP_VISIBLE shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002427{
2428 __assoc_sub_state* __state_;
2429
2430public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002432 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002434 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2435 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002436#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002437 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002438 shared_future(future<void>&& __f) : __state_(__f.__state_)
2439 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002441 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2442 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002443#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002444 ~shared_future();
2445 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002446#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002448 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:19 +00002453#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002454
2455 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002456 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002457 void get() const {__state_->copy();}
2458
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002459 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002460 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002461
2462 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002464 bool valid() const {return __state_ != nullptr;}
2465
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002467 void wait() const {__state_->wait();}
2468 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002469 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002470 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:26 +00002474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002475 future_status
2476 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2477 {return __state_->wait_until(__abs_time);}
2478};
2479
Howard Hinnant99968442011-11-29 18:15:50 +00002480template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002481inline _LIBCPP_INLINE_VISIBILITY
2482void
Howard Hinnant99968442011-11-29 18:15:50 +00002483swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y)
Howard Hinnant99be8232010-09-03 18:39:25 +00002484{
2485 __x.swap(__y);
2486}
2487
Howard Hinnant99968442011-11-29 18:15:50 +00002488template <class _Rp>
Howard Hinnant7de47902010-11-30 20:23:32 +00002489inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002490shared_future<_Rp>
2491future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002492{
Howard Hinnant99968442011-11-29 18:15:50 +00002493 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002494}
2495
Howard Hinnant99968442011-11-29 18:15:50 +00002496template <class _Rp>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002497inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002498shared_future<_Rp&>
2499future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002500{
Howard Hinnant99968442011-11-29 18:15:50 +00002501 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002502}
2503
Howard Hinnanta4451512010-12-02 16:45:21 +00002504#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2505
Howard Hinnant7de47902010-11-30 20:23:32 +00002506inline _LIBCPP_INLINE_VISIBILITY
2507shared_future<void>
2508future<void>::share()
2509{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002510 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002511}
2512
Howard Hinnanta4451512010-12-02 16:45:21 +00002513#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2514
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002515_LIBCPP_END_NAMESPACE_STD
2516
2517#endif // _LIBCPP_FUTURE