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