blob: aae707e1e4e882ed0dd4b8b72d1f9675414b387c [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 Hinnantf6d875f2011-12-02 19:36:40 +0000380_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000382 broken_promise,
383 future_already_retrieved,
384 promise_already_satisfied,
385 no_state
386};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000387_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000388
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000389template <>
390struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000391
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000392#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
393template <>
394struct _LIBCPP_VISIBLE is_error_code_enum<future_errc::_> : public true_type { };
395#endif
396
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397//enum class launch
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000398_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000399{
Howard Hinnant66895642010-11-23 18:33:54 +0000400 async = 1,
401 deferred = 2,
402 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000404_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405
406//enum class future_status
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000407_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000408{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409 ready,
410 timeout,
411 deferred
412};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000413_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000415_LIBCPP_VISIBLE
Howard Hinnanta6521722010-08-25 17:32:05 +0000416const error_category& future_category();
417
418inline _LIBCPP_INLINE_VISIBILITY
419error_code
420make_error_code(future_errc __e)
421{
422 return error_code(static_cast<int>(__e), future_category());
423}
424
425inline _LIBCPP_INLINE_VISIBILITY
426error_condition
427make_error_condition(future_errc __e)
428{
429 return error_condition(static_cast<int>(__e), future_category());
430}
431
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000432class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000433 : public logic_error
434{
435 error_code __ec_;
436public:
437 future_error(error_code __ec);
438
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta6521722010-08-25 17:32:05 +0000440 const error_code& code() const throw() {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52 +0000441
442 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000443};
444
Howard Hinnant47499b12010-08-27 20:10:19 +0000445class __assoc_sub_state
446 : public __shared_count
447{
448protected:
449 exception_ptr __exception_;
450 mutable mutex __mut_;
451 mutable condition_variable __cv_;
452 unsigned __state_;
453
Howard Hinnant1694d232011-05-28 14:41:13 +0000454 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000455 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000456public:
457 enum
458 {
459 __constructed = 1,
460 __future_attached = 2,
461 ready = 4,
462 deferred = 8
463 };
464
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000466 __assoc_sub_state() : __state_(0) {}
467
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000469 bool __has_value() const
470 {return (__state_ & __constructed) || (__exception_ != nullptr);}
471
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000473 void __set_future_attached() {__state_ |= __future_attached;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000475 bool __has_future_attached() const {return __state_ & __future_attached;}
476
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000478 void __set_deferred() {__state_ |= deferred;}
479
Howard Hinnant47499b12010-08-27 20:10:19 +0000480 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000482 bool __is_ready() const {return __state_ & ready;}
483
484 void set_value();
485 void set_value_at_thread_exit();
486
487 void set_exception(exception_ptr __p);
488 void set_exception_at_thread_exit(exception_ptr __p);
489
490 void copy();
491
Howard Hinnant54da3382010-08-30 18:46:21 +0000492 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000493 template <class _Rep, class _Period>
494 future_status
495 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
496 template <class _Clock, class _Duration>
497 future_status
498 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000499
500 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000501};
502
Howard Hinnantf39daa82010-08-28 21:01:06 +0000503template <class _Clock, class _Duration>
504future_status
505__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
506{
507 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000508 if (__state_ & deferred)
509 return future_status::deferred;
510 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000511 __cv_.wait_until(__lk, __abs_time);
512 if (__state_ & ready)
513 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000514 return future_status::timeout;
515}
516
517template <class _Rep, class _Period>
518inline _LIBCPP_INLINE_VISIBILITY
519future_status
520__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
521{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000522 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000523}
524
Howard Hinnant99968442011-11-29 18:15:50 +0000525template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000526class __assoc_state
527 : public __assoc_sub_state
528{
529 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000530 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000531protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000532 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000533
Howard Hinnant1694d232011-05-28 14:41:13 +0000534 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000535public:
536
537 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000538#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000539 void set_value(_Arg&& __arg);
540#else
541 void set_value(_Arg& __arg);
542#endif
543
544 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000545#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000546 void set_value_at_thread_exit(_Arg&& __arg);
547#else
548 void set_value_at_thread_exit(_Arg& __arg);
549#endif
550
Howard Hinnant99968442011-11-29 18:15:50 +0000551 _Rp move();
552 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000553};
554
Howard Hinnant99968442011-11-29 18:15:50 +0000555template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000556void
Howard Hinnant99968442011-11-29 18:15:50 +0000557__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000558{
559 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000560 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000561 delete this;
562}
563
Howard Hinnant99968442011-11-29 18:15:50 +0000564template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000565template <class _Arg>
566void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000567#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000568__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000569#else
Howard Hinnant99968442011-11-29 18:15:50 +0000570__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000571#endif
572{
573 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000574#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000575 if (this->__has_value())
576 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000577#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000578 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000579 this->__state_ |= base::__constructed | base::ready;
580 __lk.unlock();
581 __cv_.notify_all();
582}
583
Howard Hinnant99968442011-11-29 18:15:50 +0000584template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000585template <class _Arg>
586void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000587#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000588__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000589#else
Howard Hinnant99968442011-11-29 18:15:50 +0000590__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000591#endif
592{
593 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000594#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000595 if (this->__has_value())
596 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000597#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000598 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000599 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000600 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000601 __lk.unlock();
602}
603
Howard Hinnant99968442011-11-29 18:15:50 +0000604template <class _Rp>
605_Rp
606__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000607{
608 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000609 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000610 if (this->__exception_ != nullptr)
611 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000612 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000613}
614
Howard Hinnant99968442011-11-29 18:15:50 +0000615template <class _Rp>
616typename add_lvalue_reference<_Rp>::type
617__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000618{
619 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000620 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000621 if (this->__exception_ != nullptr)
622 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000623 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000624}
625
Howard Hinnant99968442011-11-29 18:15:50 +0000626template <class _Rp>
627class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000628 : public __assoc_sub_state
629{
630 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000631 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000632protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000633 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000634
Howard Hinnant1694d232011-05-28 14:41:13 +0000635 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000636public:
637
Howard Hinnant99968442011-11-29 18:15:50 +0000638 void set_value(_Rp& __arg);
639 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000640
Howard Hinnant99968442011-11-29 18:15:50 +0000641 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000642};
643
Howard Hinnant99968442011-11-29 18:15:50 +0000644template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000645void
Howard Hinnant99968442011-11-29 18:15:50 +0000646__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000647{
648 delete this;
649}
650
Howard Hinnant99968442011-11-29 18:15:50 +0000651template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000652void
Howard Hinnant99968442011-11-29 18:15:50 +0000653__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000654{
655 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000656#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000657 if (this->__has_value())
658 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000659#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000660 __value_ = &__arg;
661 this->__state_ |= base::__constructed | base::ready;
662 __lk.unlock();
663 __cv_.notify_all();
664}
665
Howard Hinnant99968442011-11-29 18:15:50 +0000666template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000667void
Howard Hinnant99968442011-11-29 18:15:50 +0000668__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000669{
670 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000671#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000672 if (this->__has_value())
673 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000674#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000675 __value_ = &__arg;
676 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000677 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000678 __lk.unlock();
679}
680
Howard Hinnant99968442011-11-29 18:15:50 +0000681template <class _Rp>
682_Rp&
683__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000684{
685 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000686 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000687 if (this->__exception_ != nullptr)
688 rethrow_exception(this->__exception_);
689 return *__value_;
690}
691
Howard Hinnant99968442011-11-29 18:15:50 +0000692template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000693class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000694 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000695{
Howard Hinnant99968442011-11-29 18:15:50 +0000696 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000697 _Alloc __alloc_;
698
Howard Hinnant1694d232011-05-28 14:41:13 +0000699 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000700public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000702 explicit __assoc_state_alloc(const _Alloc& __a)
703 : __alloc_(__a) {}
704};
705
Howard Hinnant99968442011-11-29 18:15:50 +0000706template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000707void
Howard Hinnant99968442011-11-29 18:15:50 +0000708__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000709{
710 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000711 reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000712 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
713 this->~__assoc_state_alloc();
714 __a.deallocate(this, 1);
715}
716
Howard Hinnant99968442011-11-29 18:15:50 +0000717template <class _Rp, class _Alloc>
718class __assoc_state_alloc<_Rp&, _Alloc>
719 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000720{
Howard Hinnant99968442011-11-29 18:15:50 +0000721 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000722 _Alloc __alloc_;
723
Howard Hinnant1694d232011-05-28 14:41:13 +0000724 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000725public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000727 explicit __assoc_state_alloc(const _Alloc& __a)
728 : __alloc_(__a) {}
729};
730
Howard Hinnant99968442011-11-29 18:15:50 +0000731template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000732void
Howard Hinnant99968442011-11-29 18:15:50 +0000733__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000734{
735 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
736 this->~__assoc_state_alloc();
737 __a.deallocate(this, 1);
738}
739
Howard Hinnant47499b12010-08-27 20:10:19 +0000740template <class _Alloc>
741class __assoc_sub_state_alloc
742 : public __assoc_sub_state
743{
744 typedef __assoc_sub_state base;
745 _Alloc __alloc_;
746
Howard Hinnant1694d232011-05-28 14:41:13 +0000747 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000748public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000749 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000750 explicit __assoc_sub_state_alloc(const _Alloc& __a)
751 : __alloc_(__a) {}
752};
753
754template <class _Alloc>
755void
Howard Hinnant1694d232011-05-28 14:41:13 +0000756__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000757{
758 this->~base();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000759 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000760 this->~__assoc_sub_state_alloc();
761 __a.deallocate(this, 1);
762}
763
Howard Hinnant99968442011-11-29 18:15:50 +0000764template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000765class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000766 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000767{
Howard Hinnant99968442011-11-29 18:15:50 +0000768 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000769
Howard Hinnant99968442011-11-29 18:15:50 +0000770 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000771
772public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000773#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000774 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000775#endif
776
777 virtual void __execute();
778};
779
Howard Hinnant73d21a42010-09-04 23:28:19 +0000780#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000781
Howard Hinnant99968442011-11-29 18:15:50 +0000782template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000783inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000784__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
785 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000786{
787 this->__set_deferred();
788}
789
Howard Hinnant73d21a42010-09-04 23:28:19 +0000790#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000791
Howard Hinnant99968442011-11-29 18:15:50 +0000792template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000793void
Howard Hinnant99968442011-11-29 18:15:50 +0000794__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000795{
796#ifndef _LIBCPP_NO_EXCEPTIONS
797 try
798 {
799#endif // _LIBCPP_NO_EXCEPTIONS
800 this->set_value(__func_());
801#ifndef _LIBCPP_NO_EXCEPTIONS
802 }
803 catch (...)
804 {
805 this->set_exception(current_exception());
806 }
807#endif // _LIBCPP_NO_EXCEPTIONS
808}
809
Howard Hinnant99968442011-11-29 18:15:50 +0000810template <class _Fp>
811class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000812 : public __assoc_sub_state
813{
814 typedef __assoc_sub_state base;
815
Howard Hinnant99968442011-11-29 18:15:50 +0000816 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000817
818public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000819#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000820 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000821#endif
822
823 virtual void __execute();
824};
825
Howard Hinnant73d21a42010-09-04 23:28:19 +0000826#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000827
Howard Hinnant99968442011-11-29 18:15:50 +0000828template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000829inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000830__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
831 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000832{
833 this->__set_deferred();
834}
835
Howard Hinnant73d21a42010-09-04 23:28:19 +0000836#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000837
Howard Hinnant99968442011-11-29 18:15:50 +0000838template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000839void
Howard Hinnant99968442011-11-29 18:15:50 +0000840__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000841{
842#ifndef _LIBCPP_NO_EXCEPTIONS
843 try
844 {
845#endif // _LIBCPP_NO_EXCEPTIONS
846 __func_();
847 this->set_value();
848#ifndef _LIBCPP_NO_EXCEPTIONS
849 }
850 catch (...)
851 {
852 this->set_exception(current_exception());
853 }
854#endif // _LIBCPP_NO_EXCEPTIONS
855}
856
Howard Hinnant99968442011-11-29 18:15:50 +0000857template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000858class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000859 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000860{
Howard Hinnant99968442011-11-29 18:15:50 +0000861 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000862
Howard Hinnant99968442011-11-29 18:15:50 +0000863 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000864
Howard Hinnant1694d232011-05-28 14:41:13 +0000865 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000866public:
867#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000868 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000869#endif
870
871 virtual void __execute();
872};
873
874#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
875
Howard Hinnant99968442011-11-29 18:15:50 +0000876template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000877inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000878__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
879 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000880{
881}
882
883#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
884
Howard Hinnant99968442011-11-29 18:15:50 +0000885template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000886void
Howard Hinnant99968442011-11-29 18:15:50 +0000887__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000888{
889#ifndef _LIBCPP_NO_EXCEPTIONS
890 try
891 {
892#endif // _LIBCPP_NO_EXCEPTIONS
893 this->set_value(__func_());
894#ifndef _LIBCPP_NO_EXCEPTIONS
895 }
896 catch (...)
897 {
898 this->set_exception(current_exception());
899 }
900#endif // _LIBCPP_NO_EXCEPTIONS
901}
902
Howard Hinnant99968442011-11-29 18:15:50 +0000903template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000904void
Howard Hinnant99968442011-11-29 18:15:50 +0000905__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000906{
907 this->wait();
908 base::__on_zero_shared();
909}
910
Howard Hinnant99968442011-11-29 18:15:50 +0000911template <class _Fp>
912class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000913 : public __assoc_sub_state
914{
915 typedef __assoc_sub_state base;
916
Howard Hinnant99968442011-11-29 18:15:50 +0000917 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000918
Howard Hinnant1694d232011-05-28 14:41:13 +0000919 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000920public:
921#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000922 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000923#endif
924
925 virtual void __execute();
926};
927
928#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
929
Howard Hinnant99968442011-11-29 18:15:50 +0000930template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000931inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000932__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
933 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000934{
935}
936
937#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
938
Howard Hinnant99968442011-11-29 18:15:50 +0000939template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000940void
Howard Hinnant99968442011-11-29 18:15:50 +0000941__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000942{
943#ifndef _LIBCPP_NO_EXCEPTIONS
944 try
945 {
946#endif // _LIBCPP_NO_EXCEPTIONS
947 __func_();
948 this->set_value();
949#ifndef _LIBCPP_NO_EXCEPTIONS
950 }
951 catch (...)
952 {
953 this->set_exception(current_exception());
954 }
955#endif // _LIBCPP_NO_EXCEPTIONS
956}
957
Howard Hinnant99968442011-11-29 18:15:50 +0000958template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000959void
Howard Hinnant99968442011-11-29 18:15:50 +0000960__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000961{
962 this->wait();
963 base::__on_zero_shared();
964}
965
Howard Hinnant99968442011-11-29 18:15:50 +0000966template <class _Rp> class promise;
967template <class _Rp> class shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +0000968
969// future
970
Howard Hinnant99968442011-11-29 18:15:50 +0000971template <class _Rp> class future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000972
Howard Hinnant99968442011-11-29 18:15:50 +0000973template <class _Rp, class _Fp>
974future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000975#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000976__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000977#else
Howard Hinnant99968442011-11-29 18:15:50 +0000978__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000979#endif
980
Howard Hinnant99968442011-11-29 18:15:50 +0000981template <class _Rp, class _Fp>
982future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000983#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000984__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000985#else
Howard Hinnant99968442011-11-29 18:15:50 +0000986__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000987#endif
988
Howard Hinnant99968442011-11-29 18:15:50 +0000989template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000990class _LIBCPP_VISIBLE future
Howard Hinnant47499b12010-08-27 20:10:19 +0000991{
Howard Hinnant99968442011-11-29 18:15:50 +0000992 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000993
Howard Hinnant99968442011-11-29 18:15:50 +0000994 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +0000995
996 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +0000997 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000998
Howard Hinnant73d21a42010-09-04 23:28:19 +0000999#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001000 template <class _R1, class _Fp>
1001 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1002 template <class _R1, class _Fp>
1003 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001004#else
Howard Hinnant99968442011-11-29 18:15:50 +00001005 template <class _R1, class _Fp>
1006 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1007 template <class _R1, class _Fp>
1008 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001009#endif
1010
Howard Hinnant47499b12010-08-27 20:10:19 +00001011public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001012 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001013 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001014#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001015 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001016 future(future&& __rhs)
1017 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1018 future(const future&) = delete;
1019 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001020 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001021 future& operator=(future&& __rhs)
1022 {
1023 future(std::move(__rhs)).swap(*this);
1024 return *this;
1025 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001026#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001027private:
1028 future(const future&);
1029 future& operator=(const future&);
1030public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001031#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001032 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001033 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001034
1035 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001036 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001037
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001038 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001039 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001040
1041 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001042 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001043 bool valid() const {return __state_ != nullptr;}
1044
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001045 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001046 void wait() const {__state_->wait();}
1047 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001049 future_status
1050 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1051 {return __state_->wait_for(__rel_time);}
1052 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001053 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001054 future_status
1055 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1056 {return __state_->wait_until(__abs_time);}
1057};
1058
Howard Hinnant99968442011-11-29 18:15:50 +00001059template <class _Rp>
1060future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001061 : __state_(__state)
1062{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001063#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001064 if (__state_->__has_future_attached())
1065 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001066#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001067 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001068 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001069}
1070
Howard Hinnant54da3382010-08-30 18:46:21 +00001071struct __release_shared_count
1072{
1073 void operator()(__shared_count* p) {p->__release_shared();}
1074};
1075
Howard Hinnant99968442011-11-29 18:15:50 +00001076template <class _Rp>
1077future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001078{
1079 if (__state_)
1080 __state_->__release_shared();
1081}
1082
Howard Hinnant99968442011-11-29 18:15:50 +00001083template <class _Rp>
1084_Rp
1085future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001086{
Howard Hinnant54da3382010-08-30 18:46:21 +00001087 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001088 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001089 __state_ = nullptr;
1090 return __s->move();
1091}
1092
Howard Hinnant99968442011-11-29 18:15:50 +00001093template <class _Rp>
1094class _LIBCPP_VISIBLE future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001095{
Howard Hinnant99968442011-11-29 18:15:50 +00001096 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001097
Howard Hinnant99968442011-11-29 18:15:50 +00001098 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001099
1100 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001101 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001102
Howard Hinnant73d21a42010-09-04 23:28:19 +00001103#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001104 template <class _R1, class _Fp>
1105 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1106 template <class _R1, class _Fp>
1107 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001108#else
Howard Hinnant99968442011-11-29 18:15:50 +00001109 template <class _R1, class _Fp>
1110 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1111 template <class _R1, class _Fp>
1112 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001113#endif
1114
Howard Hinnant47499b12010-08-27 20:10:19 +00001115public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001116 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001117 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001118#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001120 future(future&& __rhs)
1121 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1122 future(const future&) = delete;
1123 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001124 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001125 future& operator=(future&& __rhs)
1126 {
1127 future(std::move(__rhs)).swap(*this);
1128 return *this;
1129 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001130#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001131private:
1132 future(const future&);
1133 future& operator=(const future&);
1134public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001135#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001136 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001137 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001138
1139 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001140 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001141
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001142 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001143 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001144
1145 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001146 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001147 bool valid() const {return __state_ != nullptr;}
1148
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001149 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001150 void wait() const {__state_->wait();}
1151 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001152 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001153 future_status
1154 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1155 {return __state_->wait_for(__rel_time);}
1156 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001157 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001158 future_status
1159 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1160 {return __state_->wait_until(__abs_time);}
1161};
1162
Howard Hinnant99968442011-11-29 18:15:50 +00001163template <class _Rp>
1164future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001165 : __state_(__state)
1166{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001167#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001168 if (__state_->__has_future_attached())
1169 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001170#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001171 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001172 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001173}
1174
Howard Hinnant99968442011-11-29 18:15:50 +00001175template <class _Rp>
1176future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001177{
1178 if (__state_)
1179 __state_->__release_shared();
1180}
1181
Howard Hinnant99968442011-11-29 18:15:50 +00001182template <class _Rp>
1183_Rp&
1184future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001185{
Howard Hinnant54da3382010-08-30 18:46:21 +00001186 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001187 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001188 __state_ = nullptr;
1189 return __s->copy();
1190}
1191
1192template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001193class _LIBCPP_VISIBLE future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001194{
1195 __assoc_sub_state* __state_;
1196
1197 explicit future(__assoc_sub_state* __state);
1198
1199 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001200 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001201
Howard Hinnant73d21a42010-09-04 23:28:19 +00001202#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001203 template <class _R1, class _Fp>
1204 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1205 template <class _R1, class _Fp>
1206 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001207#else
Howard Hinnant99968442011-11-29 18:15:50 +00001208 template <class _R1, class _Fp>
1209 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1210 template <class _R1, class _Fp>
1211 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001212#endif
1213
Howard Hinnant47499b12010-08-27 20:10:19 +00001214public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001215 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001216 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001217#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001218 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001219 future(future&& __rhs)
1220 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1221 future(const future&) = delete;
1222 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001223 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001224 future& operator=(future&& __rhs)
1225 {
1226 future(std::move(__rhs)).swap(*this);
1227 return *this;
1228 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001229#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001230private:
1231 future(const future&);
1232 future& operator=(const future&);
1233public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001234#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001235 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001236 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001237
1238 // retrieving the value
1239 void get();
1240
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001241 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001242 void swap(future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001243
1244 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001246 bool valid() const {return __state_ != nullptr;}
1247
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001249 void wait() const {__state_->wait();}
1250 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001252 future_status
1253 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1254 {return __state_->wait_for(__rel_time);}
1255 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001257 future_status
1258 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1259 {return __state_->wait_until(__abs_time);}
1260};
1261
Howard Hinnant99968442011-11-29 18:15:50 +00001262template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001263inline _LIBCPP_INLINE_VISIBILITY
1264void
Howard Hinnant99968442011-11-29 18:15:50 +00001265swap(future<_Rp>& __x, future<_Rp>& __y)
Howard Hinnant99be8232010-09-03 18:39:25 +00001266{
1267 __x.swap(__y);
1268}
1269
Howard Hinnant47499b12010-08-27 20:10:19 +00001270// promise<R>
1271
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001272template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001273
Howard Hinnant99968442011-11-29 18:15:50 +00001274template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001275class _LIBCPP_VISIBLE promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001276{
Howard Hinnant99968442011-11-29 18:15:50 +00001277 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001278
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001279 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001280 explicit promise(nullptr_t) : __state_(nullptr) {}
1281
1282 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001283public:
1284 promise();
1285 template <class _Alloc>
1286 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001287#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001288 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001289 promise(promise&& __rhs)
1290 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1291 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001292#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001293private:
1294 promise(const promise& __rhs);
1295public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001296#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001297 ~promise();
1298
1299 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001300#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001302 promise& operator=(promise&& __rhs)
1303 {
1304 promise(std::move(__rhs)).swap(*this);
1305 return *this;
1306 }
1307 promise& operator=(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& operator=(const promise& __rhs);
1311public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001312#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001314 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001315
1316 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001317 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001318
1319 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001320 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001321#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001322 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001323#endif
1324 void set_exception(exception_ptr __p);
1325
1326 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001327 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001328#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001329 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001330#endif
1331 void set_exception_at_thread_exit(exception_ptr __p);
1332};
1333
Howard Hinnant99968442011-11-29 18:15:50 +00001334template <class _Rp>
1335promise<_Rp>::promise()
1336 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001337{
1338}
1339
Howard Hinnant99968442011-11-29 18:15:50 +00001340template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001341template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001342promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001343{
Howard Hinnant99968442011-11-29 18:15:50 +00001344 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001345 typedef __allocator_destructor<_A2> _D2;
1346 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001347 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1348 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001349 __state_ = __hold.release();
1350}
1351
Howard Hinnant99968442011-11-29 18:15:50 +00001352template <class _Rp>
1353promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001354{
1355 if (__state_)
1356 {
1357 if (!__state_->__has_value() && __state_->use_count() > 1)
1358 __state_->set_exception(make_exception_ptr(
1359 future_error(make_error_code(future_errc::broken_promise))
1360 ));
1361 __state_->__release_shared();
1362 }
1363}
1364
Howard Hinnant99968442011-11-29 18:15:50 +00001365template <class _Rp>
1366future<_Rp>
1367promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001368{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001369#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001370 if (__state_ == nullptr)
1371 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001372#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001373 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001374}
1375
Howard Hinnant99968442011-11-29 18:15:50 +00001376template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001377void
Howard Hinnant99968442011-11-29 18:15:50 +00001378promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001379{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001380#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001381 if (__state_ == nullptr)
1382 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001383#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001384 __state_->set_value(__r);
1385}
1386
Howard Hinnant73d21a42010-09-04 23:28:19 +00001387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001388
Howard Hinnant99968442011-11-29 18:15:50 +00001389template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001390void
Howard Hinnant99968442011-11-29 18:15:50 +00001391promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001392{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001393#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001394 if (__state_ == nullptr)
1395 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001396#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001397 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001398}
1399
Howard Hinnant73d21a42010-09-04 23:28:19 +00001400#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001401
Howard Hinnant99968442011-11-29 18:15:50 +00001402template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001403void
Howard Hinnant99968442011-11-29 18:15:50 +00001404promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001405{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001406#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001407 if (__state_ == nullptr)
1408 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001409#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001410 __state_->set_exception(__p);
1411}
1412
Howard Hinnant99968442011-11-29 18:15:50 +00001413template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001414void
Howard Hinnant99968442011-11-29 18:15:50 +00001415promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001416{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001417#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001418 if (__state_ == nullptr)
1419 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001420#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001421 __state_->set_value_at_thread_exit(__r);
1422}
1423
Howard Hinnant73d21a42010-09-04 23:28:19 +00001424#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001425
Howard Hinnant99968442011-11-29 18:15:50 +00001426template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001427void
Howard Hinnant99968442011-11-29 18:15:50 +00001428promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001429{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001430#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001431 if (__state_ == nullptr)
1432 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001433#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001434 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001435}
1436
Howard Hinnant73d21a42010-09-04 23:28:19 +00001437#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001438
Howard Hinnant99968442011-11-29 18:15:50 +00001439template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001440void
Howard Hinnant99968442011-11-29 18:15:50 +00001441promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001442{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001443#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001444 if (__state_ == nullptr)
1445 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001446#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001447 __state_->set_exception_at_thread_exit(__p);
1448}
1449
1450// promise<R&>
1451
Howard Hinnant99968442011-11-29 18:15:50 +00001452template <class _Rp>
1453class _LIBCPP_VISIBLE promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001454{
Howard Hinnant99968442011-11-29 18:15:50 +00001455 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001456
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001458 explicit promise(nullptr_t) : __state_(nullptr) {}
1459
1460 template <class> friend class packaged_task;
1461
Howard Hinnant47499b12010-08-27 20:10:19 +00001462public:
1463 promise();
1464 template <class _Allocator>
1465 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001466#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001467 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001468 promise(promise&& __rhs)
1469 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1470 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001471#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001472private:
1473 promise(const promise& __rhs);
1474public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001475#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001476 ~promise();
1477
1478 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001479#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001480 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001481 promise& operator=(promise&& __rhs)
1482 {
1483 promise(std::move(__rhs)).swap(*this);
1484 return *this;
1485 }
1486 promise& operator=(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& operator=(const promise& __rhs);
1490public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001491#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001493 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001494
1495 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001496 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001497
1498 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001499 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001500 void set_exception(exception_ptr __p);
1501
1502 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001503 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001504 void set_exception_at_thread_exit(exception_ptr __p);
1505};
1506
Howard Hinnant99968442011-11-29 18:15:50 +00001507template <class _Rp>
1508promise<_Rp&>::promise()
1509 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001510{
1511}
1512
Howard Hinnant99968442011-11-29 18:15:50 +00001513template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001514template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001515promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001516{
Howard Hinnant99968442011-11-29 18:15:50 +00001517 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001518 typedef __allocator_destructor<_A2> _D2;
1519 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001520 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1521 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001522 __state_ = __hold.release();
1523}
1524
Howard Hinnant99968442011-11-29 18:15:50 +00001525template <class _Rp>
1526promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001527{
1528 if (__state_)
1529 {
1530 if (!__state_->__has_value() && __state_->use_count() > 1)
1531 __state_->set_exception(make_exception_ptr(
1532 future_error(make_error_code(future_errc::broken_promise))
1533 ));
1534 __state_->__release_shared();
1535 }
1536}
1537
Howard Hinnant99968442011-11-29 18:15:50 +00001538template <class _Rp>
1539future<_Rp&>
1540promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001541{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001542#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001543 if (__state_ == nullptr)
1544 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001545#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001546 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001547}
1548
Howard Hinnant99968442011-11-29 18:15:50 +00001549template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001550void
Howard Hinnant99968442011-11-29 18:15:50 +00001551promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001552{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001553#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001554 if (__state_ == nullptr)
1555 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001556#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001557 __state_->set_value(__r);
1558}
1559
Howard Hinnant99968442011-11-29 18:15:50 +00001560template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001561void
Howard Hinnant99968442011-11-29 18:15:50 +00001562promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001563{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001564#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001565 if (__state_ == nullptr)
1566 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001567#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001568 __state_->set_exception(__p);
1569}
1570
Howard Hinnant99968442011-11-29 18:15:50 +00001571template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001572void
Howard Hinnant99968442011-11-29 18:15:50 +00001573promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001574{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001575#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001576 if (__state_ == nullptr)
1577 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001578#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001579 __state_->set_value_at_thread_exit(__r);
1580}
1581
Howard Hinnant99968442011-11-29 18:15:50 +00001582template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001583void
Howard Hinnant99968442011-11-29 18:15:50 +00001584promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001585{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001586#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001587 if (__state_ == nullptr)
1588 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001589#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001590 __state_->set_exception_at_thread_exit(__p);
1591}
1592
1593// promise<void>
1594
1595template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001596class _LIBCPP_VISIBLE promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001597{
1598 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001599
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001600 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001601 explicit promise(nullptr_t) : __state_(nullptr) {}
1602
1603 template <class> friend class packaged_task;
1604
Howard Hinnant47499b12010-08-27 20:10:19 +00001605public:
1606 promise();
1607 template <class _Allocator>
1608 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001609#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001610 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001611 promise(promise&& __rhs)
1612 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1613 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001614#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001615private:
1616 promise(const promise& __rhs);
1617public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001618#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001619 ~promise();
1620
1621 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001622#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001623 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001624 promise& operator=(promise&& __rhs)
1625 {
1626 promise(std::move(__rhs)).swap(*this);
1627 return *this;
1628 }
1629 promise& operator=(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& operator=(const promise& __rhs);
1633public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001634#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001635 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00001636 void swap(promise& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001637
1638 // retrieving the result
1639 future<void> get_future();
1640
1641 // setting the result
1642 void set_value();
1643 void set_exception(exception_ptr __p);
1644
1645 // setting the result with deferred notification
1646 void set_value_at_thread_exit();
1647 void set_exception_at_thread_exit(exception_ptr __p);
1648};
1649
1650template <class _Alloc>
1651promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1652{
1653 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1654 typedef __allocator_destructor<_A2> _D2;
1655 _A2 __a(__a0);
1656 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1657 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1658 __state_ = __hold.release();
1659}
1660
Howard Hinnant99968442011-11-29 18:15:50 +00001661template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001662inline _LIBCPP_INLINE_VISIBILITY
1663void
Howard Hinnant99968442011-11-29 18:15:50 +00001664swap(promise<_Rp>& __x, promise<_Rp>& __y)
Howard Hinnant47499b12010-08-27 20:10:19 +00001665{
1666 __x.swap(__y);
1667}
1668
Howard Hinnant99968442011-11-29 18:15:50 +00001669template <class _Rp, class _Alloc>
1670 struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001671 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001672
Howard Hinnant54da3382010-08-30 18:46:21 +00001673#ifndef _LIBCPP_HAS_NO_VARIADICS
1674
1675// packaged_task
1676
1677template<class _Fp> class __packaged_task_base;
1678
Howard Hinnant99968442011-11-29 18:15:50 +00001679template<class _Rp, class ..._ArgTypes>
1680class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001681{
1682 __packaged_task_base(const __packaged_task_base&);
1683 __packaged_task_base& operator=(const __packaged_task_base&);
1684public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001685 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001686 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001687 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001688 virtual ~__packaged_task_base() {}
1689 virtual void __move_to(__packaged_task_base*) = 0;
1690 virtual void destroy() = 0;
1691 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001692 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001693};
1694
1695template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1696
Howard Hinnant99968442011-11-29 18:15:50 +00001697template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1698class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1699 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001700{
Howard Hinnant99968442011-11-29 18:15:50 +00001701 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001702public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001704 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001705 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001706 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001707 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001708 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001709 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001711 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001712 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001713 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*);
Howard Hinnant54da3382010-08-30 18:46:21 +00001714 virtual void destroy();
1715 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001716 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001717};
1718
Howard Hinnant99968442011-11-29 18:15:50 +00001719template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001720void
Howard Hinnant99968442011-11-29 18:15:50 +00001721__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1722 __packaged_task_base<_Rp(_ArgTypes...)>* __p)
Howard Hinnant54da3382010-08-30 18:46:21 +00001723{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001724 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001725}
1726
Howard Hinnant99968442011-11-29 18:15:50 +00001727template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001728void
Howard Hinnant99968442011-11-29 18:15:50 +00001729__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001730{
Howard Hinnant99968442011-11-29 18:15:50 +00001731 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001732}
1733
Howard Hinnant99968442011-11-29 18:15:50 +00001734template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001735void
Howard Hinnant99968442011-11-29 18:15:50 +00001736__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001737{
Howard Hinnant99968442011-11-29 18:15:50 +00001738 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1739 _Ap __a(__f_.second());
1740 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001741 __a.deallocate(this, 1);
1742}
1743
Howard Hinnant99968442011-11-29 18:15:50 +00001744template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1745_Rp
1746__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001747{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001748 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001749}
1750
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001751template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001752
Howard Hinnant99968442011-11-29 18:15:50 +00001753template<class _Rp, class ..._ArgTypes>
1754class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001755{
Howard Hinnant99968442011-11-29 18:15:50 +00001756 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant54da3382010-08-30 18:46:21 +00001757 aligned_storage<3*sizeof(void*)>::type __buf_;
1758 __base* __f_;
1759
1760public:
Howard Hinnant99968442011-11-29 18:15:50 +00001761 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001762
1763 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001764 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001765 __packaged_task_function() : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001766 template<class _Fp>
1767 __packaged_task_function(_Fp&& __f);
1768 template<class _Fp, class _Alloc>
1769 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001770
1771 __packaged_task_function(__packaged_task_function&&);
1772 __packaged_task_function& operator=(__packaged_task_function&&);
1773
1774 __packaged_task_function(const __packaged_task_function&) = delete;
1775 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1776
1777 ~__packaged_task_function();
1778
1779 void swap(__packaged_task_function&);
1780
Howard Hinnant99968442011-11-29 18:15:50 +00001781 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001782};
1783
Howard Hinnant99968442011-11-29 18:15:50 +00001784template<class _Rp, class ..._ArgTypes>
1785__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001786{
1787 if (__f.__f_ == nullptr)
1788 __f_ = nullptr;
1789 else if (__f.__f_ == (__base*)&__f.__buf_)
1790 {
1791 __f_ = (__base*)&__buf_;
1792 __f.__f_->__move_to(__f_);
1793 }
1794 else
1795 {
1796 __f_ = __f.__f_;
1797 __f.__f_ = nullptr;
1798 }
1799}
1800
Howard Hinnant99968442011-11-29 18:15:50 +00001801template<class _Rp, class ..._ArgTypes>
1802template <class _Fp>
1803__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001804 : __f_(nullptr)
1805{
Howard Hinnant99968442011-11-29 18:15:50 +00001806 typedef typename remove_reference<_Fp>::type _FR;
1807 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001808 if (sizeof(_FF) <= sizeof(__buf_))
1809 {
1810 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001811 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001812 }
1813 else
1814 {
Howard Hinnant99968442011-11-29 18:15:50 +00001815 typedef allocator<_FF> _Ap;
1816 _Ap __a;
1817 typedef __allocator_destructor<_Ap> _Dp;
1818 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1819 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001820 __f_ = __hold.release();
1821 }
1822}
1823
Howard Hinnant99968442011-11-29 18:15:50 +00001824template<class _Rp, class ..._ArgTypes>
1825template <class _Fp, class _Alloc>
1826__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1827 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001828 : __f_(nullptr)
1829{
1830 typedef allocator_traits<_Alloc> __alloc_traits;
Howard Hinnant99968442011-11-29 18:15:50 +00001831 typedef typename remove_reference<_Fp>::type _FR;
1832 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001833 if (sizeof(_FF) <= sizeof(__buf_))
1834 {
1835 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001836 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001837 }
1838 else
1839 {
1840 typedef typename __alloc_traits::template
1841#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1842 rebind_alloc<_FF>
1843#else
1844 rebind_alloc<_FF>::other
1845#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001846 _Ap;
1847 _Ap __a(__a0);
1848 typedef __allocator_destructor<_Ap> _Dp;
1849 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1850 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001851 __f_ = __hold.release();
1852 }
1853}
1854
Howard Hinnant99968442011-11-29 18:15:50 +00001855template<class _Rp, class ..._ArgTypes>
1856__packaged_task_function<_Rp(_ArgTypes...)>&
1857__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001858{
1859 if (__f_ == (__base*)&__buf_)
1860 __f_->destroy();
1861 else if (__f_)
1862 __f_->destroy_deallocate();
1863 __f_ = nullptr;
1864 if (__f.__f_ == nullptr)
1865 __f_ = nullptr;
1866 else if (__f.__f_ == (__base*)&__f.__buf_)
1867 {
1868 __f_ = (__base*)&__buf_;
1869 __f.__f_->__move_to(__f_);
1870 }
1871 else
1872 {
1873 __f_ = __f.__f_;
1874 __f.__f_ = nullptr;
1875 }
1876}
1877
Howard Hinnant99968442011-11-29 18:15:50 +00001878template<class _Rp, class ..._ArgTypes>
1879__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001880{
1881 if (__f_ == (__base*)&__buf_)
1882 __f_->destroy();
1883 else if (__f_)
1884 __f_->destroy_deallocate();
1885}
1886
Howard Hinnant99968442011-11-29 18:15:50 +00001887template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001888void
Howard Hinnant99968442011-11-29 18:15:50 +00001889__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001890{
1891 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1892 {
1893 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1894 __base* __t = (__base*)&__tempbuf;
1895 __f_->__move_to(__t);
1896 __f_->destroy();
1897 __f_ = nullptr;
1898 __f.__f_->__move_to((__base*)&__buf_);
1899 __f.__f_->destroy();
1900 __f.__f_ = nullptr;
1901 __f_ = (__base*)&__buf_;
1902 __t->__move_to((__base*)&__f.__buf_);
1903 __t->destroy();
1904 __f.__f_ = (__base*)&__f.__buf_;
1905 }
1906 else if (__f_ == (__base*)&__buf_)
1907 {
1908 __f_->__move_to((__base*)&__f.__buf_);
1909 __f_->destroy();
1910 __f_ = __f.__f_;
1911 __f.__f_ = (__base*)&__f.__buf_;
1912 }
1913 else if (__f.__f_ == (__base*)&__f.__buf_)
1914 {
1915 __f.__f_->__move_to((__base*)&__buf_);
1916 __f.__f_->destroy();
1917 __f.__f_ = __f_;
1918 __f_ = (__base*)&__buf_;
1919 }
1920 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001921 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001922}
1923
Howard Hinnant99968442011-11-29 18:15:50 +00001924template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001925inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001926_Rp
1927__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00001928{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001929 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001930}
1931
Howard Hinnant99968442011-11-29 18:15:50 +00001932template<class _Rp, class ..._ArgTypes>
1933class _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001934{
1935public:
Howard Hinnant99968442011-11-29 18:15:50 +00001936 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001937
1938private:
1939 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1940 promise<result_type> __p_;
1941
1942public:
1943 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001944 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001945 packaged_task() : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001946 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001947 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001948 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
1949 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001950 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001951 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1952 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00001953 __p_(allocator_arg, __a) {}
1954 // ~packaged_task() = default;
1955
1956 // no copy
1957 packaged_task(packaged_task&) = delete;
1958 packaged_task& operator=(packaged_task&) = delete;
1959
1960 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001961 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001962 packaged_task(packaged_task&& __other)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001963 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001964 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001965 packaged_task& operator=(packaged_task&& __other)
1966 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001967 __f_ = _VSTD::move(__other.__f_);
1968 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001969 return *this;
1970 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001971 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001972 void swap(packaged_task& __other)
1973 {
1974 __f_.swap(__other.__f_);
1975 __p_.swap(__other.__p_);
1976 }
1977
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001978 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00001979 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00001980
1981 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001982 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001983 future<result_type> get_future() {return __p_.get_future();}
1984
1985 // execution
1986 void operator()(_ArgTypes... __args);
1987 void make_ready_at_thread_exit(_ArgTypes... __args);
1988
1989 void reset();
1990};
1991
Howard Hinnant99968442011-11-29 18:15:50 +00001992template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001993void
Howard Hinnant99968442011-11-29 18:15:50 +00001994packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00001995{
1996#ifndef _LIBCPP_NO_EXCEPTIONS
1997 if (__p_.__state_ == nullptr)
1998 throw future_error(make_error_code(future_errc::no_state));
1999 if (__p_.__state_->__has_value())
2000 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2001 try
2002 {
2003#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002004 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002005#ifndef _LIBCPP_NO_EXCEPTIONS
2006 }
2007 catch (...)
2008 {
2009 __p_.set_exception(current_exception());
2010 }
2011#endif // _LIBCPP_NO_EXCEPTIONS
2012}
2013
Howard Hinnant99968442011-11-29 18:15:50 +00002014template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002015void
Howard Hinnant99968442011-11-29 18:15:50 +00002016packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002017{
2018#ifndef _LIBCPP_NO_EXCEPTIONS
2019 if (__p_.__state_ == nullptr)
2020 throw future_error(make_error_code(future_errc::no_state));
2021 if (__p_.__state_->__has_value())
2022 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2023 try
2024 {
2025#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002026 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002027#ifndef _LIBCPP_NO_EXCEPTIONS
2028 }
2029 catch (...)
2030 {
2031 __p_.set_exception_at_thread_exit(current_exception());
2032 }
2033#endif // _LIBCPP_NO_EXCEPTIONS
2034}
2035
Howard Hinnant99968442011-11-29 18:15:50 +00002036template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002037void
Howard Hinnant99968442011-11-29 18:15:50 +00002038packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002039{
2040#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002041 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002042 throw future_error(make_error_code(future_errc::no_state));
2043#endif // _LIBCPP_NO_EXCEPTIONS
2044 __p_ = promise<result_type>();
2045}
2046
2047template<class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002048class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002049{
2050public:
2051 typedef void result_type;
2052
2053private:
2054 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2055 promise<result_type> __p_;
2056
2057public:
2058 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002060 packaged_task() : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00002061 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002063 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2064 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002066 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2067 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002068 __p_(allocator_arg, __a) {}
2069 // ~packaged_task() = default;
2070
2071 // no copy
2072 packaged_task(packaged_task&) = delete;
2073 packaged_task& operator=(packaged_task&) = delete;
2074
2075 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002077 packaged_task(packaged_task&& __other)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002078 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002079 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002080 packaged_task& operator=(packaged_task&& __other)
2081 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002082 __f_ = _VSTD::move(__other.__f_);
2083 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002084 return *this;
2085 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002086 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002087 void swap(packaged_task& __other)
2088 {
2089 __f_.swap(__other.__f_);
2090 __p_.swap(__other.__p_);
2091 }
2092
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002093 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00002094 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002095
2096 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002098 future<result_type> get_future() {return __p_.get_future();}
2099
2100 // execution
2101 void operator()(_ArgTypes... __args);
2102 void make_ready_at_thread_exit(_ArgTypes... __args);
2103
2104 void reset();
2105};
2106
2107template<class ..._ArgTypes>
2108void
2109packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2110{
2111#ifndef _LIBCPP_NO_EXCEPTIONS
2112 if (__p_.__state_ == nullptr)
2113 throw future_error(make_error_code(future_errc::no_state));
2114 if (__p_.__state_->__has_value())
2115 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2116 try
2117 {
2118#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002119 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002120 __p_.set_value();
2121#ifndef _LIBCPP_NO_EXCEPTIONS
2122 }
2123 catch (...)
2124 {
2125 __p_.set_exception(current_exception());
2126 }
2127#endif // _LIBCPP_NO_EXCEPTIONS
2128}
2129
2130template<class ..._ArgTypes>
2131void
2132packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2133{
2134#ifndef _LIBCPP_NO_EXCEPTIONS
2135 if (__p_.__state_ == nullptr)
2136 throw future_error(make_error_code(future_errc::no_state));
2137 if (__p_.__state_->__has_value())
2138 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2139 try
2140 {
2141#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002142 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002143 __p_.set_value_at_thread_exit();
2144#ifndef _LIBCPP_NO_EXCEPTIONS
2145 }
2146 catch (...)
2147 {
2148 __p_.set_exception_at_thread_exit(current_exception());
2149 }
2150#endif // _LIBCPP_NO_EXCEPTIONS
2151}
2152
2153template<class ..._ArgTypes>
2154void
2155packaged_task<void(_ArgTypes...)>::reset()
2156{
2157#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002158 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002159 throw future_error(make_error_code(future_errc::no_state));
2160#endif // _LIBCPP_NO_EXCEPTIONS
2161 __p_ = promise<result_type>();
2162}
2163
2164template <class _Callable>
2165inline _LIBCPP_INLINE_VISIBILITY
2166void
2167swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y)
2168{
2169 __x.swap(__y);
2170}
2171
2172template <class _Callable, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002173struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2174 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002175
Howard Hinnant99968442011-11-29 18:15:50 +00002176template <class _Rp, class _Fp>
2177future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002178#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002179__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002180#else
Howard Hinnant99968442011-11-29 18:15:50 +00002181__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002182#endif
2183{
Howard Hinnant99968442011-11-29 18:15:50 +00002184 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2185 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2186 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002187}
2188
Howard Hinnant99968442011-11-29 18:15:50 +00002189template <class _Rp, class _Fp>
2190future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002191#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002192__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002193#else
Howard Hinnant99968442011-11-29 18:15:50 +00002194__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002195#endif
2196{
Howard Hinnant99968442011-11-29 18:15:50 +00002197 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2198 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2199 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2200 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002201}
2202
Howard Hinnant99968442011-11-29 18:15:50 +00002203template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002204class __async_func
2205{
Howard Hinnant99968442011-11-29 18:15:50 +00002206 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002207
2208public:
Howard Hinnant99968442011-11-29 18:15:50 +00002209 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002210
2211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002212 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002213 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002214
2215 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002216 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002217
Howard Hinnant99968442011-11-29 18:15:50 +00002218 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002219 {
2220 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2221 return __execute(_Index());
2222 }
2223private:
2224 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002225 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002226 __execute(__tuple_indices<_Indices...>)
2227 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002228 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002229 }
2230};
2231
Howard Hinnant99968442011-11-29 18:15:50 +00002232template <class _Fp, class... _Args>
2233future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2234async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002235{
Howard Hinnant99968442011-11-29 18:15:50 +00002236 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2237 typedef typename _BF::_Rp _Rp;
2238 future<_Rp> __r;
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002239 if (int(__policy) & int(launch::async))
Howard Hinnant99968442011-11-29 18:15:50 +00002240 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002241 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002242 else if (int(__policy) & int(launch::deferred))
Howard Hinnant99968442011-11-29 18:15:50 +00002243 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002244 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002245 return __r;
2246}
2247
Howard Hinnant99968442011-11-29 18:15:50 +00002248template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002249inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002250future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2251async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002252{
Howard Hinnant99968442011-11-29 18:15:50 +00002253 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002254 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002255}
2256
2257#endif // _LIBCPP_HAS_NO_VARIADICS
2258
Howard Hinnante6e4d012010-09-03 21:46:37 +00002259// shared_future
2260
Howard Hinnant99968442011-11-29 18:15:50 +00002261template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002262class _LIBCPP_VISIBLE shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002263{
Howard Hinnant99968442011-11-29 18:15:50 +00002264 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002265
2266public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002268 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002269 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002270 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2271 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002272#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002273 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002274 shared_future(future<_Rp>&& __f) : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002275 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002276 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002277 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2278 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002279#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002280 ~shared_future();
2281 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002282#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002284 shared_future& operator=(shared_future&& __rhs)
2285 {
2286 shared_future(std::move(__rhs)).swap(*this);
2287 return *this;
2288 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002289#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002290
2291 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002293 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002294
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002296 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002297
2298 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002300 bool valid() const {return __state_ != nullptr;}
2301
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002302 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002303 void wait() const {__state_->wait();}
2304 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002306 future_status
2307 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2308 {return __state_->wait_for(__rel_time);}
2309 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002311 future_status
2312 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2313 {return __state_->wait_until(__abs_time);}
2314};
2315
Howard Hinnant99968442011-11-29 18:15:50 +00002316template <class _Rp>
2317shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002318{
2319 if (__state_)
2320 __state_->__release_shared();
2321}
2322
Howard Hinnant99968442011-11-29 18:15:50 +00002323template <class _Rp>
2324shared_future<_Rp>&
2325shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002326{
2327 if (__rhs.__state_)
2328 __rhs.__state_->__add_shared();
2329 if (__state_)
2330 __state_->__release_shared();
2331 __state_ = __rhs.__state_;
2332 return *this;
2333}
2334
Howard Hinnant99968442011-11-29 18:15:50 +00002335template <class _Rp>
2336class _LIBCPP_VISIBLE shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002337{
Howard Hinnant99968442011-11-29 18:15:50 +00002338 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002339
2340public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002341 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002342 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002344 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2345 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002346#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002347 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002348 shared_future(future<_Rp&>&& __f) : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002349 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002350 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002351 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2352 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002353#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002354 ~shared_future();
2355 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002356#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002357 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002358 shared_future& operator=(shared_future&& __rhs)
2359 {
2360 shared_future(std::move(__rhs)).swap(*this);
2361 return *this;
2362 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002363#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002364
2365 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002367 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002368
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002369 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002370 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002371
2372 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002373 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002374 bool valid() const {return __state_ != nullptr;}
2375
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002376 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002377 void wait() const {__state_->wait();}
2378 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002379 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002380 future_status
2381 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2382 {return __state_->wait_for(__rel_time);}
2383 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002385 future_status
2386 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2387 {return __state_->wait_until(__abs_time);}
2388};
2389
Howard Hinnant99968442011-11-29 18:15:50 +00002390template <class _Rp>
2391shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002392{
2393 if (__state_)
2394 __state_->__release_shared();
2395}
2396
Howard Hinnant99968442011-11-29 18:15:50 +00002397template <class _Rp>
2398shared_future<_Rp&>&
2399shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002400{
2401 if (__rhs.__state_)
2402 __rhs.__state_->__add_shared();
2403 if (__state_)
2404 __state_->__release_shared();
2405 __state_ = __rhs.__state_;
2406 return *this;
2407}
2408
2409template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002410class _LIBCPP_VISIBLE shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002411{
2412 __assoc_sub_state* __state_;
2413
2414public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002415 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002416 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002418 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2419 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002420#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002422 shared_future(future<void>&& __f) : __state_(__f.__state_)
2423 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002424 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002425 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2426 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002427#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002428 ~shared_future();
2429 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002430#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002432 shared_future& operator=(shared_future&& __rhs)
2433 {
2434 shared_future(std::move(__rhs)).swap(*this);
2435 return *this;
2436 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002437#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002438
2439 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002441 void get() const {__state_->copy();}
2442
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002444 void swap(shared_future& __rhs) {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002445
2446 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002448 bool valid() const {return __state_ != nullptr;}
2449
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002451 void wait() const {__state_->wait();}
2452 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002454 future_status
2455 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2456 {return __state_->wait_for(__rel_time);}
2457 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002459 future_status
2460 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2461 {return __state_->wait_until(__abs_time);}
2462};
2463
Howard Hinnant99968442011-11-29 18:15:50 +00002464template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002465inline _LIBCPP_INLINE_VISIBILITY
2466void
Howard Hinnant99968442011-11-29 18:15:50 +00002467swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y)
Howard Hinnant99be8232010-09-03 18:39:25 +00002468{
2469 __x.swap(__y);
2470}
2471
Howard Hinnant99968442011-11-29 18:15:50 +00002472template <class _Rp>
Howard Hinnant7de47902010-11-30 20:23:32 +00002473inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002474shared_future<_Rp>
2475future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002476{
Howard Hinnant99968442011-11-29 18:15:50 +00002477 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002478}
2479
Howard Hinnant99968442011-11-29 18:15:50 +00002480template <class _Rp>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002481inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002482shared_future<_Rp&>
2483future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002484{
Howard Hinnant99968442011-11-29 18:15:50 +00002485 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002486}
2487
Howard Hinnanta4451512010-12-02 16:45:21 +00002488#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2489
Howard Hinnant7de47902010-11-30 20:23:32 +00002490inline _LIBCPP_INLINE_VISIBILITY
2491shared_future<void>
2492future<void>::share()
2493{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002494 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002495}
2496
Howard Hinnanta4451512010-12-02 16:45:21 +00002497#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2498
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002499_LIBCPP_END_NAMESPACE_STD
2500
2501#endif // _LIBCPP_FUTURE