xref: /freebsd/contrib/llvm-project/libcxx/include/future (revision 6966ac055c3b7a39266fb982493330df7a097997)
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