blob: d482577e525aacd2bf698d4b2fcce1e7c6c6fa65 [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
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000450struct _LIBCPP_VISIBLE future_errc
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000451{
452enum _ {
453 broken_promise,
454 future_already_retrieved,
455 promise_already_satisfied,
456 no_state
457};
458
459 _ __v_;
460
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000461 _LIBCPP_INLINE_VISIBILITY future_errc(_ __v) : __v_(__v) {}
462 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000463
464};
465
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000466template <>
467struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000468
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000469//enum class launch
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000470struct _LIBCPP_VISIBLE launch
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000471{
472enum _ {
473 any,
474 async,
475 sync
476};
477
478 _ __v_;
479
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000480 _LIBCPP_INLINE_VISIBILITY launch(_ __v) : __v_(__v) {}
481 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000482
483};
484
485//enum class future_status
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000486struct _LIBCPP_VISIBLE future_status
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000487{
488enum _ {
489 ready,
490 timeout,
491 deferred
492};
493
494 _ __v_;
495
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000496 _LIBCPP_INLINE_VISIBILITY future_status(_ __v) : __v_(__v) {}
497 _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000498
499};
500
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000501_LIBCPP_VISIBLE
Howard Hinnanta6521722010-08-25 17:32:05 +0000502const error_category& future_category();
503
504inline _LIBCPP_INLINE_VISIBILITY
505error_code
506make_error_code(future_errc __e)
507{
508 return error_code(static_cast<int>(__e), future_category());
509}
510
511inline _LIBCPP_INLINE_VISIBILITY
512error_condition
513make_error_condition(future_errc __e)
514{
515 return error_condition(static_cast<int>(__e), future_category());
516}
517
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000518class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000519 : public logic_error
520{
521 error_code __ec_;
522public:
523 future_error(error_code __ec);
524
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000525 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta6521722010-08-25 17:32:05 +0000526 const error_code& code() const throw() {return __ec_;}
527};
528
Howard Hinnant47499b12010-08-27 20:10:19 +0000529class __assoc_sub_state
530 : public __shared_count
531{
532protected:
533 exception_ptr __exception_;
534 mutable mutex __mut_;
535 mutable condition_variable __cv_;
536 unsigned __state_;
537
538 virtual void __on_zero_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +0000539 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000540public:
541 enum
542 {
543 __constructed = 1,
544 __future_attached = 2,
545 ready = 4,
546 deferred = 8
547 };
548
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000550 __assoc_sub_state() : __state_(0) {}
551
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000553 bool __has_value() const
554 {return (__state_ & __constructed) || (__exception_ != nullptr);}
555
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000557 void __set_future_attached() {__state_ |= __future_attached;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000559 bool __has_future_attached() const {return __state_ & __future_attached;}
560
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000562 void __set_deferred() {__state_ |= deferred;}
563
Howard Hinnant47499b12010-08-27 20:10:19 +0000564 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000566 bool __is_ready() const {return __state_ & ready;}
567
568 void set_value();
569 void set_value_at_thread_exit();
570
571 void set_exception(exception_ptr __p);
572 void set_exception_at_thread_exit(exception_ptr __p);
573
574 void copy();
575
Howard Hinnant54da3382010-08-30 18:46:21 +0000576 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000577 template <class _Rep, class _Period>
578 future_status
579 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
580 template <class _Clock, class _Duration>
581 future_status
582 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000583
584 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000585};
586
Howard Hinnantf39daa82010-08-28 21:01:06 +0000587template <class _Clock, class _Duration>
588future_status
589__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
590{
591 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000592 if (__state_ & deferred)
593 return future_status::deferred;
594 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000595 __cv_.wait_until(__lk, __abs_time);
596 if (__state_ & ready)
597 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000598 return future_status::timeout;
599}
600
601template <class _Rep, class _Period>
602inline _LIBCPP_INLINE_VISIBILITY
603future_status
604__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
605{
606 return wait_until(chrono::monotonic_clock::now() + __rel_time);
607}
608
Howard Hinnant47499b12010-08-27 20:10:19 +0000609template <class _R>
610class __assoc_state
611 : public __assoc_sub_state
612{
613 typedef __assoc_sub_state base;
614 typedef typename aligned_storage<sizeof(_R), alignment_of<_R>::value>::type _U;
615protected:
616 _U __value_;
617
618 virtual void __on_zero_shared();
619public:
620
621 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000622#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000623 void set_value(_Arg&& __arg);
624#else
625 void set_value(_Arg& __arg);
626#endif
627
628 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000629#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000630 void set_value_at_thread_exit(_Arg&& __arg);
631#else
632 void set_value_at_thread_exit(_Arg& __arg);
633#endif
634
635 _R move();
636 typename add_lvalue_reference<_R>::type copy();
637};
638
639template <class _R>
640void
641__assoc_state<_R>::__on_zero_shared()
642{
643 if (this->__state_ & base::__constructed)
644 reinterpret_cast<_R*>(&__value_)->~_R();
645 delete this;
646}
647
648template <class _R>
649template <class _Arg>
650void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000651#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000652__assoc_state<_R>::set_value(_Arg&& __arg)
653#else
654__assoc_state<_R>::set_value(_Arg& __arg)
655#endif
656{
657 unique_lock<mutex> __lk(this->__mut_);
658 if (this->__has_value())
659 throw future_error(make_error_code(future_errc::promise_already_satisfied));
660 ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
661 this->__state_ |= base::__constructed | base::ready;
662 __lk.unlock();
663 __cv_.notify_all();
664}
665
666template <class _R>
667template <class _Arg>
668void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000669#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000670__assoc_state<_R>::set_value_at_thread_exit(_Arg&& __arg)
671#else
672__assoc_state<_R>::set_value_at_thread_exit(_Arg& __arg)
673#endif
674{
675 unique_lock<mutex> __lk(this->__mut_);
676 if (this->__has_value())
677 throw future_error(make_error_code(future_errc::promise_already_satisfied));
678 ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
679 this->__state_ |= base::__constructed;
680 __thread_local_data->__make_ready_at_thread_exit(this);
681 __lk.unlock();
682}
683
684template <class _R>
685_R
686__assoc_state<_R>::move()
687{
688 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000689 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000690 if (this->__exception_ != nullptr)
691 rethrow_exception(this->__exception_);
692 return _STD::move(*reinterpret_cast<_R*>(&__value_));
693}
694
695template <class _R>
696typename add_lvalue_reference<_R>::type
697__assoc_state<_R>::copy()
698{
699 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000700 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000701 if (this->__exception_ != nullptr)
702 rethrow_exception(this->__exception_);
703 return *reinterpret_cast<_R*>(&__value_);
704}
705
Howard Hinnantf39daa82010-08-28 21:01:06 +0000706template <class _R>
707class __assoc_state<_R&>
708 : public __assoc_sub_state
709{
710 typedef __assoc_sub_state base;
711 typedef _R* _U;
712protected:
713 _U __value_;
714
715 virtual void __on_zero_shared();
716public:
717
718 void set_value(_R& __arg);
719 void set_value_at_thread_exit(_R& __arg);
720
721 _R& copy();
722};
723
724template <class _R>
725void
726__assoc_state<_R&>::__on_zero_shared()
727{
728 delete this;
729}
730
731template <class _R>
732void
733__assoc_state<_R&>::set_value(_R& __arg)
734{
735 unique_lock<mutex> __lk(this->__mut_);
736 if (this->__has_value())
737 throw future_error(make_error_code(future_errc::promise_already_satisfied));
738 __value_ = &__arg;
739 this->__state_ |= base::__constructed | base::ready;
740 __lk.unlock();
741 __cv_.notify_all();
742}
743
744template <class _R>
745void
746__assoc_state<_R&>::set_value_at_thread_exit(_R& __arg)
747{
748 unique_lock<mutex> __lk(this->__mut_);
749 if (this->__has_value())
750 throw future_error(make_error_code(future_errc::promise_already_satisfied));
751 __value_ = &__arg;
752 this->__state_ |= base::__constructed;
753 __thread_local_data->__make_ready_at_thread_exit(this);
754 __lk.unlock();
755}
756
757template <class _R>
758_R&
759__assoc_state<_R&>::copy()
760{
761 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000762 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000763 if (this->__exception_ != nullptr)
764 rethrow_exception(this->__exception_);
765 return *__value_;
766}
767
Howard Hinnant47499b12010-08-27 20:10:19 +0000768template <class _R, class _Alloc>
769class __assoc_state_alloc
770 : public __assoc_state<_R>
771{
772 typedef __assoc_state<_R> base;
773 _Alloc __alloc_;
774
775 virtual void __on_zero_shared();
776public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000778 explicit __assoc_state_alloc(const _Alloc& __a)
779 : __alloc_(__a) {}
780};
781
782template <class _R, class _Alloc>
783void
784__assoc_state_alloc<_R, _Alloc>::__on_zero_shared()
785{
786 if (this->__state_ & base::__constructed)
787 reinterpret_cast<_R*>(&this->__value_)->~_R();
788 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
789 this->~__assoc_state_alloc();
790 __a.deallocate(this, 1);
791}
792
Howard Hinnantf39daa82010-08-28 21:01:06 +0000793template <class _R, class _Alloc>
794class __assoc_state_alloc<_R&, _Alloc>
795 : public __assoc_state<_R&>
796{
797 typedef __assoc_state<_R&> base;
798 _Alloc __alloc_;
799
800 virtual void __on_zero_shared();
801public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000802 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000803 explicit __assoc_state_alloc(const _Alloc& __a)
804 : __alloc_(__a) {}
805};
806
807template <class _R, class _Alloc>
808void
809__assoc_state_alloc<_R&, _Alloc>::__on_zero_shared()
810{
811 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
812 this->~__assoc_state_alloc();
813 __a.deallocate(this, 1);
814}
815
Howard Hinnant47499b12010-08-27 20:10:19 +0000816template <class _Alloc>
817class __assoc_sub_state_alloc
818 : public __assoc_sub_state
819{
820 typedef __assoc_sub_state base;
821 _Alloc __alloc_;
822
823 virtual void __on_zero_shared();
824public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000825 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000826 explicit __assoc_sub_state_alloc(const _Alloc& __a)
827 : __alloc_(__a) {}
828};
829
830template <class _Alloc>
831void
832__assoc_sub_state_alloc<_Alloc>::__on_zero_shared()
833{
834 this->~base();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000835 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000836 this->~__assoc_sub_state_alloc();
837 __a.deallocate(this, 1);
838}
839
Howard Hinnant54da3382010-08-30 18:46:21 +0000840template <class _R, class _F>
841class __deferred_assoc_state
842 : public __assoc_state<_R>
843{
844 typedef __assoc_state<_R> base;
845
846 _F __func_;
847
848public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000849#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000850 explicit __deferred_assoc_state(_F&& __f);
851#endif
852
853 virtual void __execute();
854};
855
Howard Hinnant73d21a42010-09-04 23:28:19 +0000856#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000857
858template <class _R, class _F>
859inline _LIBCPP_INLINE_VISIBILITY
860__deferred_assoc_state<_R, _F>::__deferred_assoc_state(_F&& __f)
861 : __func_(_STD::forward<_F>(__f))
862{
863 this->__set_deferred();
864}
865
Howard Hinnant73d21a42010-09-04 23:28:19 +0000866#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000867
868template <class _R, class _F>
869void
870__deferred_assoc_state<_R, _F>::__execute()
871{
872#ifndef _LIBCPP_NO_EXCEPTIONS
873 try
874 {
875#endif // _LIBCPP_NO_EXCEPTIONS
876 this->set_value(__func_());
877#ifndef _LIBCPP_NO_EXCEPTIONS
878 }
879 catch (...)
880 {
881 this->set_exception(current_exception());
882 }
883#endif // _LIBCPP_NO_EXCEPTIONS
884}
885
886template <class _F>
887class __deferred_assoc_state<void, _F>
888 : public __assoc_sub_state
889{
890 typedef __assoc_sub_state base;
891
892 _F __func_;
893
894public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000895#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000896 explicit __deferred_assoc_state(_F&& __f);
897#endif
898
899 virtual void __execute();
900};
901
Howard Hinnant73d21a42010-09-04 23:28:19 +0000902#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000903
904template <class _F>
905inline _LIBCPP_INLINE_VISIBILITY
906__deferred_assoc_state<void, _F>::__deferred_assoc_state(_F&& __f)
907 : __func_(_STD::forward<_F>(__f))
908{
909 this->__set_deferred();
910}
911
Howard Hinnant73d21a42010-09-04 23:28:19 +0000912#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000913
914template <class _F>
915void
916__deferred_assoc_state<void, _F>::__execute()
917{
918#ifndef _LIBCPP_NO_EXCEPTIONS
919 try
920 {
921#endif // _LIBCPP_NO_EXCEPTIONS
922 __func_();
923 this->set_value();
924#ifndef _LIBCPP_NO_EXCEPTIONS
925 }
926 catch (...)
927 {
928 this->set_exception(current_exception());
929 }
930#endif // _LIBCPP_NO_EXCEPTIONS
931}
932
Howard Hinnant47499b12010-08-27 20:10:19 +0000933template <class> class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +0000934template <class> class shared_future;
935template <class> class atomic_future;
Howard Hinnant47499b12010-08-27 20:10:19 +0000936
937// future
938
Howard Hinnant54da3382010-08-30 18:46:21 +0000939template <class _R> class future;
940
941template <class _R, class _F>
942future<_R>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000943#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000944__make_deferred_assoc_state(_F&& __f);
945#else
946__make_deferred_assoc_state(_F __f);
947#endif
948
Howard Hinnant47499b12010-08-27 20:10:19 +0000949template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000950class _LIBCPP_VISIBLE future
Howard Hinnant47499b12010-08-27 20:10:19 +0000951{
952 __assoc_state<_R>* __state_;
953
954 explicit future(__assoc_state<_R>* __state);
955
956 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +0000957 template <class> friend class shared_future;
958 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000959
960 template <class _R1, class _F>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000961#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000962 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
963#else
964 friend future<_R1> __make_deferred_assoc_state(_F __f);
965#endif
966
Howard Hinnant47499b12010-08-27 20:10:19 +0000967public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000968 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000969 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +0000970#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000971 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000972 future(future&& __rhs)
973 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
974 future(const future&) = delete;
975 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000976 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000977 future& operator=(future&& __rhs)
978 {
979 future(std::move(__rhs)).swap(*this);
980 return *this;
981 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000982#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000983private:
984 future(const future&);
985 future& operator=(const future&);
986public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000987#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000988 ~future();
989
990 // retrieving the value
991 _R get();
992
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000993 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000994 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
995
996 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000997 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000998 bool valid() const {return __state_ != nullptr;}
999
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001000 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001001 void wait() const {__state_->wait();}
1002 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001003 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001004 future_status
1005 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1006 {return __state_->wait_for(__rel_time);}
1007 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001008 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001009 future_status
1010 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1011 {return __state_->wait_until(__abs_time);}
1012};
1013
1014template <class _R>
1015future<_R>::future(__assoc_state<_R>* __state)
1016 : __state_(__state)
1017{
1018 if (__state_->__has_future_attached())
1019 throw future_error(make_error_code(future_errc::future_already_retrieved));
1020 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001021 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001022}
1023
Howard Hinnant54da3382010-08-30 18:46:21 +00001024struct __release_shared_count
1025{
1026 void operator()(__shared_count* p) {p->__release_shared();}
1027};
1028
Howard Hinnant47499b12010-08-27 20:10:19 +00001029template <class _R>
1030future<_R>::~future()
1031{
1032 if (__state_)
1033 __state_->__release_shared();
1034}
1035
1036template <class _R>
1037_R
1038future<_R>::get()
1039{
Howard Hinnant54da3382010-08-30 18:46:21 +00001040 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001041 __assoc_state<_R>* __s = __state_;
1042 __state_ = nullptr;
1043 return __s->move();
1044}
1045
1046template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001047class _LIBCPP_VISIBLE future<_R&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001048{
1049 __assoc_state<_R&>* __state_;
1050
1051 explicit future(__assoc_state<_R&>* __state);
1052
1053 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001054 template <class> friend class shared_future;
1055 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001056
1057 template <class _R1, class _F>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001058#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +00001059 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
1060#else
1061 friend future<_R1> __make_deferred_assoc_state(_F __f);
1062#endif
1063
Howard Hinnant47499b12010-08-27 20:10:19 +00001064public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001066 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001067#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001069 future(future&& __rhs)
1070 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1071 future(const future&) = delete;
1072 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001074 future& operator=(future&& __rhs)
1075 {
1076 future(std::move(__rhs)).swap(*this);
1077 return *this;
1078 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001079#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001080private:
1081 future(const future&);
1082 future& operator=(const future&);
1083public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001084#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001085 ~future();
1086
1087 // retrieving the value
1088 _R& get();
1089
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001090 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001091 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1092
1093 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001094 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001095 bool valid() const {return __state_ != nullptr;}
1096
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001098 void wait() const {__state_->wait();}
1099 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001100 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001101 future_status
1102 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1103 {return __state_->wait_for(__rel_time);}
1104 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001105 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001106 future_status
1107 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1108 {return __state_->wait_until(__abs_time);}
1109};
1110
1111template <class _R>
1112future<_R&>::future(__assoc_state<_R&>* __state)
1113 : __state_(__state)
1114{
1115 if (__state_->__has_future_attached())
1116 throw future_error(make_error_code(future_errc::future_already_retrieved));
1117 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001118 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001119}
1120
1121template <class _R>
1122future<_R&>::~future()
1123{
1124 if (__state_)
1125 __state_->__release_shared();
1126}
1127
1128template <class _R>
1129_R&
1130future<_R&>::get()
1131{
Howard Hinnant54da3382010-08-30 18:46:21 +00001132 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantf39daa82010-08-28 21:01:06 +00001133 __assoc_state<_R&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001134 __state_ = nullptr;
1135 return __s->copy();
1136}
1137
1138template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001139class _LIBCPP_VISIBLE future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001140{
1141 __assoc_sub_state* __state_;
1142
1143 explicit future(__assoc_sub_state* __state);
1144
1145 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001146 template <class> friend class shared_future;
1147 template <class> friend class atomic_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001148
1149 template <class _R1, class _F>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001150#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +00001151 friend future<_R1> __make_deferred_assoc_state(_F&& __f);
1152#else
1153 friend future<_R1> __make_deferred_assoc_state(_F __f);
1154#endif
1155
Howard Hinnant47499b12010-08-27 20:10:19 +00001156public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001157 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001158 future() : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001159#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001160 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001161 future(future&& __rhs)
1162 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1163 future(const future&) = delete;
1164 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001165 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001166 future& operator=(future&& __rhs)
1167 {
1168 future(std::move(__rhs)).swap(*this);
1169 return *this;
1170 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001171#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001172private:
1173 future(const future&);
1174 future& operator=(const future&);
1175public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001176#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001177 ~future();
1178
1179 // retrieving the value
1180 void get();
1181
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001182 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001183 void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1184
1185 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001186 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001187 bool valid() const {return __state_ != nullptr;}
1188
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001190 void wait() const {__state_->wait();}
1191 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001192 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001193 future_status
1194 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1195 {return __state_->wait_for(__rel_time);}
1196 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001198 future_status
1199 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1200 {return __state_->wait_until(__abs_time);}
1201};
1202
Howard Hinnant99be8232010-09-03 18:39:25 +00001203template <class _R>
1204inline _LIBCPP_INLINE_VISIBILITY
1205void
1206swap(future<_R>& __x, future<_R>& __y)
1207{
1208 __x.swap(__y);
1209}
1210
Howard Hinnant47499b12010-08-27 20:10:19 +00001211// promise<R>
1212
Howard Hinnant54da3382010-08-30 18:46:21 +00001213template <class> class packaged_task;
1214
Howard Hinnant47499b12010-08-27 20:10:19 +00001215template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001216class _LIBCPP_VISIBLE promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001217{
1218 __assoc_state<_R>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001219
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001220 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001221 explicit promise(nullptr_t) : __state_(nullptr) {}
1222
1223 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001224public:
1225 promise();
1226 template <class _Alloc>
1227 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001228#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001229 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001230 promise(promise&& __rhs)
1231 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1232 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001233#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001234private:
1235 promise(const promise& __rhs);
1236public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001237#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001238 ~promise();
1239
1240 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001241#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001243 promise& operator=(promise&& __rhs)
1244 {
1245 promise(std::move(__rhs)).swap(*this);
1246 return *this;
1247 }
1248 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001249#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001250private:
1251 promise& operator=(const promise& __rhs);
1252public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001253#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001255 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1256
1257 // retrieving the result
1258 future<_R> get_future();
1259
1260 // setting the result
1261 void set_value(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001262#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001263 void set_value(_R&& __r);
1264#endif
1265 void set_exception(exception_ptr __p);
1266
1267 // setting the result with deferred notification
1268 void set_value_at_thread_exit(const _R& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001269#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001270 void set_value_at_thread_exit(_R&& __r);
1271#endif
1272 void set_exception_at_thread_exit(exception_ptr __p);
1273};
1274
1275template <class _R>
1276promise<_R>::promise()
1277 : __state_(new __assoc_state<_R>)
1278{
1279}
1280
1281template <class _R>
1282template <class _Alloc>
1283promise<_R>::promise(allocator_arg_t, const _Alloc& __a0)
1284{
1285 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R, _Alloc> >::other _A2;
1286 typedef __allocator_destructor<_A2> _D2;
1287 _A2 __a(__a0);
1288 unique_ptr<__assoc_state_alloc<_R, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1289 ::new(__hold.get()) __assoc_state_alloc<_R, _Alloc>(__a0);
1290 __state_ = __hold.release();
1291}
1292
1293template <class _R>
1294promise<_R>::~promise()
1295{
1296 if (__state_)
1297 {
1298 if (!__state_->__has_value() && __state_->use_count() > 1)
1299 __state_->set_exception(make_exception_ptr(
1300 future_error(make_error_code(future_errc::broken_promise))
1301 ));
1302 __state_->__release_shared();
1303 }
1304}
1305
1306template <class _R>
1307future<_R>
1308promise<_R>::get_future()
1309{
1310 if (__state_ == nullptr)
1311 throw future_error(make_error_code(future_errc::no_state));
1312 return future<_R>(__state_);
1313}
1314
1315template <class _R>
1316void
1317promise<_R>::set_value(const _R& __r)
1318{
1319 if (__state_ == nullptr)
1320 throw future_error(make_error_code(future_errc::no_state));
1321 __state_->set_value(__r);
1322}
1323
Howard Hinnant73d21a42010-09-04 23:28:19 +00001324#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001325
1326template <class _R>
1327void
1328promise<_R>::set_value(_R&& __r)
1329{
1330 if (__state_ == nullptr)
1331 throw future_error(make_error_code(future_errc::no_state));
1332 __state_->set_value(_STD::move(__r));
1333}
1334
Howard Hinnant73d21a42010-09-04 23:28:19 +00001335#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001336
1337template <class _R>
1338void
1339promise<_R>::set_exception(exception_ptr __p)
1340{
1341 if (__state_ == nullptr)
1342 throw future_error(make_error_code(future_errc::no_state));
1343 __state_->set_exception(__p);
1344}
1345
1346template <class _R>
1347void
1348promise<_R>::set_value_at_thread_exit(const _R& __r)
1349{
1350 if (__state_ == nullptr)
1351 throw future_error(make_error_code(future_errc::no_state));
1352 __state_->set_value_at_thread_exit(__r);
1353}
1354
Howard Hinnant73d21a42010-09-04 23:28:19 +00001355#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001356
1357template <class _R>
1358void
1359promise<_R>::set_value_at_thread_exit(_R&& __r)
1360{
1361 if (__state_ == nullptr)
1362 throw future_error(make_error_code(future_errc::no_state));
1363 __state_->set_value_at_thread_exit(_STD::move(__r));
1364}
1365
Howard Hinnant73d21a42010-09-04 23:28:19 +00001366#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001367
1368template <class _R>
1369void
1370promise<_R>::set_exception_at_thread_exit(exception_ptr __p)
1371{
1372 if (__state_ == nullptr)
1373 throw future_error(make_error_code(future_errc::no_state));
1374 __state_->set_exception_at_thread_exit(__p);
1375}
1376
1377// promise<R&>
1378
1379template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001380class _LIBCPP_VISIBLE promise<_R&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001381{
1382 __assoc_state<_R&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001383
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001385 explicit promise(nullptr_t) : __state_(nullptr) {}
1386
1387 template <class> friend class packaged_task;
1388
Howard Hinnant47499b12010-08-27 20:10:19 +00001389public:
1390 promise();
1391 template <class _Allocator>
1392 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001393#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001395 promise(promise&& __rhs)
1396 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1397 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001398#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001399private:
1400 promise(const promise& __rhs);
1401public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001402#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001403 ~promise();
1404
1405 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001406#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001408 promise& operator=(promise&& __rhs)
1409 {
1410 promise(std::move(__rhs)).swap(*this);
1411 return *this;
1412 }
1413 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001414#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001415private:
1416 promise& operator=(const promise& __rhs);
1417public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001418#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001419 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001420 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1421
1422 // retrieving the result
1423 future<_R&> get_future();
1424
1425 // setting the result
1426 void set_value(_R& __r);
1427 void set_exception(exception_ptr __p);
1428
1429 // setting the result with deferred notification
1430 void set_value_at_thread_exit(_R&);
1431 void set_exception_at_thread_exit(exception_ptr __p);
1432};
1433
1434template <class _R>
1435promise<_R&>::promise()
1436 : __state_(new __assoc_state<_R&>)
1437{
1438}
1439
1440template <class _R>
1441template <class _Alloc>
1442promise<_R&>::promise(allocator_arg_t, const _Alloc& __a0)
1443{
1444 typedef typename _Alloc::template rebind<__assoc_state_alloc<_R&, _Alloc> >::other _A2;
1445 typedef __allocator_destructor<_A2> _D2;
1446 _A2 __a(__a0);
1447 unique_ptr<__assoc_state_alloc<_R&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1448 ::new(__hold.get()) __assoc_state_alloc<_R&, _Alloc>(__a0);
1449 __state_ = __hold.release();
1450}
1451
1452template <class _R>
1453promise<_R&>::~promise()
1454{
1455 if (__state_)
1456 {
1457 if (!__state_->__has_value() && __state_->use_count() > 1)
1458 __state_->set_exception(make_exception_ptr(
1459 future_error(make_error_code(future_errc::broken_promise))
1460 ));
1461 __state_->__release_shared();
1462 }
1463}
1464
1465template <class _R>
1466future<_R&>
1467promise<_R&>::get_future()
1468{
1469 if (__state_ == nullptr)
1470 throw future_error(make_error_code(future_errc::no_state));
1471 return future<_R&>(__state_);
1472}
1473
1474template <class _R>
1475void
1476promise<_R&>::set_value(_R& __r)
1477{
1478 if (__state_ == nullptr)
1479 throw future_error(make_error_code(future_errc::no_state));
1480 __state_->set_value(__r);
1481}
1482
1483template <class _R>
1484void
1485promise<_R&>::set_exception(exception_ptr __p)
1486{
1487 if (__state_ == nullptr)
1488 throw future_error(make_error_code(future_errc::no_state));
1489 __state_->set_exception(__p);
1490}
1491
1492template <class _R>
1493void
1494promise<_R&>::set_value_at_thread_exit(_R& __r)
1495{
1496 if (__state_ == nullptr)
1497 throw future_error(make_error_code(future_errc::no_state));
1498 __state_->set_value_at_thread_exit(__r);
1499}
1500
1501template <class _R>
1502void
1503promise<_R&>::set_exception_at_thread_exit(exception_ptr __p)
1504{
1505 if (__state_ == nullptr)
1506 throw future_error(make_error_code(future_errc::no_state));
1507 __state_->set_exception_at_thread_exit(__p);
1508}
1509
1510// promise<void>
1511
1512template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001513class _LIBCPP_VISIBLE promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001514{
1515 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001516
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001517 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001518 explicit promise(nullptr_t) : __state_(nullptr) {}
1519
1520 template <class> friend class packaged_task;
1521
Howard Hinnant47499b12010-08-27 20:10:19 +00001522public:
1523 promise();
1524 template <class _Allocator>
1525 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001526#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001527 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001528 promise(promise&& __rhs)
1529 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1530 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001531#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001532private:
1533 promise(const promise& __rhs);
1534public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001535#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001536 ~promise();
1537
1538 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001539#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001541 promise& operator=(promise&& __rhs)
1542 {
1543 promise(std::move(__rhs)).swap(*this);
1544 return *this;
1545 }
1546 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001547#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001548private:
1549 promise& operator=(const promise& __rhs);
1550public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001551#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001553 void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
1554
1555 // retrieving the result
1556 future<void> get_future();
1557
1558 // setting the result
1559 void set_value();
1560 void set_exception(exception_ptr __p);
1561
1562 // setting the result with deferred notification
1563 void set_value_at_thread_exit();
1564 void set_exception_at_thread_exit(exception_ptr __p);
1565};
1566
1567template <class _Alloc>
1568promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1569{
1570 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1571 typedef __allocator_destructor<_A2> _D2;
1572 _A2 __a(__a0);
1573 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1574 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1575 __state_ = __hold.release();
1576}
1577
1578template <class _R>
1579inline _LIBCPP_INLINE_VISIBILITY
1580void
1581swap(promise<_R>& __x, promise<_R>& __y)
1582{
1583 __x.swap(__y);
1584}
1585
1586template <class _R, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001587 struct _LIBCPP_VISIBLE uses_allocator<promise<_R>, _Alloc>
1588 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001589
Howard Hinnant54da3382010-08-30 18:46:21 +00001590#ifndef _LIBCPP_HAS_NO_VARIADICS
1591
1592// packaged_task
1593
1594template<class _Fp> class __packaged_task_base;
1595
1596template<class _R, class ..._ArgTypes>
1597class __packaged_task_base<_R(_ArgTypes...)>
1598{
1599 __packaged_task_base(const __packaged_task_base&);
1600 __packaged_task_base& operator=(const __packaged_task_base&);
1601public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001602 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001603 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001604 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001605 virtual ~__packaged_task_base() {}
1606 virtual void __move_to(__packaged_task_base*) = 0;
1607 virtual void destroy() = 0;
1608 virtual void destroy_deallocate() = 0;
1609 virtual _R operator()(_ArgTypes&& ...) = 0;
1610};
1611
1612template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1613
1614template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1615class __packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>
1616 : public __packaged_task_base<_R(_ArgTypes...)>
1617{
1618 __compressed_pair<_F, _Alloc> __f_;
1619public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001620 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001621 explicit __packaged_task_func(const _F& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001623 explicit __packaged_task_func(_F&& __f) : __f_(_STD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001624 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001625 __packaged_task_func(const _F& __f, const _Alloc& __a)
1626 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001627 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001628 __packaged_task_func(_F&& __f, const _Alloc& __a)
1629 : __f_(_STD::move(__f), __a) {}
1630 virtual void __move_to(__packaged_task_base<_R(_ArgTypes...)>*);
1631 virtual void destroy();
1632 virtual void destroy_deallocate();
1633 virtual _R operator()(_ArgTypes&& ... __args);
1634};
1635
1636template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1637void
1638__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::__move_to(
1639 __packaged_task_base<_R(_ArgTypes...)>* __p)
1640{
1641 ::new (__p) __packaged_task_func(_STD::move(__f_.first()), _STD::move(__f_.second()));
1642}
1643
1644template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1645void
1646__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy()
1647{
1648 __f_.~__compressed_pair<_F, _Alloc>();
1649}
1650
1651template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1652void
1653__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::destroy_deallocate()
1654{
1655 typedef typename _Alloc::template rebind<__packaged_task_func>::other _A;
1656 _A __a(__f_.second());
1657 __f_.~__compressed_pair<_F, _Alloc>();
1658 __a.deallocate(this, 1);
1659}
1660
1661template<class _F, class _Alloc, class _R, class ..._ArgTypes>
1662_R
1663__packaged_task_func<_F, _Alloc, _R(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1664{
1665 return __invoke(__f_.first(), _STD::forward<_ArgTypes>(__arg)...);
1666}
1667
1668template <class> class __packaged_task_function;
1669
1670template<class _R, class ..._ArgTypes>
1671class __packaged_task_function<_R(_ArgTypes...)>
1672{
1673 typedef __packaged_task_base<_R(_ArgTypes...)> __base;
1674 aligned_storage<3*sizeof(void*)>::type __buf_;
1675 __base* __f_;
1676
1677public:
1678 typedef _R result_type;
1679
1680 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001681 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001682 __packaged_task_function() : __f_(nullptr) {}
1683 template<class _F>
1684 __packaged_task_function(_F&& __f);
1685 template<class _F, class _Alloc>
1686 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _F&& __f);
1687
1688 __packaged_task_function(__packaged_task_function&&);
1689 __packaged_task_function& operator=(__packaged_task_function&&);
1690
1691 __packaged_task_function(const __packaged_task_function&) = delete;
1692 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1693
1694 ~__packaged_task_function();
1695
1696 void swap(__packaged_task_function&);
1697
1698 _R operator()(_ArgTypes...) const;
1699};
1700
1701template<class _R, class ..._ArgTypes>
1702__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f)
1703{
1704 if (__f.__f_ == nullptr)
1705 __f_ = nullptr;
1706 else if (__f.__f_ == (__base*)&__f.__buf_)
1707 {
1708 __f_ = (__base*)&__buf_;
1709 __f.__f_->__move_to(__f_);
1710 }
1711 else
1712 {
1713 __f_ = __f.__f_;
1714 __f.__f_ = nullptr;
1715 }
1716}
1717
1718template<class _R, class ..._ArgTypes>
1719template <class _F>
1720__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(_F&& __f)
1721 : __f_(nullptr)
1722{
1723 typedef typename remove_reference<_F>::type _FR;
1724 typedef __packaged_task_func<_FR, allocator<_FR>, _R(_ArgTypes...)> _FF;
1725 if (sizeof(_FF) <= sizeof(__buf_))
1726 {
1727 __f_ = (__base*)&__buf_;
1728 ::new (__f_) _FF(_STD::forward<_F>(__f));
1729 }
1730 else
1731 {
1732 typedef allocator<_FF> _A;
1733 _A __a;
1734 typedef __allocator_destructor<_A> _D;
1735 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1736 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), allocator<_FR>(__a));
1737 __f_ = __hold.release();
1738 }
1739}
1740
1741template<class _R, class ..._ArgTypes>
1742template <class _F, class _Alloc>
1743__packaged_task_function<_R(_ArgTypes...)>::__packaged_task_function(
1744 allocator_arg_t, const _Alloc& __a0, _F&& __f)
1745 : __f_(nullptr)
1746{
1747 typedef allocator_traits<_Alloc> __alloc_traits;
1748 typedef typename remove_reference<_F>::type _FR;
1749 typedef __packaged_task_func<_FR, _Alloc, _R(_ArgTypes...)> _FF;
1750 if (sizeof(_FF) <= sizeof(__buf_))
1751 {
1752 __f_ = (__base*)&__buf_;
1753 ::new (__f_) _FF(_STD::forward<_F>(__f));
1754 }
1755 else
1756 {
1757 typedef typename __alloc_traits::template
1758#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1759 rebind_alloc<_FF>
1760#else
1761 rebind_alloc<_FF>::other
1762#endif
1763 _A;
1764 _A __a(__a0);
1765 typedef __allocator_destructor<_A> _D;
1766 unique_ptr<__base, _D> __hold(__a.allocate(1), _D(__a, 1));
1767 ::new (__hold.get()) _FF(_STD::forward<_F>(__f), _Alloc(__a));
1768 __f_ = __hold.release();
1769 }
1770}
1771
1772template<class _R, class ..._ArgTypes>
1773__packaged_task_function<_R(_ArgTypes...)>&
1774__packaged_task_function<_R(_ArgTypes...)>::operator=(__packaged_task_function&& __f)
1775{
1776 if (__f_ == (__base*)&__buf_)
1777 __f_->destroy();
1778 else if (__f_)
1779 __f_->destroy_deallocate();
1780 __f_ = nullptr;
1781 if (__f.__f_ == nullptr)
1782 __f_ = nullptr;
1783 else if (__f.__f_ == (__base*)&__f.__buf_)
1784 {
1785 __f_ = (__base*)&__buf_;
1786 __f.__f_->__move_to(__f_);
1787 }
1788 else
1789 {
1790 __f_ = __f.__f_;
1791 __f.__f_ = nullptr;
1792 }
1793}
1794
1795template<class _R, class ..._ArgTypes>
1796__packaged_task_function<_R(_ArgTypes...)>::~__packaged_task_function()
1797{
1798 if (__f_ == (__base*)&__buf_)
1799 __f_->destroy();
1800 else if (__f_)
1801 __f_->destroy_deallocate();
1802}
1803
1804template<class _R, class ..._ArgTypes>
1805void
1806__packaged_task_function<_R(_ArgTypes...)>::swap(__packaged_task_function& __f)
1807{
1808 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1809 {
1810 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1811 __base* __t = (__base*)&__tempbuf;
1812 __f_->__move_to(__t);
1813 __f_->destroy();
1814 __f_ = nullptr;
1815 __f.__f_->__move_to((__base*)&__buf_);
1816 __f.__f_->destroy();
1817 __f.__f_ = nullptr;
1818 __f_ = (__base*)&__buf_;
1819 __t->__move_to((__base*)&__f.__buf_);
1820 __t->destroy();
1821 __f.__f_ = (__base*)&__f.__buf_;
1822 }
1823 else if (__f_ == (__base*)&__buf_)
1824 {
1825 __f_->__move_to((__base*)&__f.__buf_);
1826 __f_->destroy();
1827 __f_ = __f.__f_;
1828 __f.__f_ = (__base*)&__f.__buf_;
1829 }
1830 else if (__f.__f_ == (__base*)&__f.__buf_)
1831 {
1832 __f.__f_->__move_to((__base*)&__buf_);
1833 __f.__f_->destroy();
1834 __f.__f_ = __f_;
1835 __f_ = (__base*)&__buf_;
1836 }
1837 else
1838 _STD::swap(__f_, __f.__f_);
1839}
1840
1841template<class _R, class ..._ArgTypes>
1842inline _LIBCPP_INLINE_VISIBILITY
1843_R
1844__packaged_task_function<_R(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1845{
1846 return (*__f_)(_STD::forward<_ArgTypes>(__arg)...);
1847}
1848
1849template<class _R, class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001850class _LIBCPP_VISIBLE packaged_task<_R(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001851{
1852public:
1853 typedef _R result_type;
1854
1855private:
1856 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1857 promise<result_type> __p_;
1858
1859public:
1860 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001861 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001862 packaged_task() : __p_(nullptr) {}
1863 template <class _F>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001864 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001865 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
1866 template <class _F, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001867 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001868 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
1869 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
1870 __p_(allocator_arg, __a) {}
1871 // ~packaged_task() = default;
1872
1873 // no copy
1874 packaged_task(packaged_task&) = delete;
1875 packaged_task& operator=(packaged_task&) = delete;
1876
1877 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001878 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001879 packaged_task(packaged_task&& __other)
1880 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001881 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001882 packaged_task& operator=(packaged_task&& __other)
1883 {
1884 __f_ = _STD::move(__other.__f_);
1885 __p_ = _STD::move(__other.__p_);
1886 return *this;
1887 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001888 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001889 void swap(packaged_task& __other)
1890 {
1891 __f_.swap(__other.__f_);
1892 __p_.swap(__other.__p_);
1893 }
1894
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001895 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001896 //explicit
1897 operator bool() const {return __p_.__state_ != nullptr;}
1898
1899 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001900 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001901 future<result_type> get_future() {return __p_.get_future();}
1902
1903 // execution
1904 void operator()(_ArgTypes... __args);
1905 void make_ready_at_thread_exit(_ArgTypes... __args);
1906
1907 void reset();
1908};
1909
1910template<class _R, class ..._ArgTypes>
1911void
1912packaged_task<_R(_ArgTypes...)>::operator()(_ArgTypes... __args)
1913{
1914#ifndef _LIBCPP_NO_EXCEPTIONS
1915 if (__p_.__state_ == nullptr)
1916 throw future_error(make_error_code(future_errc::no_state));
1917 if (__p_.__state_->__has_value())
1918 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1919 try
1920 {
1921#endif // _LIBCPP_NO_EXCEPTIONS
1922 __p_.set_value(__f_(_STD::forward<_ArgTypes>(__args)...));
1923#ifndef _LIBCPP_NO_EXCEPTIONS
1924 }
1925 catch (...)
1926 {
1927 __p_.set_exception(current_exception());
1928 }
1929#endif // _LIBCPP_NO_EXCEPTIONS
1930}
1931
1932template<class _R, class ..._ArgTypes>
1933void
1934packaged_task<_R(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
1935{
1936#ifndef _LIBCPP_NO_EXCEPTIONS
1937 if (__p_.__state_ == nullptr)
1938 throw future_error(make_error_code(future_errc::no_state));
1939 if (__p_.__state_->__has_value())
1940 throw future_error(make_error_code(future_errc::promise_already_satisfied));
1941 try
1942 {
1943#endif // _LIBCPP_NO_EXCEPTIONS
1944 __p_.set_value_at_thread_exit(__f_(_STD::forward<_ArgTypes>(__args)...));
1945#ifndef _LIBCPP_NO_EXCEPTIONS
1946 }
1947 catch (...)
1948 {
1949 __p_.set_exception_at_thread_exit(current_exception());
1950 }
1951#endif // _LIBCPP_NO_EXCEPTIONS
1952}
1953
1954template<class _R, class ..._ArgTypes>
1955void
1956packaged_task<_R(_ArgTypes...)>::reset()
1957{
1958#ifndef _LIBCPP_NO_EXCEPTIONS
1959 if (!(*this))
1960 throw future_error(make_error_code(future_errc::no_state));
1961#endif // _LIBCPP_NO_EXCEPTIONS
1962 __p_ = promise<result_type>();
1963}
1964
1965template<class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001966class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001967{
1968public:
1969 typedef void result_type;
1970
1971private:
1972 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1973 promise<result_type> __p_;
1974
1975public:
1976 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001978 packaged_task() : __p_(nullptr) {}
1979 template <class _F>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001980 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001981 explicit packaged_task(_F&& __f) : __f_(_STD::forward<_F>(__f)) {}
1982 template <class _F, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001983 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001984 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _F&& __f)
1985 : __f_(allocator_arg, __a, _STD::forward<_F>(__f)),
1986 __p_(allocator_arg, __a) {}
1987 // ~packaged_task() = default;
1988
1989 // no copy
1990 packaged_task(packaged_task&) = delete;
1991 packaged_task& operator=(packaged_task&) = delete;
1992
1993 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001994 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001995 packaged_task(packaged_task&& __other)
1996 : __f_(_STD::move(__other.__f_)), __p_(_STD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001997 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001998 packaged_task& operator=(packaged_task&& __other)
1999 {
2000 __f_ = _STD::move(__other.__f_);
2001 __p_ = _STD::move(__other.__p_);
2002 return *this;
2003 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002004 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002005 void swap(packaged_task& __other)
2006 {
2007 __f_.swap(__other.__f_);
2008 __p_.swap(__other.__p_);
2009 }
2010
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002012 //explicit
2013 operator bool() const {return __p_.__state_ != nullptr;}
2014
2015 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002016 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002017 future<result_type> get_future() {return __p_.get_future();}
2018
2019 // execution
2020 void operator()(_ArgTypes... __args);
2021 void make_ready_at_thread_exit(_ArgTypes... __args);
2022
2023 void reset();
2024};
2025
2026template<class ..._ArgTypes>
2027void
2028packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2029{
2030#ifndef _LIBCPP_NO_EXCEPTIONS
2031 if (__p_.__state_ == nullptr)
2032 throw future_error(make_error_code(future_errc::no_state));
2033 if (__p_.__state_->__has_value())
2034 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2035 try
2036 {
2037#endif // _LIBCPP_NO_EXCEPTIONS
2038 __f_(_STD::forward<_ArgTypes>(__args)...);
2039 __p_.set_value();
2040#ifndef _LIBCPP_NO_EXCEPTIONS
2041 }
2042 catch (...)
2043 {
2044 __p_.set_exception(current_exception());
2045 }
2046#endif // _LIBCPP_NO_EXCEPTIONS
2047}
2048
2049template<class ..._ArgTypes>
2050void
2051packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2052{
2053#ifndef _LIBCPP_NO_EXCEPTIONS
2054 if (__p_.__state_ == nullptr)
2055 throw future_error(make_error_code(future_errc::no_state));
2056 if (__p_.__state_->__has_value())
2057 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2058 try
2059 {
2060#endif // _LIBCPP_NO_EXCEPTIONS
2061 __f_(_STD::forward<_ArgTypes>(__args)...);
2062 __p_.set_value_at_thread_exit();
2063#ifndef _LIBCPP_NO_EXCEPTIONS
2064 }
2065 catch (...)
2066 {
2067 __p_.set_exception_at_thread_exit(current_exception());
2068 }
2069#endif // _LIBCPP_NO_EXCEPTIONS
2070}
2071
2072template<class ..._ArgTypes>
2073void
2074packaged_task<void(_ArgTypes...)>::reset()
2075{
2076#ifndef _LIBCPP_NO_EXCEPTIONS
2077 if (!(*this))
2078 throw future_error(make_error_code(future_errc::no_state));
2079#endif // _LIBCPP_NO_EXCEPTIONS
2080 __p_ = promise<result_type>();
2081}
2082
2083template <class _Callable>
2084inline _LIBCPP_INLINE_VISIBILITY
2085void
2086swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y)
2087{
2088 __x.swap(__y);
2089}
2090
2091template <class _Callable, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002092struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2093 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002094
2095template <class _R, class _F>
2096future<_R>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002097#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +00002098__make_deferred_assoc_state(_F&& __f)
2099#else
2100__make_deferred_assoc_state(_F __f)
2101#endif
2102{
2103 unique_ptr<__deferred_assoc_state<_R, _F>, __release_shared_count>
2104 __h(new __deferred_assoc_state<_R, _F>(_STD::forward<_F>(__f)));
2105 return future<_R>(__h.get());
2106}
2107
2108template <class _F, class... _Args>
2109future<typename result_of<_F(_Args...)>::type>
2110async(launch __policy, _F&& __f, _Args&&... __args)
2111{
2112 typedef typename result_of<_F(_Args...)>::type _R;
2113 future<_R> __r;
2114 if (__policy == launch::sync)
2115 __r = _STD::__make_deferred_assoc_state<_R>(bind(_STD::forward<_F>(__f),
2116 _STD::forward<_Args>(__args)...));
2117 else
2118 {
2119 packaged_task<_R()> __pk(bind(_STD::forward<_F>(__f),
2120 _STD::forward<_Args>(__args)...));
2121 __r = __pk.get_future();
2122 thread(_STD::move(__pk)).detach();
2123 }
2124 return __r;
2125}
2126
2127template <class _F, class... _Args>
2128inline _LIBCPP_INLINE_VISIBILITY
2129typename enable_if
2130<
2131 !is_same<typename decay<_F>::type, launch>::value,
2132 future<typename result_of<_F(_Args...)>::type>
2133>::type
2134async(_F&& __f, _Args&&... __args)
2135{
2136 return async(launch::any, _STD::forward<_F>(__f),
2137 _STD::forward<_Args>(__args)...);
2138}
2139
2140#endif // _LIBCPP_HAS_NO_VARIADICS
2141
Howard Hinnante6e4d012010-09-03 21:46:37 +00002142// shared_future
2143
Howard Hinnant99be8232010-09-03 18:39:25 +00002144template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002145class _LIBCPP_VISIBLE shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002146{
2147 __assoc_state<_R>* __state_;
2148
2149public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002150 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002151 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002152 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002153 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2154 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002155#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002156 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002157 shared_future(future<_R>&& __f) : __state_(__f.__state_)
2158 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002159 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002160 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2161 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002162#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002163 ~shared_future();
2164 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002165#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002166 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002167 shared_future& operator=(shared_future&& __rhs)
2168 {
2169 shared_future(std::move(__rhs)).swap(*this);
2170 return *this;
2171 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002172#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002173
2174 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002176 const _R& get() const {return __state_->copy();}
2177
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002178 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002179 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2180
2181 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002182 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002183 bool valid() const {return __state_ != nullptr;}
2184
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002185 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002186 void wait() const {__state_->wait();}
2187 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002188 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002189 future_status
2190 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2191 {return __state_->wait_for(__rel_time);}
2192 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002193 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002194 future_status
2195 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2196 {return __state_->wait_until(__abs_time);}
2197};
2198
2199template <class _R>
2200shared_future<_R>::~shared_future()
2201{
2202 if (__state_)
2203 __state_->__release_shared();
2204}
2205
2206template <class _R>
2207shared_future<_R>&
2208shared_future<_R>::operator=(const shared_future& __rhs)
2209{
2210 if (__rhs.__state_)
2211 __rhs.__state_->__add_shared();
2212 if (__state_)
2213 __state_->__release_shared();
2214 __state_ = __rhs.__state_;
2215 return *this;
2216}
2217
2218template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002219class _LIBCPP_VISIBLE shared_future<_R&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002220{
2221 __assoc_state<_R&>* __state_;
2222
2223public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002224 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002225 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002226 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002227 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2228 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002229#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002230 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002231 shared_future(future<_R&>&& __f) : __state_(__f.__state_)
2232 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002234 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2235 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002236#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002237 ~shared_future();
2238 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002239#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002241 shared_future& operator=(shared_future&& __rhs)
2242 {
2243 shared_future(std::move(__rhs)).swap(*this);
2244 return *this;
2245 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002246#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002247
2248 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002250 _R& get() const {return __state_->copy();}
2251
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002252 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002253 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2254
2255 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002257 bool valid() const {return __state_ != nullptr;}
2258
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002259 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002260 void wait() const {__state_->wait();}
2261 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002262 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002263 future_status
2264 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2265 {return __state_->wait_for(__rel_time);}
2266 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002268 future_status
2269 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2270 {return __state_->wait_until(__abs_time);}
2271};
2272
2273template <class _R>
2274shared_future<_R&>::~shared_future()
2275{
2276 if (__state_)
2277 __state_->__release_shared();
2278}
2279
2280template <class _R>
2281shared_future<_R&>&
2282shared_future<_R&>::operator=(const shared_future& __rhs)
2283{
2284 if (__rhs.__state_)
2285 __rhs.__state_->__add_shared();
2286 if (__state_)
2287 __state_->__release_shared();
2288 __state_ = __rhs.__state_;
2289 return *this;
2290}
2291
2292template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002293class _LIBCPP_VISIBLE shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002294{
2295 __assoc_sub_state* __state_;
2296
2297public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002298 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002299 shared_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002301 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2302 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002303#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002305 shared_future(future<void>&& __f) : __state_(__f.__state_)
2306 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002308 shared_future(shared_future&& __rhs) : __state_(__rhs.__state_)
2309 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002310#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002311 ~shared_future();
2312 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002313#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002315 shared_future& operator=(shared_future&& __rhs)
2316 {
2317 shared_future(std::move(__rhs)).swap(*this);
2318 return *this;
2319 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002320#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002321
2322 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002324 void get() const {__state_->copy();}
2325
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002327 void swap(shared_future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
2328
2329 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002331 bool valid() const {return __state_ != nullptr;}
2332
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002334 void wait() const {__state_->wait();}
2335 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002336 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002337 future_status
2338 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2339 {return __state_->wait_for(__rel_time);}
2340 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002341 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002342 future_status
2343 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2344 {return __state_->wait_until(__abs_time);}
2345};
2346
2347template <class _R>
2348inline _LIBCPP_INLINE_VISIBILITY
2349void
2350swap(shared_future<_R>& __x, shared_future<_R>& __y)
2351{
2352 __x.swap(__y);
2353}
2354
Howard Hinnante6e4d012010-09-03 21:46:37 +00002355// atomic_future
2356
2357template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002358class _LIBCPP_VISIBLE atomic_future
Howard Hinnante6e4d012010-09-03 21:46:37 +00002359{
2360 __assoc_state<_R>* __state_;
2361 mutable mutex __mut_;
2362
2363public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002364 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002365 atomic_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002367 atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_)
2368 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002369#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002371 atomic_future(future<_R>&& __f) : __state_(__f.__state_)
2372 {__f.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002373#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002374 ~atomic_future();
2375 atomic_future& operator=(const atomic_future& __rhs);
2376
2377 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002378 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002379 const _R& get() const {return __state_->copy();}
2380
2381 void swap(atomic_future& __rhs);
2382
2383 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002385 bool valid() const {return __state_ != nullptr;}
2386
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002388 void wait() const {__state_->wait();}
2389 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002391 future_status
2392 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2393 {return __state_->wait_for(__rel_time);}
2394 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002396 future_status
2397 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2398 {return __state_->wait_until(__abs_time);}
2399};
2400
2401template <class _R>
2402atomic_future<_R>::~atomic_future()
2403{
2404 if (__state_)
2405 __state_->__release_shared();
2406}
2407
2408template <class _R>
2409atomic_future<_R>&
2410atomic_future<_R>::operator=(const atomic_future& __rhs)
2411{
2412 if (this != &__rhs)
2413 {
2414 unique_lock<mutex> __this(__mut_, defer_lock);
2415 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2416 _STD::lock(__this, __that);
2417 if (__rhs.__state_)
2418 __rhs.__state_->__add_shared();
2419 if (__state_)
2420 __state_->__release_shared();
2421 __state_ = __rhs.__state_;
2422 }
2423 return *this;
2424}
2425
2426template <class _R>
2427void
2428atomic_future<_R>::swap(atomic_future& __rhs)
2429{
2430 if (this != &__rhs)
2431 {
2432 unique_lock<mutex> __this(__mut_, defer_lock);
2433 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2434 _STD::lock(__this, __that);
2435 _STD::swap(__state_, __rhs.__state_);
2436 }
2437}
2438
2439template <class _R>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002440class _LIBCPP_VISIBLE atomic_future<_R&>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002441{
2442 __assoc_state<_R&>* __state_;
2443 mutable mutex __mut_;
2444
2445public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002447 atomic_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002449 atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_)
2450 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002451#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002453 atomic_future(future<_R&>&& __f) : __state_(__f.__state_)
2454 {__f.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002455#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002456 ~atomic_future();
2457 atomic_future& operator=(const atomic_future& __rhs);
2458
2459 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002460 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002461 _R& get() const {return __state_->copy();}
2462
2463 void swap(atomic_future& __rhs);
2464
2465 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002467 bool valid() const {return __state_ != nullptr;}
2468
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002469 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002470 void wait() const {__state_->wait();}
2471 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002473 future_status
2474 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2475 {return __state_->wait_for(__rel_time);}
2476 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002478 future_status
2479 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2480 {return __state_->wait_until(__abs_time);}
2481};
2482
2483template <class _R>
2484atomic_future<_R&>::~atomic_future()
2485{
2486 if (__state_)
2487 __state_->__release_shared();
2488}
2489
2490template <class _R>
2491atomic_future<_R&>&
2492atomic_future<_R&>::operator=(const atomic_future& __rhs)
2493{
2494 if (this != &__rhs)
2495 {
2496 unique_lock<mutex> __this(__mut_, defer_lock);
2497 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2498 _STD::lock(__this, __that);
2499 if (__rhs.__state_)
2500 __rhs.__state_->__add_shared();
2501 if (__state_)
2502 __state_->__release_shared();
2503 __state_ = __rhs.__state_;
2504 }
2505 return *this;
2506}
2507
2508template <class _R>
2509void
2510atomic_future<_R&>::swap(atomic_future& __rhs)
2511{
2512 if (this != &__rhs)
2513 {
2514 unique_lock<mutex> __this(__mut_, defer_lock);
2515 unique_lock<mutex> __that(__rhs.__mut_, defer_lock);
2516 _STD::lock(__this, __that);
2517 _STD::swap(__state_, __rhs.__state_);
2518 }
2519}
2520
2521template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002522class _LIBCPP_VISIBLE atomic_future<void>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002523{
2524 __assoc_sub_state* __state_;
2525 mutable mutex __mut_;
2526
2527public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002529 atomic_future() : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002531 atomic_future(const atomic_future& __rhs) : __state_(__rhs.__state_)
2532 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002533#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002535 atomic_future(future<void>&& __f) : __state_(__f.__state_)
2536 {__f.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002537#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante6e4d012010-09-03 21:46:37 +00002538 ~atomic_future();
2539 atomic_future& operator=(const atomic_future& __rhs);
2540
2541 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002543 void get() const {__state_->copy();}
2544
2545 void swap(atomic_future& __rhs);
2546
2547 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002549 bool valid() const {return __state_ != nullptr;}
2550
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002552 void wait() const {__state_->wait();}
2553 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002555 future_status
2556 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2557 {return __state_->wait_for(__rel_time);}
2558 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002559 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante6e4d012010-09-03 21:46:37 +00002560 future_status
2561 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2562 {return __state_->wait_until(__abs_time);}
2563};
2564
2565template <class _R>
2566inline _LIBCPP_INLINE_VISIBILITY
2567void
2568swap(atomic_future<_R>& __x, atomic_future<_R>& __y)
2569{
2570 __x.swap(__y);
2571}
2572
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002573_LIBCPP_END_NAMESPACE_STD
2574
2575#endif // _LIBCPP_FUTURE