1// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUTURE
11#define _LIBCPP_FUTURE
12
13/*
14 future synopsis
15
16namespace std
17{
18
19enum class future_errc
20{
21 future_already_retrieved = 1,
22 promise_already_satisfied,
23 no_state,
24 broken_promise
25};
26
27enum class launch
28{
29 async = 1,
30 deferred = 2,
31 any = async | deferred
32};
33
34enum class future_status
35{
36 ready,
37 timeout,
38 deferred
39};
40
41template <> struct is_error_code_enum<future_errc> : public true_type { };
42error_code make_error_code(future_errc e) noexcept;
43error_condition make_error_condition(future_errc e) noexcept;
44
45const error_category& future_category() noexcept;
46
47class future_error
48 : public logic_error
49{
50public:
51 future_error(error_code ec); // exposition only
52 explicit future_error(future_errc); // C++17
53 const error_code& code() const noexcept;
54 const char* what() const noexcept;
55};
56
57template <class R>
58class promise
59{
60public:
61 promise();
62 template <class Allocator>
63 promise(allocator_arg_t, const Allocator& a);
64 promise(promise&& rhs) noexcept;
65 promise(const promise& rhs) = delete;
66 ~promise();
67
68 // assignment
69 promise& operator=(promise&& rhs) noexcept;
70 promise& operator=(const promise& rhs) = delete;
71 void swap(promise& other) noexcept;
72
73 // retrieving the result
74 future<R> get_future();
75
76 // setting the result
77 void set_value(const R& r);
78 void set_value(R&& r);
79 void set_exception(exception_ptr p);
80
81 // setting the result with deferred notification
82 void set_value_at_thread_exit(const R& r);
83 void set_value_at_thread_exit(R&& r);
84 void set_exception_at_thread_exit(exception_ptr p);
85};
86
87template <class R>
88class promise<R&>
89{
90public:
91 promise();
92 template <class Allocator>
93 promise(allocator_arg_t, const Allocator& a);
94 promise(promise&& rhs) noexcept;
95 promise(const promise& rhs) = delete;
96 ~promise();
97
98 // assignment
99 promise& operator=(promise&& rhs) noexcept;
100 promise& operator=(const promise& rhs) = delete;
101 void swap(promise& other) noexcept;
102
103 // retrieving the result
104 future<R&> get_future();
105
106 // setting the result
107 void set_value(R& r);
108 void set_exception(exception_ptr p);
109
110 // setting the result with deferred notification
111 void set_value_at_thread_exit(R&);
112 void set_exception_at_thread_exit(exception_ptr p);
113};
114
115template <>
116class promise<void>
117{
118public:
119 promise();
120 template <class Allocator>
121 promise(allocator_arg_t, const Allocator& a);
122 promise(promise&& rhs) noexcept;
123 promise(const promise& rhs) = delete;
124 ~promise();
125
126 // assignment
127 promise& operator=(promise&& rhs) noexcept;
128 promise& operator=(const promise& rhs) = delete;
129 void swap(promise& other) noexcept;
130
131 // retrieving the result
132 future<void> get_future();
133
134 // setting the result
135 void set_value();
136 void set_exception(exception_ptr p);
137
138 // setting the result with deferred notification
139 void set_value_at_thread_exit();
140 void set_exception_at_thread_exit(exception_ptr p);
141};
142
143template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
144
145template <class R, class Alloc>
146 struct uses_allocator<promise<R>, Alloc> : public true_type {};
147
148template <class R>
149class future
150{
151public:
152 future() noexcept;
153 future(future&&) noexcept;
154 future(const future& rhs) = delete;
155 ~future();
156 future& operator=(const future& rhs) = delete;
157 future& operator=(future&&) noexcept;
158 shared_future<R> share() noexcept;
159
160 // retrieving the value
161 R get();
162
163 // functions to check state
164 bool valid() const noexcept;
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() noexcept;
180 future(future&&) noexcept;
181 future(const future& rhs) = delete;
182 ~future();
183 future& operator=(const future& rhs) = delete;
184 future& operator=(future&&) noexcept;
185 shared_future<R&> share() noexcept;
186
187 // retrieving the value
188 R& get();
189
190 // functions to check state
191 bool valid() const noexcept;
192
193 void wait() const;
194 template <class Rep, class Period>
195 future_status
196 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
197 template <class Clock, class Duration>
198 future_status
199 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
200};
201
202template <>
203class future<void>
204{
205public:
206 future() noexcept;
207 future(future&&) noexcept;
208 future(const future& rhs) = delete;
209 ~future();
210 future& operator=(const future& rhs) = delete;
211 future& operator=(future&&) noexcept;
212 shared_future<void> share() noexcept;
213
214 // retrieving the value
215 void get();
216
217 // functions to check state
218 bool valid() const noexcept;
219
220 void wait() const;
221 template <class Rep, class Period>
222 future_status
223 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
224 template <class Clock, class Duration>
225 future_status
226 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
227};
228
229template <class R>
230class shared_future
231{
232public:
233 shared_future() noexcept;
234 shared_future(const shared_future& rhs);
235 shared_future(future<R>&&) noexcept;
236 shared_future(shared_future&& rhs) noexcept;
237 ~shared_future();
238 shared_future& operator=(const shared_future& rhs);
239 shared_future& operator=(shared_future&& rhs) noexcept;
240
241 // retrieving the value
242 const R& get() const;
243
244 // functions to check state
245 bool valid() const noexcept;
246
247 void wait() const;
248 template <class Rep, class Period>
249 future_status
250 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
251 template <class Clock, class Duration>
252 future_status
253 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
254};
255
256template <class R>
257class shared_future<R&>
258{
259public:
260 shared_future() noexcept;
261 shared_future(const shared_future& rhs);
262 shared_future(future<R&>&&) noexcept;
263 shared_future(shared_future&& rhs) noexcept;
264 ~shared_future();
265 shared_future& operator=(const shared_future& rhs);
266 shared_future& operator=(shared_future&& rhs) noexcept;
267
268 // retrieving the value
269 R& get() const;
270
271 // functions to check state
272 bool valid() const noexcept;
273
274 void wait() const;
275 template <class Rep, class Period>
276 future_status
277 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
278 template <class Clock, class Duration>
279 future_status
280 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
281};
282
283template <>
284class shared_future<void>
285{
286public:
287 shared_future() noexcept;
288 shared_future(const shared_future& rhs);
289 shared_future(future<void>&&) noexcept;
290 shared_future(shared_future&& rhs) noexcept;
291 ~shared_future();
292 shared_future& operator=(const shared_future& rhs);
293 shared_future& operator=(shared_future&& rhs) noexcept;
294
295 // retrieving the value
296 void get() const;
297
298 // functions to check state
299 bool valid() const noexcept;
300
301 void wait() const;
302 template <class Rep, class Period>
303 future_status
304 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
305 template <class Clock, class Duration>
306 future_status
307 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
308};
309
310template <class F, class... Args>
311 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
312 async(F&& f, Args&&... args);
313
314template <class F, class... Args>
315 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
316 async(launch policy, F&& f, Args&&... args);
317
318template <class> class packaged_task; // undefined
319
320template <class R, class... ArgTypes>
321class packaged_task<R(ArgTypes...)>
322{
323public:
324 typedef R result_type; // extension
325
326 // construction and destruction
327 packaged_task() noexcept;
328 template <class F>
329 explicit packaged_task(F&& f);
330 template <class F, class Allocator>
331 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
332 ~packaged_task();
333
334 // no copy
335 packaged_task(const packaged_task&) = delete;
336 packaged_task& operator=(const packaged_task&) = delete;
337
338 // move support
339 packaged_task(packaged_task&& other) noexcept;
340 packaged_task& operator=(packaged_task&& other) noexcept;
341 void swap(packaged_task& other) noexcept;
342
343 bool valid() const noexcept;
344
345 // result retrieval
346 future<R> get_future();
347
348 // execution
349 void operator()(ArgTypes... );
350 void make_ready_at_thread_exit(ArgTypes...);
351
352 void reset();
353};
354
355template <class R>
356 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
357
358template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
359
360} // std
361
362*/
363
364#include <__config>
365#include <system_error>
366#include <memory>
367#include <chrono>
368#include <exception>
369#include <mutex>
370#include <thread>
371
372#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
373#pragma GCC system_header
374#endif
375
376#ifdef _LIBCPP_HAS_NO_THREADS
377#error <future> is not supported on this single threaded system
378#else // !_LIBCPP_HAS_NO_THREADS
379
380_LIBCPP_BEGIN_NAMESPACE_STD
381
382//enum class future_errc
383_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
384{
385 future_already_retrieved = 1,
386 promise_already_satisfied,
387 no_state,
388 broken_promise
389};
390_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
391
392template <>
393struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
394
395#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
396template <>
397struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
398#endif
399
400//enum class launch
401_LIBCPP_DECLARE_STRONG_ENUM(launch)
402{
403 async = 1,
404 deferred = 2,
405 any = async | deferred
406};
407_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
408
409#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
410
411typedef underlying_type<launch>::type __launch_underlying_type;
412
413inline _LIBCPP_INLINE_VISIBILITY
414_LIBCPP_CONSTEXPR
415launch
416operator&(launch __x, launch __y)
417{
418 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
419 static_cast<__launch_underlying_type>(__y));
420}
421
422inline _LIBCPP_INLINE_VISIBILITY
423_LIBCPP_CONSTEXPR
424launch
425operator|(launch __x, launch __y)
426{
427 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
428 static_cast<__launch_underlying_type>(__y));
429}
430
431inline _LIBCPP_INLINE_VISIBILITY
432_LIBCPP_CONSTEXPR
433launch
434operator^(launch __x, launch __y)
435{
436 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
437 static_cast<__launch_underlying_type>(__y));
438}
439
440inline _LIBCPP_INLINE_VISIBILITY
441_LIBCPP_CONSTEXPR
442launch
443operator~(launch __x)
444{
445 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
446}
447
448inline _LIBCPP_INLINE_VISIBILITY
449launch&
450operator&=(launch& __x, launch __y)
451{
452 __x = __x & __y; return __x;
453}
454
455inline _LIBCPP_INLINE_VISIBILITY
456launch&
457operator|=(launch& __x, launch __y)
458{
459 __x = __x | __y; return __x;
460}
461
462inline _LIBCPP_INLINE_VISIBILITY
463launch&
464operator^=(launch& __x, launch __y)
465{
466 __x = __x ^ __y; return __x;
467}
468
469#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
470
471//enum class future_status
472_LIBCPP_DECLARE_STRONG_ENUM(future_status)
473{
474 ready,
475 timeout,
476 deferred
477};
478_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
479
480_LIBCPP_FUNC_VIS
481const error_category& future_category() _NOEXCEPT;
482
483inline _LIBCPP_INLINE_VISIBILITY
484error_code
485make_error_code(future_errc __e) _NOEXCEPT
486{
487 return error_code(static_cast<int>(__e), future_category());
488}
489
490inline _LIBCPP_INLINE_VISIBILITY
491error_condition
492make_error_condition(future_errc __e) _NOEXCEPT
493{
494 return error_condition(static_cast<int>(__e), future_category());
495}
496
497class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
498 : public logic_error
499{
500 error_code __ec_;
501public:
502 future_error(error_code __ec);
503#if _LIBCPP_STD_VERS > 14
504 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
505#endif
506 _LIBCPP_INLINE_VISIBILITY
507 const error_code& code() const _NOEXCEPT {return __ec_;}
508
509 virtual ~future_error() _NOEXCEPT;
510};
511
512_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
513#ifndef _LIBCPP_NO_EXCEPTIONS
514_LIBCPP_AVAILABILITY_FUTURE_ERROR
515#endif
516void __throw_future_error(future_errc _Ev)
517{
518#ifndef _LIBCPP_NO_EXCEPTIONS
519 throw future_error(make_error_code(_Ev));
520#else
521 ((void)_Ev);
522 _VSTD::abort();
523#endif
524}
525
526class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
527 : public __shared_count
528{
529protected:
530 exception_ptr __exception_;
531 mutable mutex __mut_;
532 mutable condition_variable __cv_;
533 unsigned __state_;
534
535 virtual void __on_zero_shared() _NOEXCEPT;
536 void __sub_wait(unique_lock<mutex>& __lk);
537public:
538 enum
539 {
540 __constructed = 1,
541 __future_attached = 2,
542 ready = 4,
543 deferred = 8
544 };
545
546 _LIBCPP_INLINE_VISIBILITY
547 __assoc_sub_state() : __state_(0) {}
548
549 _LIBCPP_INLINE_VISIBILITY
550 bool __has_value() const
551 {return (__state_ & __constructed) || (__exception_ != nullptr);}
552
553 _LIBCPP_INLINE_VISIBILITY
554 void __attach_future() {
555 lock_guard<mutex> __lk(__mut_);
556 bool __has_future_attached = (__state_ & __future_attached) != 0;
557 if (__has_future_attached)
558 __throw_future_error(future_errc::future_already_retrieved);
559 this->__add_shared();
560 __state_ |= __future_attached;
561 }
562
563 _LIBCPP_INLINE_VISIBILITY
564 void __set_deferred() {__state_ |= deferred;}
565
566 void __make_ready();
567 _LIBCPP_INLINE_VISIBILITY
568 bool __is_ready() const {return (__state_ & ready) != 0;}
569
570 void set_value();
571 void set_value_at_thread_exit();
572
573 void set_exception(exception_ptr __p);
574 void set_exception_at_thread_exit(exception_ptr __p);
575
576 void copy();
577
578 void wait();
579 template <class _Rep, class _Period>
580 future_status
581 _LIBCPP_INLINE_VISIBILITY
582 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
583 template <class _Clock, class _Duration>
584 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
585 future_status
586 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
587
588 virtual void __execute();
589};
590
591template <class _Clock, class _Duration>
592future_status
593__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
594{
595 unique_lock<mutex> __lk(__mut_);
596 if (__state_ & deferred)
597 return future_status::deferred;
598 while (!(__state_ & ready) && _Clock::now() < __abs_time)
599 __cv_.wait_until(__lk, __abs_time);
600 if (__state_ & ready)
601 return future_status::ready;
602 return future_status::timeout;
603}
604
605template <class _Rep, class _Period>
606inline
607future_status
608__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
609{
610 return wait_until(chrono::steady_clock::now() + __rel_time);
611}
612
613template <class _Rp>
614class _LIBCPP_AVAILABILITY_FUTURE __assoc_state
615 : public __assoc_sub_state
616{
617 typedef __assoc_sub_state base;
618 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
619protected:
620 _Up __value_;
621
622 virtual void __on_zero_shared() _NOEXCEPT;
623public:
624
625 template <class _Arg>
626#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
627 void set_value(_Arg&& __arg);
628#else
629 void set_value(_Arg& __arg);
630#endif
631
632 template <class _Arg>
633#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
634 void set_value_at_thread_exit(_Arg&& __arg);
635#else
636 void set_value_at_thread_exit(_Arg& __arg);
637#endif
638
639 _Rp move();
640 typename add_lvalue_reference<_Rp>::type copy();
641};
642
643template <class _Rp>
644void
645__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
646{
647 if (this->__state_ & base::__constructed)
648 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
649 delete this;
650}
651
652template <class _Rp>
653template <class _Arg>
654_LIBCPP_AVAILABILITY_FUTURE
655void
656#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
657__assoc_state<_Rp>::set_value(_Arg&& __arg)
658#else
659__assoc_state<_Rp>::set_value(_Arg& __arg)
660#endif
661{
662 unique_lock<mutex> __lk(this->__mut_);
663 if (this->__has_value())
664 __throw_future_error(future_errc::promise_already_satisfied);
665 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
666 this->__state_ |= base::__constructed | base::ready;
667 __cv_.notify_all();
668}
669
670template <class _Rp>
671template <class _Arg>
672void
673#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
674__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
675#else
676__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
677#endif
678{
679 unique_lock<mutex> __lk(this->__mut_);
680 if (this->__has_value())
681 __throw_future_error(future_errc::promise_already_satisfied);
682 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
683 this->__state_ |= base::__constructed;
684 __thread_local_data()->__make_ready_at_thread_exit(this);
685}
686
687template <class _Rp>
688_Rp
689__assoc_state<_Rp>::move()
690{
691 unique_lock<mutex> __lk(this->__mut_);
692 this->__sub_wait(__lk);
693 if (this->__exception_ != nullptr)
694 rethrow_exception(this->__exception_);
695 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
696}
697
698template <class _Rp>
699typename add_lvalue_reference<_Rp>::type
700__assoc_state<_Rp>::copy()
701{
702 unique_lock<mutex> __lk(this->__mut_);
703 this->__sub_wait(__lk);
704 if (this->__exception_ != nullptr)
705 rethrow_exception(this->__exception_);
706 return *reinterpret_cast<_Rp*>(&__value_);
707}
708
709template <class _Rp>
710class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
711 : public __assoc_sub_state
712{
713 typedef __assoc_sub_state base;
714 typedef _Rp* _Up;
715protected:
716 _Up __value_;
717
718 virtual void __on_zero_shared() _NOEXCEPT;
719public:
720
721 void set_value(_Rp& __arg);
722 void set_value_at_thread_exit(_Rp& __arg);
723
724 _Rp& copy();
725};
726
727template <class _Rp>
728void
729__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
730{
731 delete this;
732}
733
734template <class _Rp>
735void
736__assoc_state<_Rp&>::set_value(_Rp& __arg)
737{
738 unique_lock<mutex> __lk(this->__mut_);
739 if (this->__has_value())
740 __throw_future_error(future_errc::promise_already_satisfied);
741 __value_ = _VSTD::addressof(__arg);
742 this->__state_ |= base::__constructed | base::ready;
743 __cv_.notify_all();
744}
745
746template <class _Rp>
747void
748__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
749{
750 unique_lock<mutex> __lk(this->__mut_);
751 if (this->__has_value())
752 __throw_future_error(future_errc::promise_already_satisfied);
753 __value_ = _VSTD::addressof(__arg);
754 this->__state_ |= base::__constructed;
755 __thread_local_data()->__make_ready_at_thread_exit(this);
756}
757
758template <class _Rp>
759_Rp&
760__assoc_state<_Rp&>::copy()
761{
762 unique_lock<mutex> __lk(this->__mut_);
763 this->__sub_wait(__lk);
764 if (this->__exception_ != nullptr)
765 rethrow_exception(this->__exception_);
766 return *__value_;
767}
768
769template <class _Rp, class _Alloc>
770class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
771 : public __assoc_state<_Rp>
772{
773 typedef __assoc_state<_Rp> base;
774 _Alloc __alloc_;
775
776 virtual void __on_zero_shared() _NOEXCEPT;
777public:
778 _LIBCPP_INLINE_VISIBILITY
779 explicit __assoc_state_alloc(const _Alloc& __a)
780 : __alloc_(__a) {}
781};
782
783template <class _Rp, class _Alloc>
784void
785__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
786{
787 if (this->__state_ & base::__constructed)
788 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
789 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
790 typedef allocator_traits<_Al> _ATraits;
791 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
792 _Al __a(__alloc_);
793 this->~__assoc_state_alloc();
794 __a.deallocate(_PTraits::pointer_to(*this), 1);
795}
796
797template <class _Rp, class _Alloc>
798class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
799 : public __assoc_state<_Rp&>
800{
801 typedef __assoc_state<_Rp&> base;
802 _Alloc __alloc_;
803
804 virtual void __on_zero_shared() _NOEXCEPT;
805public:
806 _LIBCPP_INLINE_VISIBILITY
807 explicit __assoc_state_alloc(const _Alloc& __a)
808 : __alloc_(__a) {}
809};
810
811template <class _Rp, class _Alloc>
812void
813__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
814{
815 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
816 typedef allocator_traits<_Al> _ATraits;
817 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
818 _Al __a(__alloc_);
819 this->~__assoc_state_alloc();
820 __a.deallocate(_PTraits::pointer_to(*this), 1);
821}
822
823template <class _Alloc>
824class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
825 : public __assoc_sub_state
826{
827 typedef __assoc_sub_state base;
828 _Alloc __alloc_;
829
830 virtual void __on_zero_shared() _NOEXCEPT;
831public:
832 _LIBCPP_INLINE_VISIBILITY
833 explicit __assoc_sub_state_alloc(const _Alloc& __a)
834 : __alloc_(__a) {}
835};
836
837template <class _Alloc>
838void
839__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
840{
841 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
842 typedef allocator_traits<_Al> _ATraits;
843 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
844 _Al __a(__alloc_);
845 this->~__assoc_sub_state_alloc();
846 __a.deallocate(_PTraits::pointer_to(*this), 1);
847}
848
849template <class _Rp, class _Fp>
850class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
851 : public __assoc_state<_Rp>
852{
853 typedef __assoc_state<_Rp> base;
854
855 _Fp __func_;
856
857public:
858#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
859 _LIBCPP_INLINE_VISIBILITY
860 explicit __deferred_assoc_state(_Fp&& __f);
861#endif
862
863 virtual void __execute();
864};
865
866#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
867
868template <class _Rp, class _Fp>
869inline
870__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
871 : __func_(_VSTD::forward<_Fp>(__f))
872{
873 this->__set_deferred();
874}
875
876#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
877
878template <class _Rp, class _Fp>
879void
880__deferred_assoc_state<_Rp, _Fp>::__execute()
881{
882#ifndef _LIBCPP_NO_EXCEPTIONS
883 try
884 {
885#endif // _LIBCPP_NO_EXCEPTIONS
886 this->set_value(__func_());
887#ifndef _LIBCPP_NO_EXCEPTIONS
888 }
889 catch (...)
890 {
891 this->set_exception(current_exception());
892 }
893#endif // _LIBCPP_NO_EXCEPTIONS
894}
895
896template <class _Fp>
897class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
898 : public __assoc_sub_state
899{
900 typedef __assoc_sub_state base;
901
902 _Fp __func_;
903
904public:
905#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
906 _LIBCPP_INLINE_VISIBILITY
907 explicit __deferred_assoc_state(_Fp&& __f);
908#endif
909
910 virtual void __execute();
911};
912
913#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
914
915template <class _Fp>
916inline
917__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
918 : __func_(_VSTD::forward<_Fp>(__f))
919{
920 this->__set_deferred();
921}
922
923#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
924
925template <class _Fp>
926void
927__deferred_assoc_state<void, _Fp>::__execute()
928{
929#ifndef _LIBCPP_NO_EXCEPTIONS
930 try
931 {
932#endif // _LIBCPP_NO_EXCEPTIONS
933 __func_();
934 this->set_value();
935#ifndef _LIBCPP_NO_EXCEPTIONS
936 }
937 catch (...)
938 {
939 this->set_exception(current_exception());
940 }
941#endif // _LIBCPP_NO_EXCEPTIONS
942}
943
944template <class _Rp, class _Fp>
945class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
946 : public __assoc_state<_Rp>
947{
948 typedef __assoc_state<_Rp> base;
949
950 _Fp __func_;
951
952 virtual void __on_zero_shared() _NOEXCEPT;
953public:
954#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
955 _LIBCPP_INLINE_VISIBILITY
956 explicit __async_assoc_state(_Fp&& __f);
957#endif
958
959 virtual void __execute();
960};
961
962#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
963
964template <class _Rp, class _Fp>
965inline
966__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
967 : __func_(_VSTD::forward<_Fp>(__f))
968{
969}
970
971#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
972
973template <class _Rp, class _Fp>
974void
975__async_assoc_state<_Rp, _Fp>::__execute()
976{
977#ifndef _LIBCPP_NO_EXCEPTIONS
978 try
979 {
980#endif // _LIBCPP_NO_EXCEPTIONS
981 this->set_value(__func_());
982#ifndef _LIBCPP_NO_EXCEPTIONS
983 }
984 catch (...)
985 {
986 this->set_exception(current_exception());
987 }
988#endif // _LIBCPP_NO_EXCEPTIONS
989}
990
991template <class _Rp, class _Fp>
992void
993__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
994{
995 this->wait();
996 base::__on_zero_shared();
997}
998
999template <class _Fp>
1000class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
1001 : public __assoc_sub_state
1002{
1003 typedef __assoc_sub_state base;
1004
1005 _Fp __func_;
1006
1007 virtual void __on_zero_shared() _NOEXCEPT;
1008public:
1009#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1010 _LIBCPP_INLINE_VISIBILITY
1011 explicit __async_assoc_state(_Fp&& __f);
1012#endif
1013
1014 virtual void __execute();
1015};
1016
1017#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018
1019template <class _Fp>
1020inline
1021__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1022 : __func_(_VSTD::forward<_Fp>(__f))
1023{
1024}
1025
1026#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1027
1028template <class _Fp>
1029void
1030__async_assoc_state<void, _Fp>::__execute()
1031{
1032#ifndef _LIBCPP_NO_EXCEPTIONS
1033 try
1034 {
1035#endif // _LIBCPP_NO_EXCEPTIONS
1036 __func_();
1037 this->set_value();
1038#ifndef _LIBCPP_NO_EXCEPTIONS
1039 }
1040 catch (...)
1041 {
1042 this->set_exception(current_exception());
1043 }
1044#endif // _LIBCPP_NO_EXCEPTIONS
1045}
1046
1047template <class _Fp>
1048void
1049__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
1050{
1051 this->wait();
1052 base::__on_zero_shared();
1053}
1054
1055template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1056template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
1057
1058// future
1059
1060template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
1061
1062template <class _Rp, class _Fp>
1063future<_Rp>
1064#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1065__make_deferred_assoc_state(_Fp&& __f);
1066#else
1067__make_deferred_assoc_state(_Fp __f);
1068#endif
1069
1070template <class _Rp, class _Fp>
1071future<_Rp>
1072#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1073__make_async_assoc_state(_Fp&& __f);
1074#else
1075__make_async_assoc_state(_Fp __f);
1076#endif
1077
1078template <class _Rp>
1079class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
1080{
1081 __assoc_state<_Rp>* __state_;
1082
1083 explicit future(__assoc_state<_Rp>* __state);
1084
1085 template <class> friend class promise;
1086 template <class> friend class shared_future;
1087
1088#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1089 template <class _R1, class _Fp>
1090 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1091 template <class _R1, class _Fp>
1092 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1093#else
1094 template <class _R1, class _Fp>
1095 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1096 template <class _R1, class _Fp>
1097 friend future<_R1> __make_async_assoc_state(_Fp __f);
1098#endif
1099
1100public:
1101 _LIBCPP_INLINE_VISIBILITY
1102 future() _NOEXCEPT : __state_(nullptr) {}
1103#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1104 _LIBCPP_INLINE_VISIBILITY
1105 future(future&& __rhs) _NOEXCEPT
1106 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1107 future(const future&) = delete;
1108 future& operator=(const future&) = delete;
1109 _LIBCPP_INLINE_VISIBILITY
1110 future& operator=(future&& __rhs) _NOEXCEPT
1111 {
1112 future(std::move(__rhs)).swap(*this);
1113 return *this;
1114 }
1115#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1116private:
1117 future(const future&);
1118 future& operator=(const future&);
1119public:
1120#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1121 ~future();
1122 _LIBCPP_INLINE_VISIBILITY
1123 shared_future<_Rp> share() _NOEXCEPT;
1124
1125 // retrieving the value
1126 _Rp get();
1127
1128 _LIBCPP_INLINE_VISIBILITY
1129 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1130
1131 // functions to check state
1132 _LIBCPP_INLINE_VISIBILITY
1133 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1134
1135 _LIBCPP_INLINE_VISIBILITY
1136 void wait() const {__state_->wait();}
1137 template <class _Rep, class _Period>
1138 _LIBCPP_INLINE_VISIBILITY
1139 future_status
1140 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1141 {return __state_->wait_for(__rel_time);}
1142 template <class _Clock, class _Duration>
1143 _LIBCPP_INLINE_VISIBILITY
1144 future_status
1145 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1146 {return __state_->wait_until(__abs_time);}
1147};
1148
1149template <class _Rp>
1150future<_Rp>::future(__assoc_state<_Rp>* __state)
1151 : __state_(__state)
1152{
1153 __state_->__attach_future();
1154}
1155
1156struct __release_shared_count
1157{
1158 void operator()(__shared_count* p) {p->__release_shared();}
1159};
1160
1161template <class _Rp>
1162future<_Rp>::~future()
1163{
1164 if (__state_)
1165 __state_->__release_shared();
1166}
1167
1168template <class _Rp>
1169_Rp
1170future<_Rp>::get()
1171{
1172 unique_ptr<__shared_count, __release_shared_count> __(__state_);
1173 __assoc_state<_Rp>* __s = __state_;
1174 __state_ = nullptr;
1175 return __s->move();
1176}
1177
1178template <class _Rp>
1179class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
1180{
1181 __assoc_state<_Rp&>* __state_;
1182
1183 explicit future(__assoc_state<_Rp&>* __state);
1184
1185 template <class> friend class promise;
1186 template <class> friend class shared_future;
1187
1188#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1189 template <class _R1, class _Fp>
1190 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1191 template <class _R1, class _Fp>
1192 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1193#else
1194 template <class _R1, class _Fp>
1195 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1196 template <class _R1, class _Fp>
1197 friend future<_R1> __make_async_assoc_state(_Fp __f);
1198#endif
1199
1200public:
1201 _LIBCPP_INLINE_VISIBILITY
1202 future() _NOEXCEPT : __state_(nullptr) {}
1203#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1204 _LIBCPP_INLINE_VISIBILITY
1205 future(future&& __rhs) _NOEXCEPT
1206 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1207 future(const future&) = delete;
1208 future& operator=(const future&) = delete;
1209 _LIBCPP_INLINE_VISIBILITY
1210 future& operator=(future&& __rhs) _NOEXCEPT
1211 {
1212 future(std::move(__rhs)).swap(*this);
1213 return *this;
1214 }
1215#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1216private:
1217 future(const future&);
1218 future& operator=(const future&);
1219public:
1220#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1221 ~future();
1222 _LIBCPP_INLINE_VISIBILITY
1223 shared_future<_Rp&> share() _NOEXCEPT;
1224
1225 // retrieving the value
1226 _Rp& get();
1227
1228 _LIBCPP_INLINE_VISIBILITY
1229 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1230
1231 // functions to check state
1232 _LIBCPP_INLINE_VISIBILITY
1233 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1234
1235 _LIBCPP_INLINE_VISIBILITY
1236 void wait() const {__state_->wait();}
1237 template <class _Rep, class _Period>
1238 _LIBCPP_INLINE_VISIBILITY
1239 future_status
1240 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1241 {return __state_->wait_for(__rel_time);}
1242 template <class _Clock, class _Duration>
1243 _LIBCPP_INLINE_VISIBILITY
1244 future_status
1245 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1246 {return __state_->wait_until(__abs_time);}
1247};
1248
1249template <class _Rp>
1250future<_Rp&>::future(__assoc_state<_Rp&>* __state)
1251 : __state_(__state)
1252{
1253 __state_->__attach_future();
1254}
1255
1256template <class _Rp>
1257future<_Rp&>::~future()
1258{
1259 if (__state_)
1260 __state_->__release_shared();
1261}
1262
1263template <class _Rp>
1264_Rp&
1265future<_Rp&>::get()
1266{
1267 unique_ptr<__shared_count, __release_shared_count> __(__state_);
1268 __assoc_state<_Rp&>* __s = __state_;
1269 __state_ = nullptr;
1270 return __s->copy();
1271}
1272
1273template <>
1274class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
1275{
1276 __assoc_sub_state* __state_;
1277
1278 explicit future(__assoc_sub_state* __state);
1279
1280 template <class> friend class promise;
1281 template <class> friend class shared_future;
1282
1283#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1284 template <class _R1, class _Fp>
1285 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1286 template <class _R1, class _Fp>
1287 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1288#else
1289 template <class _R1, class _Fp>
1290 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1291 template <class _R1, class _Fp>
1292 friend future<_R1> __make_async_assoc_state(_Fp __f);
1293#endif
1294
1295public:
1296 _LIBCPP_INLINE_VISIBILITY
1297 future() _NOEXCEPT : __state_(nullptr) {}
1298#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1299 _LIBCPP_INLINE_VISIBILITY
1300 future(future&& __rhs) _NOEXCEPT
1301 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1302 future(const future&) = delete;
1303 future& operator=(const future&) = delete;
1304 _LIBCPP_INLINE_VISIBILITY
1305 future& operator=(future&& __rhs) _NOEXCEPT
1306 {
1307 future(std::move(__rhs)).swap(*this);
1308 return *this;
1309 }
1310#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1311private:
1312 future(const future&);
1313 future& operator=(const future&);
1314public:
1315#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1316 ~future();
1317 _LIBCPP_INLINE_VISIBILITY
1318 shared_future<void> share() _NOEXCEPT;
1319
1320 // retrieving the value
1321 void get();
1322
1323 _LIBCPP_INLINE_VISIBILITY
1324 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1325
1326 // functions to check state
1327 _LIBCPP_INLINE_VISIBILITY
1328 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1329
1330 _LIBCPP_INLINE_VISIBILITY
1331 void wait() const {__state_->wait();}
1332 template <class _Rep, class _Period>
1333 _LIBCPP_INLINE_VISIBILITY
1334 future_status
1335 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1336 {return __state_->wait_for(__rel_time);}
1337 template <class _Clock, class _Duration>
1338 _LIBCPP_INLINE_VISIBILITY
1339 future_status
1340 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1341 {return __state_->wait_until(__abs_time);}
1342};
1343
1344template <class _Rp>
1345inline _LIBCPP_INLINE_VISIBILITY
1346void
1347swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1348{
1349 __x.swap(__y);
1350}
1351
1352// promise<R>
1353
1354template <class _Callable> class packaged_task;
1355
1356template <class _Rp>
1357class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
1358{
1359 __assoc_state<_Rp>* __state_;
1360
1361 _LIBCPP_INLINE_VISIBILITY
1362 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1363
1364 template <class> friend class packaged_task;
1365public:
1366 promise();
1367 template <class _Alloc>
1368 promise(allocator_arg_t, const _Alloc& __a);
1369#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1370 _LIBCPP_INLINE_VISIBILITY
1371 promise(promise&& __rhs) _NOEXCEPT
1372 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1373 promise(const promise& __rhs) = delete;
1374#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1375private:
1376 promise(const promise& __rhs);
1377public:
1378#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1379 ~promise();
1380
1381 // assignment
1382#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1383 _LIBCPP_INLINE_VISIBILITY
1384 promise& operator=(promise&& __rhs) _NOEXCEPT
1385 {
1386 promise(std::move(__rhs)).swap(*this);
1387 return *this;
1388 }
1389 promise& operator=(const promise& __rhs) = delete;
1390#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391private:
1392 promise& operator=(const promise& __rhs);
1393public:
1394#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1395 _LIBCPP_INLINE_VISIBILITY
1396 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1397
1398 // retrieving the result
1399 future<_Rp> get_future();
1400
1401 // setting the result
1402 void set_value(const _Rp& __r);
1403#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1404 void set_value(_Rp&& __r);
1405#endif
1406 void set_exception(exception_ptr __p);
1407
1408 // setting the result with deferred notification
1409 void set_value_at_thread_exit(const _Rp& __r);
1410#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1411 void set_value_at_thread_exit(_Rp&& __r);
1412#endif
1413 void set_exception_at_thread_exit(exception_ptr __p);
1414};
1415
1416template <class _Rp>
1417promise<_Rp>::promise()
1418 : __state_(new __assoc_state<_Rp>)
1419{
1420}
1421
1422template <class _Rp>
1423template <class _Alloc>
1424promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1425{
1426 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1427 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1428 typedef __allocator_destructor<_A2> _D2;
1429 _A2 __a(__a0);
1430 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1431 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1432 __state_ = _VSTD::addressof(*__hold.release());
1433}
1434
1435template <class _Rp>
1436promise<_Rp>::~promise()
1437{
1438 if (__state_)
1439 {
1440 if (!__state_->__has_value() && __state_->use_count() > 1)
1441 __state_->set_exception(make_exception_ptr(
1442 future_error(make_error_code(future_errc::broken_promise))
1443 ));
1444 __state_->__release_shared();
1445 }
1446}
1447
1448template <class _Rp>
1449future<_Rp>
1450promise<_Rp>::get_future()
1451{
1452 if (__state_ == nullptr)
1453 __throw_future_error(future_errc::no_state);
1454 return future<_Rp>(__state_);
1455}
1456
1457template <class _Rp>
1458void
1459promise<_Rp>::set_value(const _Rp& __r)
1460{
1461 if (__state_ == nullptr)
1462 __throw_future_error(future_errc::no_state);
1463 __state_->set_value(__r);
1464}
1465
1466#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1467
1468template <class _Rp>
1469void
1470promise<_Rp>::set_value(_Rp&& __r)
1471{
1472 if (__state_ == nullptr)
1473 __throw_future_error(future_errc::no_state);
1474 __state_->set_value(_VSTD::move(__r));
1475}
1476
1477#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1478
1479template <class _Rp>
1480void
1481promise<_Rp>::set_exception(exception_ptr __p)
1482{
1483 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1484 if (__state_ == nullptr)
1485 __throw_future_error(future_errc::no_state);
1486 __state_->set_exception(__p);
1487}
1488
1489template <class _Rp>
1490void
1491promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1492{
1493 if (__state_ == nullptr)
1494 __throw_future_error(future_errc::no_state);
1495 __state_->set_value_at_thread_exit(__r);
1496}
1497
1498#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1499
1500template <class _Rp>
1501void
1502promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1503{
1504 if (__state_ == nullptr)
1505 __throw_future_error(future_errc::no_state);
1506 __state_->set_value_at_thread_exit(_VSTD::move(__r));
1507}
1508
1509#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1510
1511template <class _Rp>
1512void
1513promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1514{
1515 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1516 if (__state_ == nullptr)
1517 __throw_future_error(future_errc::no_state);
1518 __state_->set_exception_at_thread_exit(__p);
1519}
1520
1521// promise<R&>
1522
1523template <class _Rp>
1524class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
1525{
1526 __assoc_state<_Rp&>* __state_;
1527
1528 _LIBCPP_INLINE_VISIBILITY
1529 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1530
1531 template <class> friend class packaged_task;
1532
1533public:
1534 promise();
1535 template <class _Allocator>
1536 promise(allocator_arg_t, const _Allocator& __a);
1537#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1538 _LIBCPP_INLINE_VISIBILITY
1539 promise(promise&& __rhs) _NOEXCEPT
1540 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1541 promise(const promise& __rhs) = delete;
1542#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1543private:
1544 promise(const promise& __rhs);
1545public:
1546#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1547 ~promise();
1548
1549 // assignment
1550#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1551 _LIBCPP_INLINE_VISIBILITY
1552 promise& operator=(promise&& __rhs) _NOEXCEPT
1553 {
1554 promise(std::move(__rhs)).swap(*this);
1555 return *this;
1556 }
1557 promise& operator=(const promise& __rhs) = delete;
1558#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1559private:
1560 promise& operator=(const promise& __rhs);
1561public:
1562#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1563 _LIBCPP_INLINE_VISIBILITY
1564 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1565
1566 // retrieving the result
1567 future<_Rp&> get_future();
1568
1569 // setting the result
1570 void set_value(_Rp& __r);
1571 void set_exception(exception_ptr __p);
1572
1573 // setting the result with deferred notification
1574 void set_value_at_thread_exit(_Rp&);
1575 void set_exception_at_thread_exit(exception_ptr __p);
1576};
1577
1578template <class _Rp>
1579promise<_Rp&>::promise()
1580 : __state_(new __assoc_state<_Rp&>)
1581{
1582}
1583
1584template <class _Rp>
1585template <class _Alloc>
1586promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1587{
1588 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1589 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1590 typedef __allocator_destructor<_A2> _D2;
1591 _A2 __a(__a0);
1592 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1593 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1594 __state_ = _VSTD::addressof(*__hold.release());
1595}
1596
1597template <class _Rp>
1598promise<_Rp&>::~promise()
1599{
1600 if (__state_)
1601 {
1602 if (!__state_->__has_value() && __state_->use_count() > 1)
1603 __state_->set_exception(make_exception_ptr(
1604 future_error(make_error_code(future_errc::broken_promise))
1605 ));
1606 __state_->__release_shared();
1607 }
1608}
1609
1610template <class _Rp>
1611future<_Rp&>
1612promise<_Rp&>::get_future()
1613{
1614 if (__state_ == nullptr)
1615 __throw_future_error(future_errc::no_state);
1616 return future<_Rp&>(__state_);
1617}
1618
1619template <class _Rp>
1620void
1621promise<_Rp&>::set_value(_Rp& __r)
1622{
1623 if (__state_ == nullptr)
1624 __throw_future_error(future_errc::no_state);
1625 __state_->set_value(__r);
1626}
1627
1628template <class _Rp>
1629void
1630promise<_Rp&>::set_exception(exception_ptr __p)
1631{
1632 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1633 if (__state_ == nullptr)
1634 __throw_future_error(future_errc::no_state);
1635 __state_->set_exception(__p);
1636}
1637
1638template <class _Rp>
1639void
1640promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1641{
1642 if (__state_ == nullptr)
1643 __throw_future_error(future_errc::no_state);
1644 __state_->set_value_at_thread_exit(__r);
1645}
1646
1647template <class _Rp>
1648void
1649promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1650{
1651 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1652 if (__state_ == nullptr)
1653 __throw_future_error(future_errc::no_state);
1654 __state_->set_exception_at_thread_exit(__p);
1655}
1656
1657// promise<void>
1658
1659template <>
1660class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
1661{
1662 __assoc_sub_state* __state_;
1663
1664 _LIBCPP_INLINE_VISIBILITY
1665 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1666
1667 template <class> friend class packaged_task;
1668
1669public:
1670 promise();
1671 template <class _Allocator>
1672 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1673 promise(allocator_arg_t, const _Allocator& __a);
1674#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1675 _LIBCPP_INLINE_VISIBILITY
1676 promise(promise&& __rhs) _NOEXCEPT
1677 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1678 promise(const promise& __rhs) = delete;
1679#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1680private:
1681 promise(const promise& __rhs);
1682public:
1683#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1684 ~promise();
1685
1686 // assignment
1687#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1688 _LIBCPP_INLINE_VISIBILITY
1689 promise& operator=(promise&& __rhs) _NOEXCEPT
1690 {
1691 promise(std::move(__rhs)).swap(*this);
1692 return *this;
1693 }
1694 promise& operator=(const promise& __rhs) = delete;
1695#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1696private:
1697 promise& operator=(const promise& __rhs);
1698public:
1699#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1700 _LIBCPP_INLINE_VISIBILITY
1701 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1702
1703 // retrieving the result
1704 future<void> get_future();
1705
1706 // setting the result
1707 void set_value();
1708 void set_exception(exception_ptr __p);
1709
1710 // setting the result with deferred notification
1711 void set_value_at_thread_exit();
1712 void set_exception_at_thread_exit(exception_ptr __p);
1713};
1714
1715template <class _Alloc>
1716promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1717{
1718 typedef __assoc_sub_state_alloc<_Alloc> _State;
1719 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1720 typedef __allocator_destructor<_A2> _D2;
1721 _A2 __a(__a0);
1722 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1723 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1724 __state_ = _VSTD::addressof(*__hold.release());
1725}
1726
1727template <class _Rp>
1728inline _LIBCPP_INLINE_VISIBILITY
1729void
1730swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1731{
1732 __x.swap(__y);
1733}
1734
1735template <class _Rp, class _Alloc>
1736 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
1737 : public true_type {};
1738
1739#ifndef _LIBCPP_HAS_NO_VARIADICS
1740
1741// packaged_task
1742
1743template<class _Fp> class __packaged_task_base;
1744
1745template<class _Rp, class ..._ArgTypes>
1746class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
1747{
1748 __packaged_task_base(const __packaged_task_base&);
1749 __packaged_task_base& operator=(const __packaged_task_base&);
1750public:
1751 _LIBCPP_INLINE_VISIBILITY
1752 __packaged_task_base() {}
1753 _LIBCPP_INLINE_VISIBILITY
1754 virtual ~__packaged_task_base() {}
1755 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1756 virtual void destroy() = 0;
1757 virtual void destroy_deallocate() = 0;
1758 virtual _Rp operator()(_ArgTypes&& ...) = 0;
1759};
1760
1761template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1762
1763template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1764class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1765 : public __packaged_task_base<_Rp(_ArgTypes...)>
1766{
1767 __compressed_pair<_Fp, _Alloc> __f_;
1768public:
1769 _LIBCPP_INLINE_VISIBILITY
1770 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1771 _LIBCPP_INLINE_VISIBILITY
1772 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1773 _LIBCPP_INLINE_VISIBILITY
1774 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1775 : __f_(__f, __a) {}
1776 _LIBCPP_INLINE_VISIBILITY
1777 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1778 : __f_(_VSTD::move(__f), __a) {}
1779 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1780 virtual void destroy();
1781 virtual void destroy_deallocate();
1782 virtual _Rp operator()(_ArgTypes&& ... __args);
1783};
1784
1785template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1786void
1787__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1788 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1789{
1790 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1791}
1792
1793template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1794void
1795__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1796{
1797 __f_.~__compressed_pair<_Fp, _Alloc>();
1798}
1799
1800template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1801void
1802__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1803{
1804 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1805 typedef allocator_traits<_Ap> _ATraits;
1806 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
1807 _Ap __a(__f_.second());
1808 __f_.~__compressed_pair<_Fp, _Alloc>();
1809 __a.deallocate(_PTraits::pointer_to(*this), 1);
1810}
1811
1812template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1813_Rp
1814__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1815{
1816 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1817}
1818
1819template <class _Callable> class __packaged_task_function;
1820
1821template<class _Rp, class ..._ArgTypes>
1822class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
1823{
1824 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1825 typename aligned_storage<3*sizeof(void*)>::type __buf_;
1826 __base* __f_;
1827
1828public:
1829 typedef _Rp result_type;
1830
1831 // construct/copy/destroy:
1832 _LIBCPP_INLINE_VISIBILITY
1833 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1834 template<class _Fp>
1835 __packaged_task_function(_Fp&& __f);
1836 template<class _Fp, class _Alloc>
1837 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1838
1839 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1840 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1841
1842 __packaged_task_function(const __packaged_task_function&) = delete;
1843 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1844
1845 ~__packaged_task_function();
1846
1847 void swap(__packaged_task_function&) _NOEXCEPT;
1848
1849 _LIBCPP_INLINE_VISIBILITY
1850 _Rp operator()(_ArgTypes...) const;
1851};
1852
1853template<class _Rp, class ..._ArgTypes>
1854__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1855{
1856 if (__f.__f_ == nullptr)
1857 __f_ = nullptr;
1858 else if (__f.__f_ == (__base*)&__f.__buf_)
1859 {
1860 __f_ = (__base*)&__buf_;
1861 __f.__f_->__move_to(__f_);
1862 }
1863 else
1864 {
1865 __f_ = __f.__f_;
1866 __f.__f_ = nullptr;
1867 }
1868}
1869
1870template<class _Rp, class ..._ArgTypes>
1871template <class _Fp>
1872__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1873 : __f_(nullptr)
1874{
1875 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1876 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1877 if (sizeof(_FF) <= sizeof(__buf_))
1878 {
1879 __f_ = (__base*)&__buf_;
1880 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1881 }
1882 else
1883 {
1884 typedef allocator<_FF> _Ap;
1885 _Ap __a;
1886 typedef __allocator_destructor<_Ap> _Dp;
1887 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1888 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1889 __f_ = __hold.release();
1890 }
1891}
1892
1893template<class _Rp, class ..._ArgTypes>
1894template <class _Fp, class _Alloc>
1895__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1896 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1897 : __f_(nullptr)
1898{
1899 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1900 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1901 if (sizeof(_FF) <= sizeof(__buf_))
1902 {
1903 __f_ = (__base*)&__buf_;
1904 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1905 }
1906 else
1907 {
1908 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
1909 _Ap __a(__a0);
1910 typedef __allocator_destructor<_Ap> _Dp;
1911 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1912 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1913 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1914 __f_ = _VSTD::addressof(*__hold.release());
1915 }
1916}
1917
1918template<class _Rp, class ..._ArgTypes>
1919__packaged_task_function<_Rp(_ArgTypes...)>&
1920__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1921{
1922 if (__f_ == (__base*)&__buf_)
1923 __f_->destroy();
1924 else if (__f_)
1925 __f_->destroy_deallocate();
1926 __f_ = nullptr;
1927 if (__f.__f_ == nullptr)
1928 __f_ = nullptr;
1929 else if (__f.__f_ == (__base*)&__f.__buf_)
1930 {
1931 __f_ = (__base*)&__buf_;
1932 __f.__f_->__move_to(__f_);
1933 }
1934 else
1935 {
1936 __f_ = __f.__f_;
1937 __f.__f_ = nullptr;
1938 }
1939 return *this;
1940}
1941
1942template<class _Rp, class ..._ArgTypes>
1943__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1944{
1945 if (__f_ == (__base*)&__buf_)
1946 __f_->destroy();
1947 else if (__f_)
1948 __f_->destroy_deallocate();
1949}
1950
1951template<class _Rp, class ..._ArgTypes>
1952void
1953__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1954{
1955 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1956 {
1957 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1958 __base* __t = (__base*)&__tempbuf;
1959 __f_->__move_to(__t);
1960 __f_->destroy();
1961 __f_ = nullptr;
1962 __f.__f_->__move_to((__base*)&__buf_);
1963 __f.__f_->destroy();
1964 __f.__f_ = nullptr;
1965 __f_ = (__base*)&__buf_;
1966 __t->__move_to((__base*)&__f.__buf_);
1967 __t->destroy();
1968 __f.__f_ = (__base*)&__f.__buf_;
1969 }
1970 else if (__f_ == (__base*)&__buf_)
1971 {
1972 __f_->__move_to((__base*)&__f.__buf_);
1973 __f_->destroy();
1974 __f_ = __f.__f_;
1975 __f.__f_ = (__base*)&__f.__buf_;
1976 }
1977 else if (__f.__f_ == (__base*)&__f.__buf_)
1978 {
1979 __f.__f_->__move_to((__base*)&__buf_);
1980 __f.__f_->destroy();
1981 __f.__f_ = __f_;
1982 __f_ = (__base*)&__buf_;
1983 }
1984 else
1985 _VSTD::swap(__f_, __f.__f_);
1986}
1987
1988template<class _Rp, class ..._ArgTypes>
1989inline
1990_Rp
1991__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1992{
1993 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
1994}
1995
1996template<class _Rp, class ..._ArgTypes>
1997class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
1998{
1999public:
2000 typedef _Rp result_type; // extension
2001
2002private:
2003 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2004 promise<result_type> __p_;
2005
2006public:
2007 // construction and destruction
2008 _LIBCPP_INLINE_VISIBILITY
2009 packaged_task() _NOEXCEPT : __p_(nullptr) {}
2010 template <class _Fp,
2011 class = typename enable_if
2012 <
2013 !is_same<
2014 typename __uncvref<_Fp>::type,
2015 packaged_task
2016 >::value
2017 >::type
2018 >
2019 _LIBCPP_INLINE_VISIBILITY
2020 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2021 template <class _Fp, class _Allocator,
2022 class = typename enable_if
2023 <
2024 !is_same<
2025 typename __uncvref<_Fp>::type,
2026 packaged_task
2027 >::value
2028 >::type
2029 >
2030 _LIBCPP_INLINE_VISIBILITY
2031 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2032 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2033 __p_(allocator_arg, __a) {}
2034 // ~packaged_task() = default;
2035
2036 // no copy
2037 packaged_task(const packaged_task&) = delete;
2038 packaged_task& operator=(const packaged_task&) = delete;
2039
2040 // move support
2041 _LIBCPP_INLINE_VISIBILITY
2042 packaged_task(packaged_task&& __other) _NOEXCEPT
2043 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2044 _LIBCPP_INLINE_VISIBILITY
2045 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2046 {
2047 __f_ = _VSTD::move(__other.__f_);
2048 __p_ = _VSTD::move(__other.__p_);
2049 return *this;
2050 }
2051 _LIBCPP_INLINE_VISIBILITY
2052 void swap(packaged_task& __other) _NOEXCEPT
2053 {
2054 __f_.swap(__other.__f_);
2055 __p_.swap(__other.__p_);
2056 }
2057
2058 _LIBCPP_INLINE_VISIBILITY
2059 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2060
2061 // result retrieval
2062 _LIBCPP_INLINE_VISIBILITY
2063 future<result_type> get_future() {return __p_.get_future();}
2064
2065 // execution
2066 void operator()(_ArgTypes... __args);
2067 void make_ready_at_thread_exit(_ArgTypes... __args);
2068
2069 void reset();
2070};
2071
2072template<class _Rp, class ..._ArgTypes>
2073void
2074packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
2075{
2076 if (__p_.__state_ == nullptr)
2077 __throw_future_error(future_errc::no_state);
2078 if (__p_.__state_->__has_value())
2079 __throw_future_error(future_errc::promise_already_satisfied);
2080#ifndef _LIBCPP_NO_EXCEPTIONS
2081 try
2082 {
2083#endif // _LIBCPP_NO_EXCEPTIONS
2084 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2085#ifndef _LIBCPP_NO_EXCEPTIONS
2086 }
2087 catch (...)
2088 {
2089 __p_.set_exception(current_exception());
2090 }
2091#endif // _LIBCPP_NO_EXCEPTIONS
2092}
2093
2094template<class _Rp, class ..._ArgTypes>
2095void
2096packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2097{
2098 if (__p_.__state_ == nullptr)
2099 __throw_future_error(future_errc::no_state);
2100 if (__p_.__state_->__has_value())
2101 __throw_future_error(future_errc::promise_already_satisfied);
2102#ifndef _LIBCPP_NO_EXCEPTIONS
2103 try
2104 {
2105#endif // _LIBCPP_NO_EXCEPTIONS
2106 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2107#ifndef _LIBCPP_NO_EXCEPTIONS
2108 }
2109 catch (...)
2110 {
2111 __p_.set_exception_at_thread_exit(current_exception());
2112 }
2113#endif // _LIBCPP_NO_EXCEPTIONS
2114}
2115
2116template<class _Rp, class ..._ArgTypes>
2117void
2118packaged_task<_Rp(_ArgTypes...)>::reset()
2119{
2120 if (!valid())
2121 __throw_future_error(future_errc::no_state);
2122 __p_ = promise<result_type>();
2123}
2124
2125template<class ..._ArgTypes>
2126class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
2127{
2128public:
2129 typedef void result_type; // extension
2130
2131private:
2132 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2133 promise<result_type> __p_;
2134
2135public:
2136 // construction and destruction
2137 _LIBCPP_INLINE_VISIBILITY
2138 packaged_task() _NOEXCEPT : __p_(nullptr) {}
2139 template <class _Fp,
2140 class = typename enable_if
2141 <
2142 !is_same<
2143 typename __uncvref<_Fp>::type,
2144 packaged_task
2145 >::value
2146 >::type
2147 >
2148 _LIBCPP_INLINE_VISIBILITY
2149 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2150 template <class _Fp, class _Allocator,
2151 class = typename enable_if
2152 <
2153 !is_same<
2154 typename __uncvref<_Fp>::type,
2155 packaged_task
2156 >::value
2157 >::type
2158 >
2159 _LIBCPP_INLINE_VISIBILITY
2160 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2161 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2162 __p_(allocator_arg, __a) {}
2163 // ~packaged_task() = default;
2164
2165 // no copy
2166 packaged_task(const packaged_task&) = delete;
2167 packaged_task& operator=(const packaged_task&) = delete;
2168
2169 // move support
2170 _LIBCPP_INLINE_VISIBILITY
2171 packaged_task(packaged_task&& __other) _NOEXCEPT
2172 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2173 _LIBCPP_INLINE_VISIBILITY
2174 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2175 {
2176 __f_ = _VSTD::move(__other.__f_);
2177 __p_ = _VSTD::move(__other.__p_);
2178 return *this;
2179 }
2180 _LIBCPP_INLINE_VISIBILITY
2181 void swap(packaged_task& __other) _NOEXCEPT
2182 {
2183 __f_.swap(__other.__f_);
2184 __p_.swap(__other.__p_);
2185 }
2186
2187 _LIBCPP_INLINE_VISIBILITY
2188 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2189
2190 // result retrieval
2191 _LIBCPP_INLINE_VISIBILITY
2192 future<result_type> get_future() {return __p_.get_future();}
2193
2194 // execution
2195 void operator()(_ArgTypes... __args);
2196 void make_ready_at_thread_exit(_ArgTypes... __args);
2197
2198 void reset();
2199};
2200
2201template<class ..._ArgTypes>
2202void
2203packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2204{
2205 if (__p_.__state_ == nullptr)
2206 __throw_future_error(future_errc::no_state);
2207 if (__p_.__state_->__has_value())
2208 __throw_future_error(future_errc::promise_already_satisfied);
2209#ifndef _LIBCPP_NO_EXCEPTIONS
2210 try
2211 {
2212#endif // _LIBCPP_NO_EXCEPTIONS
2213 __f_(_VSTD::forward<_ArgTypes>(__args)...);
2214 __p_.set_value();
2215#ifndef _LIBCPP_NO_EXCEPTIONS
2216 }
2217 catch (...)
2218 {
2219 __p_.set_exception(current_exception());
2220 }
2221#endif // _LIBCPP_NO_EXCEPTIONS
2222}
2223
2224template<class ..._ArgTypes>
2225void
2226packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2227{
2228 if (__p_.__state_ == nullptr)
2229 __throw_future_error(future_errc::no_state);
2230 if (__p_.__state_->__has_value())
2231 __throw_future_error(future_errc::promise_already_satisfied);
2232#ifndef _LIBCPP_NO_EXCEPTIONS
2233 try
2234 {
2235#endif // _LIBCPP_NO_EXCEPTIONS
2236 __f_(_VSTD::forward<_ArgTypes>(__args)...);
2237 __p_.set_value_at_thread_exit();
2238#ifndef _LIBCPP_NO_EXCEPTIONS
2239 }
2240 catch (...)
2241 {
2242 __p_.set_exception_at_thread_exit(current_exception());
2243 }
2244#endif // _LIBCPP_NO_EXCEPTIONS
2245}
2246
2247template<class ..._ArgTypes>
2248void
2249packaged_task<void(_ArgTypes...)>::reset()
2250{
2251 if (!valid())
2252 __throw_future_error(future_errc::no_state);
2253 __p_ = promise<result_type>();
2254}
2255
2256template <class _Callable>
2257inline _LIBCPP_INLINE_VISIBILITY
2258void
2259swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2260{
2261 __x.swap(__y);
2262}
2263
2264template <class _Callable, class _Alloc>
2265struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2266 : public true_type {};
2267
2268template <class _Rp, class _Fp>
2269future<_Rp>
2270#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2271__make_deferred_assoc_state(_Fp&& __f)
2272#else
2273__make_deferred_assoc_state(_Fp __f)
2274#endif
2275{
2276 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2277 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2278 return future<_Rp>(__h.get());
2279}
2280
2281template <class _Rp, class _Fp>
2282future<_Rp>
2283#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2284__make_async_assoc_state(_Fp&& __f)
2285#else
2286__make_async_assoc_state(_Fp __f)
2287#endif
2288{
2289 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2290 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2291 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2292 return future<_Rp>(__h.get());
2293}
2294
2295template <class _Fp, class... _Args>
2296class __async_func
2297{
2298 tuple<_Fp, _Args...> __f_;
2299
2300public:
2301 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2302
2303 _LIBCPP_INLINE_VISIBILITY
2304 explicit __async_func(_Fp&& __f, _Args&&... __args)
2305 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2306
2307 _LIBCPP_INLINE_VISIBILITY
2308 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2309
2310 _Rp operator()()
2311 {
2312 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2313 return __execute(_Index());
2314 }
2315private:
2316 template <size_t ..._Indices>
2317 _Rp
2318 __execute(__tuple_indices<_Indices...>)
2319 {
2320 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2321 }
2322};
2323
2324inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
2325{ return (int(__policy) & int(__value)) != 0; }
2326
2327template <class _Fp, class... _Args>
2328_LIBCPP_NODISCARD_AFTER_CXX17
2329future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2330async(launch __policy, _Fp&& __f, _Args&&... __args)
2331{
2332 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2333 typedef typename _BF::_Rp _Rp;
2334
2335#ifndef _LIBCPP_NO_EXCEPTIONS
2336 try
2337 {
2338#endif
2339 if (__does_policy_contain(__policy, launch::async))
2340 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2341 __decay_copy(_VSTD::forward<_Args>(__args))...));
2342#ifndef _LIBCPP_NO_EXCEPTIONS
2343 }
2344 catch ( ... ) { if (__policy == launch::async) throw ; }
2345#endif
2346
2347 if (__does_policy_contain(__policy, launch::deferred))
2348 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2349 __decay_copy(_VSTD::forward<_Args>(__args))...));
2350 return future<_Rp>{};
2351}
2352
2353template <class _Fp, class... _Args>
2354_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
2355future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2356async(_Fp&& __f, _Args&&... __args)
2357{
2358 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2359 _VSTD::forward<_Args>(__args)...);
2360}
2361
2362#endif // _LIBCPP_HAS_NO_VARIADICS
2363
2364// shared_future
2365
2366template <class _Rp>
2367class _LIBCPP_TEMPLATE_VIS shared_future
2368{
2369 __assoc_state<_Rp>* __state_;
2370
2371public:
2372 _LIBCPP_INLINE_VISIBILITY
2373 shared_future() _NOEXCEPT : __state_(nullptr) {}
2374 _LIBCPP_INLINE_VISIBILITY
2375 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2376 {if (__state_) __state_->__add_shared();}
2377#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2378 _LIBCPP_INLINE_VISIBILITY
2379 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2380 {__f.__state_ = nullptr;}
2381 _LIBCPP_INLINE_VISIBILITY
2382 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2383 {__rhs.__state_ = nullptr;}
2384#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2385 ~shared_future();
2386 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
2387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2388 _LIBCPP_INLINE_VISIBILITY
2389 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2390 {
2391 shared_future(std::move(__rhs)).swap(*this);
2392 return *this;
2393 }
2394#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2395
2396 // retrieving the value
2397 _LIBCPP_INLINE_VISIBILITY
2398 const _Rp& get() const {return __state_->copy();}
2399
2400 _LIBCPP_INLINE_VISIBILITY
2401 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2402
2403 // functions to check state
2404 _LIBCPP_INLINE_VISIBILITY
2405 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2406
2407 _LIBCPP_INLINE_VISIBILITY
2408 void wait() const {__state_->wait();}
2409 template <class _Rep, class _Period>
2410 _LIBCPP_INLINE_VISIBILITY
2411 future_status
2412 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2413 {return __state_->wait_for(__rel_time);}
2414 template <class _Clock, class _Duration>
2415 _LIBCPP_INLINE_VISIBILITY
2416 future_status
2417 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2418 {return __state_->wait_until(__abs_time);}
2419};
2420
2421template <class _Rp>
2422shared_future<_Rp>::~shared_future()
2423{
2424 if (__state_)
2425 __state_->__release_shared();
2426}
2427
2428template <class _Rp>
2429shared_future<_Rp>&
2430shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
2431{
2432 if (__rhs.__state_)
2433 __rhs.__state_->__add_shared();
2434 if (__state_)
2435 __state_->__release_shared();
2436 __state_ = __rhs.__state_;
2437 return *this;
2438}
2439
2440template <class _Rp>
2441class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
2442{
2443 __assoc_state<_Rp&>* __state_;
2444
2445public:
2446 _LIBCPP_INLINE_VISIBILITY
2447 shared_future() _NOEXCEPT : __state_(nullptr) {}
2448 _LIBCPP_INLINE_VISIBILITY
2449 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2450 {if (__state_) __state_->__add_shared();}
2451#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2452 _LIBCPP_INLINE_VISIBILITY
2453 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2454 {__f.__state_ = nullptr;}
2455 _LIBCPP_INLINE_VISIBILITY
2456 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2457 {__rhs.__state_ = nullptr;}
2458#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2459 ~shared_future();
2460 shared_future& operator=(const shared_future& __rhs);
2461#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2462 _LIBCPP_INLINE_VISIBILITY
2463 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2464 {
2465 shared_future(std::move(__rhs)).swap(*this);
2466 return *this;
2467 }
2468#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2469
2470 // retrieving the value
2471 _LIBCPP_INLINE_VISIBILITY
2472 _Rp& get() const {return __state_->copy();}
2473
2474 _LIBCPP_INLINE_VISIBILITY
2475 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2476
2477 // functions to check state
2478 _LIBCPP_INLINE_VISIBILITY
2479 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2480
2481 _LIBCPP_INLINE_VISIBILITY
2482 void wait() const {__state_->wait();}
2483 template <class _Rep, class _Period>
2484 _LIBCPP_INLINE_VISIBILITY
2485 future_status
2486 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2487 {return __state_->wait_for(__rel_time);}
2488 template <class _Clock, class _Duration>
2489 _LIBCPP_INLINE_VISIBILITY
2490 future_status
2491 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2492 {return __state_->wait_until(__abs_time);}
2493};
2494
2495template <class _Rp>
2496shared_future<_Rp&>::~shared_future()
2497{
2498 if (__state_)
2499 __state_->__release_shared();
2500}
2501
2502template <class _Rp>
2503shared_future<_Rp&>&
2504shared_future<_Rp&>::operator=(const shared_future& __rhs)
2505{
2506 if (__rhs.__state_)
2507 __rhs.__state_->__add_shared();
2508 if (__state_)
2509 __state_->__release_shared();
2510 __state_ = __rhs.__state_;
2511 return *this;
2512}
2513
2514template <>
2515class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
2516{
2517 __assoc_sub_state* __state_;
2518
2519public:
2520 _LIBCPP_INLINE_VISIBILITY
2521 shared_future() _NOEXCEPT : __state_(nullptr) {}
2522 _LIBCPP_INLINE_VISIBILITY
2523 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2524 {if (__state_) __state_->__add_shared();}
2525#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2526 _LIBCPP_INLINE_VISIBILITY
2527 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2528 {__f.__state_ = nullptr;}
2529 _LIBCPP_INLINE_VISIBILITY
2530 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2531 {__rhs.__state_ = nullptr;}
2532#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2533 ~shared_future();
2534 shared_future& operator=(const shared_future& __rhs);
2535#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2536 _LIBCPP_INLINE_VISIBILITY
2537 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2538 {
2539 shared_future(std::move(__rhs)).swap(*this);
2540 return *this;
2541 }
2542#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2543
2544 // retrieving the value
2545 _LIBCPP_INLINE_VISIBILITY
2546 void get() const {__state_->copy();}
2547
2548 _LIBCPP_INLINE_VISIBILITY
2549 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2550
2551 // functions to check state
2552 _LIBCPP_INLINE_VISIBILITY
2553 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2554
2555 _LIBCPP_INLINE_VISIBILITY
2556 void wait() const {__state_->wait();}
2557 template <class _Rep, class _Period>
2558 _LIBCPP_INLINE_VISIBILITY
2559 future_status
2560 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2561 {return __state_->wait_for(__rel_time);}
2562 template <class _Clock, class _Duration>
2563 _LIBCPP_INLINE_VISIBILITY
2564 future_status
2565 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2566 {return __state_->wait_until(__abs_time);}
2567};
2568
2569template <class _Rp>
2570inline _LIBCPP_INLINE_VISIBILITY
2571void
2572swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2573{
2574 __x.swap(__y);
2575}
2576
2577template <class _Rp>
2578inline
2579shared_future<_Rp>
2580future<_Rp>::share() _NOEXCEPT
2581{
2582 return shared_future<_Rp>(_VSTD::move(*this));
2583}
2584
2585template <class _Rp>
2586inline
2587shared_future<_Rp&>
2588future<_Rp&>::share() _NOEXCEPT
2589{
2590 return shared_future<_Rp&>(_VSTD::move(*this));
2591}
2592
2593#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2594
2595inline
2596shared_future<void>
2597future<void>::share() _NOEXCEPT
2598{
2599 return shared_future<void>(_VSTD::move(*this));
2600}
2601
2602#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2603
2604_LIBCPP_END_NAMESPACE_STD
2605
2606#endif // !_LIBCPP_HAS_NO_THREADS
2607
2608#endif // _LIBCPP_FUTURE
2609