blob: 7a2eaa5612da6ec7e7f7dbd6b51f632a00b6b170 [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//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
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{
30 any,
31 async,
32 sync
33};
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&&);
159
160 // retrieving the value
161 R get();
162
163 // functions to check state
164 bool valid() const;
165
166 void wait() const;
167 template <class Rep, class Period>
168 future_status
169 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
170 template <class Clock, class Duration>
171 future_status
172 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
173};
174
175template <class R>
176class future<R&>
177{
178public:
179 future();
180 future(future&&);
181 future(const future& rhs) = delete;
182 ~future();
183 future& operator=(const future& rhs) = delete;
184 future& operator=(future&&);
185
186 // retrieving the value
187 R& get();
188
189 // functions to check state
190 bool valid() const;
191
192 void wait() const;
193 template <class Rep, class Period>
194 future_status
195 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
196 template <class Clock, class Duration>
197 future_status
198 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
199};
200
201template <>
202class future<void>
203{
204public:
205 future();
206 future(future&&);
207 future(const future& rhs) = delete;
208 ~future();
209 future& operator=(const future& rhs) = delete;
210 future& operator=(future&&);
211
212 // retrieving the value
213 void get();
214
215 // functions to check state
216 bool valid() const;
217
218 void wait() const;
219 template <class Rep, class Period>
220 future_status
221 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
222 template <class Clock, class Duration>
223 future_status
224 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
225};
226
227template <class R>
228class shared_future
229{
230public:
231 shared_future();
232 shared_future(const shared_future& rhs);
233 shared_future(future<R>&&);
234 shared_future(shared_future&& rhs);
235 ~shared_future();
236 shared_future& operator=(const shared_future& rhs);
237 shared_future& operator=(shared_future&& rhs);
238
239 // retrieving the value
240 const R& get() const;
241
242 // functions to check state
243 bool valid() const;
244
245 void wait() const;
246 template <class Rep, class Period>
247 future_status
248 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
249 template <class Clock, class Duration>
250 future_status
251 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
252};
253
254template <class R>
255class shared_future<R&>
256{
257public:
258 shared_future();
259 shared_future(const shared_future& rhs);
Howard Hinnant99be8232010-09-03 18:39:25 +0000260 shared_future(future<R&>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000261 shared_future(shared_future&& rhs);
262 ~shared_future();
263 shared_future& operator=(const shared_future& rhs);
264 shared_future& operator=(shared_future&& rhs);
265
266 // retrieving the value
267 R& get() const;
268
269 // functions to check state
270 bool valid() const;
271
272 void wait() const;
273 template <class Rep, class Period>
274 future_status
275 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
276 template <class Clock, class Duration>
277 future_status
278 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
279};
280
281template <>
282class shared_future<void>
283{
284public:
285 shared_future();
286 shared_future(const shared_future& rhs);
Howard Hinnant99be8232010-09-03 18:39:25 +0000287 shared_future(future<void>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000288 shared_future(shared_future&& rhs);
289 ~shared_future();
290 shared_future& operator=(const shared_future& rhs);
291 shared_future& operator=(shared_future&& rhs);
292
293 // retrieving the value
294 void get() const;
295
296 // functions to check state
297 bool valid() const;
298
299 void wait() const;
300 template <class Rep, class Period>
301 future_status
302 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
303 template <class Clock, class Duration>
304 future_status
305 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
306};
307
308template <class R>
309class atomic_future
310{
311public:
312 atomic_future();
313 atomic_future(const atomic_future& rhs);
314 atomic_future(future<R>&&);
315 ~atomic_future();
316 atomic_future& operator=(const atomic_future& rhs);
317
318 // retrieving the value
319 const R& get() const;
320
321 // functions to check state
322 bool valid() const;
323
324 void wait() const;
325 template <class Rep, class Period>
326 future_status
327 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
328 template <class Clock, class Duration>
329 future_status
330 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
331};
332
333template <class R>
334class atomic_future<R&>
335{
336public:
337 atomic_future();
338 atomic_future(const atomic_future& rhs);
339 atomic_future(future<R>&&);
340 ~atomic_future();
341 atomic_future& operator=(const atomic_future& rhs);
342
343 // retrieving the value
344 R& get() const;
345
346 // functions to check state
347 bool valid() const;
348
349 void wait() const;
350 template <class Rep, class Period>
351 future_status
352 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
353 template <class Clock, class Duration>
354 future_status
355 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
356};
357
358template <>
359class atomic_future<void>
360{
361public:
362 atomic_future();
363 atomic_future(const atomic_future& rhs);
364 atomic_future(future<R>&&);
365 ~atomic_future();
366 atomic_future& operator=(const atomic_future& rhs);
367
368 // retrieving the value
369 void get() const;
370
371 // functions to check state
372 bool valid() const;
373
374 void wait() const;
375 template <class Rep, class Period>
376 future_status
377 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
378 template <class Clock, class Duration>
379 future_status
380 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
381};
382
383template <class F, class... Args>
384 future<typename result_of<F(Args...)>::type>
385 async(F&& f, Args&&... args);
386
387template <class F, class... Args>
388 future<typename result_of<F(Args...)>::type>
389 async(launch policy, F&& f, Args&&... args);
390
Howard Hinnantf5256e12010-05-11 21:36:01 +0000391template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000392
393template <class R, class... ArgTypes>
394class packaged_task<R(ArgTypes...)>
395{
396public:
397 typedef R result_type;
398
399 // construction and destruction
400 packaged_task();
401 template <class F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000402 explicit packaged_task(F&& f);
403 template <class F, class Allocator>
404 explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
405 ~packaged_task();
406
407 // no copy
408 packaged_task(packaged_task&) = delete;
409 packaged_task& operator=(packaged_task&) = delete;
410
411 // move support
412 packaged_task(packaged_task&& other);
413 packaged_task& operator=(packaged_task&& other);
414 void swap(packaged_task& other);
415
416 explicit operator bool() const;
417
418 // result retrieval
419 future<R> get_future();
420
421 // execution
422 void operator()(ArgTypes... );
423 void make_ready_at_thread_exit(ArgTypes...);
424
425 void reset();
426};
427
428template <class R>
429 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&);
430
431template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
432
433} // std
434
435*/
436
437#include <__config>
438#include <system_error>
Howard Hinnant47499b12010-08-27 20:10:19 +0000439#include <memory>
440#include <chrono>
441#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37 +0000442#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19 +0000443#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000444
445#pragma GCC system_header
446
447_LIBCPP_BEGIN_NAMESPACE_STD
448
449//enum class future_errc
450struct future_errc
451{
452enum _ {
453 broken_promise,
454 future_already_retrieved,
455 promise_already_satisfied,
456 no_state
457};
458
459 _ __v_;
460
461 future_errc(_ __v) : __v_(__v) {}
462 operator int() const {return __v_;}
463
464};
465
Howard Hinnanta6521722010-08-25 17:32:05 +0000466template <> struct is_error_code_enum<future_errc> : public true_type {};
467
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000468//enum class launch
469struct launch
470{
471enum _ {
472 any,
473 async,
474 sync
475};
476
477 _ __v_;
478
479 launch(_ __v) : __v_(__v) {}
480 operator int() const {return __v_;}
481
482};
483
484//enum class future_status
485struct future_status
486{
487enum _ {
488 ready,
489 timeout,
490 deferred
491};
492
493 _ __v_;
494
495 future_status(_ __v) : __v_(__v) {}
496 operator int() const {return __v_;}
497
498};
499
Howard Hinnanta6521722010-08-25 17:32:05 +0000500const error_category& future_category();
501
502inline _LIBCPP_INLINE_VISIBILITY
503error_code
504make_error_code(future_errc __e)
505{
506 return error_code(static_cast<int>(__e), future_category());
507}
508
509inline _LIBCPP_INLINE_VISIBILITY
510error_condition
511make_error_condition(future_errc __e)
512{
513 return error_condition(static_cast<int>(__e), future_category());
514}
515
516class future_error
517 : public logic_error
518{
519 error_code __ec_;
520public:
521 future_error(error_code __ec);
522
523 const error_code& code() const throw() {return __ec_;}
524};
525
Howard Hinnant47499b12010-08-27 20:10:19 +0000526class __assoc_sub_state
527 : public __shared_count
528{
529protected:
530 exception_ptr __exception_;
531 mutable mutex __mut_;
532 mutable condition_variable __cv_;
533 unsigned __state_;
534
535 virtual void __on_zero_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +0000536 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000537public:
538 enum
539 {
540 __constructed = 1,
541 __future_attached = 2,
542 ready = 4,
543 deferred = 8
544 };
545
546 __assoc_sub_state() : __state_(0) {}
547
548 bool __has_value() const
549 {return (__state_ & __constructed) || (__exception_ != nullptr);}
550
551 void __set_future_attached() {__state_ |= __future_attached;}
552 bool __has_future_attached() const {return __state_ & __future_attached;}
553
Howard Hinnant54da3382010-08-30 18:46:21 +0000554 void __set_deferred() {__state_ |= deferred;}
555
Howard Hinnant47499b12010-08-27 20:10:19 +0000556 void __make_ready();
557 bool __is_ready() const {return __state_ & ready;}
558
559 void set_value();
560 void set_value_at_thread_exit();
561
562 void set_exception(exception_ptr __p);
563 void set_exception_at_thread_exit(exception_ptr __p);
564
565 void copy();
566
Howard Hinnant54da3382010-08-30 18:46:21 +0000567 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000568 template <class _Rep, class _Period>
569 future_status
570 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
571 template <class _Clock, class _Duration>
572 future_status
573 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000574
575 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000576};
577
Howard Hinnantf39daa82010-08-28 21:01:06 +0000578template <class _Clock, class _Duration>
579future_status
580__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
581{
582 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000583 if (__state_ & deferred)
584 return future_status::deferred;
585 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000586 __cv_.wait_until(__lk, __abs_time);
587 if (__state_ & ready)
588 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000589 return future_status::timeout;
590}
591
592template <class _Rep, class _Period>
593inline _LIBCPP_INLINE_VISIBILITY
594future_status
595__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
596{
597 return wait_until(chrono::monotonic_clock::now() + __rel_time);
598}
599
Howard Hinnant47499b12010-08-27 20:10:19 +0000600template <class _R>
601class __assoc_state
602 : public __assoc_sub_state
603{
604 typedef __assoc_sub_state base;
605 typedef typename aligned_storage<sizeof(_R), alignment_of<_R>::value>::type _U;
606protected:
607 _U __value_;
608
609 virtual void __on_zero_shared();
610public:
611
612 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000613#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000614 void set_value(_Arg&& __arg);
615#else
616 void set_value(_Arg& __arg);
617#endif
618
619 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000620#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000621 void set_value_at_thread_exit(_Arg&& __arg);
622#else
623 void set_value_at_thread_exit(_Arg& __arg);
624#endif
625
626 _R move();
627 typename add_lvalue_reference<_R>::type copy();
628};
629
630template <class _R>
631void
632__assoc_state<_R>::__on_zero_shared()
633{
634 if (this->__state_ & base::__constructed)
635 reinterpret_cast<_R*>(&__value_)->~_R();
636 delete this;
637}
638
639template <class _R>
640template <class _Arg>
641void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000642#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000643__assoc_state<_R>::set_value(_Arg&& __arg)
644#else
645__assoc_state<_R>::set_value(_Arg& __arg)
646#endif
647{
648 unique_lock<mutex> __lk(this->__mut_);
649 if (this->__has_value())
650 throw future_error(make_error_code(future_errc::promise_already_satisfied));
651 ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
652 this->__state_ |= base::__constructed | base::ready;
653 __lk.unlock();
654 __cv_.notify_all();
655}
656
657template <class _R>
658template <class _Arg>
659void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000660#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000661__assoc_state<_R>::set_value_at_thread_exit(_Arg&& __arg)
662#else
663__assoc_state<_R>::set_value_at_thread_exit(_Arg& __arg)
664#endif
665{
666 unique_lock<mutex> __lk(this->__mut_);
667 if (this->__has_value())
668 throw future_error(make_error_code(future_errc::promise_already_satisfied));
669 ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
670 this->__state_ |= base::__constructed;
671 __thread_local_data->__make_ready_at_thread_exit(this);
672 __lk.unlock();
673}
674
675template <class _R>
676_R
677__assoc_state<_R>::move()
678{
679 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000680 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000681 if (this->__exception_ != nullptr)
682 rethrow_exception(this->__exception_);
683 return _STD::move(*reinterpret_cast<_R*>(&__value_));
684}
685
686template <class _R>
687typename add_lvalue_reference<_R>::type
688__assoc_state<_R>::copy()
689{
690 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000691 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000692 if (this->__exception_ != nullptr)
693 rethrow_exception(this->__exception_);
694 return *reinterpret_cast<_R*>(&__value_);
695}
696
Howard Hinnantf39daa82010-08-28 21:01:06 +0000697template <class _R>
698class __assoc_state<_R&>
699 : public __assoc_sub_state
700{
701 typedef __assoc_sub_state base;
702 typedef _R* _U;
703protected:
704 _U __value_;
705
706 virtual void __on_zero_shared();
707public:
708
709 void set_value(_R& __arg);
710 void set_value_at_thread_exit(_R& __arg);
711
712 _R& copy();
713};
714
715template <class _R>
716void
717__assoc_state<_R&>::__on_zero_shared()
718{
719 delete this;
720}
721
722template <class _R>
723void
724__assoc_state<_R&>::set_value(_R& __arg)
725{
726 unique_lock<mutex> __lk(this->__mut_);
727 if (this->__has_value())
728 throw future_error(make_error_code(future_errc::promise_already_satisfied));
729 __value_ = &__arg;
730 this->__state_ |= base::__constructed | base::ready;
731 __lk.unlock();
732 __cv_.notify_all();
733}
734
735template <class _R>
736void
737__assoc_state<_R&>::set_value_at_thread_exit(_R& __arg)
738{
739 unique_lock<mutex> __lk(this->__mut_);
740 if (this->__has_value())
741 throw future_error(make_error_code(future_errc::promise_already_satisfied));
742 __value_ = &__arg;
743 this->__state_ |= base::__constructed;
744 __thread_local_data->__make_ready_at_thread_exit(this);
745 __lk.unlock();
746}
747
748template <class _R>
749_R&
750__assoc_state<_R&>::copy()
751{
752 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000753 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000754 if (this->__exception_ != nullptr)
755 rethrow_exception(this->__exception_);
756 return *__value_;
757}
758
Howard Hinnant47499b12010-08-27 20:10:19 +0000759template <class _R, class _Alloc>
760class __assoc_state_alloc
761 : public __assoc_state<_R>
762{
763 typedef __assoc_state<_R> base;
764 _Alloc __alloc_;
765
766 virtual void __on_zero_shared();
767public:
768 explicit __assoc_state_alloc(const _Alloc& __a)
769 : __alloc_(__a) {}
770};
771
772template <class _R, class _Alloc>
773void
774__assoc_state_alloc<_R, _Alloc>::__on_zero_shared()
775{
776 if (this->__state_ & base::__constructed)
777 reinterpret_cast<_R*>(&this->__value_)->~_R();
778 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
779 this->~__assoc_state_alloc();
780 __a.deallocate(this, 1);
781}
782
Howard Hinnantf39daa82010-08-28 21:01:06 +0000783template <class _R, class _Alloc>
784class __assoc_state_alloc<_R&, _Alloc>
785 : public __assoc_state<_R&>
786{
787 typedef __assoc_state<_R&> base;
788 _Alloc __alloc_;
789
790 virtual void __on_zero_shared();
791public:
792 explicit __assoc_state_alloc(const _Alloc& __a)
793 : __alloc_(__a) {}
794};
795
796template <class _R, class _Alloc>
797void
798__assoc_state_alloc<_R&, _Alloc>::__on_zero_shared()
799{
800 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
801 this->~__assoc_state_alloc();
802 __a.deallocate(this, 1);
803}
804
Howard Hinnant47499b12010-08-27 20:10:19 +0000805template <class _Alloc>
806class __assoc_sub_state_alloc
807 : public __assoc_sub_state
808{
809 typedef __assoc_sub_state base;
810 _Alloc __alloc_;
811
812 virtual void __on_zero_shared();
813public:
814 explicit __assoc_sub_state_alloc(const _Alloc& __a)
815 : __alloc_(__a) {}
816};
817
818template <class _Alloc>
819void
820__assoc_sub_state_alloc<_Alloc>::__on_zero_shared()
821{
822 this->~base();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000823 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000824 this->~__assoc_sub_state_alloc();
825 __a.deallocate(this, 1);
826}
827
Howard Hinnant54da3382010-08-30 18:46:21 +0000828template <class _R, class _F>
829class __deferred_assoc_state
830 : public __assoc_state<_R>
831{
832 typedef __assoc_state<_R> base;
833
834 _F __func_;
835
836public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000837#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000838 explicit __deferred_assoc_state(_F&& __f);
839#endif
840
841 virtual void __execute();
842};
843
Howard Hinnant73d21a42010-09-04 23:28:19 +0000844#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000845
846template <class _R, class _F>
847inline _LIBCPP_INLINE_VISIBILITY
848__deferred_assoc_state<_R, _F>::__deferred_assoc_state(_F&& __f)
849 : __func_(_STD::forward<_F>(__f))
850{
851 this->__set_deferred();
852}
853
Howard Hinnant73d21a42010-09-04 23:28:19 +0000854#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000855
856template <class _R, class _F>
857void
858__deferred_assoc_state<_R, _F>::__execute()
859{
860#ifndef _LIBCPP_NO_EXCEPTIONS
861 try
862 {
863#endif // _LIBCPP_NO_EXCEPTIONS
864 this->set_value(__func_());
865#ifndef _LIBCPP_NO_EXCEPTIONS
866 }
867 catch (...)
868 {
869 this->set_exception(current_exception());
870 }
871#endif // _LIBCPP_NO_EXCEPTIONS
872}
873
874template <class _F>
875class __deferred_assoc_state<void, _F>
876 : public __assoc_sub_state
877{
878 typedef __assoc_sub_state base;
879
880 _F __func_;
881
882public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000883#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000884 explicit __deferred_assoc_state(_F&& __f);
885#endif
886
887 virtual void __execute();
888};
889
Howard Hinnant73d21a42010-09-04 23:28:19 +0000890#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000891
892template <class _F>
893inline _LIBCPP_INLINE_VISIBILITY
894__deferred_assoc_state<void, _F>::__deferred_assoc_state(_F&& __f)
895 : __func_(_STD::forward<_F>(__f))
896{
897 this->__set_deferred();
898}
899
Howard Hinnant73d21a42010-09-04 23:28:19 +0000900#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000901
902template <class _F>
903void
904__deferred_assoc_state<void, _F>::__execute()
905{
906#ifndef _LIBCPP_NO_EXCEPTIONS
907 try
908 {
909#endif // _LIBCPP_NO_EXCEPTIONS
910 __func_();
911 this->set_value();
912#ifndef _LIBCPP_NO_EXCEPTIONS
913 }
914 catch (...)
915 {
916 this->set_exception(current_exception());
917 }
918#endif // _LIBCPP_NO_EXCEPTIONS
919}
920
Howard Hinnant47499b12010-08-27 20:10:19 +0000921template <class> class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +0000922template <class> class shared_future;
923template <class> class atomic_future;
Howard Hinnant47499b12010-08-27 20:10:19 +0000924
925// future
926
Howard Hinnant54da3382010-08-30 18:46:21 +0000927template <class _R> class future;
928
929template <class _R, class _F>
930future<_R>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000931#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000932__make_deferred_assoc_state(_F&& __f);
933#else
934__make_deferred_assoc_state(_F __f);
935#endif
936
Howard Hinnant47499b12010-08-27 20:10:19 +0000937template <class _R>
938class future
939{
940 __assoc_state<_R>* __state_;
941
942 explicit future(__assoc_state<_R>* __state);
943
944 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +0000945 template <class> friend class shared_future;
946 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000947
948 template <class _R1, class _F>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000949#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000950 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
951#else
952 friend future<_R1> __make_deferred_assoc_state(_F __f);
953#endif
954
Howard Hinnant47499b12010-08-27 20:10:19 +0000955public:
956 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000957#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000958 future(future&& __rhs)
959 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
960 future(const future&) = delete;
961 future& operator=(const future&) = delete;
962 future& operator=(future&& __rhs)
963 {
964 future(std::move(__rhs)).swap(*this);
965 return *this;
966 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000967#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000968private:
969 future(const future&);
970 future& operator=(const future&);
971public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000972#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000973 ~future();
974
975 // retrieving the value
976 _R get();
977
978 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
979
980 // functions to check state
981 bool valid() const {return __state_ != nullptr;}
982
983 void wait() const {__state_->wait();}
984 template <class _Rep, class _Period>
985 future_status
986 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
987 {return __state_->wait_for(__rel_time);}
988 template <class _Clock, class _Duration>
989 future_status
990 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
991 {return __state_->wait_until(__abs_time);}
992};
993
994template <class _R>
995future<_R>::future(__assoc_state<_R>* __state)
996 : __state_(__state)
997{
998 if (__state_->__has_future_attached())
999 throw future_error(make_error_code(future_errc::future_already_retrieved));
1000 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001001 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001002}
1003
Howard Hinnant54da3382010-08-30 18:46:21 +00001004struct __release_shared_count
1005{
1006 void operator()(__shared_count* p) {p->__release_shared();}
1007};
1008
Howard Hinnant47499b12010-08-27 20:10:19 +00001009template <class _R>
1010future<_R>::~future()
1011{
1012 if (__state_)
1013 __state_->__release_shared();
1014}
1015
1016template <class _R>
1017_R
1018future<_R>::get()
1019{
Howard Hinnant54da3382010-08-30 18:46:21 +00001020 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001021 __assoc_state<_R>* __s = __state_;
1022 __state_ = nullptr;
1023 return __s->move();
1024}
1025
1026template <class _R>
1027class future<_R&>
1028{
1029 __assoc_state<_R&>* __state_;
1030
1031 explicit future(__assoc_state<_R&>* __state);
1032
1033 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001034 template <class> friend class shared_future;
1035 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001036
1037 template <class _R1, class _F>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001038#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +00001039 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
1040#else
1041 friend future<_R1> __make_deferred_assoc_state(_F __f);
1042#endif
1043
Howard Hinnant47499b12010-08-27 20:10:19 +00001044public:
1045 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001046#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001047 future(future&& __rhs)
1048 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1049 future(const future&) = delete;
1050 future& operator=(const future&) = delete;
1051 future& operator=(future&& __rhs)
1052 {
1053 future(std::move(__rhs)).swap(*this);
1054 return *this;
1055 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001056#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001057private:
1058 future(const future&);
1059 future& operator=(const future&);
1060public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001061#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001062 ~future();
1063
1064 // retrieving the value
1065 _R& get();
1066
1067 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1068
1069 // functions to check state
1070 bool valid() const {return __state_ != nullptr;}
1071
1072 void wait() const {__state_->wait();}
1073 template <class _Rep, class _Period>
1074 future_status
1075 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1076 {return __state_->wait_for(__rel_time);}
1077 template <class _Clock, class _Duration>
1078 future_status
1079 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1080 {return __state_->wait_until(__abs_time);}
1081};
1082
1083template <class _R>
1084future<_R&>::future(__assoc_state<_R&>* __state)
1085 : __state_(__state)
1086{
1087 if (__state_->__has_future_attached())
1088 throw future_error(make_error_code(future_errc::future_already_retrieved));
1089 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001090 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001091}
1092
1093template <class _R>
1094future<_R&>::~future()
1095{
1096 if (__state_)
1097 __state_->__release_shared();
1098}
1099
1100template <class _R>
1101_R&
1102future<_R&>::get()
1103{
Howard Hinnant54da3382010-08-30 18:46:21 +00001104 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantf39daa82010-08-28 21:01:06 +00001105 __assoc_state<_R&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001106 __state_ = nullptr;
1107 return __s->copy();
1108}
1109
1110template <>
1111class future<void>
1112{
1113 __assoc_sub_state* __state_;
1114
1115 explicit future(__assoc_sub_state* __state);
1116
1117 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001118 template <class> friend class shared_future;
1119 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001120
1121 template <class _R1, class _F>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001122#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +00001123 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
1124#else
1125 friend future<_R1> __make_deferred_assoc_state(_F __f);
1126#endif
1127
Howard Hinnant47499b12010-08-27 20:10:19 +00001128public:
1129 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001130#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001131 future(future&& __rhs)
1132 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1133 future(const future&) = delete;
1134 future& operator=(const future&) = delete;
1135 future& operator=(future&& __rhs)
1136 {
1137 future(std::move(__rhs)).swap(*this);
1138 return *this;
1139 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001140#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001141private:
1142 future(const future&);
1143 future& operator=(const future&);
1144public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001145#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001146 ~future();
1147
1148 // retrieving the value
1149 void get();
1150
1151 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1152
1153 // functions to check state
1154 bool valid() const {return __state_ != nullptr;}
1155
1156 void wait() const {__state_->wait();}
1157 template <class _Rep, class _Period>
1158 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>
1162 future_status
1163 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1164 {return __state_->wait_until(__abs_time);}
1165};
1166
Howard Hinnant99be8232010-09-03 18:39:25 +00001167template <class _R>
1168inline _LIBCPP_INLINE_VISIBILITY
1169void
1170swap(future<_R>& __x, future<_R>& __y)
1171{
1172 __x.swap(__y);
1173}
1174
Howard Hinnant47499b12010-08-27 20:10:19 +00001175// promise<R>
1176
Howard Hinnant54da3382010-08-30 18:46:21 +00001177template <class> class packaged_task;
1178
Howard Hinnant47499b12010-08-27 20:10:19 +00001179template <class _R>
1180class promise
1181{
1182 __assoc_state<_R>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001183
1184 explicit promise(nullptr_t) : __state_(nullptr) {}
1185
1186 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001187public:
1188 promise();
1189 template <class _Alloc>
1190 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001191#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001192 promise(promise&& __rhs)
1193 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1194 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001195#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001196private:
1197 promise(const promise& __rhs);
1198public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001199#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001200 ~promise();
1201
1202 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001203#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001204 promise& operator=(promise&& __rhs)
1205 {
1206 promise(std::move(__rhs)).swap(*this);
1207 return *this;
1208 }
1209 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001210#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001211private:
1212 promise& operator=(const promise& __rhs);
1213public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001214#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001215 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1216
1217 // retrieving the result
1218 future<_R> get_future();
1219
1220 // setting the result
1221 void set_value(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001222#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001223 void set_value(_R&& __r);
1224#endif
1225 void set_exception(exception_ptr __p);
1226
1227 // setting the result with deferred notification
1228 void set_value_at_thread_exit(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001229#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001230 void set_value_at_thread_exit(_R&& __r);
1231#endif
1232 void set_exception_at_thread_exit(exception_ptr __p);
1233};
1234
1235template <class _R>
1236promise<_R>::promise()
1237 : __state_(new __assoc_state<_R>)
1238{
1239}
1240
1241template <class _R>
1242template <class _Alloc>
1243promise<_R>::promise(allocator_arg_t, const _Alloc& __a0)
1244{
1245 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R, _Alloc> >::other _A2;
1246 typedef __allocator_destructor<_A2> _D2;
1247 _A2 __a(__a0);
1248 unique_ptr<__assoc_state_alloc<_R, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1249 ::new(__hold.get()) __assoc_state_alloc<_R, _Alloc>(__a0);
1250 __state_ = __hold.release();
1251}
1252
1253template <class _R>
1254promise<_R>::~promise()
1255{
1256 if (__state_)
1257 {
1258 if (!__state_->__has_value() && __state_->use_count() > 1)
1259 __state_->set_exception(make_exception_ptr(
1260 future_error(make_error_code(future_errc::broken_promise))
1261 ));
1262 __state_->__release_shared();
1263 }
1264}
1265
1266template <class _R>
1267future<_R>
1268promise<_R>::get_future()
1269{
1270 if (__state_ == nullptr)
1271 throw future_error(make_error_code(future_errc::no_state));
1272 return future<_R>(__state_);
1273}
1274
1275template <class _R>
1276void
1277promise<_R>::set_value(const _R& __r)
1278{
1279 if (__state_ == nullptr)
1280 throw future_error(make_error_code(future_errc::no_state));
1281 __state_->set_value(__r);
1282}
1283
Howard Hinnant73d21a42010-09-04 23:28:19 +00001284#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001285
1286template <class _R>
1287void
1288promise<_R>::set_value(_R&& __r)
1289{
1290 if (__state_ == nullptr)
1291 throw future_error(make_error_code(future_errc::no_state));
1292 __state_->set_value(_STD::move(__r));
1293}
1294
Howard Hinnant73d21a42010-09-04 23:28:19 +00001295#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001296
1297template <class _R>
1298void
1299promise<_R>::set_exception(exception_ptr __p)
1300{
1301 if (__state_ == nullptr)
1302 throw future_error(make_error_code(future_errc::no_state));
1303 __state_->set_exception(__p);
1304}
1305
1306template <class _R>
1307void
1308promise<_R>::set_value_at_thread_exit(const _R& __r)
1309{
1310 if (__state_ == nullptr)
1311 throw future_error(make_error_code(future_errc::no_state));
1312 __state_->set_value_at_thread_exit(__r);
1313}
1314
Howard Hinnant73d21a42010-09-04 23:28:19 +00001315#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001316
1317template <class _R>
1318void
1319promise<_R>::set_value_at_thread_exit(_R&& __r)
1320{
1321 if (__state_ == nullptr)
1322 throw future_error(make_error_code(future_errc::no_state));
1323 __state_->set_value_at_thread_exit(_STD::move(__r));
1324}
1325
Howard Hinnant73d21a42010-09-04 23:28:19 +00001326#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001327
1328template <class _R>
1329void
1330promise<_R>::set_exception_at_thread_exit(exception_ptr __p)
1331{
1332 if (__state_ == nullptr)
1333 throw future_error(make_error_code(future_errc::no_state));
1334 __state_->set_exception_at_thread_exit(__p);
1335}
1336
1337// promise<R&>
1338
1339template <class _R>
1340class promise<_R&>
1341{
1342 __assoc_state<_R&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001343
1344 explicit promise(nullptr_t) : __state_(nullptr) {}
1345
1346 template <class> friend class packaged_task;
1347
Howard Hinnant47499b12010-08-27 20:10:19 +00001348public:
1349 promise();
1350 template <class _Allocator>
1351 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001352#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001353 promise(promise&& __rhs)
1354 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1355 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001356#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001357private:
1358 promise(const promise& __rhs);
1359public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001360#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001361 ~promise();
1362
1363 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001364#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001365 promise& operator=(promise&& __rhs)
1366 {
1367 promise(std::move(__rhs)).swap(*this);
1368 return *this;
1369 }
1370 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001371#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001372private:
1373 promise& operator=(const promise& __rhs);
1374public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001375#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001376 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1377
1378 // retrieving the result
1379 future<_R&> get_future();
1380
1381 // setting the result
1382 void set_value(_R& __r);
1383 void set_exception(exception_ptr __p);
1384
1385 // setting the result with deferred notification
1386 void set_value_at_thread_exit(_R&);
1387 void set_exception_at_thread_exit(exception_ptr __p);
1388};
1389
1390template <class _R>
1391promise<_R&>::promise()
1392 : __state_(new __assoc_state<_R&>)
1393{
1394}
1395
1396template <class _R>
1397template <class _Alloc>
1398promise<_R&>::promise(allocator_arg_t, const _Alloc& __a0)
1399{
1400 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R&, _Alloc> >::other _A2;
1401 typedef __allocator_destructor<_A2> _D2;
1402 _A2 __a(__a0);
1403 unique_ptr<__assoc_state_alloc<_R&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1404 ::new(__hold.get()) __assoc_state_alloc<_R&, _Alloc>(__a0);
1405 __state_ = __hold.release();
1406}
1407
1408template <class _R>
1409promise<_R&>::~promise()
1410{
1411 if (__state_)
1412 {
1413 if (!__state_->__has_value() && __state_->use_count() > 1)
1414 __state_->set_exception(make_exception_ptr(
1415 future_error(make_error_code(future_errc::broken_promise))
1416 ));
1417 __state_->__release_shared();
1418 }
1419}
1420
1421template <class _R>
1422future<_R&>
1423promise<_R&>::get_future()
1424{
1425 if (__state_ == nullptr)
1426 throw future_error(make_error_code(future_errc::no_state));
1427 return future<_R&>(__state_);
1428}
1429
1430template <class _R>
1431void
1432promise<_R&>::set_value(_R& __r)
1433{
1434 if (__state_ == nullptr)
1435 throw future_error(make_error_code(future_errc::no_state));
1436 __state_->set_value(__r);
1437}
1438
1439template <class _R>
1440void
1441promise<_R&>::set_exception(exception_ptr __p)
1442{
1443 if (__state_ == nullptr)
1444 throw future_error(make_error_code(future_errc::no_state));
1445 __state_->set_exception(__p);
1446}
1447
1448template <class _R>
1449void
1450promise<_R&>::set_value_at_thread_exit(_R& __r)
1451{
1452 if (__state_ == nullptr)
1453 throw future_error(make_error_code(future_errc::no_state));
1454 __state_->set_value_at_thread_exit(__r);
1455}
1456
1457template <class _R>
1458void
1459promise<_R&>::set_exception_at_thread_exit(exception_ptr __p)
1460{
1461 if (__state_ == nullptr)
1462 throw future_error(make_error_code(future_errc::no_state));
1463 __state_->set_exception_at_thread_exit(__p);
1464}
1465
1466// promise<void>
1467
1468template <>
1469class promise<void>
1470{
1471 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001472
1473 explicit promise(nullptr_t) : __state_(nullptr) {}
1474
1475 template <class> friend class packaged_task;
1476
Howard Hinnant47499b12010-08-27 20:10:19 +00001477public:
1478 promise();
1479 template <class _Allocator>
1480 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001481#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001482 promise(promise&& __rhs)
1483 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1484 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001485#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001486private:
1487 promise(const promise& __rhs);
1488public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001489#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001490 ~promise();
1491
1492 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001493#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001494 promise& operator=(promise&& __rhs)
1495 {
1496 promise(std::move(__rhs)).swap(*this);
1497 return *this;
1498 }
1499 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001500#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001501private:
1502 promise& operator=(const promise& __rhs);
1503public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001504#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001505 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1506
1507 // retrieving the result
1508 future<void> get_future();
1509
1510 // setting the result
1511 void set_value();
1512 void set_exception(exception_ptr __p);
1513
1514 // setting the result with deferred notification
1515 void set_value_at_thread_exit();
1516 void set_exception_at_thread_exit(exception_ptr __p);
1517};
1518
1519template <class _Alloc>
1520promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1521{
1522 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1523 typedef __allocator_destructor<_A2> _D2;
1524 _A2 __a(__a0);
1525 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1526 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1527 __state_ = __hold.release();
1528}
1529
1530template <class _R>
1531inline _LIBCPP_INLINE_VISIBILITY
1532void
1533swap(promise<_R>& __x, promise<_R>& __y)
1534{
1535 __x.swap(__y);
1536}
1537
1538template <class _R, class _Alloc>
1539 struct uses_allocator<promise<_R>, _Alloc> : public true_type {};
1540
Howard Hinnant54da3382010-08-30 18:46:21 +00001541#ifndef _LIBCPP_HAS_NO_VARIADICS
1542
1543// packaged_task
1544
1545template<class _Fp> class __packaged_task_base;
1546
1547template<class _R, class ..._ArgTypes>
1548class __packaged_task_base<_R(_ArgTypes...)>
1549{
1550 __packaged_task_base(const __packaged_task_base&);
1551 __packaged_task_base& operator=(const __packaged_task_base&);
1552public:
1553 __packaged_task_base() {}
1554 virtual ~__packaged_task_base() {}
1555 virtual void __move_to(__packaged_task_base*) = 0;
1556 virtual void destroy() = 0;
1557 virtual void destroy_deallocate() = 0;
1558 virtual _R operator()(_ArgTypes&& ...) = 0;
1559};
1560
1561template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1562
1563template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1564class __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>
1565 : public __packaged_task_base<_R(_ArgTypes...)>
1566{
1567 __compressed_pair<_F, _Alloc> __f_;
1568public:
1569 explicit __packaged_task_func(const _F& __f) : __f_(__f) {}
1570 explicit __packaged_task_func(_F&& __f) : __f_(_STD::move(__f)) {}
1571 __packaged_task_func(const _F& __f, const _Alloc& __a)
1572 : __f_(__f, __a) {}
1573 __packaged_task_func(_F&& __f, const _Alloc& __a)
1574 : __f_(_STD::move(__f), __a) {}
1575 virtual void __move_to(__packaged_task_base<_R(_ArgTypes...)>*);
1576 virtual void destroy();
1577 virtual void destroy_deallocate();
1578 virtual _R operator()(_ArgTypes&& ... __args);
1579};
1580
1581template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1582void
1583__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::__move_to(
1584 __packaged_task_base<_R(_ArgTypes...)>* __p)
1585{
1586 ::new (__p) __packaged_task_func(_STD::move(__f_.first()), _STD::move(__f_.second()));
1587}
1588
1589template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1590void
1591__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy()
1592{
1593 __f_.~__compressed_pair<_F, _Alloc>();
1594}
1595
1596template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1597void
1598__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy_deallocate()
1599{
1600 typedef typename _Alloc::template rebind<__packaged_task_func>::other _A;
1601 _A __a(__f_.second());
1602 __f_.~__compressed_pair<_F, _Alloc>();
1603 __a.deallocate(this, 1);
1604}
1605
1606template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1607_R
1608__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1609{
1610 return __invoke(__f_.first(), _STD::forward<_ArgTypes>(__arg)...);
1611}
1612
1613template <class> class __packaged_task_function;
1614
1615template<class _R, class ..._ArgTypes>
1616class __packaged_task_function<_R(_ArgTypes...)>
1617{
1618 typedef __packaged_task_base<_R(_ArgTypes...)> __base;
1619 aligned_storage<3*sizeof(void*)>::type __buf_;
1620 __base* __f_;
1621
1622public:
1623 typedef _R result_type;
1624
1625 // construct/copy/destroy:
1626 __packaged_task_function() : __f_(nullptr) {}
1627 template<class _F>
1628 __packaged_task_function(_F&& __f);
1629 template<class _F, class _Alloc>
1630 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _F&& __f);
1631
1632 __packaged_task_function(__packaged_task_function&&);
1633 __packaged_task_function& operator=(__packaged_task_function&&);
1634
1635 __packaged_task_function(const __packaged_task_function&) = delete;
1636 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1637
1638 ~__packaged_task_function();
1639
1640 void swap(__packaged_task_function&);
1641
1642 _R operator()(_ArgTypes...) const;
1643};
1644
1645template<class _R, class ..._ArgTypes>
1646__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f)
1647{
1648 if (__f.__f_ == nullptr)
1649 __f_ = nullptr;
1650 else if (__f.__f_ == (__base*)&__f.__buf_)
1651 {
1652 __f_ = (__base*)&__buf_;
1653 __f.__f_->__move_to(__f_);
1654 }
1655 else
1656 {
1657 __f_ = __f.__f_;
1658 __f.__f_ = nullptr;
1659 }
1660}
1661
1662template<class _R, class ..._ArgTypes>
1663template <class _F>
1664__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(_F&& __f)
1665 : __f_(nullptr)
1666{
1667 typedef typename remove_reference<_F>::type _FR;
1668 typedef __packaged_task_func<_FR, allocator<_FR>, _R(_ArgTypes...)> _FF;
1669 if (sizeof(_FF) <= sizeof(__buf_))
1670 {
1671 __f_ = (__base*)&__buf_;
1672 ::new (__f_) _FF(_STD::forward<_F>(__f));
1673 }
1674 else
1675 {
1676 typedef allocator<_FF> _A;
1677 _A __a;
1678 typedef __allocator_destructor<_A> _D;
1679 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1680 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), allocator<_FR>(__a));
1681 __f_ = __hold.release();
1682 }
1683}
1684
1685template<class _R, class ..._ArgTypes>
1686template <class _F, class _Alloc>
1687__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(
1688 allocator_arg_t, const _Alloc& __a0, _F&& __f)
1689 : __f_(nullptr)
1690{
1691 typedef allocator_traits<_Alloc> __alloc_traits;
1692 typedef typename remove_reference<_F>::type _FR;
1693 typedef __packaged_task_func<_FR, _Alloc, _R(_ArgTypes...)> _FF;
1694 if (sizeof(_FF) <= sizeof(__buf_))
1695 {
1696 __f_ = (__base*)&__buf_;
1697 ::new (__f_) _FF(_STD::forward<_F>(__f));
1698 }
1699 else
1700 {
1701 typedef typename __alloc_traits::template
1702#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1703 rebind_alloc<_FF>
1704#else
1705 rebind_alloc<_FF>::other
1706#endif
1707 _A;
1708 _A __a(__a0);
1709 typedef __allocator_destructor<_A> _D;
1710 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1711 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), _Alloc(__a));
1712 __f_ = __hold.release();
1713 }
1714}
1715
1716template<class _R, class ..._ArgTypes>
1717__packaged_task_function<_R(_ArgTypes...)>&
1718__packaged_task_function<_R(_ArgTypes...)>::operator=(__packaged_task_function&& __f)
1719{
1720 if (__f_ == (__base*)&__buf_)
1721 __f_->destroy();
1722 else if (__f_)
1723 __f_->destroy_deallocate();
1724 __f_ = nullptr;
1725 if (__f.__f_ == nullptr)
1726 __f_ = nullptr;
1727 else if (__f.__f_ == (__base*)&__f.__buf_)
1728 {
1729 __f_ = (__base*)&__buf_;
1730 __f.__f_->__move_to(__f_);
1731 }
1732 else
1733 {
1734 __f_ = __f.__f_;
1735 __f.__f_ = nullptr;
1736 }
1737}
1738
1739template<class _R, class ..._ArgTypes>
1740__packaged_task_function<_R(_ArgTypes...)>::~__packaged_task_function()
1741{
1742 if (__f_ == (__base*)&__buf_)
1743 __f_->destroy();
1744 else if (__f_)
1745 __f_->destroy_deallocate();
1746}
1747
1748template<class _R, class ..._ArgTypes>
1749void
1750__packaged_task_function<_R(_ArgTypes...)>::swap(__packaged_task_function& __f)
1751{
1752 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1753 {
1754 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1755 __base* __t = (__base*)&__tempbuf;
1756 __f_->__move_to(__t);
1757 __f_->destroy();
1758 __f_ = nullptr;
1759 __f.__f_->__move_to((__base*)&__buf_);
1760 __f.__f_->destroy();
1761 __f.__f_ = nullptr;
1762 __f_ = (__base*)&__buf_;
1763 __t->__move_to((__base*)&__f.__buf_);
1764 __t->destroy();
1765 __f.__f_ = (__base*)&__f.__buf_;
1766 }
1767 else if (__f_ == (__base*)&__buf_)
1768 {
1769 __f_->__move_to((__base*)&__f.__buf_);
1770 __f_->destroy();
1771 __f_ = __f.__f_;
1772 __f.__f_ = (__base*)&__f.__buf_;
1773 }
1774 else if (__f.__f_ == (__base*)&__f.__buf_)
1775 {
1776 __f.__f_->__move_to((__base*)&__buf_);
1777 __f.__f_->destroy();
1778 __f.__f_ = __f_;
1779 __f_ = (__base*)&__buf_;
1780 }
1781 else
1782 _STD::swap(__f_, __f.__f_);
1783}
1784
1785template<class _R, class ..._ArgTypes>
1786inline _LIBCPP_INLINE_VISIBILITY
1787_R
1788__packaged_task_function<_R(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1789{
1790 return (*__f_)(_STD::forward<_ArgTypes>(__arg)...);
1791}
1792
1793template<class _R, class ..._ArgTypes>
1794class packaged_task<_R(_ArgTypes...)>
1795{
1796public:
1797 typedef _R result_type;
1798
1799private:
1800 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1801 promise<result_type> __p_;
1802
1803public:
1804 // construction and destruction
1805 packaged_task() : __p_(nullptr) {}
1806 template <class _F>
1807 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
1808 template <class _F, class _Allocator>
1809 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
1810 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
1811 __p_(allocator_arg, __a) {}
1812 // ~packaged_task() = default;
1813
1814 // no copy
1815 packaged_task(packaged_task&) = delete;
1816 packaged_task& operator=(packaged_task&) = delete;
1817
1818 // move support
1819 packaged_task(packaged_task&& __other)
1820 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
1821 packaged_task& operator=(packaged_task&& __other)
1822 {
1823 __f_ = _STD::move(__other.__f_);
1824 __p_ = _STD::move(__other.__p_);
1825 return *this;
1826 }
1827 void swap(packaged_task& __other)
1828 {
1829 __f_.swap(__other.__f_);
1830 __p_.swap(__other.__p_);
1831 }
1832
1833 //explicit
1834 operator bool() const {return __p_.__state_ != nullptr;}
1835
1836 // result retrieval
1837 future<result_type> get_future() {return __p_.get_future();}
1838
1839 // execution
1840 void operator()(_ArgTypes... __args);
1841 void make_ready_at_thread_exit(_ArgTypes... __args);
1842
1843 void reset();
1844};
1845
1846template<class _R, class ..._ArgTypes>
1847void
1848packaged_task<_R(_ArgTypes...)>::operator()(_ArgTypes... __args)
1849{
1850#ifndef _LIBCPP_NO_EXCEPTIONS
1851 if (__p_.__state_ == nullptr)
1852 throw future_error(make_error_code(future_errc::no_state));
1853 if (__p_.__state_->__has_value())
1854 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1855 try
1856 {
1857#endif // _LIBCPP_NO_EXCEPTIONS
1858 __p_.set_value(__f_(_STD::forward<_ArgTypes>(__args)...));
1859#ifndef _LIBCPP_NO_EXCEPTIONS
1860 }
1861 catch (...)
1862 {
1863 __p_.set_exception(current_exception());
1864 }
1865#endif // _LIBCPP_NO_EXCEPTIONS
1866}
1867
1868template<class _R, class ..._ArgTypes>
1869void
1870packaged_task<_R(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
1871{
1872#ifndef _LIBCPP_NO_EXCEPTIONS
1873 if (__p_.__state_ == nullptr)
1874 throw future_error(make_error_code(future_errc::no_state));
1875 if (__p_.__state_->__has_value())
1876 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1877 try
1878 {
1879#endif // _LIBCPP_NO_EXCEPTIONS
1880 __p_.set_value_at_thread_exit(__f_(_STD::forward<_ArgTypes>(__args)...));
1881#ifndef _LIBCPP_NO_EXCEPTIONS
1882 }
1883 catch (...)
1884 {
1885 __p_.set_exception_at_thread_exit(current_exception());
1886 }
1887#endif // _LIBCPP_NO_EXCEPTIONS
1888}
1889
1890template<class _R, class ..._ArgTypes>
1891void
1892packaged_task<_R(_ArgTypes...)>::reset()
1893{
1894#ifndef _LIBCPP_NO_EXCEPTIONS
1895 if (!(*this))
1896 throw future_error(make_error_code(future_errc::no_state));
1897#endif // _LIBCPP_NO_EXCEPTIONS
1898 __p_ = promise<result_type>();
1899}
1900
1901template<class ..._ArgTypes>
1902class packaged_task<void(_ArgTypes...)>
1903{
1904public:
1905 typedef void result_type;
1906
1907private:
1908 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1909 promise<result_type> __p_;
1910
1911public:
1912 // construction and destruction
1913 packaged_task() : __p_(nullptr) {}
1914 template <class _F>
1915 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
1916 template <class _F, class _Allocator>
1917 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
1918 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
1919 __p_(allocator_arg, __a) {}
1920 // ~packaged_task() = default;
1921
1922 // no copy
1923 packaged_task(packaged_task&) = delete;
1924 packaged_task& operator=(packaged_task&) = delete;
1925
1926 // move support
1927 packaged_task(packaged_task&& __other)
1928 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
1929 packaged_task& operator=(packaged_task&& __other)
1930 {
1931 __f_ = _STD::move(__other.__f_);
1932 __p_ = _STD::move(__other.__p_);
1933 return *this;
1934 }
1935 void swap(packaged_task& __other)
1936 {
1937 __f_.swap(__other.__f_);
1938 __p_.swap(__other.__p_);
1939 }
1940
1941 //explicit
1942 operator bool() const {return __p_.__state_ != nullptr;}
1943
1944 // result retrieval
1945 future<result_type> get_future() {return __p_.get_future();}
1946
1947 // execution
1948 void operator()(_ArgTypes... __args);
1949 void make_ready_at_thread_exit(_ArgTypes... __args);
1950
1951 void reset();
1952};
1953
1954template<class ..._ArgTypes>
1955void
1956packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
1957{
1958#ifndef _LIBCPP_NO_EXCEPTIONS
1959 if (__p_.__state_ == nullptr)
1960 throw future_error(make_error_code(future_errc::no_state));
1961 if (__p_.__state_->__has_value())
1962 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1963 try
1964 {
1965#endif // _LIBCPP_NO_EXCEPTIONS
1966 __f_(_STD::forward<_ArgTypes>(__args)...);
1967 __p_.set_value();
1968#ifndef _LIBCPP_NO_EXCEPTIONS
1969 }
1970 catch (...)
1971 {
1972 __p_.set_exception(current_exception());
1973 }
1974#endif // _LIBCPP_NO_EXCEPTIONS
1975}
1976
1977template<class ..._ArgTypes>
1978void
1979packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
1980{
1981#ifndef _LIBCPP_NO_EXCEPTIONS
1982 if (__p_.__state_ == nullptr)
1983 throw future_error(make_error_code(future_errc::no_state));
1984 if (__p_.__state_->__has_value())
1985 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1986 try
1987 {
1988#endif // _LIBCPP_NO_EXCEPTIONS
1989 __f_(_STD::forward<_ArgTypes>(__args)...);
1990 __p_.set_value_at_thread_exit();
1991#ifndef _LIBCPP_NO_EXCEPTIONS
1992 }
1993 catch (...)
1994 {
1995 __p_.set_exception_at_thread_exit(current_exception());
1996 }
1997#endif // _LIBCPP_NO_EXCEPTIONS
1998}
1999
2000template<class ..._ArgTypes>
2001void
2002packaged_task<void(_ArgTypes...)>::reset()
2003{
2004#ifndef _LIBCPP_NO_EXCEPTIONS
2005 if (!(*this))
2006 throw future_error(make_error_code(future_errc::no_state));
2007#endif // _LIBCPP_NO_EXCEPTIONS
2008 __p_ = promise<result_type>();
2009}
2010
2011template <class _Callable>
2012inline _LIBCPP_INLINE_VISIBILITY
2013void
2014swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y)
2015{
2016 __x.swap(__y);
2017}
2018
2019template <class _Callable, class _Alloc>
2020struct uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
2021
2022template <class _R, class _F>
2023future<_R>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002024#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +00002025__make_deferred_assoc_state(_F&& __f)
2026#else
2027__make_deferred_assoc_state(_F __f)
2028#endif
2029{
2030 unique_ptr<__deferred_assoc_state<_R, _F>, __release_shared_count>
2031 __h(new __deferred_assoc_state<_R, _F>(_STD::forward<_F>(__f)));
2032 return future<_R>(__h.get());
2033}
2034
2035template <class _F, class... _Args>
2036future<typename result_of<_F(_Args...)>::type>
2037async(launch __policy, _F&& __f, _Args&&... __args)
2038{
2039 typedef typename result_of<_F(_Args...)>::type _R;
2040 future<_R> __r;
2041 if (__policy == launch::sync)
2042 __r = _STD::__make_deferred_assoc_state<_R>(bind(_STD::forward<_F>(__f),
2043 _STD::forward<_Args>(__args)...));
2044 else
2045 {
2046 packaged_task<_R()> __pk(bind(_STD::forward<_F>(__f),
2047 _STD::forward<_Args>(__args)...));
2048 __r = __pk.get_future();
2049 thread(_STD::move(__pk)).detach();
2050 }
2051 return __r;
2052}
2053
2054template <class _F, class... _Args>
2055inline _LIBCPP_INLINE_VISIBILITY
2056typename enable_if
2057<
2058 !is_same<typename decay<_F>::type, launch>::value,
2059 future<typename result_of<_F(_Args...)>::type>
2060>::type
2061async(_F&& __f, _Args&&... __args)
2062{
2063 return async(launch::any, _STD::forward<_F>(__f),
2064 _STD::forward<_Args>(__args)...);
2065}
2066
2067#endif // _LIBCPP_HAS_NO_VARIADICS
2068
Howard Hinnante6e4d012010-09-03 21:46:37 +00002069// shared_future
2070
Howard Hinnant99be8232010-09-03 18:39:25 +00002071template <class _R>
2072class shared_future
2073{
2074 __assoc_state<_R>* __state_;
2075
2076public:
2077 shared_future() : __state_(nullptr) {}
2078 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2079 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002080#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002081 shared_future(future<_R>&& __f) : __state_(__f.__state_)
2082 {__f.__state_ = nullptr;}
2083 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2084 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002085#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002086 ~shared_future();
2087 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002088#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002089 shared_future& operator=(shared_future&& __rhs)
2090 {
2091 shared_future(std::move(__rhs)).swap(*this);
2092 return *this;
2093 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002094#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002095
2096 // retrieving the value
2097 const _R& get() const {return __state_->copy();}
2098
2099 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2100
2101 // functions to check state
2102 bool valid() const {return __state_ != nullptr;}
2103
2104 void wait() const {__state_->wait();}
2105 template <class _Rep, class _Period>
2106 future_status
2107 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2108 {return __state_->wait_for(__rel_time);}
2109 template <class _Clock, class _Duration>
2110 future_status
2111 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2112 {return __state_->wait_until(__abs_time);}
2113};
2114
2115template <class _R>
2116shared_future<_R>::~shared_future()
2117{
2118 if (__state_)
2119 __state_->__release_shared();
2120}
2121
2122template <class _R>
2123shared_future<_R>&
2124shared_future<_R>::operator=(const shared_future& __rhs)
2125{
2126 if (__rhs.__state_)
2127 __rhs.__state_->__add_shared();
2128 if (__state_)
2129 __state_->__release_shared();
2130 __state_ = __rhs.__state_;
2131 return *this;
2132}
2133
2134template <class _R>
2135class shared_future<_R&>
2136{
2137 __assoc_state<_R&>* __state_;
2138
2139public:
2140 shared_future() : __state_(nullptr) {}
2141 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2142 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002143#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002144 shared_future(future<_R&>&& __f) : __state_(__f.__state_)
2145 {__f.__state_ = nullptr;}
2146 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2147 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002148#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002149 ~shared_future();
2150 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002151#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002152 shared_future& operator=(shared_future&& __rhs)
2153 {
2154 shared_future(std::move(__rhs)).swap(*this);
2155 return *this;
2156 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002157#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002158
2159 // retrieving the value
2160 _R& get() const {return __state_->copy();}
2161
2162 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2163
2164 // functions to check state
2165 bool valid() const {return __state_ != nullptr;}
2166
2167 void wait() const {__state_->wait();}
2168 template <class _Rep, class _Period>
2169 future_status
2170 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2171 {return __state_->wait_for(__rel_time);}
2172 template <class _Clock, class _Duration>
2173 future_status
2174 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2175 {return __state_->wait_until(__abs_time);}
2176};
2177
2178template <class _R>
2179shared_future<_R&>::~shared_future()
2180{
2181 if (__state_)
2182 __state_->__release_shared();
2183}
2184
2185template <class _R>
2186shared_future<_R&>&
2187shared_future<_R&>::operator=(const shared_future& __rhs)
2188{
2189 if (__rhs.__state_)
2190 __rhs.__state_->__add_shared();
2191 if (__state_)
2192 __state_->__release_shared();
2193 __state_ = __rhs.__state_;
2194 return *this;
2195}
2196
2197template <>
2198class shared_future<void>
2199{
2200 __assoc_sub_state* __state_;
2201
2202public:
2203 shared_future() : __state_(nullptr) {}
2204 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2205 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002206#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002207 shared_future(future<void>&& __f) : __state_(__f.__state_)
2208 {__f.__state_ = nullptr;}
2209 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2210 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002211#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002212 ~shared_future();
2213 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002214#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002215 shared_future& operator=(shared_future&& __rhs)
2216 {
2217 shared_future(std::move(__rhs)).swap(*this);
2218 return *this;
2219 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002220#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002221
2222 // retrieving the value
2223 void get() const {__state_->copy();}
2224
2225 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2226
2227 // functions to check state
2228 bool valid() const {return __state_ != nullptr;}
2229
2230 void wait() const {__state_->wait();}
2231 template <class _Rep, class _Period>
2232 future_status
2233 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2234 {return __state_->wait_for(__rel_time);}
2235 template <class _Clock, class _Duration>
2236 future_status
2237 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2238 {return __state_->wait_until(__abs_time);}
2239};
2240
2241template <class _R>
2242inline _LIBCPP_INLINE_VISIBILITY
2243void
2244swap(shared_future<_R>& __x, shared_future<_R>& __y)
2245{
2246 __x.swap(__y);
2247}
2248
Howard Hinnante6e4d012010-09-03 21:46:37 +00002249// atomic_future
2250
2251template <class _R>
2252class atomic_future
2253{
2254 __assoc_state<_R>* __state_;
2255 mutable mutex __mut_;
2256
2257public:
2258 atomic_future() : __state_(nullptr) {}
2259 atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_)
2260 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002261#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002262 atomic_future(future<_R>&& __f) : __state_(__f.__state_)
2263 {__f.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002264#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002265 ~atomic_future();
2266 atomic_future& operator=(const atomic_future& __rhs);
2267
2268 // retrieving the value
2269 const _R& get() const {return __state_->copy();}
2270
2271 void swap(atomic_future& __rhs);
2272
2273 // functions to check state
2274 bool valid() const {return __state_ != nullptr;}
2275
2276 void wait() const {__state_->wait();}
2277 template <class _Rep, class _Period>
2278 future_status
2279 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2280 {return __state_->wait_for(__rel_time);}
2281 template <class _Clock, class _Duration>
2282 future_status
2283 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2284 {return __state_->wait_until(__abs_time);}
2285};
2286
2287template <class _R>
2288atomic_future<_R>::~atomic_future()
2289{
2290 if (__state_)
2291 __state_->__release_shared();
2292}
2293
2294template <class _R>
2295atomic_future<_R>&
2296atomic_future<_R>::operator=(const atomic_future& __rhs)
2297{
2298 if (this != &__rhs)
2299 {
2300 unique_lock<mutex> __this(__mut_, defer_lock);
2301 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2302 _STD::lock(__this, __that);
2303 if (__rhs.__state_)
2304 __rhs.__state_->__add_shared();
2305 if (__state_)
2306 __state_->__release_shared();
2307 __state_ = __rhs.__state_;
2308 }
2309 return *this;
2310}
2311
2312template <class _R>
2313void
2314atomic_future<_R>::swap(atomic_future& __rhs)
2315{
2316 if (this != &__rhs)
2317 {
2318 unique_lock<mutex> __this(__mut_, defer_lock);
2319 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2320 _STD::lock(__this, __that);
2321 _STD::swap(__state_, __rhs.__state_);
2322 }
2323}
2324
2325template <class _R>
2326class atomic_future<_R&>
2327{
2328 __assoc_state<_R&>* __state_;
2329 mutable mutex __mut_;
2330
2331public:
2332 atomic_future() : __state_(nullptr) {}
2333 atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_)
2334 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002335#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002336 atomic_future(future<_R&>&& __f) : __state_(__f.__state_)
2337 {__f.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002338#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002339 ~atomic_future();
2340 atomic_future& operator=(const atomic_future& __rhs);
2341
2342 // retrieving the value
2343 _R& get() const {return __state_->copy();}
2344
2345 void swap(atomic_future& __rhs);
2346
2347 // functions to check state
2348 bool valid() const {return __state_ != nullptr;}
2349
2350 void wait() const {__state_->wait();}
2351 template <class _Rep, class _Period>
2352 future_status
2353 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2354 {return __state_->wait_for(__rel_time);}
2355 template <class _Clock, class _Duration>
2356 future_status
2357 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2358 {return __state_->wait_until(__abs_time);}
2359};
2360
2361template <class _R>
2362atomic_future<_R&>::~atomic_future()
2363{
2364 if (__state_)
2365 __state_->__release_shared();
2366}
2367
2368template <class _R>
2369atomic_future<_R&>&
2370atomic_future<_R&>::operator=(const atomic_future& __rhs)
2371{
2372 if (this != &__rhs)
2373 {
2374 unique_lock<mutex> __this(__mut_, defer_lock);
2375 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2376 _STD::lock(__this, __that);
2377 if (__rhs.__state_)
2378 __rhs.__state_->__add_shared();
2379 if (__state_)
2380 __state_->__release_shared();
2381 __state_ = __rhs.__state_;
2382 }
2383 return *this;
2384}
2385
2386template <class _R>
2387void
2388atomic_future<_R&>::swap(atomic_future& __rhs)
2389{
2390 if (this != &__rhs)
2391 {
2392 unique_lock<mutex> __this(__mut_, defer_lock);
2393 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2394 _STD::lock(__this, __that);
2395 _STD::swap(__state_, __rhs.__state_);
2396 }
2397}
2398
2399template <>
2400class atomic_future<void>
2401{
2402 __assoc_sub_state* __state_;
2403 mutable mutex __mut_;
2404
2405public:
2406 atomic_future() : __state_(nullptr) {}
2407 atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_)
2408 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002409#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002410 atomic_future(future<void>&& __f) : __state_(__f.__state_)
2411 {__f.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002412#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002413 ~atomic_future();
2414 atomic_future& operator=(const atomic_future& __rhs);
2415
2416 // retrieving the value
2417 void get() const {__state_->copy();}
2418
2419 void swap(atomic_future& __rhs);
2420
2421 // functions to check state
2422 bool valid() const {return __state_ != nullptr;}
2423
2424 void wait() const {__state_->wait();}
2425 template <class _Rep, class _Period>
2426 future_status
2427 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2428 {return __state_->wait_for(__rel_time);}
2429 template <class _Clock, class _Duration>
2430 future_status
2431 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2432 {return __state_->wait_until(__abs_time);}
2433};
2434
2435template <class _R>
2436inline _LIBCPP_INLINE_VISIBILITY
2437void
2438swap(atomic_future<_R>& __x, atomic_future<_R>& __y)
2439{
2440 __x.swap(__y);
2441}
2442
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002443_LIBCPP_END_NAMESPACE_STD
2444
2445#endif // _LIBCPP_FUTURE