blob: 471e1f2e6d4f9c0aa480eb37cf3fee48d25ad368 [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
373#pragma GCC system_header
374
375_LIBCPP_BEGIN_NAMESPACE_STD
376
377//enum class future_errc
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000378struct _LIBCPP_VISIBLE future_errc
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000379{
380enum _ {
381 broken_promise,
382 future_already_retrieved,
383 promise_already_satisfied,
384 no_state
385};
386
387 _ __v_;
388
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000389 _LIBCPP_INLINE_VISIBILITY future_errc(_ __v) : __v_(__v) {}
390 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000391
392};
393
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000394template <>
395struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000396
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397//enum class launch
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000398struct _LIBCPP_VISIBLE launch
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000399{
400enum _ {
Howard Hinnant66895642010-11-23 18:33:54 +0000401 async = 1,
402 deferred = 2,
403 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000404};
405
406 _ __v_;
407
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000408 _LIBCPP_INLINE_VISIBILITY launch(_ __v) : __v_(__v) {}
409 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000410
411};
412
413//enum class future_status
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000414struct _LIBCPP_VISIBLE future_status
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000415{
416enum _ {
417 ready,
418 timeout,
419 deferred
420};
421
422 _ __v_;
423
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000424 _LIBCPP_INLINE_VISIBILITY future_status(_ __v) : __v_(__v) {}
425 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000426
427};
428
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000429_LIBCPP_VISIBLE
Howard Hinnanta6521722010-08-25 17:32:05 +0000430const error_category& future_category();
431
432inline _LIBCPP_INLINE_VISIBILITY
433error_code
434make_error_code(future_errc __e)
435{
436 return error_code(static_cast<int>(__e), future_category());
437}
438
439inline _LIBCPP_INLINE_VISIBILITY
440error_condition
441make_error_condition(future_errc __e)
442{
443 return error_condition(static_cast<int>(__e), future_category());
444}
445
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000446class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000447 : public logic_error
448{
449 error_code __ec_;
450public:
451 future_error(error_code __ec);
452
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta6521722010-08-25 17:32:05 +0000454 const error_code& code() const throw() {return __ec_;}
455};
456
Howard Hinnant47499b12010-08-27 20:10:19 +0000457class __assoc_sub_state
458 : public __shared_count
459{
460protected:
461 exception_ptr __exception_;
462 mutable mutex __mut_;
463 mutable condition_variable __cv_;
464 unsigned __state_;
465
466 virtual void __on_zero_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +0000467 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000468public:
469 enum
470 {
471 __constructed = 1,
472 __future_attached = 2,
473 ready = 4,
474 deferred = 8
475 };
476
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000478 __assoc_sub_state() : __state_(0) {}
479
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000480 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000481 bool __has_value() const
482 {return (__state_ & __constructed) || (__exception_ != nullptr);}
483
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000485 void __set_future_attached() {__state_ |= __future_attached;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000486 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000487 bool __has_future_attached() const {return __state_ & __future_attached;}
488
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000489 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000490 void __set_deferred() {__state_ |= deferred;}
491
Howard Hinnant47499b12010-08-27 20:10:19 +0000492 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000493 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000494 bool __is_ready() const {return __state_ & ready;}
495
496 void set_value();
497 void set_value_at_thread_exit();
498
499 void set_exception(exception_ptr __p);
500 void set_exception_at_thread_exit(exception_ptr __p);
501
502 void copy();
503
Howard Hinnant54da3382010-08-30 18:46:21 +0000504 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000505 template <class _Rep, class _Period>
506 future_status
507 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
508 template <class _Clock, class _Duration>
509 future_status
510 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000511
512 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000513};
514
Howard Hinnantf39daa82010-08-28 21:01:06 +0000515template <class _Clock, class _Duration>
516future_status
517__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
518{
519 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000520 if (__state_ & deferred)
521 return future_status::deferred;
522 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000523 __cv_.wait_until(__lk, __abs_time);
524 if (__state_ & ready)
525 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000526 return future_status::timeout;
527}
528
529template <class _Rep, class _Period>
530inline _LIBCPP_INLINE_VISIBILITY
531future_status
532__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
533{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000534 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000535}
536
Howard Hinnant47499b12010-08-27 20:10:19 +0000537template <class _R>
538class __assoc_state
539 : public __assoc_sub_state
540{
541 typedef __assoc_sub_state base;
542 typedef typename aligned_storage<sizeof(_R), alignment_of<_R>::value>::type _U;
543protected:
544 _U __value_;
545
546 virtual void __on_zero_shared();
547public:
548
549 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000550#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000551 void set_value(_Arg&& __arg);
552#else
553 void set_value(_Arg& __arg);
554#endif
555
556 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000557#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000558 void set_value_at_thread_exit(_Arg&& __arg);
559#else
560 void set_value_at_thread_exit(_Arg& __arg);
561#endif
562
563 _R move();
564 typename add_lvalue_reference<_R>::type copy();
565};
566
567template <class _R>
568void
569__assoc_state<_R>::__on_zero_shared()
570{
571 if (this->__state_ & base::__constructed)
572 reinterpret_cast<_R*>(&__value_)->~_R();
573 delete this;
574}
575
576template <class _R>
577template <class _Arg>
578void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000579#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000580__assoc_state<_R>::set_value(_Arg&& __arg)
581#else
582__assoc_state<_R>::set_value(_Arg& __arg)
583#endif
584{
585 unique_lock<mutex> __lk(this->__mut_);
586 if (this->__has_value())
587 throw future_error(make_error_code(future_errc::promise_already_satisfied));
588 ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
589 this->__state_ |= base::__constructed | base::ready;
590 __lk.unlock();
591 __cv_.notify_all();
592}
593
594template <class _R>
595template <class _Arg>
596void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000597#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000598__assoc_state<_R>::set_value_at_thread_exit(_Arg&& __arg)
599#else
600__assoc_state<_R>::set_value_at_thread_exit(_Arg& __arg)
601#endif
602{
603 unique_lock<mutex> __lk(this->__mut_);
604 if (this->__has_value())
605 throw future_error(make_error_code(future_errc::promise_already_satisfied));
606 ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
607 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000608 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000609 __lk.unlock();
610}
611
612template <class _R>
613_R
614__assoc_state<_R>::move()
615{
616 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000617 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000618 if (this->__exception_ != nullptr)
619 rethrow_exception(this->__exception_);
620 return _STD::move(*reinterpret_cast<_R*>(&__value_));
621}
622
623template <class _R>
624typename add_lvalue_reference<_R>::type
625__assoc_state<_R>::copy()
626{
627 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000628 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000629 if (this->__exception_ != nullptr)
630 rethrow_exception(this->__exception_);
631 return *reinterpret_cast<_R*>(&__value_);
632}
633
Howard Hinnantf39daa82010-08-28 21:01:06 +0000634template <class _R>
635class __assoc_state<_R&>
636 : public __assoc_sub_state
637{
638 typedef __assoc_sub_state base;
639 typedef _R* _U;
640protected:
641 _U __value_;
642
643 virtual void __on_zero_shared();
644public:
645
646 void set_value(_R& __arg);
647 void set_value_at_thread_exit(_R& __arg);
648
649 _R& copy();
650};
651
652template <class _R>
653void
654__assoc_state<_R&>::__on_zero_shared()
655{
656 delete this;
657}
658
659template <class _R>
660void
661__assoc_state<_R&>::set_value(_R& __arg)
662{
663 unique_lock<mutex> __lk(this->__mut_);
664 if (this->__has_value())
665 throw future_error(make_error_code(future_errc::promise_already_satisfied));
666 __value_ = &__arg;
667 this->__state_ |= base::__constructed | base::ready;
668 __lk.unlock();
669 __cv_.notify_all();
670}
671
672template <class _R>
673void
674__assoc_state<_R&>::set_value_at_thread_exit(_R& __arg)
675{
676 unique_lock<mutex> __lk(this->__mut_);
677 if (this->__has_value())
678 throw future_error(make_error_code(future_errc::promise_already_satisfied));
679 __value_ = &__arg;
680 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000681 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000682 __lk.unlock();
683}
684
685template <class _R>
686_R&
687__assoc_state<_R&>::copy()
688{
689 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000690 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000691 if (this->__exception_ != nullptr)
692 rethrow_exception(this->__exception_);
693 return *__value_;
694}
695
Howard Hinnant47499b12010-08-27 20:10:19 +0000696template <class _R, class _Alloc>
697class __assoc_state_alloc
698 : public __assoc_state<_R>
699{
700 typedef __assoc_state<_R> base;
701 _Alloc __alloc_;
702
703 virtual void __on_zero_shared();
704public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000705 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000706 explicit __assoc_state_alloc(const _Alloc& __a)
707 : __alloc_(__a) {}
708};
709
710template <class _R, class _Alloc>
711void
712__assoc_state_alloc<_R, _Alloc>::__on_zero_shared()
713{
714 if (this->__state_ & base::__constructed)
715 reinterpret_cast<_R*>(&this->__value_)->~_R();
716 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
717 this->~__assoc_state_alloc();
718 __a.deallocate(this, 1);
719}
720
Howard Hinnantf39daa82010-08-28 21:01:06 +0000721template <class _R, class _Alloc>
722class __assoc_state_alloc<_R&, _Alloc>
723 : public __assoc_state<_R&>
724{
725 typedef __assoc_state<_R&> base;
726 _Alloc __alloc_;
727
728 virtual void __on_zero_shared();
729public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000730 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000731 explicit __assoc_state_alloc(const _Alloc& __a)
732 : __alloc_(__a) {}
733};
734
735template <class _R, class _Alloc>
736void
737__assoc_state_alloc<_R&, _Alloc>::__on_zero_shared()
738{
739 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
740 this->~__assoc_state_alloc();
741 __a.deallocate(this, 1);
742}
743
Howard Hinnant47499b12010-08-27 20:10:19 +0000744template <class _Alloc>
745class __assoc_sub_state_alloc
746 : public __assoc_sub_state
747{
748 typedef __assoc_sub_state base;
749 _Alloc __alloc_;
750
751 virtual void __on_zero_shared();
752public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000753 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000754 explicit __assoc_sub_state_alloc(const _Alloc& __a)
755 : __alloc_(__a) {}
756};
757
758template <class _Alloc>
759void
760__assoc_sub_state_alloc<_Alloc>::__on_zero_shared()
761{
762 this->~base();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000763 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000764 this->~__assoc_sub_state_alloc();
765 __a.deallocate(this, 1);
766}
767
Howard Hinnant54da3382010-08-30 18:46:21 +0000768template <class _R, class _F>
769class __deferred_assoc_state
770 : public __assoc_state<_R>
771{
772 typedef __assoc_state<_R> base;
773
774 _F __func_;
775
776public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000777#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000778 explicit __deferred_assoc_state(_F&& __f);
779#endif
780
781 virtual void __execute();
782};
783
Howard Hinnant73d21a42010-09-04 23:28:19 +0000784#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000785
786template <class _R, class _F>
787inline _LIBCPP_INLINE_VISIBILITY
788__deferred_assoc_state<_R, _F>::__deferred_assoc_state(_F&& __f)
789 : __func_(_STD::forward<_F>(__f))
790{
791 this->__set_deferred();
792}
793
Howard Hinnant73d21a42010-09-04 23:28:19 +0000794#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000795
796template <class _R, class _F>
797void
798__deferred_assoc_state<_R, _F>::__execute()
799{
800#ifndef _LIBCPP_NO_EXCEPTIONS
801 try
802 {
803#endif // _LIBCPP_NO_EXCEPTIONS
804 this->set_value(__func_());
805#ifndef _LIBCPP_NO_EXCEPTIONS
806 }
807 catch (...)
808 {
809 this->set_exception(current_exception());
810 }
811#endif // _LIBCPP_NO_EXCEPTIONS
812}
813
814template <class _F>
815class __deferred_assoc_state<void, _F>
816 : public __assoc_sub_state
817{
818 typedef __assoc_sub_state base;
819
820 _F __func_;
821
822public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000823#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000824 explicit __deferred_assoc_state(_F&& __f);
825#endif
826
827 virtual void __execute();
828};
829
Howard Hinnant73d21a42010-09-04 23:28:19 +0000830#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000831
832template <class _F>
833inline _LIBCPP_INLINE_VISIBILITY
834__deferred_assoc_state<void, _F>::__deferred_assoc_state(_F&& __f)
835 : __func_(_STD::forward<_F>(__f))
836{
837 this->__set_deferred();
838}
839
Howard Hinnant73d21a42010-09-04 23:28:19 +0000840#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000841
842template <class _F>
843void
844__deferred_assoc_state<void, _F>::__execute()
845{
846#ifndef _LIBCPP_NO_EXCEPTIONS
847 try
848 {
849#endif // _LIBCPP_NO_EXCEPTIONS
850 __func_();
851 this->set_value();
852#ifndef _LIBCPP_NO_EXCEPTIONS
853 }
854 catch (...)
855 {
856 this->set_exception(current_exception());
857 }
858#endif // _LIBCPP_NO_EXCEPTIONS
859}
860
Howard Hinnant57cff292011-05-19 15:05:04 +0000861template <class _R, class _F>
862class __async_assoc_state
863 : public __assoc_state<_R>
864{
865 typedef __assoc_state<_R> base;
866
867 _F __func_;
868
869 virtual void __on_zero_shared();
870public:
871#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
872 explicit __async_assoc_state(_F&& __f);
873#endif
874
875 virtual void __execute();
876};
877
878#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
879
880template <class _R, class _F>
881inline _LIBCPP_INLINE_VISIBILITY
882__async_assoc_state<_R, _F>::__async_assoc_state(_F&& __f)
883 : __func_(_STD::forward<_F>(__f))
884{
885}
886
887#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
888
889template <class _R, class _F>
890void
891__async_assoc_state<_R, _F>::__execute()
892{
893#ifndef _LIBCPP_NO_EXCEPTIONS
894 try
895 {
896#endif // _LIBCPP_NO_EXCEPTIONS
897 this->set_value(__func_());
898#ifndef _LIBCPP_NO_EXCEPTIONS
899 }
900 catch (...)
901 {
902 this->set_exception(current_exception());
903 }
904#endif // _LIBCPP_NO_EXCEPTIONS
905}
906
907template <class _R, class _F>
908void
909__async_assoc_state<_R, _F>::__on_zero_shared()
910{
911 this->wait();
912 base::__on_zero_shared();
913}
914
915template <class _F>
916class __async_assoc_state<void, _F>
917 : public __assoc_sub_state
918{
919 typedef __assoc_sub_state base;
920
921 _F __func_;
922
923 virtual void __on_zero_shared();
924public:
925#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
926 explicit __async_assoc_state(_F&& __f);
927#endif
928
929 virtual void __execute();
930};
931
932#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
933
934template <class _F>
935inline _LIBCPP_INLINE_VISIBILITY
936__async_assoc_state<void, _F>::__async_assoc_state(_F&& __f)
937 : __func_(_STD::forward<_F>(__f))
938{
939}
940
941#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
942
943template <class _F>
944void
945__async_assoc_state<void, _F>::__execute()
946{
947#ifndef _LIBCPP_NO_EXCEPTIONS
948 try
949 {
950#endif // _LIBCPP_NO_EXCEPTIONS
951 __func_();
952 this->set_value();
953#ifndef _LIBCPP_NO_EXCEPTIONS
954 }
955 catch (...)
956 {
957 this->set_exception(current_exception());
958 }
959#endif // _LIBCPP_NO_EXCEPTIONS
960}
961
962template <class _F>
963void
964__async_assoc_state<void, _F>::__on_zero_shared()
965{
966 this->wait();
967 base::__on_zero_shared();
968}
969
Howard Hinnant47499b12010-08-27 20:10:19 +0000970template <class> class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +0000971template <class> class shared_future;
972template <class> class atomic_future;
Howard Hinnant47499b12010-08-27 20:10:19 +0000973
974// future
975
Howard Hinnant54da3382010-08-30 18:46:21 +0000976template <class _R> class future;
977
978template <class _R, class _F>
979future<_R>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000980#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000981__make_deferred_assoc_state(_F&& __f);
982#else
983__make_deferred_assoc_state(_F __f);
984#endif
985
Howard Hinnant57cff292011-05-19 15:05:04 +0000986template <class _R, class _F>
987future<_R>
988#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
989__make_async_assoc_state(_F&& __f);
990#else
991__make_async_assoc_state(_F __f);
992#endif
993
Howard Hinnant47499b12010-08-27 20:10:19 +0000994template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000995class _LIBCPP_VISIBLE future
Howard Hinnant47499b12010-08-27 20:10:19 +0000996{
997 __assoc_state<_R>* __state_;
998
999 explicit future(__assoc_state<_R>* __state);
1000
1001 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001002 template <class> friend class shared_future;
1003 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001004
Howard Hinnant73d21a42010-09-04 23:28:19 +00001005#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant57cff292011-05-19 15:05:04 +00001006 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:21 +00001007 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001008 template <class _R1, class _F>
1009 friend future<_R1> __make_async_assoc_state(_F&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001010#else
Howard Hinnant57cff292011-05-19 15:05:04 +00001011 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:21 +00001012 friend future<_R1> __make_deferred_assoc_state(_F __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001013 template <class _R1, class _F>
1014 friend future<_R1> __make_async_assoc_state(_F __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001015#endif
1016
Howard Hinnant47499b12010-08-27 20:10:19 +00001017public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001018 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001019 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001020#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001021 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001022 future(future&& __rhs)
1023 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1024 future(const future&) = delete;
1025 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001026 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001027 future& operator=(future&& __rhs)
1028 {
1029 future(std::move(__rhs)).swap(*this);
1030 return *this;
1031 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001032#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001033private:
1034 future(const future&);
1035 future& operator=(const future&);
1036public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001037#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001038 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001039 shared_future<_R> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001040
1041 // retrieving the value
1042 _R get();
1043
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001045 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1046
1047 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001049 bool valid() const {return __state_ != nullptr;}
1050
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001052 void wait() const {__state_->wait();}
1053 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001055 future_status
1056 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1057 {return __state_->wait_for(__rel_time);}
1058 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001060 future_status
1061 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1062 {return __state_->wait_until(__abs_time);}
1063};
1064
1065template <class _R>
1066future<_R>::future(__assoc_state<_R>* __state)
1067 : __state_(__state)
1068{
1069 if (__state_->__has_future_attached())
1070 throw future_error(make_error_code(future_errc::future_already_retrieved));
1071 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001072 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001073}
1074
Howard Hinnant54da3382010-08-30 18:46:21 +00001075struct __release_shared_count
1076{
1077 void operator()(__shared_count* p) {p->__release_shared();}
1078};
1079
Howard Hinnant47499b12010-08-27 20:10:19 +00001080template <class _R>
1081future<_R>::~future()
1082{
1083 if (__state_)
1084 __state_->__release_shared();
1085}
1086
1087template <class _R>
1088_R
1089future<_R>::get()
1090{
Howard Hinnant54da3382010-08-30 18:46:21 +00001091 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001092 __assoc_state<_R>* __s = __state_;
1093 __state_ = nullptr;
1094 return __s->move();
1095}
1096
1097template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001098class _LIBCPP_VISIBLE future<_R&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001099{
1100 __assoc_state<_R&>* __state_;
1101
1102 explicit future(__assoc_state<_R&>* __state);
1103
1104 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001105 template <class> friend class shared_future;
1106 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001107
Howard Hinnant73d21a42010-09-04 23:28:19 +00001108#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant57cff292011-05-19 15:05:04 +00001109 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:21 +00001110 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001111 template <class _R1, class _F>
1112 friend future<_R1> __make_async_assoc_state(_F&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001113#else
Howard Hinnant57cff292011-05-19 15:05:04 +00001114 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:21 +00001115 friend future<_R1> __make_deferred_assoc_state(_F __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001116 template <class _R1, class _F>
1117 friend future<_R1> __make_async_assoc_state(_F __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001118#endif
1119
Howard Hinnant47499b12010-08-27 20:10:19 +00001120public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001121 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001122 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001123#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001124 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001125 future(future&& __rhs)
1126 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1127 future(const future&) = delete;
1128 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001129 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001130 future& operator=(future&& __rhs)
1131 {
1132 future(std::move(__rhs)).swap(*this);
1133 return *this;
1134 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001135#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001136private:
1137 future(const future&);
1138 future& operator=(const future&);
1139public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001140#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001141 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001142 shared_future<_R&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001143
1144 // retrieving the value
1145 _R& get();
1146
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001147 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001148 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1149
1150 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001151 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001152 bool valid() const {return __state_ != nullptr;}
1153
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001154 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001155 void wait() const {__state_->wait();}
1156 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001157 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001158 future_status
1159 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1160 {return __state_->wait_for(__rel_time);}
1161 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001162 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001163 future_status
1164 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1165 {return __state_->wait_until(__abs_time);}
1166};
1167
1168template <class _R>
1169future<_R&>::future(__assoc_state<_R&>* __state)
1170 : __state_(__state)
1171{
1172 if (__state_->__has_future_attached())
1173 throw future_error(make_error_code(future_errc::future_already_retrieved));
1174 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001175 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001176}
1177
1178template <class _R>
1179future<_R&>::~future()
1180{
1181 if (__state_)
1182 __state_->__release_shared();
1183}
1184
1185template <class _R>
1186_R&
1187future<_R&>::get()
1188{
Howard Hinnant54da3382010-08-30 18:46:21 +00001189 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantf39daa82010-08-28 21:01:06 +00001190 __assoc_state<_R&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001191 __state_ = nullptr;
1192 return __s->copy();
1193}
1194
1195template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001196class _LIBCPP_VISIBLE future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001197{
1198 __assoc_sub_state* __state_;
1199
1200 explicit future(__assoc_sub_state* __state);
1201
1202 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001203 template <class> friend class shared_future;
1204 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001205
Howard Hinnant73d21a42010-09-04 23:28:19 +00001206#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant57cff292011-05-19 15:05:04 +00001207 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:21 +00001208 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001209 template <class _R1, class _F>
1210 friend future<_R1> __make_async_assoc_state(_F&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001211#else
Howard Hinnant57cff292011-05-19 15:05:04 +00001212 template <class _R1, class _F>
Howard Hinnant54da3382010-08-30 18:46:21 +00001213 friend future<_R1> __make_deferred_assoc_state(_F __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001214 template <class _R1, class _F>
1215 friend future<_R1> __make_async_assoc_state(_F __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001216#endif
1217
Howard Hinnant47499b12010-08-27 20:10:19 +00001218public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001219 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001220 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001221#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001222 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001223 future(future&& __rhs)
1224 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1225 future(const future&) = delete;
1226 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001227 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001228 future& operator=(future&& __rhs)
1229 {
1230 future(std::move(__rhs)).swap(*this);
1231 return *this;
1232 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001233#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001234private:
1235 future(const future&);
1236 future& operator=(const future&);
1237public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001238#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001239 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001240 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001241
1242 // retrieving the value
1243 void get();
1244
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001246 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1247
1248 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001250 bool valid() const {return __state_ != nullptr;}
1251
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001252 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001253 void wait() const {__state_->wait();}
1254 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001255 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001256 future_status
1257 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1258 {return __state_->wait_for(__rel_time);}
1259 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001260 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001261 future_status
1262 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1263 {return __state_->wait_until(__abs_time);}
1264};
1265
Howard Hinnant99be8232010-09-03 18:39:25 +00001266template <class _R>
1267inline _LIBCPP_INLINE_VISIBILITY
1268void
1269swap(future<_R>& __x, future<_R>& __y)
1270{
1271 __x.swap(__y);
1272}
1273
Howard Hinnant47499b12010-08-27 20:10:19 +00001274// promise<R>
1275
Howard Hinnant54da3382010-08-30 18:46:21 +00001276template <class> class packaged_task;
1277
Howard Hinnant47499b12010-08-27 20:10:19 +00001278template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001279class _LIBCPP_VISIBLE promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001280{
1281 __assoc_state<_R>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001282
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001284 explicit promise(nullptr_t) : __state_(nullptr) {}
1285
1286 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001287public:
1288 promise();
1289 template <class _Alloc>
1290 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001291#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001293 promise(promise&& __rhs)
1294 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1295 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001296#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001297private:
1298 promise(const promise& __rhs);
1299public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001300#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001301 ~promise();
1302
1303 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001304#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001306 promise& operator=(promise&& __rhs)
1307 {
1308 promise(std::move(__rhs)).swap(*this);
1309 return *this;
1310 }
1311 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001312#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001313private:
1314 promise& operator=(const promise& __rhs);
1315public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001316#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001318 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1319
1320 // retrieving the result
1321 future<_R> get_future();
1322
1323 // setting the result
1324 void set_value(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001325#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001326 void set_value(_R&& __r);
1327#endif
1328 void set_exception(exception_ptr __p);
1329
1330 // setting the result with deferred notification
1331 void set_value_at_thread_exit(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001332#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001333 void set_value_at_thread_exit(_R&& __r);
1334#endif
1335 void set_exception_at_thread_exit(exception_ptr __p);
1336};
1337
1338template <class _R>
1339promise<_R>::promise()
1340 : __state_(new __assoc_state<_R>)
1341{
1342}
1343
1344template <class _R>
1345template <class _Alloc>
1346promise<_R>::promise(allocator_arg_t, const _Alloc& __a0)
1347{
1348 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R, _Alloc> >::other _A2;
1349 typedef __allocator_destructor<_A2> _D2;
1350 _A2 __a(__a0);
1351 unique_ptr<__assoc_state_alloc<_R, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1352 ::new(__hold.get()) __assoc_state_alloc<_R, _Alloc>(__a0);
1353 __state_ = __hold.release();
1354}
1355
1356template <class _R>
1357promise<_R>::~promise()
1358{
1359 if (__state_)
1360 {
1361 if (!__state_->__has_value() && __state_->use_count() > 1)
1362 __state_->set_exception(make_exception_ptr(
1363 future_error(make_error_code(future_errc::broken_promise))
1364 ));
1365 __state_->__release_shared();
1366 }
1367}
1368
1369template <class _R>
1370future<_R>
1371promise<_R>::get_future()
1372{
1373 if (__state_ == nullptr)
1374 throw future_error(make_error_code(future_errc::no_state));
1375 return future<_R>(__state_);
1376}
1377
1378template <class _R>
1379void
1380promise<_R>::set_value(const _R& __r)
1381{
1382 if (__state_ == nullptr)
1383 throw future_error(make_error_code(future_errc::no_state));
1384 __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
1389template <class _R>
1390void
1391promise<_R>::set_value(_R&& __r)
1392{
1393 if (__state_ == nullptr)
1394 throw future_error(make_error_code(future_errc::no_state));
1395 __state_->set_value(_STD::move(__r));
1396}
1397
Howard Hinnant73d21a42010-09-04 23:28:19 +00001398#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001399
1400template <class _R>
1401void
1402promise<_R>::set_exception(exception_ptr __p)
1403{
1404 if (__state_ == nullptr)
1405 throw future_error(make_error_code(future_errc::no_state));
1406 __state_->set_exception(__p);
1407}
1408
1409template <class _R>
1410void
1411promise<_R>::set_value_at_thread_exit(const _R& __r)
1412{
1413 if (__state_ == nullptr)
1414 throw future_error(make_error_code(future_errc::no_state));
1415 __state_->set_value_at_thread_exit(__r);
1416}
1417
Howard Hinnant73d21a42010-09-04 23:28:19 +00001418#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001419
1420template <class _R>
1421void
1422promise<_R>::set_value_at_thread_exit(_R&& __r)
1423{
1424 if (__state_ == nullptr)
1425 throw future_error(make_error_code(future_errc::no_state));
1426 __state_->set_value_at_thread_exit(_STD::move(__r));
1427}
1428
Howard Hinnant73d21a42010-09-04 23:28:19 +00001429#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001430
1431template <class _R>
1432void
1433promise<_R>::set_exception_at_thread_exit(exception_ptr __p)
1434{
1435 if (__state_ == nullptr)
1436 throw future_error(make_error_code(future_errc::no_state));
1437 __state_->set_exception_at_thread_exit(__p);
1438}
1439
1440// promise<R&>
1441
1442template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001443class _LIBCPP_VISIBLE promise<_R&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001444{
1445 __assoc_state<_R&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001446
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001448 explicit promise(nullptr_t) : __state_(nullptr) {}
1449
1450 template <class> friend class packaged_task;
1451
Howard Hinnant47499b12010-08-27 20:10:19 +00001452public:
1453 promise();
1454 template <class _Allocator>
1455 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001456#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001458 promise(promise&& __rhs)
1459 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1460 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001461#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001462private:
1463 promise(const promise& __rhs);
1464public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001465#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001466 ~promise();
1467
1468 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001469#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001470 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001471 promise& operator=(promise&& __rhs)
1472 {
1473 promise(std::move(__rhs)).swap(*this);
1474 return *this;
1475 }
1476 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001477#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001478private:
1479 promise& operator=(const promise& __rhs);
1480public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001481#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001482 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001483 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1484
1485 // retrieving the result
1486 future<_R&> get_future();
1487
1488 // setting the result
1489 void set_value(_R& __r);
1490 void set_exception(exception_ptr __p);
1491
1492 // setting the result with deferred notification
1493 void set_value_at_thread_exit(_R&);
1494 void set_exception_at_thread_exit(exception_ptr __p);
1495};
1496
1497template <class _R>
1498promise<_R&>::promise()
1499 : __state_(new __assoc_state<_R&>)
1500{
1501}
1502
1503template <class _R>
1504template <class _Alloc>
1505promise<_R&>::promise(allocator_arg_t, const _Alloc& __a0)
1506{
1507 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R&, _Alloc> >::other _A2;
1508 typedef __allocator_destructor<_A2> _D2;
1509 _A2 __a(__a0);
1510 unique_ptr<__assoc_state_alloc<_R&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1511 ::new(__hold.get()) __assoc_state_alloc<_R&, _Alloc>(__a0);
1512 __state_ = __hold.release();
1513}
1514
1515template <class _R>
1516promise<_R&>::~promise()
1517{
1518 if (__state_)
1519 {
1520 if (!__state_->__has_value() && __state_->use_count() > 1)
1521 __state_->set_exception(make_exception_ptr(
1522 future_error(make_error_code(future_errc::broken_promise))
1523 ));
1524 __state_->__release_shared();
1525 }
1526}
1527
1528template <class _R>
1529future<_R&>
1530promise<_R&>::get_future()
1531{
1532 if (__state_ == nullptr)
1533 throw future_error(make_error_code(future_errc::no_state));
1534 return future<_R&>(__state_);
1535}
1536
1537template <class _R>
1538void
1539promise<_R&>::set_value(_R& __r)
1540{
1541 if (__state_ == nullptr)
1542 throw future_error(make_error_code(future_errc::no_state));
1543 __state_->set_value(__r);
1544}
1545
1546template <class _R>
1547void
1548promise<_R&>::set_exception(exception_ptr __p)
1549{
1550 if (__state_ == nullptr)
1551 throw future_error(make_error_code(future_errc::no_state));
1552 __state_->set_exception(__p);
1553}
1554
1555template <class _R>
1556void
1557promise<_R&>::set_value_at_thread_exit(_R& __r)
1558{
1559 if (__state_ == nullptr)
1560 throw future_error(make_error_code(future_errc::no_state));
1561 __state_->set_value_at_thread_exit(__r);
1562}
1563
1564template <class _R>
1565void
1566promise<_R&>::set_exception_at_thread_exit(exception_ptr __p)
1567{
1568 if (__state_ == nullptr)
1569 throw future_error(make_error_code(future_errc::no_state));
1570 __state_->set_exception_at_thread_exit(__p);
1571}
1572
1573// promise<void>
1574
1575template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001576class _LIBCPP_VISIBLE promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001577{
1578 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001579
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001580 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001581 explicit promise(nullptr_t) : __state_(nullptr) {}
1582
1583 template <class> friend class packaged_task;
1584
Howard Hinnant47499b12010-08-27 20:10:19 +00001585public:
1586 promise();
1587 template <class _Allocator>
1588 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001589#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001590 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001591 promise(promise&& __rhs)
1592 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1593 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001594#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001595private:
1596 promise(const promise& __rhs);
1597public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001598#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001599 ~promise();
1600
1601 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001602#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001604 promise& operator=(promise&& __rhs)
1605 {
1606 promise(std::move(__rhs)).swap(*this);
1607 return *this;
1608 }
1609 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001610#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001611private:
1612 promise& operator=(const promise& __rhs);
1613public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001614#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001615 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001616 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1617
1618 // retrieving the result
1619 future<void> get_future();
1620
1621 // setting the result
1622 void set_value();
1623 void set_exception(exception_ptr __p);
1624
1625 // setting the result with deferred notification
1626 void set_value_at_thread_exit();
1627 void set_exception_at_thread_exit(exception_ptr __p);
1628};
1629
1630template <class _Alloc>
1631promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1632{
1633 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1634 typedef __allocator_destructor<_A2> _D2;
1635 _A2 __a(__a0);
1636 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1637 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1638 __state_ = __hold.release();
1639}
1640
1641template <class _R>
1642inline _LIBCPP_INLINE_VISIBILITY
1643void
1644swap(promise<_R>& __x, promise<_R>& __y)
1645{
1646 __x.swap(__y);
1647}
1648
1649template <class _R, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001650 struct _LIBCPP_VISIBLE uses_allocator<promise<_R>, _Alloc>
1651 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001652
Howard Hinnant54da3382010-08-30 18:46:21 +00001653#ifndef _LIBCPP_HAS_NO_VARIADICS
1654
1655// packaged_task
1656
1657template<class _Fp> class __packaged_task_base;
1658
1659template<class _R, class ..._ArgTypes>
1660class __packaged_task_base<_R(_ArgTypes...)>
1661{
1662 __packaged_task_base(const __packaged_task_base&);
1663 __packaged_task_base& operator=(const __packaged_task_base&);
1664public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001665 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001666 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001667 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001668 virtual ~__packaged_task_base() {}
1669 virtual void __move_to(__packaged_task_base*) = 0;
1670 virtual void destroy() = 0;
1671 virtual void destroy_deallocate() = 0;
1672 virtual _R operator()(_ArgTypes&& ...) = 0;
1673};
1674
1675template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1676
1677template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1678class __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>
1679 : public __packaged_task_base<_R(_ArgTypes...)>
1680{
1681 __compressed_pair<_F, _Alloc> __f_;
1682public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001683 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001684 explicit __packaged_task_func(const _F& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001685 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001686 explicit __packaged_task_func(_F&& __f) : __f_(_STD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001687 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001688 __packaged_task_func(const _F& __f, const _Alloc& __a)
1689 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001690 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001691 __packaged_task_func(_F&& __f, const _Alloc& __a)
1692 : __f_(_STD::move(__f), __a) {}
1693 virtual void __move_to(__packaged_task_base<_R(_ArgTypes...)>*);
1694 virtual void destroy();
1695 virtual void destroy_deallocate();
1696 virtual _R operator()(_ArgTypes&& ... __args);
1697};
1698
1699template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1700void
1701__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::__move_to(
1702 __packaged_task_base<_R(_ArgTypes...)>* __p)
1703{
1704 ::new (__p) __packaged_task_func(_STD::move(__f_.first()), _STD::move(__f_.second()));
1705}
1706
1707template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1708void
1709__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy()
1710{
1711 __f_.~__compressed_pair<_F, _Alloc>();
1712}
1713
1714template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1715void
1716__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy_deallocate()
1717{
1718 typedef typename _Alloc::template rebind<__packaged_task_func>::other _A;
1719 _A __a(__f_.second());
1720 __f_.~__compressed_pair<_F, _Alloc>();
1721 __a.deallocate(this, 1);
1722}
1723
1724template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1725_R
1726__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1727{
1728 return __invoke(__f_.first(), _STD::forward<_ArgTypes>(__arg)...);
1729}
1730
1731template <class> class __packaged_task_function;
1732
1733template<class _R, class ..._ArgTypes>
1734class __packaged_task_function<_R(_ArgTypes...)>
1735{
1736 typedef __packaged_task_base<_R(_ArgTypes...)> __base;
1737 aligned_storage<3*sizeof(void*)>::type __buf_;
1738 __base* __f_;
1739
1740public:
1741 typedef _R result_type;
1742
1743 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001744 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001745 __packaged_task_function() : __f_(nullptr) {}
1746 template<class _F>
1747 __packaged_task_function(_F&& __f);
1748 template<class _F, class _Alloc>
1749 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _F&& __f);
1750
1751 __packaged_task_function(__packaged_task_function&&);
1752 __packaged_task_function& operator=(__packaged_task_function&&);
1753
1754 __packaged_task_function(const __packaged_task_function&) = delete;
1755 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1756
1757 ~__packaged_task_function();
1758
1759 void swap(__packaged_task_function&);
1760
1761 _R operator()(_ArgTypes...) const;
1762};
1763
1764template<class _R, class ..._ArgTypes>
1765__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f)
1766{
1767 if (__f.__f_ == nullptr)
1768 __f_ = nullptr;
1769 else if (__f.__f_ == (__base*)&__f.__buf_)
1770 {
1771 __f_ = (__base*)&__buf_;
1772 __f.__f_->__move_to(__f_);
1773 }
1774 else
1775 {
1776 __f_ = __f.__f_;
1777 __f.__f_ = nullptr;
1778 }
1779}
1780
1781template<class _R, class ..._ArgTypes>
1782template <class _F>
1783__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(_F&& __f)
1784 : __f_(nullptr)
1785{
1786 typedef typename remove_reference<_F>::type _FR;
1787 typedef __packaged_task_func<_FR, allocator<_FR>, _R(_ArgTypes...)> _FF;
1788 if (sizeof(_FF) <= sizeof(__buf_))
1789 {
1790 __f_ = (__base*)&__buf_;
1791 ::new (__f_) _FF(_STD::forward<_F>(__f));
1792 }
1793 else
1794 {
1795 typedef allocator<_FF> _A;
1796 _A __a;
1797 typedef __allocator_destructor<_A> _D;
1798 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1799 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), allocator<_FR>(__a));
1800 __f_ = __hold.release();
1801 }
1802}
1803
1804template<class _R, class ..._ArgTypes>
1805template <class _F, class _Alloc>
1806__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(
1807 allocator_arg_t, const _Alloc& __a0, _F&& __f)
1808 : __f_(nullptr)
1809{
1810 typedef allocator_traits<_Alloc> __alloc_traits;
1811 typedef typename remove_reference<_F>::type _FR;
1812 typedef __packaged_task_func<_FR, _Alloc, _R(_ArgTypes...)> _FF;
1813 if (sizeof(_FF) <= sizeof(__buf_))
1814 {
1815 __f_ = (__base*)&__buf_;
1816 ::new (__f_) _FF(_STD::forward<_F>(__f));
1817 }
1818 else
1819 {
1820 typedef typename __alloc_traits::template
1821#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1822 rebind_alloc<_FF>
1823#else
1824 rebind_alloc<_FF>::other
1825#endif
1826 _A;
1827 _A __a(__a0);
1828 typedef __allocator_destructor<_A> _D;
1829 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1830 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), _Alloc(__a));
1831 __f_ = __hold.release();
1832 }
1833}
1834
1835template<class _R, class ..._ArgTypes>
1836__packaged_task_function<_R(_ArgTypes...)>&
1837__packaged_task_function<_R(_ArgTypes...)>::operator=(__packaged_task_function&& __f)
1838{
1839 if (__f_ == (__base*)&__buf_)
1840 __f_->destroy();
1841 else if (__f_)
1842 __f_->destroy_deallocate();
1843 __f_ = nullptr;
1844 if (__f.__f_ == nullptr)
1845 __f_ = nullptr;
1846 else if (__f.__f_ == (__base*)&__f.__buf_)
1847 {
1848 __f_ = (__base*)&__buf_;
1849 __f.__f_->__move_to(__f_);
1850 }
1851 else
1852 {
1853 __f_ = __f.__f_;
1854 __f.__f_ = nullptr;
1855 }
1856}
1857
1858template<class _R, class ..._ArgTypes>
1859__packaged_task_function<_R(_ArgTypes...)>::~__packaged_task_function()
1860{
1861 if (__f_ == (__base*)&__buf_)
1862 __f_->destroy();
1863 else if (__f_)
1864 __f_->destroy_deallocate();
1865}
1866
1867template<class _R, class ..._ArgTypes>
1868void
1869__packaged_task_function<_R(_ArgTypes...)>::swap(__packaged_task_function& __f)
1870{
1871 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1872 {
1873 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1874 __base* __t = (__base*)&__tempbuf;
1875 __f_->__move_to(__t);
1876 __f_->destroy();
1877 __f_ = nullptr;
1878 __f.__f_->__move_to((__base*)&__buf_);
1879 __f.__f_->destroy();
1880 __f.__f_ = nullptr;
1881 __f_ = (__base*)&__buf_;
1882 __t->__move_to((__base*)&__f.__buf_);
1883 __t->destroy();
1884 __f.__f_ = (__base*)&__f.__buf_;
1885 }
1886 else if (__f_ == (__base*)&__buf_)
1887 {
1888 __f_->__move_to((__base*)&__f.__buf_);
1889 __f_->destroy();
1890 __f_ = __f.__f_;
1891 __f.__f_ = (__base*)&__f.__buf_;
1892 }
1893 else if (__f.__f_ == (__base*)&__f.__buf_)
1894 {
1895 __f.__f_->__move_to((__base*)&__buf_);
1896 __f.__f_->destroy();
1897 __f.__f_ = __f_;
1898 __f_ = (__base*)&__buf_;
1899 }
1900 else
1901 _STD::swap(__f_, __f.__f_);
1902}
1903
1904template<class _R, class ..._ArgTypes>
1905inline _LIBCPP_INLINE_VISIBILITY
1906_R
1907__packaged_task_function<_R(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1908{
1909 return (*__f_)(_STD::forward<_ArgTypes>(__arg)...);
1910}
1911
1912template<class _R, class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001913class _LIBCPP_VISIBLE packaged_task<_R(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001914{
1915public:
1916 typedef _R result_type;
1917
1918private:
1919 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1920 promise<result_type> __p_;
1921
1922public:
1923 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001924 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001925 packaged_task() : __p_(nullptr) {}
1926 template <class _F>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001927 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001928 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
1929 template <class _F, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001930 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001931 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
1932 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
1933 __p_(allocator_arg, __a) {}
1934 // ~packaged_task() = default;
1935
1936 // no copy
1937 packaged_task(packaged_task&) = delete;
1938 packaged_task& operator=(packaged_task&) = delete;
1939
1940 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001941 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001942 packaged_task(packaged_task&& __other)
1943 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001944 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001945 packaged_task& operator=(packaged_task&& __other)
1946 {
1947 __f_ = _STD::move(__other.__f_);
1948 __p_ = _STD::move(__other.__p_);
1949 return *this;
1950 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001951 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001952 void swap(packaged_task& __other)
1953 {
1954 __f_.swap(__other.__f_);
1955 __p_.swap(__other.__p_);
1956 }
1957
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001958 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00001959 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00001960
1961 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001962 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001963 future<result_type> get_future() {return __p_.get_future();}
1964
1965 // execution
1966 void operator()(_ArgTypes... __args);
1967 void make_ready_at_thread_exit(_ArgTypes... __args);
1968
1969 void reset();
1970};
1971
1972template<class _R, class ..._ArgTypes>
1973void
1974packaged_task<_R(_ArgTypes...)>::operator()(_ArgTypes... __args)
1975{
1976#ifndef _LIBCPP_NO_EXCEPTIONS
1977 if (__p_.__state_ == nullptr)
1978 throw future_error(make_error_code(future_errc::no_state));
1979 if (__p_.__state_->__has_value())
1980 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1981 try
1982 {
1983#endif // _LIBCPP_NO_EXCEPTIONS
1984 __p_.set_value(__f_(_STD::forward<_ArgTypes>(__args)...));
1985#ifndef _LIBCPP_NO_EXCEPTIONS
1986 }
1987 catch (...)
1988 {
1989 __p_.set_exception(current_exception());
1990 }
1991#endif // _LIBCPP_NO_EXCEPTIONS
1992}
1993
1994template<class _R, class ..._ArgTypes>
1995void
1996packaged_task<_R(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
1997{
1998#ifndef _LIBCPP_NO_EXCEPTIONS
1999 if (__p_.__state_ == nullptr)
2000 throw future_error(make_error_code(future_errc::no_state));
2001 if (__p_.__state_->__has_value())
2002 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2003 try
2004 {
2005#endif // _LIBCPP_NO_EXCEPTIONS
2006 __p_.set_value_at_thread_exit(__f_(_STD::forward<_ArgTypes>(__args)...));
2007#ifndef _LIBCPP_NO_EXCEPTIONS
2008 }
2009 catch (...)
2010 {
2011 __p_.set_exception_at_thread_exit(current_exception());
2012 }
2013#endif // _LIBCPP_NO_EXCEPTIONS
2014}
2015
2016template<class _R, class ..._ArgTypes>
2017void
2018packaged_task<_R(_ArgTypes...)>::reset()
2019{
2020#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002021 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002022 throw future_error(make_error_code(future_errc::no_state));
2023#endif // _LIBCPP_NO_EXCEPTIONS
2024 __p_ = promise<result_type>();
2025}
2026
2027template<class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002028class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002029{
2030public:
2031 typedef void result_type;
2032
2033private:
2034 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2035 promise<result_type> __p_;
2036
2037public:
2038 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002039 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002040 packaged_task() : __p_(nullptr) {}
2041 template <class _F>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002042 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002043 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
2044 template <class _F, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002045 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002046 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
2047 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
2048 __p_(allocator_arg, __a) {}
2049 // ~packaged_task() = default;
2050
2051 // no copy
2052 packaged_task(packaged_task&) = delete;
2053 packaged_task& operator=(packaged_task&) = delete;
2054
2055 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002057 packaged_task(packaged_task&& __other)
2058 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002060 packaged_task& operator=(packaged_task&& __other)
2061 {
2062 __f_ = _STD::move(__other.__f_);
2063 __p_ = _STD::move(__other.__p_);
2064 return *this;
2065 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002067 void swap(packaged_task& __other)
2068 {
2069 __f_.swap(__other.__f_);
2070 __p_.swap(__other.__p_);
2071 }
2072
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00002074 bool valid() const {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002075
2076 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002077 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002078 future<result_type> get_future() {return __p_.get_future();}
2079
2080 // execution
2081 void operator()(_ArgTypes... __args);
2082 void make_ready_at_thread_exit(_ArgTypes... __args);
2083
2084 void reset();
2085};
2086
2087template<class ..._ArgTypes>
2088void
2089packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2090{
2091#ifndef _LIBCPP_NO_EXCEPTIONS
2092 if (__p_.__state_ == nullptr)
2093 throw future_error(make_error_code(future_errc::no_state));
2094 if (__p_.__state_->__has_value())
2095 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2096 try
2097 {
2098#endif // _LIBCPP_NO_EXCEPTIONS
2099 __f_(_STD::forward<_ArgTypes>(__args)...);
2100 __p_.set_value();
2101#ifndef _LIBCPP_NO_EXCEPTIONS
2102 }
2103 catch (...)
2104 {
2105 __p_.set_exception(current_exception());
2106 }
2107#endif // _LIBCPP_NO_EXCEPTIONS
2108}
2109
2110template<class ..._ArgTypes>
2111void
2112packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2113{
2114#ifndef _LIBCPP_NO_EXCEPTIONS
2115 if (__p_.__state_ == nullptr)
2116 throw future_error(make_error_code(future_errc::no_state));
2117 if (__p_.__state_->__has_value())
2118 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2119 try
2120 {
2121#endif // _LIBCPP_NO_EXCEPTIONS
2122 __f_(_STD::forward<_ArgTypes>(__args)...);
2123 __p_.set_value_at_thread_exit();
2124#ifndef _LIBCPP_NO_EXCEPTIONS
2125 }
2126 catch (...)
2127 {
2128 __p_.set_exception_at_thread_exit(current_exception());
2129 }
2130#endif // _LIBCPP_NO_EXCEPTIONS
2131}
2132
2133template<class ..._ArgTypes>
2134void
2135packaged_task<void(_ArgTypes...)>::reset()
2136{
2137#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002138 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002139 throw future_error(make_error_code(future_errc::no_state));
2140#endif // _LIBCPP_NO_EXCEPTIONS
2141 __p_ = promise<result_type>();
2142}
2143
2144template <class _Callable>
2145inline _LIBCPP_INLINE_VISIBILITY
2146void
2147swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y)
2148{
2149 __x.swap(__y);
2150}
2151
2152template <class _Callable, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002153struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2154 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002155
2156template <class _R, class _F>
2157future<_R>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002158#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +00002159__make_deferred_assoc_state(_F&& __f)
2160#else
2161__make_deferred_assoc_state(_F __f)
2162#endif
2163{
2164 unique_ptr<__deferred_assoc_state<_R, _F>, __release_shared_count>
2165 __h(new __deferred_assoc_state<_R, _F>(_STD::forward<_F>(__f)));
2166 return future<_R>(__h.get());
2167}
2168
Howard Hinnant57cff292011-05-19 15:05:04 +00002169template <class _R, class _F>
2170future<_R>
2171#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2172__make_async_assoc_state(_F&& __f)
2173#else
2174__make_async_assoc_state(_F __f)
2175#endif
2176{
2177 unique_ptr<__async_assoc_state<_R, _F>, __release_shared_count>
2178 __h(new __async_assoc_state<_R, _F>(_STD::forward<_F>(__f)));
2179 _STD::thread(&__async_assoc_state<_R, _F>::__execute, __h.get()).detach();
2180 return future<_R>(__h.get());
2181}
2182
Howard Hinnant54da3382010-08-30 18:46:21 +00002183template <class _F, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002184class __async_func
2185{
2186 tuple<_F, _Args...> __f_;
2187
2188public:
2189 typedef typename __invoke_of<_F, _Args...>::type _R;
2190
2191 _LIBCPP_INLINE_VISIBILITY
2192 explicit __async_func(_F&& __f, _Args&&... __args)
2193 : __f_(_STD::move(__f), _STD::move(__args)...) {}
2194
2195 _LIBCPP_INLINE_VISIBILITY
2196 __async_func(__async_func&& __f) : __f_(_STD::move(__f.__f_)) {}
2197
2198 _R operator()()
2199 {
2200 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2201 return __execute(_Index());
2202 }
2203private:
2204 template <size_t ..._Indices>
2205 _R
2206 __execute(__tuple_indices<_Indices...>)
2207 {
2208 return __invoke(_STD::move(_STD::get<0>(__f_)), _STD::move(_STD::get<_Indices>(__f_))...);
2209 }
2210};
2211
2212template <class _F, class... _Args>
2213future<typename __invoke_of<typename decay<_F>::type, typename decay<_Args>::type...>::type>
Howard Hinnant54da3382010-08-30 18:46:21 +00002214async(launch __policy, _F&& __f, _Args&&... __args)
2215{
Howard Hinnant57cff292011-05-19 15:05:04 +00002216 typedef __async_func<typename decay<_F>::type, typename decay<_Args>::type...> _BF;
2217 typedef typename _BF::_R _R;
Howard Hinnant54da3382010-08-30 18:46:21 +00002218 future<_R> __r;
Howard Hinnant66895642010-11-23 18:33:54 +00002219 if (__policy & launch::async)
Howard Hinnant57cff292011-05-19 15:05:04 +00002220 __r = _STD::__make_async_assoc_state<_R>(_BF(__decay_copy(_STD::forward<_F>(__f)),
2221 __decay_copy(_STD::forward<_Args>(__args))...));
Howard Hinnant66895642010-11-23 18:33:54 +00002222 else if (__policy & launch::deferred)
Howard Hinnant57cff292011-05-19 15:05:04 +00002223 __r = _STD::__make_deferred_assoc_state<_R>(_BF(__decay_copy(_STD::forward<_F>(__f)),
2224 __decay_copy(_STD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002225 return __r;
2226}
2227
2228template <class _F, class... _Args>
2229inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant57cff292011-05-19 15:05:04 +00002230future<typename __invoke_of<typename decay<_F>::type, typename decay<_Args>::type...>::type>
Howard Hinnant54da3382010-08-30 18:46:21 +00002231async(_F&& __f, _Args&&... __args)
2232{
Howard Hinnanted22f562011-05-16 16:20:59 +00002233 return _STD::async(launch::any, _STD::forward<_F>(__f),
2234 _STD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002235}
2236
2237#endif // _LIBCPP_HAS_NO_VARIADICS
2238
Howard Hinnante6e4d012010-09-03 21:46:37 +00002239// shared_future
2240
Howard Hinnant99be8232010-09-03 18:39:25 +00002241template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002242class _LIBCPP_VISIBLE shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002243{
2244 __assoc_state<_R>* __state_;
2245
2246public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002248 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002250 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2251 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002252#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002253 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002254 shared_future(future<_R>&& __f) : __state_(__f.__state_)
2255 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002257 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2258 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002259#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002260 ~shared_future();
2261 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002262#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002263 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002264 shared_future& operator=(shared_future&& __rhs)
2265 {
2266 shared_future(std::move(__rhs)).swap(*this);
2267 return *this;
2268 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002269#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002270
2271 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002272 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002273 const _R& get() const {return __state_->copy();}
2274
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002275 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002276 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2277
2278 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002279 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002280 bool valid() const {return __state_ != nullptr;}
2281
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002282 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002283 void wait() const {__state_->wait();}
2284 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002286 future_status
2287 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2288 {return __state_->wait_for(__rel_time);}
2289 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002290 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002291 future_status
2292 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2293 {return __state_->wait_until(__abs_time);}
2294};
2295
2296template <class _R>
2297shared_future<_R>::~shared_future()
2298{
2299 if (__state_)
2300 __state_->__release_shared();
2301}
2302
2303template <class _R>
2304shared_future<_R>&
2305shared_future<_R>::operator=(const shared_future& __rhs)
2306{
2307 if (__rhs.__state_)
2308 __rhs.__state_->__add_shared();
2309 if (__state_)
2310 __state_->__release_shared();
2311 __state_ = __rhs.__state_;
2312 return *this;
2313}
2314
2315template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002316class _LIBCPP_VISIBLE shared_future<_R&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002317{
2318 __assoc_state<_R&>* __state_;
2319
2320public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002322 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002324 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2325 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002326#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002328 shared_future(future<_R&>&& __f) : __state_(__f.__state_)
2329 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002331 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2332 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002333#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002334 ~shared_future();
2335 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002336#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002337 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002338 shared_future& operator=(shared_future&& __rhs)
2339 {
2340 shared_future(std::move(__rhs)).swap(*this);
2341 return *this;
2342 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002343#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002344
2345 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002346 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002347 _R& get() const {return __state_->copy();}
2348
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002349 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002350 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2351
2352 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002353 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002354 bool valid() const {return __state_ != nullptr;}
2355
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002356 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002357 void wait() const {__state_->wait();}
2358 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002359 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002360 future_status
2361 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2362 {return __state_->wait_for(__rel_time);}
2363 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002364 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002365 future_status
2366 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2367 {return __state_->wait_until(__abs_time);}
2368};
2369
2370template <class _R>
2371shared_future<_R&>::~shared_future()
2372{
2373 if (__state_)
2374 __state_->__release_shared();
2375}
2376
2377template <class _R>
2378shared_future<_R&>&
2379shared_future<_R&>::operator=(const shared_future& __rhs)
2380{
2381 if (__rhs.__state_)
2382 __rhs.__state_->__add_shared();
2383 if (__state_)
2384 __state_->__release_shared();
2385 __state_ = __rhs.__state_;
2386 return *this;
2387}
2388
2389template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002390class _LIBCPP_VISIBLE shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002391{
2392 __assoc_sub_state* __state_;
2393
2394public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002396 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002397 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002398 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2399 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002400#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002402 shared_future(future<void>&& __f) : __state_(__f.__state_)
2403 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002405 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2406 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002407#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002408 ~shared_future();
2409 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002410#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002412 shared_future& operator=(shared_future&& __rhs)
2413 {
2414 shared_future(std::move(__rhs)).swap(*this);
2415 return *this;
2416 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002417#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002418
2419 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002421 void get() const {__state_->copy();}
2422
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002424 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2425
2426 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002427 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002428 bool valid() const {return __state_ != nullptr;}
2429
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002430 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002431 void wait() const {__state_->wait();}
2432 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002434 future_status
2435 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2436 {return __state_->wait_for(__rel_time);}
2437 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002438 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002439 future_status
2440 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2441 {return __state_->wait_until(__abs_time);}
2442};
2443
2444template <class _R>
2445inline _LIBCPP_INLINE_VISIBILITY
2446void
2447swap(shared_future<_R>& __x, shared_future<_R>& __y)
2448{
2449 __x.swap(__y);
2450}
2451
Howard Hinnante6e4d012010-09-03 21:46:37 +00002452template <class _R>
Howard Hinnant7de47902010-11-30 20:23:32 +00002453inline _LIBCPP_INLINE_VISIBILITY
2454shared_future<_R>
2455future<_R>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002456{
Howard Hinnant7de47902010-11-30 20:23:32 +00002457 return shared_future<_R>(_STD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002458}
2459
2460template <class _R>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002461inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00002462shared_future<_R&>
2463future<_R&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002464{
Howard Hinnant7de47902010-11-30 20:23:32 +00002465 return shared_future<_R&>(_STD::move(*this));
2466}
2467
Howard Hinnanta4451512010-12-02 16:45:21 +00002468#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2469
Howard Hinnant7de47902010-11-30 20:23:32 +00002470inline _LIBCPP_INLINE_VISIBILITY
2471shared_future<void>
2472future<void>::share()
2473{
2474 return shared_future<void>(_STD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002475}
2476
Howard Hinnanta4451512010-12-02 16:45:21 +00002477#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2478
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002479_LIBCPP_END_NAMESPACE_STD
2480
2481#endif // _LIBCPP_FUTURE