blob: b75014ac123924818acbe581b9122c7d73d6af1c [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);
260 shared_future(future<R>&&);
261 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);
287 shared_future(future<R>&&);
288 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>
442#include <__mutex_base>
443#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>
613#ifdef _LIBCPP_MOVE
614 void set_value(_Arg&& __arg);
615#else
616 void set_value(_Arg& __arg);
617#endif
618
619 template <class _Arg>
620#ifdef _LIBCPP_MOVE
621 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
642#ifdef _LIBCPP_MOVE
643__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
660#ifdef _LIBCPP_MOVE
661__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:
837#ifdef _LIBCPP_MOVE
838 explicit __deferred_assoc_state(_F&& __f);
839#endif
840
841 virtual void __execute();
842};
843
844#ifdef _LIBCPP_MOVE
845
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
854#endif // _LIBCPP_MOVE
855
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:
883#ifdef _LIBCPP_MOVE
884 explicit __deferred_assoc_state(_F&& __f);
885#endif
886
887 virtual void __execute();
888};
889
890#ifdef _LIBCPP_MOVE
891
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
900#endif // _LIBCPP_MOVE
901
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;
922
923// future
924
Howard Hinnant54da3382010-08-30 18:46:21 +0000925template <class _R> class future;
926
927template <class _R, class _F>
928future<_R>
929#ifdef _LIBCPP_MOVE
930__make_deferred_assoc_state(_F&& __f);
931#else
932__make_deferred_assoc_state(_F __f);
933#endif
934
Howard Hinnant47499b12010-08-27 20:10:19 +0000935template <class _R>
936class future
937{
938 __assoc_state<_R>* __state_;
939
940 explicit future(__assoc_state<_R>* __state);
941
942 template <class> friend class promise;
Howard Hinnant54da3382010-08-30 18:46:21 +0000943
944 template <class _R1, class _F>
945#ifdef _LIBCPP_MOVE
946 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
947#else
948 friend future<_R1> __make_deferred_assoc_state(_F __f);
949#endif
950
Howard Hinnant47499b12010-08-27 20:10:19 +0000951public:
952 future() : __state_(nullptr) {}
953#ifdef _LIBCPP_MOVE
954 future(future&& __rhs)
955 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
956 future(const future&) = delete;
957 future& operator=(const future&) = delete;
958 future& operator=(future&& __rhs)
959 {
960 future(std::move(__rhs)).swap(*this);
961 return *this;
962 }
963#else // _LIBCPP_MOVE
964private:
965 future(const future&);
966 future& operator=(const future&);
967public:
968#endif // _LIBCPP_MOVE
969 ~future();
970
971 // retrieving the value
972 _R get();
973
974 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
975
976 // functions to check state
977 bool valid() const {return __state_ != nullptr;}
978
979 void wait() const {__state_->wait();}
980 template <class _Rep, class _Period>
981 future_status
982 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
983 {return __state_->wait_for(__rel_time);}
984 template <class _Clock, class _Duration>
985 future_status
986 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
987 {return __state_->wait_until(__abs_time);}
988};
989
990template <class _R>
991future<_R>::future(__assoc_state<_R>* __state)
992 : __state_(__state)
993{
994 if (__state_->__has_future_attached())
995 throw future_error(make_error_code(future_errc::future_already_retrieved));
996 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +0000997 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +0000998}
999
Howard Hinnant54da3382010-08-30 18:46:21 +00001000struct __release_shared_count
1001{
1002 void operator()(__shared_count* p) {p->__release_shared();}
1003};
1004
Howard Hinnant47499b12010-08-27 20:10:19 +00001005template <class _R>
1006future<_R>::~future()
1007{
1008 if (__state_)
1009 __state_->__release_shared();
1010}
1011
1012template <class _R>
1013_R
1014future<_R>::get()
1015{
Howard Hinnant54da3382010-08-30 18:46:21 +00001016 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001017 __assoc_state<_R>* __s = __state_;
1018 __state_ = nullptr;
1019 return __s->move();
1020}
1021
1022template <class _R>
1023class future<_R&>
1024{
1025 __assoc_state<_R&>* __state_;
1026
1027 explicit future(__assoc_state<_R&>* __state);
1028
1029 template <class> friend class promise;
Howard Hinnant54da3382010-08-30 18:46:21 +00001030
1031 template <class _R1, class _F>
1032#ifdef _LIBCPP_MOVE
1033 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
1034#else
1035 friend future<_R1> __make_deferred_assoc_state(_F __f);
1036#endif
1037
Howard Hinnant47499b12010-08-27 20:10:19 +00001038public:
1039 future() : __state_(nullptr) {}
1040#ifdef _LIBCPP_MOVE
1041 future(future&& __rhs)
1042 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1043 future(const future&) = delete;
1044 future& operator=(const future&) = delete;
1045 future& operator=(future&& __rhs)
1046 {
1047 future(std::move(__rhs)).swap(*this);
1048 return *this;
1049 }
1050#else // _LIBCPP_MOVE
1051private:
1052 future(const future&);
1053 future& operator=(const future&);
1054public:
1055#endif // _LIBCPP_MOVE
1056 ~future();
1057
1058 // retrieving the value
1059 _R& get();
1060
1061 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1062
1063 // functions to check state
1064 bool valid() const {return __state_ != nullptr;}
1065
1066 void wait() const {__state_->wait();}
1067 template <class _Rep, class _Period>
1068 future_status
1069 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1070 {return __state_->wait_for(__rel_time);}
1071 template <class _Clock, class _Duration>
1072 future_status
1073 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1074 {return __state_->wait_until(__abs_time);}
1075};
1076
1077template <class _R>
1078future<_R&>::future(__assoc_state<_R&>* __state)
1079 : __state_(__state)
1080{
1081 if (__state_->__has_future_attached())
1082 throw future_error(make_error_code(future_errc::future_already_retrieved));
1083 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001084 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001085}
1086
1087template <class _R>
1088future<_R&>::~future()
1089{
1090 if (__state_)
1091 __state_->__release_shared();
1092}
1093
1094template <class _R>
1095_R&
1096future<_R&>::get()
1097{
Howard Hinnant54da3382010-08-30 18:46:21 +00001098 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantf39daa82010-08-28 21:01:06 +00001099 __assoc_state<_R&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001100 __state_ = nullptr;
1101 return __s->copy();
1102}
1103
1104template <>
1105class future<void>
1106{
1107 __assoc_sub_state* __state_;
1108
1109 explicit future(__assoc_sub_state* __state);
1110
1111 template <class> friend class promise;
Howard Hinnant54da3382010-08-30 18:46:21 +00001112
1113 template <class _R1, class _F>
1114#ifdef _LIBCPP_MOVE
1115 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
1116#else
1117 friend future<_R1> __make_deferred_assoc_state(_F __f);
1118#endif
1119
Howard Hinnant47499b12010-08-27 20:10:19 +00001120public:
1121 future() : __state_(nullptr) {}
1122#ifdef _LIBCPP_MOVE
1123 future(future&& __rhs)
1124 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1125 future(const future&) = delete;
1126 future& operator=(const future&) = delete;
1127 future& operator=(future&& __rhs)
1128 {
1129 future(std::move(__rhs)).swap(*this);
1130 return *this;
1131 }
1132#else // _LIBCPP_MOVE
1133private:
1134 future(const future&);
1135 future& operator=(const future&);
1136public:
1137#endif // _LIBCPP_MOVE
1138 ~future();
1139
1140 // retrieving the value
1141 void get();
1142
1143 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1144
1145 // functions to check state
1146 bool valid() const {return __state_ != nullptr;}
1147
1148 void wait() const {__state_->wait();}
1149 template <class _Rep, class _Period>
1150 future_status
1151 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1152 {return __state_->wait_for(__rel_time);}
1153 template <class _Clock, class _Duration>
1154 future_status
1155 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1156 {return __state_->wait_until(__abs_time);}
1157};
1158
1159// promise<R>
1160
Howard Hinnant54da3382010-08-30 18:46:21 +00001161template <class> class packaged_task;
1162
Howard Hinnant47499b12010-08-27 20:10:19 +00001163template <class _R>
1164class promise
1165{
1166 __assoc_state<_R>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001167
1168 explicit promise(nullptr_t) : __state_(nullptr) {}
1169
1170 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001171public:
1172 promise();
1173 template <class _Alloc>
1174 promise(allocator_arg_t, const _Alloc& __a);
1175#ifdef _LIBCPP_MOVE
1176 promise(promise&& __rhs)
1177 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1178 promise(const promise& __rhs) = delete;
1179#else // _LIBCPP_MOVE
1180private:
1181 promise(const promise& __rhs);
1182public:
1183#endif // _LIBCPP_MOVE
1184 ~promise();
1185
1186 // assignment
1187#ifdef _LIBCPP_MOVE
1188 promise& operator=(promise&& __rhs)
1189 {
1190 promise(std::move(__rhs)).swap(*this);
1191 return *this;
1192 }
1193 promise& operator=(const promise& __rhs) = delete;
1194#else // _LIBCPP_MOVE
1195private:
1196 promise& operator=(const promise& __rhs);
1197public:
1198#endif // _LIBCPP_MOVE
1199 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1200
1201 // retrieving the result
1202 future<_R> get_future();
1203
1204 // setting the result
1205 void set_value(const _R& __r);
1206#ifdef _LIBCPP_MOVE
1207 void set_value(_R&& __r);
1208#endif
1209 void set_exception(exception_ptr __p);
1210
1211 // setting the result with deferred notification
1212 void set_value_at_thread_exit(const _R& __r);
1213#ifdef _LIBCPP_MOVE
1214 void set_value_at_thread_exit(_R&& __r);
1215#endif
1216 void set_exception_at_thread_exit(exception_ptr __p);
1217};
1218
1219template <class _R>
1220promise<_R>::promise()
1221 : __state_(new __assoc_state<_R>)
1222{
1223}
1224
1225template <class _R>
1226template <class _Alloc>
1227promise<_R>::promise(allocator_arg_t, const _Alloc& __a0)
1228{
1229 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R, _Alloc> >::other _A2;
1230 typedef __allocator_destructor<_A2> _D2;
1231 _A2 __a(__a0);
1232 unique_ptr<__assoc_state_alloc<_R, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1233 ::new(__hold.get()) __assoc_state_alloc<_R, _Alloc>(__a0);
1234 __state_ = __hold.release();
1235}
1236
1237template <class _R>
1238promise<_R>::~promise()
1239{
1240 if (__state_)
1241 {
1242 if (!__state_->__has_value() && __state_->use_count() > 1)
1243 __state_->set_exception(make_exception_ptr(
1244 future_error(make_error_code(future_errc::broken_promise))
1245 ));
1246 __state_->__release_shared();
1247 }
1248}
1249
1250template <class _R>
1251future<_R>
1252promise<_R>::get_future()
1253{
1254 if (__state_ == nullptr)
1255 throw future_error(make_error_code(future_errc::no_state));
1256 return future<_R>(__state_);
1257}
1258
1259template <class _R>
1260void
1261promise<_R>::set_value(const _R& __r)
1262{
1263 if (__state_ == nullptr)
1264 throw future_error(make_error_code(future_errc::no_state));
1265 __state_->set_value(__r);
1266}
1267
1268#ifdef _LIBCPP_MOVE
1269
1270template <class _R>
1271void
1272promise<_R>::set_value(_R&& __r)
1273{
1274 if (__state_ == nullptr)
1275 throw future_error(make_error_code(future_errc::no_state));
1276 __state_->set_value(_STD::move(__r));
1277}
1278
1279#endif // _LIBCPP_MOVE
1280
1281template <class _R>
1282void
1283promise<_R>::set_exception(exception_ptr __p)
1284{
1285 if (__state_ == nullptr)
1286 throw future_error(make_error_code(future_errc::no_state));
1287 __state_->set_exception(__p);
1288}
1289
1290template <class _R>
1291void
1292promise<_R>::set_value_at_thread_exit(const _R& __r)
1293{
1294 if (__state_ == nullptr)
1295 throw future_error(make_error_code(future_errc::no_state));
1296 __state_->set_value_at_thread_exit(__r);
1297}
1298
1299#ifdef _LIBCPP_MOVE
1300
1301template <class _R>
1302void
1303promise<_R>::set_value_at_thread_exit(_R&& __r)
1304{
1305 if (__state_ == nullptr)
1306 throw future_error(make_error_code(future_errc::no_state));
1307 __state_->set_value_at_thread_exit(_STD::move(__r));
1308}
1309
1310#endif // _LIBCPP_MOVE
1311
1312template <class _R>
1313void
1314promise<_R>::set_exception_at_thread_exit(exception_ptr __p)
1315{
1316 if (__state_ == nullptr)
1317 throw future_error(make_error_code(future_errc::no_state));
1318 __state_->set_exception_at_thread_exit(__p);
1319}
1320
1321// promise<R&>
1322
1323template <class _R>
1324class promise<_R&>
1325{
1326 __assoc_state<_R&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001327
1328 explicit promise(nullptr_t) : __state_(nullptr) {}
1329
1330 template <class> friend class packaged_task;
1331
Howard Hinnant47499b12010-08-27 20:10:19 +00001332public:
1333 promise();
1334 template <class _Allocator>
1335 promise(allocator_arg_t, const _Allocator& __a);
1336#ifdef _LIBCPP_MOVE
1337 promise(promise&& __rhs)
1338 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1339 promise(const promise& __rhs) = delete;
1340#else // _LIBCPP_MOVE
1341private:
1342 promise(const promise& __rhs);
1343public:
1344#endif // _LIBCPP_MOVE
1345 ~promise();
1346
1347 // assignment
1348#ifdef _LIBCPP_MOVE
1349 promise& operator=(promise&& __rhs)
1350 {
1351 promise(std::move(__rhs)).swap(*this);
1352 return *this;
1353 }
1354 promise& operator=(const promise& __rhs) = delete;
1355#else // _LIBCPP_MOVE
1356private:
1357 promise& operator=(const promise& __rhs);
1358public:
1359#endif // _LIBCPP_MOVE
1360 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1361
1362 // retrieving the result
1363 future<_R&> get_future();
1364
1365 // setting the result
1366 void set_value(_R& __r);
1367 void set_exception(exception_ptr __p);
1368
1369 // setting the result with deferred notification
1370 void set_value_at_thread_exit(_R&);
1371 void set_exception_at_thread_exit(exception_ptr __p);
1372};
1373
1374template <class _R>
1375promise<_R&>::promise()
1376 : __state_(new __assoc_state<_R&>)
1377{
1378}
1379
1380template <class _R>
1381template <class _Alloc>
1382promise<_R&>::promise(allocator_arg_t, const _Alloc& __a0)
1383{
1384 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R&, _Alloc> >::other _A2;
1385 typedef __allocator_destructor<_A2> _D2;
1386 _A2 __a(__a0);
1387 unique_ptr<__assoc_state_alloc<_R&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1388 ::new(__hold.get()) __assoc_state_alloc<_R&, _Alloc>(__a0);
1389 __state_ = __hold.release();
1390}
1391
1392template <class _R>
1393promise<_R&>::~promise()
1394{
1395 if (__state_)
1396 {
1397 if (!__state_->__has_value() && __state_->use_count() > 1)
1398 __state_->set_exception(make_exception_ptr(
1399 future_error(make_error_code(future_errc::broken_promise))
1400 ));
1401 __state_->__release_shared();
1402 }
1403}
1404
1405template <class _R>
1406future<_R&>
1407promise<_R&>::get_future()
1408{
1409 if (__state_ == nullptr)
1410 throw future_error(make_error_code(future_errc::no_state));
1411 return future<_R&>(__state_);
1412}
1413
1414template <class _R>
1415void
1416promise<_R&>::set_value(_R& __r)
1417{
1418 if (__state_ == nullptr)
1419 throw future_error(make_error_code(future_errc::no_state));
1420 __state_->set_value(__r);
1421}
1422
1423template <class _R>
1424void
1425promise<_R&>::set_exception(exception_ptr __p)
1426{
1427 if (__state_ == nullptr)
1428 throw future_error(make_error_code(future_errc::no_state));
1429 __state_->set_exception(__p);
1430}
1431
1432template <class _R>
1433void
1434promise<_R&>::set_value_at_thread_exit(_R& __r)
1435{
1436 if (__state_ == nullptr)
1437 throw future_error(make_error_code(future_errc::no_state));
1438 __state_->set_value_at_thread_exit(__r);
1439}
1440
1441template <class _R>
1442void
1443promise<_R&>::set_exception_at_thread_exit(exception_ptr __p)
1444{
1445 if (__state_ == nullptr)
1446 throw future_error(make_error_code(future_errc::no_state));
1447 __state_->set_exception_at_thread_exit(__p);
1448}
1449
1450// promise<void>
1451
1452template <>
1453class promise<void>
1454{
1455 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001456
1457 explicit promise(nullptr_t) : __state_(nullptr) {}
1458
1459 template <class> friend class packaged_task;
1460
Howard Hinnant47499b12010-08-27 20:10:19 +00001461public:
1462 promise();
1463 template <class _Allocator>
1464 promise(allocator_arg_t, const _Allocator& __a);
1465#ifdef _LIBCPP_MOVE
1466 promise(promise&& __rhs)
1467 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1468 promise(const promise& __rhs) = delete;
1469#else // _LIBCPP_MOVE
1470private:
1471 promise(const promise& __rhs);
1472public:
1473#endif // _LIBCPP_MOVE
1474 ~promise();
1475
1476 // assignment
1477#ifdef _LIBCPP_MOVE
1478 promise& operator=(promise&& __rhs)
1479 {
1480 promise(std::move(__rhs)).swap(*this);
1481 return *this;
1482 }
1483 promise& operator=(const promise& __rhs) = delete;
1484#else // _LIBCPP_MOVE
1485private:
1486 promise& operator=(const promise& __rhs);
1487public:
1488#endif // _LIBCPP_MOVE
1489 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1490
1491 // retrieving the result
1492 future<void> get_future();
1493
1494 // setting the result
1495 void set_value();
1496 void set_exception(exception_ptr __p);
1497
1498 // setting the result with deferred notification
1499 void set_value_at_thread_exit();
1500 void set_exception_at_thread_exit(exception_ptr __p);
1501};
1502
1503template <class _Alloc>
1504promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1505{
1506 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1507 typedef __allocator_destructor<_A2> _D2;
1508 _A2 __a(__a0);
1509 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1510 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1511 __state_ = __hold.release();
1512}
1513
1514template <class _R>
1515inline _LIBCPP_INLINE_VISIBILITY
1516void
1517swap(promise<_R>& __x, promise<_R>& __y)
1518{
1519 __x.swap(__y);
1520}
1521
1522template <class _R, class _Alloc>
1523 struct uses_allocator<promise<_R>, _Alloc> : public true_type {};
1524
Howard Hinnant54da3382010-08-30 18:46:21 +00001525#ifndef _LIBCPP_HAS_NO_VARIADICS
1526
1527// packaged_task
1528
1529template<class _Fp> class __packaged_task_base;
1530
1531template<class _R, class ..._ArgTypes>
1532class __packaged_task_base<_R(_ArgTypes...)>
1533{
1534 __packaged_task_base(const __packaged_task_base&);
1535 __packaged_task_base& operator=(const __packaged_task_base&);
1536public:
1537 __packaged_task_base() {}
1538 virtual ~__packaged_task_base() {}
1539 virtual void __move_to(__packaged_task_base*) = 0;
1540 virtual void destroy() = 0;
1541 virtual void destroy_deallocate() = 0;
1542 virtual _R operator()(_ArgTypes&& ...) = 0;
1543};
1544
1545template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1546
1547template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1548class __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>
1549 : public __packaged_task_base<_R(_ArgTypes...)>
1550{
1551 __compressed_pair<_F, _Alloc> __f_;
1552public:
1553 explicit __packaged_task_func(const _F& __f) : __f_(__f) {}
1554 explicit __packaged_task_func(_F&& __f) : __f_(_STD::move(__f)) {}
1555 __packaged_task_func(const _F& __f, const _Alloc& __a)
1556 : __f_(__f, __a) {}
1557 __packaged_task_func(_F&& __f, const _Alloc& __a)
1558 : __f_(_STD::move(__f), __a) {}
1559 virtual void __move_to(__packaged_task_base<_R(_ArgTypes...)>*);
1560 virtual void destroy();
1561 virtual void destroy_deallocate();
1562 virtual _R operator()(_ArgTypes&& ... __args);
1563};
1564
1565template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1566void
1567__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::__move_to(
1568 __packaged_task_base<_R(_ArgTypes...)>* __p)
1569{
1570 ::new (__p) __packaged_task_func(_STD::move(__f_.first()), _STD::move(__f_.second()));
1571}
1572
1573template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1574void
1575__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy()
1576{
1577 __f_.~__compressed_pair<_F, _Alloc>();
1578}
1579
1580template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1581void
1582__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy_deallocate()
1583{
1584 typedef typename _Alloc::template rebind<__packaged_task_func>::other _A;
1585 _A __a(__f_.second());
1586 __f_.~__compressed_pair<_F, _Alloc>();
1587 __a.deallocate(this, 1);
1588}
1589
1590template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1591_R
1592__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1593{
1594 return __invoke(__f_.first(), _STD::forward<_ArgTypes>(__arg)...);
1595}
1596
1597template <class> class __packaged_task_function;
1598
1599template<class _R, class ..._ArgTypes>
1600class __packaged_task_function<_R(_ArgTypes...)>
1601{
1602 typedef __packaged_task_base<_R(_ArgTypes...)> __base;
1603 aligned_storage<3*sizeof(void*)>::type __buf_;
1604 __base* __f_;
1605
1606public:
1607 typedef _R result_type;
1608
1609 // construct/copy/destroy:
1610 __packaged_task_function() : __f_(nullptr) {}
1611 template<class _F>
1612 __packaged_task_function(_F&& __f);
1613 template<class _F, class _Alloc>
1614 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _F&& __f);
1615
1616 __packaged_task_function(__packaged_task_function&&);
1617 __packaged_task_function& operator=(__packaged_task_function&&);
1618
1619 __packaged_task_function(const __packaged_task_function&) = delete;
1620 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1621
1622 ~__packaged_task_function();
1623
1624 void swap(__packaged_task_function&);
1625
1626 _R operator()(_ArgTypes...) const;
1627};
1628
1629template<class _R, class ..._ArgTypes>
1630__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f)
1631{
1632 if (__f.__f_ == nullptr)
1633 __f_ = nullptr;
1634 else if (__f.__f_ == (__base*)&__f.__buf_)
1635 {
1636 __f_ = (__base*)&__buf_;
1637 __f.__f_->__move_to(__f_);
1638 }
1639 else
1640 {
1641 __f_ = __f.__f_;
1642 __f.__f_ = nullptr;
1643 }
1644}
1645
1646template<class _R, class ..._ArgTypes>
1647template <class _F>
1648__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(_F&& __f)
1649 : __f_(nullptr)
1650{
1651 typedef typename remove_reference<_F>::type _FR;
1652 typedef __packaged_task_func<_FR, allocator<_FR>, _R(_ArgTypes...)> _FF;
1653 if (sizeof(_FF) <= sizeof(__buf_))
1654 {
1655 __f_ = (__base*)&__buf_;
1656 ::new (__f_) _FF(_STD::forward<_F>(__f));
1657 }
1658 else
1659 {
1660 typedef allocator<_FF> _A;
1661 _A __a;
1662 typedef __allocator_destructor<_A> _D;
1663 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1664 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), allocator<_FR>(__a));
1665 __f_ = __hold.release();
1666 }
1667}
1668
1669template<class _R, class ..._ArgTypes>
1670template <class _F, class _Alloc>
1671__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(
1672 allocator_arg_t, const _Alloc& __a0, _F&& __f)
1673 : __f_(nullptr)
1674{
1675 typedef allocator_traits<_Alloc> __alloc_traits;
1676 typedef typename remove_reference<_F>::type _FR;
1677 typedef __packaged_task_func<_FR, _Alloc, _R(_ArgTypes...)> _FF;
1678 if (sizeof(_FF) <= sizeof(__buf_))
1679 {
1680 __f_ = (__base*)&__buf_;
1681 ::new (__f_) _FF(_STD::forward<_F>(__f));
1682 }
1683 else
1684 {
1685 typedef typename __alloc_traits::template
1686#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1687 rebind_alloc<_FF>
1688#else
1689 rebind_alloc<_FF>::other
1690#endif
1691 _A;
1692 _A __a(__a0);
1693 typedef __allocator_destructor<_A> _D;
1694 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1695 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), _Alloc(__a));
1696 __f_ = __hold.release();
1697 }
1698}
1699
1700template<class _R, class ..._ArgTypes>
1701__packaged_task_function<_R(_ArgTypes...)>&
1702__packaged_task_function<_R(_ArgTypes...)>::operator=(__packaged_task_function&& __f)
1703{
1704 if (__f_ == (__base*)&__buf_)
1705 __f_->destroy();
1706 else if (__f_)
1707 __f_->destroy_deallocate();
1708 __f_ = nullptr;
1709 if (__f.__f_ == nullptr)
1710 __f_ = nullptr;
1711 else if (__f.__f_ == (__base*)&__f.__buf_)
1712 {
1713 __f_ = (__base*)&__buf_;
1714 __f.__f_->__move_to(__f_);
1715 }
1716 else
1717 {
1718 __f_ = __f.__f_;
1719 __f.__f_ = nullptr;
1720 }
1721}
1722
1723template<class _R, class ..._ArgTypes>
1724__packaged_task_function<_R(_ArgTypes...)>::~__packaged_task_function()
1725{
1726 if (__f_ == (__base*)&__buf_)
1727 __f_->destroy();
1728 else if (__f_)
1729 __f_->destroy_deallocate();
1730}
1731
1732template<class _R, class ..._ArgTypes>
1733void
1734__packaged_task_function<_R(_ArgTypes...)>::swap(__packaged_task_function& __f)
1735{
1736 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1737 {
1738 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1739 __base* __t = (__base*)&__tempbuf;
1740 __f_->__move_to(__t);
1741 __f_->destroy();
1742 __f_ = nullptr;
1743 __f.__f_->__move_to((__base*)&__buf_);
1744 __f.__f_->destroy();
1745 __f.__f_ = nullptr;
1746 __f_ = (__base*)&__buf_;
1747 __t->__move_to((__base*)&__f.__buf_);
1748 __t->destroy();
1749 __f.__f_ = (__base*)&__f.__buf_;
1750 }
1751 else if (__f_ == (__base*)&__buf_)
1752 {
1753 __f_->__move_to((__base*)&__f.__buf_);
1754 __f_->destroy();
1755 __f_ = __f.__f_;
1756 __f.__f_ = (__base*)&__f.__buf_;
1757 }
1758 else if (__f.__f_ == (__base*)&__f.__buf_)
1759 {
1760 __f.__f_->__move_to((__base*)&__buf_);
1761 __f.__f_->destroy();
1762 __f.__f_ = __f_;
1763 __f_ = (__base*)&__buf_;
1764 }
1765 else
1766 _STD::swap(__f_, __f.__f_);
1767}
1768
1769template<class _R, class ..._ArgTypes>
1770inline _LIBCPP_INLINE_VISIBILITY
1771_R
1772__packaged_task_function<_R(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1773{
1774 return (*__f_)(_STD::forward<_ArgTypes>(__arg)...);
1775}
1776
1777template<class _R, class ..._ArgTypes>
1778class packaged_task<_R(_ArgTypes...)>
1779{
1780public:
1781 typedef _R result_type;
1782
1783private:
1784 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1785 promise<result_type> __p_;
1786
1787public:
1788 // construction and destruction
1789 packaged_task() : __p_(nullptr) {}
1790 template <class _F>
1791 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
1792 template <class _F, class _Allocator>
1793 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
1794 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
1795 __p_(allocator_arg, __a) {}
1796 // ~packaged_task() = default;
1797
1798 // no copy
1799 packaged_task(packaged_task&) = delete;
1800 packaged_task& operator=(packaged_task&) = delete;
1801
1802 // move support
1803 packaged_task(packaged_task&& __other)
1804 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
1805 packaged_task& operator=(packaged_task&& __other)
1806 {
1807 __f_ = _STD::move(__other.__f_);
1808 __p_ = _STD::move(__other.__p_);
1809 return *this;
1810 }
1811 void swap(packaged_task& __other)
1812 {
1813 __f_.swap(__other.__f_);
1814 __p_.swap(__other.__p_);
1815 }
1816
1817 //explicit
1818 operator bool() const {return __p_.__state_ != nullptr;}
1819
1820 // result retrieval
1821 future<result_type> get_future() {return __p_.get_future();}
1822
1823 // execution
1824 void operator()(_ArgTypes... __args);
1825 void make_ready_at_thread_exit(_ArgTypes... __args);
1826
1827 void reset();
1828};
1829
1830template<class _R, class ..._ArgTypes>
1831void
1832packaged_task<_R(_ArgTypes...)>::operator()(_ArgTypes... __args)
1833{
1834#ifndef _LIBCPP_NO_EXCEPTIONS
1835 if (__p_.__state_ == nullptr)
1836 throw future_error(make_error_code(future_errc::no_state));
1837 if (__p_.__state_->__has_value())
1838 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1839 try
1840 {
1841#endif // _LIBCPP_NO_EXCEPTIONS
1842 __p_.set_value(__f_(_STD::forward<_ArgTypes>(__args)...));
1843#ifndef _LIBCPP_NO_EXCEPTIONS
1844 }
1845 catch (...)
1846 {
1847 __p_.set_exception(current_exception());
1848 }
1849#endif // _LIBCPP_NO_EXCEPTIONS
1850}
1851
1852template<class _R, class ..._ArgTypes>
1853void
1854packaged_task<_R(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
1855{
1856#ifndef _LIBCPP_NO_EXCEPTIONS
1857 if (__p_.__state_ == nullptr)
1858 throw future_error(make_error_code(future_errc::no_state));
1859 if (__p_.__state_->__has_value())
1860 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1861 try
1862 {
1863#endif // _LIBCPP_NO_EXCEPTIONS
1864 __p_.set_value_at_thread_exit(__f_(_STD::forward<_ArgTypes>(__args)...));
1865#ifndef _LIBCPP_NO_EXCEPTIONS
1866 }
1867 catch (...)
1868 {
1869 __p_.set_exception_at_thread_exit(current_exception());
1870 }
1871#endif // _LIBCPP_NO_EXCEPTIONS
1872}
1873
1874template<class _R, class ..._ArgTypes>
1875void
1876packaged_task<_R(_ArgTypes...)>::reset()
1877{
1878#ifndef _LIBCPP_NO_EXCEPTIONS
1879 if (!(*this))
1880 throw future_error(make_error_code(future_errc::no_state));
1881#endif // _LIBCPP_NO_EXCEPTIONS
1882 __p_ = promise<result_type>();
1883}
1884
1885template<class ..._ArgTypes>
1886class packaged_task<void(_ArgTypes...)>
1887{
1888public:
1889 typedef void result_type;
1890
1891private:
1892 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1893 promise<result_type> __p_;
1894
1895public:
1896 // construction and destruction
1897 packaged_task() : __p_(nullptr) {}
1898 template <class _F>
1899 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
1900 template <class _F, class _Allocator>
1901 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
1902 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
1903 __p_(allocator_arg, __a) {}
1904 // ~packaged_task() = default;
1905
1906 // no copy
1907 packaged_task(packaged_task&) = delete;
1908 packaged_task& operator=(packaged_task&) = delete;
1909
1910 // move support
1911 packaged_task(packaged_task&& __other)
1912 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
1913 packaged_task& operator=(packaged_task&& __other)
1914 {
1915 __f_ = _STD::move(__other.__f_);
1916 __p_ = _STD::move(__other.__p_);
1917 return *this;
1918 }
1919 void swap(packaged_task& __other)
1920 {
1921 __f_.swap(__other.__f_);
1922 __p_.swap(__other.__p_);
1923 }
1924
1925 //explicit
1926 operator bool() const {return __p_.__state_ != nullptr;}
1927
1928 // result retrieval
1929 future<result_type> get_future() {return __p_.get_future();}
1930
1931 // execution
1932 void operator()(_ArgTypes... __args);
1933 void make_ready_at_thread_exit(_ArgTypes... __args);
1934
1935 void reset();
1936};
1937
1938template<class ..._ArgTypes>
1939void
1940packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
1941{
1942#ifndef _LIBCPP_NO_EXCEPTIONS
1943 if (__p_.__state_ == nullptr)
1944 throw future_error(make_error_code(future_errc::no_state));
1945 if (__p_.__state_->__has_value())
1946 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1947 try
1948 {
1949#endif // _LIBCPP_NO_EXCEPTIONS
1950 __f_(_STD::forward<_ArgTypes>(__args)...);
1951 __p_.set_value();
1952#ifndef _LIBCPP_NO_EXCEPTIONS
1953 }
1954 catch (...)
1955 {
1956 __p_.set_exception(current_exception());
1957 }
1958#endif // _LIBCPP_NO_EXCEPTIONS
1959}
1960
1961template<class ..._ArgTypes>
1962void
1963packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
1964{
1965#ifndef _LIBCPP_NO_EXCEPTIONS
1966 if (__p_.__state_ == nullptr)
1967 throw future_error(make_error_code(future_errc::no_state));
1968 if (__p_.__state_->__has_value())
1969 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1970 try
1971 {
1972#endif // _LIBCPP_NO_EXCEPTIONS
1973 __f_(_STD::forward<_ArgTypes>(__args)...);
1974 __p_.set_value_at_thread_exit();
1975#ifndef _LIBCPP_NO_EXCEPTIONS
1976 }
1977 catch (...)
1978 {
1979 __p_.set_exception_at_thread_exit(current_exception());
1980 }
1981#endif // _LIBCPP_NO_EXCEPTIONS
1982}
1983
1984template<class ..._ArgTypes>
1985void
1986packaged_task<void(_ArgTypes...)>::reset()
1987{
1988#ifndef _LIBCPP_NO_EXCEPTIONS
1989 if (!(*this))
1990 throw future_error(make_error_code(future_errc::no_state));
1991#endif // _LIBCPP_NO_EXCEPTIONS
1992 __p_ = promise<result_type>();
1993}
1994
1995template <class _Callable>
1996inline _LIBCPP_INLINE_VISIBILITY
1997void
1998swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y)
1999{
2000 __x.swap(__y);
2001}
2002
2003template <class _Callable, class _Alloc>
2004struct uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
2005
2006template <class _R, class _F>
2007future<_R>
2008#ifdef _LIBCPP_MOVE
2009__make_deferred_assoc_state(_F&& __f)
2010#else
2011__make_deferred_assoc_state(_F __f)
2012#endif
2013{
2014 unique_ptr<__deferred_assoc_state<_R, _F>, __release_shared_count>
2015 __h(new __deferred_assoc_state<_R, _F>(_STD::forward<_F>(__f)));
2016 return future<_R>(__h.get());
2017}
2018
2019template <class _F, class... _Args>
2020future<typename result_of<_F(_Args...)>::type>
2021async(launch __policy, _F&& __f, _Args&&... __args)
2022{
2023 typedef typename result_of<_F(_Args...)>::type _R;
2024 future<_R> __r;
2025 if (__policy == launch::sync)
2026 __r = _STD::__make_deferred_assoc_state<_R>(bind(_STD::forward<_F>(__f),
2027 _STD::forward<_Args>(__args)...));
2028 else
2029 {
2030 packaged_task<_R()> __pk(bind(_STD::forward<_F>(__f),
2031 _STD::forward<_Args>(__args)...));
2032 __r = __pk.get_future();
2033 thread(_STD::move(__pk)).detach();
2034 }
2035 return __r;
2036}
2037
2038template <class _F, class... _Args>
2039inline _LIBCPP_INLINE_VISIBILITY
2040typename enable_if
2041<
2042 !is_same<typename decay<_F>::type, launch>::value,
2043 future<typename result_of<_F(_Args...)>::type>
2044>::type
2045async(_F&& __f, _Args&&... __args)
2046{
2047 return async(launch::any, _STD::forward<_F>(__f),
2048 _STD::forward<_Args>(__args)...);
2049}
2050
2051#endif // _LIBCPP_HAS_NO_VARIADICS
2052
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002053_LIBCPP_END_NAMESPACE_STD
2054
2055#endif // _LIBCPP_FUTURE