future revision 246487
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===--------------------------- future -----------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_FUTURE
12227825Stheraven#define _LIBCPP_FUTURE
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    future synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheravenenum class future_errc
21227825Stheraven{
22227825Stheraven    broken_promise,
23227825Stheraven    future_already_retrieved,
24227825Stheraven    promise_already_satisfied,
25227825Stheraven    no_state
26227825Stheraven};
27227825Stheraven
28227825Stheravenenum class launch
29227825Stheraven{
30227825Stheraven    async = 1,
31227825Stheraven    deferred = 2,
32227825Stheraven    any = async | deferred
33227825Stheraven};
34227825Stheraven
35227825Stheravenenum class future_status
36227825Stheraven{
37227825Stheraven    ready,
38227825Stheraven    timeout,
39227825Stheraven    deferred
40227825Stheraven};
41227825Stheraven
42227825Stheraventemplate <> struct is_error_code_enum<future_errc> : public true_type { };
43241903Sdimerror_code make_error_code(future_errc e) noexcept;
44241903Sdimerror_condition make_error_condition(future_errc e) noexcept;
45227825Stheraven
46241903Sdimconst error_category& future_category() noexcept;
47227825Stheraven
48227825Stheravenclass future_error
49227825Stheraven    : public logic_error
50227825Stheraven{
51227825Stheravenpublic:
52227825Stheraven    future_error(error_code ec);  // exposition only
53227825Stheraven
54241903Sdim    const error_code& code() const noexcept;
55241903Sdim    const char*       what() const noexcept;
56227825Stheraven};
57227825Stheraven
58227825Stheraventemplate <class R>
59227825Stheravenclass promise
60227825Stheraven{
61227825Stheravenpublic:
62227825Stheraven    promise();
63227825Stheraven    template <class Allocator>
64227825Stheraven        promise(allocator_arg_t, const Allocator& a);
65241903Sdim    promise(promise&& rhs) noexcept;
66227825Stheraven    promise(const promise& rhs) = delete;
67227825Stheraven    ~promise();
68227825Stheraven
69227825Stheraven    // assignment
70241903Sdim    promise& operator=(promise&& rhs) noexcept;
71227825Stheraven    promise& operator=(const promise& rhs) = delete;
72241903Sdim    void swap(promise& other) noexcept;
73227825Stheraven
74227825Stheraven    // retrieving the result
75227825Stheraven    future<R> get_future();
76227825Stheraven
77227825Stheraven    // setting the result
78227825Stheraven    void set_value(const R& r);
79227825Stheraven    void set_value(R&& r);
80227825Stheraven    void set_exception(exception_ptr p);
81227825Stheraven
82227825Stheraven    // setting the result with deferred notification
83227825Stheraven    void set_value_at_thread_exit(const R& r);
84227825Stheraven    void set_value_at_thread_exit(R&& r);
85227825Stheraven    void set_exception_at_thread_exit(exception_ptr p);
86227825Stheraven};
87227825Stheraven
88227825Stheraventemplate <class R>
89227825Stheravenclass promise<R&>
90227825Stheraven{
91227825Stheravenpublic:
92227825Stheraven    promise();
93227825Stheraven    template <class Allocator>
94227825Stheraven        promise(allocator_arg_t, const Allocator& a);
95241903Sdim    promise(promise&& rhs) noexcept;
96227825Stheraven    promise(const promise& rhs) = delete;
97227825Stheraven    ~promise();
98227825Stheraven
99227825Stheraven    // assignment
100241903Sdim    promise& operator=(promise&& rhs) noexcept;
101227825Stheraven    promise& operator=(const promise& rhs) = delete;
102241903Sdim    void swap(promise& other) noexcept;
103227825Stheraven
104227825Stheraven    // retrieving the result
105227825Stheraven    future<R&> get_future();
106227825Stheraven
107227825Stheraven    // setting the result
108227825Stheraven    void set_value(R& r);
109227825Stheraven    void set_exception(exception_ptr p);
110227825Stheraven
111227825Stheraven    // setting the result with deferred notification
112227825Stheraven    void set_value_at_thread_exit(R&);
113227825Stheraven    void set_exception_at_thread_exit(exception_ptr p);
114227825Stheraven};
115227825Stheraven
116227825Stheraventemplate <>
117227825Stheravenclass promise<void>
118227825Stheraven{
119227825Stheravenpublic:
120227825Stheraven    promise();
121227825Stheraven    template <class Allocator>
122227825Stheraven        promise(allocator_arg_t, const Allocator& a);
123241903Sdim    promise(promise&& rhs) noexcept;
124227825Stheraven    promise(const promise& rhs) = delete;
125227825Stheraven    ~promise();
126227825Stheraven
127227825Stheraven    // assignment
128241903Sdim    promise& operator=(promise&& rhs) noexcept;
129227825Stheraven    promise& operator=(const promise& rhs) = delete;
130241903Sdim    void swap(promise& other) noexcept;
131227825Stheraven
132227825Stheraven    // retrieving the result
133227825Stheraven    future<void> get_future();
134227825Stheraven
135227825Stheraven    // setting the result
136227825Stheraven    void set_value();
137227825Stheraven    void set_exception(exception_ptr p);
138227825Stheraven
139227825Stheraven    // setting the result with deferred notification
140227825Stheraven    void set_value_at_thread_exit();
141227825Stheraven    void set_exception_at_thread_exit(exception_ptr p);
142227825Stheraven};
143227825Stheraven
144241903Sdimtemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
145227825Stheraven
146227825Stheraventemplate <class R, class Alloc>
147227825Stheraven    struct uses_allocator<promise<R>, Alloc> : public true_type {};
148227825Stheraven
149227825Stheraventemplate <class R>
150227825Stheravenclass future
151227825Stheraven{
152227825Stheravenpublic:
153241903Sdim    future() noexcept;
154241903Sdim    future(future&&) noexcept;
155227825Stheraven    future(const future& rhs) = delete;
156227825Stheraven    ~future();
157227825Stheraven    future& operator=(const future& rhs) = delete;
158241903Sdim    future& operator=(future&&) noexcept;
159241903Sdim    shared_future<R> share();
160227825Stheraven
161227825Stheraven    // retrieving the value
162227825Stheraven    R get();
163227825Stheraven
164227825Stheraven    // functions to check state
165241903Sdim    bool valid() const noexcept;
166227825Stheraven
167227825Stheraven    void wait() const;
168227825Stheraven    template <class Rep, class Period>
169227825Stheraven        future_status
170227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171227825Stheraven    template <class Clock, class Duration>
172227825Stheraven        future_status
173227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174227825Stheraven};
175227825Stheraven
176227825Stheraventemplate <class R>
177227825Stheravenclass future<R&>
178227825Stheraven{
179227825Stheravenpublic:
180241903Sdim    future() noexcept;
181241903Sdim    future(future&&) noexcept;
182227825Stheraven    future(const future& rhs) = delete;
183227825Stheraven    ~future();
184227825Stheraven    future& operator=(const future& rhs) = delete;
185241903Sdim    future& operator=(future&&) noexcept;
186241903Sdim    shared_future<R&> share();
187227825Stheraven
188227825Stheraven    // retrieving the value
189227825Stheraven    R& get();
190227825Stheraven
191227825Stheraven    // functions to check state
192241903Sdim    bool valid() const noexcept;
193227825Stheraven
194227825Stheraven    void wait() const;
195227825Stheraven    template <class Rep, class Period>
196227825Stheraven        future_status
197227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198227825Stheraven    template <class Clock, class Duration>
199227825Stheraven        future_status
200227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201227825Stheraven};
202227825Stheraven
203227825Stheraventemplate <>
204227825Stheravenclass future<void>
205227825Stheraven{
206227825Stheravenpublic:
207241903Sdim    future() noexcept;
208241903Sdim    future(future&&) noexcept;
209227825Stheraven    future(const future& rhs) = delete;
210227825Stheraven    ~future();
211227825Stheraven    future& operator=(const future& rhs) = delete;
212241903Sdim    future& operator=(future&&) noexcept;
213241903Sdim    shared_future<void> share();
214227825Stheraven
215227825Stheraven    // retrieving the value
216227825Stheraven    void get();
217227825Stheraven
218227825Stheraven    // functions to check state
219241903Sdim    bool valid() const noexcept;
220227825Stheraven
221227825Stheraven    void wait() const;
222227825Stheraven    template <class Rep, class Period>
223227825Stheraven        future_status
224227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225227825Stheraven    template <class Clock, class Duration>
226227825Stheraven        future_status
227227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228227825Stheraven};
229227825Stheraven
230227825Stheraventemplate <class R>
231227825Stheravenclass shared_future
232227825Stheraven{
233227825Stheravenpublic:
234241903Sdim    shared_future() noexcept;
235227825Stheraven    shared_future(const shared_future& rhs);
236241903Sdim    shared_future(future<R>&&) noexcept;
237241903Sdim    shared_future(shared_future&& rhs) noexcept;
238227825Stheraven    ~shared_future();
239227825Stheraven    shared_future& operator=(const shared_future& rhs);
240241903Sdim    shared_future& operator=(shared_future&& rhs) noexcept;
241227825Stheraven
242227825Stheraven    // retrieving the value
243227825Stheraven    const R& get() const;
244227825Stheraven
245227825Stheraven    // functions to check state
246241903Sdim    bool valid() const noexcept;
247227825Stheraven
248227825Stheraven    void wait() const;
249227825Stheraven    template <class Rep, class Period>
250227825Stheraven        future_status
251227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252227825Stheraven    template <class Clock, class Duration>
253227825Stheraven        future_status
254227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255227825Stheraven};
256227825Stheraven
257227825Stheraventemplate <class R>
258227825Stheravenclass shared_future<R&>
259227825Stheraven{
260227825Stheravenpublic:
261241903Sdim    shared_future() noexcept;
262227825Stheraven    shared_future(const shared_future& rhs);
263241903Sdim    shared_future(future<R&>&&) noexcept;
264241903Sdim    shared_future(shared_future&& rhs) noexcept;
265227825Stheraven    ~shared_future();
266227825Stheraven    shared_future& operator=(const shared_future& rhs);
267241903Sdim    shared_future& operator=(shared_future&& rhs) noexcept;
268227825Stheraven
269227825Stheraven    // retrieving the value
270227825Stheraven    R& get() const;
271227825Stheraven
272227825Stheraven    // functions to check state
273241903Sdim    bool valid() const noexcept;
274227825Stheraven
275227825Stheraven    void wait() const;
276227825Stheraven    template <class Rep, class Period>
277227825Stheraven        future_status
278227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279227825Stheraven    template <class Clock, class Duration>
280227825Stheraven        future_status
281227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282227825Stheraven};
283227825Stheraven
284227825Stheraventemplate <>
285227825Stheravenclass shared_future<void>
286227825Stheraven{
287227825Stheravenpublic:
288241903Sdim    shared_future() noexcept;
289227825Stheraven    shared_future(const shared_future& rhs);
290241903Sdim    shared_future(future<void>&&) noexcept;
291241903Sdim    shared_future(shared_future&& rhs) noexcept;
292227825Stheraven    ~shared_future();
293227825Stheraven    shared_future& operator=(const shared_future& rhs);
294241903Sdim    shared_future& operator=(shared_future&& rhs) noexcept;
295227825Stheraven
296227825Stheraven    // retrieving the value
297227825Stheraven    void get() const;
298227825Stheraven
299227825Stheraven    // functions to check state
300241903Sdim    bool valid() const noexcept;
301227825Stheraven
302227825Stheraven    void wait() const;
303227825Stheraven    template <class Rep, class Period>
304227825Stheraven        future_status
305227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306227825Stheraven    template <class Clock, class Duration>
307227825Stheraven        future_status
308227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309227825Stheraven};
310227825Stheraven
311227825Stheraventemplate <class F, class... Args>
312227825Stheraven  future<typename result_of<F(Args...)>::type>
313227825Stheraven  async(F&& f, Args&&... args);
314227825Stheraven
315227825Stheraventemplate <class F, class... Args>
316227825Stheraven  future<typename result_of<F(Args...)>::type>
317227825Stheraven  async(launch policy, F&& f, Args&&... args);
318227825Stheraven
319227825Stheraventemplate <class> class packaged_task; // undefined
320227825Stheraven
321227825Stheraventemplate <class R, class... ArgTypes>
322227825Stheravenclass packaged_task<R(ArgTypes...)>
323227825Stheraven{
324227825Stheravenpublic:
325227825Stheraven    typedef R result_type;
326227825Stheraven
327227825Stheraven    // construction and destruction
328241903Sdim    packaged_task() noexcept;
329227825Stheraven    template <class F>
330227825Stheraven        explicit packaged_task(F&& f);
331227825Stheraven    template <class F, class Allocator>
332227825Stheraven        explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333227825Stheraven    ~packaged_task();
334227825Stheraven
335227825Stheraven    // no copy
336241903Sdim    packaged_task(const packaged_task&) = delete;
337241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
338227825Stheraven
339227825Stheraven    // move support
340241903Sdim    packaged_task(packaged_task&& other) noexcept;
341241903Sdim    packaged_task& operator=(packaged_task&& other) noexcept;
342241903Sdim    void swap(packaged_task& other) noexcept;
343227825Stheraven
344241903Sdim    bool valid() const noexcept;
345227825Stheraven
346227825Stheraven    // result retrieval
347227825Stheraven    future<R> get_future();
348227825Stheraven
349227825Stheraven    // execution
350227825Stheraven    void operator()(ArgTypes... );
351227825Stheraven    void make_ready_at_thread_exit(ArgTypes...);
352227825Stheraven
353227825Stheraven    void reset();
354227825Stheraven};
355227825Stheraven
356227825Stheraventemplate <class R>
357241903Sdim  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
358227825Stheraven
359227825Stheraventemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360227825Stheraven
361227825Stheraven}  // std
362227825Stheraven
363227825Stheraven*/
364227825Stheraven
365227825Stheraven#include <__config>
366227825Stheraven#include <system_error>
367227825Stheraven#include <memory>
368227825Stheraven#include <chrono>
369227825Stheraven#include <exception>
370227825Stheraven#include <mutex>
371227825Stheraven#include <thread>
372227825Stheraven
373227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
374227825Stheraven#pragma GCC system_header
375227825Stheraven#endif
376227825Stheraven
377227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
378227825Stheraven
379227825Stheraven//enum class future_errc
380232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
381227825Stheraven{
382227825Stheraven    broken_promise,
383227825Stheraven    future_already_retrieved,
384227825Stheraven    promise_already_satisfied,
385227825Stheraven    no_state
386227825Stheraven};
387232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
388227825Stheraven
389227825Stheraventemplate <>
390227825Stheravenstruct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
391227825Stheraven
392232950Stheraven#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
393232950Stheraventemplate <>
394242945Stheravenstruct _LIBCPP_VISIBLE is_error_code_enum<future_errc::__lx> : public true_type { };
395232950Stheraven#endif
396232950Stheraven
397227825Stheraven//enum class launch
398232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(launch)
399227825Stheraven{
400227825Stheraven    async = 1,
401227825Stheraven    deferred = 2,
402227825Stheraven    any = async | deferred
403227825Stheraven};
404232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
405227825Stheraven
406227825Stheraven//enum class future_status
407232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_status)
408227825Stheraven{
409227825Stheraven    ready,
410227825Stheraven    timeout,
411227825Stheraven    deferred
412227825Stheraven};
413232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
414227825Stheraven
415227825Stheraven_LIBCPP_VISIBLE
416241903Sdimconst error_category& future_category() _NOEXCEPT;
417227825Stheraven
418227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
419227825Stheravenerror_code
420241903Sdimmake_error_code(future_errc __e) _NOEXCEPT
421227825Stheraven{
422227825Stheraven    return error_code(static_cast<int>(__e), future_category());
423227825Stheraven}
424227825Stheraven
425227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
426227825Stheravenerror_condition
427241903Sdimmake_error_condition(future_errc __e) _NOEXCEPT
428227825Stheraven{
429227825Stheraven    return error_condition(static_cast<int>(__e), future_category());
430227825Stheraven}
431227825Stheraven
432227825Stheravenclass _LIBCPP_EXCEPTION_ABI future_error
433227825Stheraven    : public logic_error
434227825Stheraven{
435227825Stheraven    error_code __ec_;
436227825Stheravenpublic:
437227825Stheraven    future_error(error_code __ec);
438227825Stheraven
439227825Stheraven    _LIBCPP_INLINE_VISIBILITY
440241903Sdim    const error_code& code() const _NOEXCEPT {return __ec_;}
441227825Stheraven
442227825Stheraven    virtual ~future_error() _NOEXCEPT;
443227825Stheraven};
444227825Stheraven
445227825Stheravenclass __assoc_sub_state
446227825Stheraven    : public __shared_count
447227825Stheraven{
448227825Stheravenprotected:
449227825Stheraven    exception_ptr __exception_;
450227825Stheraven    mutable mutex __mut_;
451227825Stheraven    mutable condition_variable __cv_;
452227825Stheraven    unsigned __state_;
453227825Stheraven
454227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
455227825Stheraven    void __sub_wait(unique_lock<mutex>& __lk);
456227825Stheravenpublic:
457227825Stheraven    enum
458227825Stheraven    {
459227825Stheraven        __constructed = 1,
460227825Stheraven        __future_attached = 2,
461227825Stheraven        ready = 4,
462227825Stheraven        deferred = 8
463227825Stheraven    };
464227825Stheraven
465227825Stheraven    _LIBCPP_INLINE_VISIBILITY
466227825Stheraven    __assoc_sub_state() : __state_(0) {}
467227825Stheraven
468227825Stheraven    _LIBCPP_INLINE_VISIBILITY
469227825Stheraven    bool __has_value() const
470227825Stheraven        {return (__state_ & __constructed) || (__exception_ != nullptr);}
471227825Stheraven
472227825Stheraven    _LIBCPP_INLINE_VISIBILITY
473246487Stheraven    void __set_future_attached()
474246487Stheraven    {
475246487Stheraven        lock_guard<mutex> __lk(__mut_);
476246487Stheraven        __state_ |= __future_attached;
477246487Stheraven    }
478227825Stheraven    _LIBCPP_INLINE_VISIBILITY
479227825Stheraven    bool __has_future_attached() const {return __state_ & __future_attached;}
480227825Stheraven
481227825Stheraven    _LIBCPP_INLINE_VISIBILITY
482227825Stheraven    void __set_deferred() {__state_ |= deferred;}
483227825Stheraven
484227825Stheraven    void __make_ready();
485227825Stheraven    _LIBCPP_INLINE_VISIBILITY
486227825Stheraven    bool __is_ready() const {return __state_ & ready;}
487227825Stheraven
488227825Stheraven    void set_value();
489227825Stheraven    void set_value_at_thread_exit();
490227825Stheraven
491227825Stheraven    void set_exception(exception_ptr __p);
492227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
493227825Stheraven
494227825Stheraven    void copy();
495227825Stheraven
496227825Stheraven    void wait();
497227825Stheraven    template <class _Rep, class _Period>
498227825Stheraven        future_status
499227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
500227825Stheraven    template <class _Clock, class _Duration>
501227825Stheraven        future_status
502227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
503227825Stheraven
504227825Stheraven    virtual void __execute();
505227825Stheraven};
506227825Stheraven
507227825Stheraventemplate <class _Clock, class _Duration>
508227825Stheravenfuture_status
509227825Stheraven__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
510227825Stheraven{
511227825Stheraven    unique_lock<mutex> __lk(__mut_);
512227825Stheraven    if (__state_ & deferred)
513227825Stheraven        return future_status::deferred;
514227825Stheraven    while (!(__state_ & ready) && _Clock::now() < __abs_time)
515227825Stheraven        __cv_.wait_until(__lk, __abs_time);
516227825Stheraven    if (__state_ & ready)
517227825Stheraven        return future_status::ready;
518227825Stheraven    return future_status::timeout;
519227825Stheraven}
520227825Stheraven
521227825Stheraventemplate <class _Rep, class _Period>
522227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
523227825Stheravenfuture_status
524227825Stheraven__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
525227825Stheraven{
526227825Stheraven    return wait_until(chrono::steady_clock::now() + __rel_time);
527227825Stheraven}
528227825Stheraven
529232950Stheraventemplate <class _Rp>
530227825Stheravenclass __assoc_state
531227825Stheraven    : public __assoc_sub_state
532227825Stheraven{
533227825Stheraven    typedef __assoc_sub_state base;
534232950Stheraven    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
535227825Stheravenprotected:
536232950Stheraven    _Up __value_;
537227825Stheraven
538227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
539227825Stheravenpublic:
540227825Stheraven
541227825Stheraven    template <class _Arg>
542227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
543227825Stheraven        void set_value(_Arg&& __arg);
544227825Stheraven#else
545227825Stheraven        void set_value(_Arg& __arg);
546227825Stheraven#endif
547227825Stheraven
548227825Stheraven    template <class _Arg>
549227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
550227825Stheraven        void set_value_at_thread_exit(_Arg&& __arg);
551227825Stheraven#else
552227825Stheraven        void set_value_at_thread_exit(_Arg& __arg);
553227825Stheraven#endif
554227825Stheraven
555232950Stheraven    _Rp move();
556232950Stheraven    typename add_lvalue_reference<_Rp>::type copy();
557227825Stheraven};
558227825Stheraven
559232950Stheraventemplate <class _Rp>
560227825Stheravenvoid
561232950Stheraven__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
562227825Stheraven{
563227825Stheraven    if (this->__state_ & base::__constructed)
564232950Stheraven        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
565227825Stheraven    delete this;
566227825Stheraven}
567227825Stheraven
568232950Stheraventemplate <class _Rp>
569227825Stheraventemplate <class _Arg>
570227825Stheravenvoid
571227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
572232950Stheraven__assoc_state<_Rp>::set_value(_Arg&& __arg)
573227825Stheraven#else
574232950Stheraven__assoc_state<_Rp>::set_value(_Arg& __arg)
575227825Stheraven#endif
576227825Stheraven{
577227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
578227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
579227825Stheraven    if (this->__has_value())
580227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
581227825Stheraven#endif
582232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
583227825Stheraven    this->__state_ |= base::__constructed | base::ready;
584227825Stheraven    __lk.unlock();
585227825Stheraven    __cv_.notify_all();
586227825Stheraven}
587227825Stheraven
588232950Stheraventemplate <class _Rp>
589227825Stheraventemplate <class _Arg>
590227825Stheravenvoid
591227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
592232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
593227825Stheraven#else
594232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
595227825Stheraven#endif
596227825Stheraven{
597227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
598227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
599227825Stheraven    if (this->__has_value())
600227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
601227825Stheraven#endif
602232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
603227825Stheraven    this->__state_ |= base::__constructed;
604227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
605227825Stheraven    __lk.unlock();
606227825Stheraven}
607227825Stheraven
608232950Stheraventemplate <class _Rp>
609232950Stheraven_Rp
610232950Stheraven__assoc_state<_Rp>::move()
611227825Stheraven{
612227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
613227825Stheraven    this->__sub_wait(__lk);
614227825Stheraven    if (this->__exception_ != nullptr)
615227825Stheraven        rethrow_exception(this->__exception_);
616232950Stheraven    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
617227825Stheraven}
618227825Stheraven
619232950Stheraventemplate <class _Rp>
620232950Stheraventypename add_lvalue_reference<_Rp>::type
621232950Stheraven__assoc_state<_Rp>::copy()
622227825Stheraven{
623227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
624227825Stheraven    this->__sub_wait(__lk);
625227825Stheraven    if (this->__exception_ != nullptr)
626227825Stheraven        rethrow_exception(this->__exception_);
627232950Stheraven    return *reinterpret_cast<_Rp*>(&__value_);
628227825Stheraven}
629227825Stheraven
630232950Stheraventemplate <class _Rp>
631232950Stheravenclass __assoc_state<_Rp&>
632227825Stheraven    : public __assoc_sub_state
633227825Stheraven{
634227825Stheraven    typedef __assoc_sub_state base;
635232950Stheraven    typedef _Rp* _Up;
636227825Stheravenprotected:
637232950Stheraven    _Up __value_;
638227825Stheraven
639227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
640227825Stheravenpublic:
641227825Stheraven
642232950Stheraven    void set_value(_Rp& __arg);
643232950Stheraven    void set_value_at_thread_exit(_Rp& __arg);
644227825Stheraven
645232950Stheraven    _Rp& copy();
646227825Stheraven};
647227825Stheraven
648232950Stheraventemplate <class _Rp>
649227825Stheravenvoid
650232950Stheraven__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
651227825Stheraven{
652227825Stheraven    delete this;
653227825Stheraven}
654227825Stheraven
655232950Stheraventemplate <class _Rp>
656227825Stheravenvoid
657232950Stheraven__assoc_state<_Rp&>::set_value(_Rp& __arg)
658227825Stheraven{
659227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
660227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
661227825Stheraven    if (this->__has_value())
662227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
663227825Stheraven#endif
664227825Stheraven    __value_ = &__arg;
665227825Stheraven    this->__state_ |= base::__constructed | base::ready;
666227825Stheraven    __lk.unlock();
667227825Stheraven    __cv_.notify_all();
668227825Stheraven}
669227825Stheraven
670232950Stheraventemplate <class _Rp>
671227825Stheravenvoid
672232950Stheraven__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
673227825Stheraven{
674227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
675227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
676227825Stheraven    if (this->__has_value())
677227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
678227825Stheraven#endif
679227825Stheraven    __value_ = &__arg;
680227825Stheraven    this->__state_ |= base::__constructed;
681227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
682227825Stheraven    __lk.unlock();
683227825Stheraven}
684227825Stheraven
685232950Stheraventemplate <class _Rp>
686232950Stheraven_Rp&
687232950Stheraven__assoc_state<_Rp&>::copy()
688227825Stheraven{
689227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
690227825Stheraven    this->__sub_wait(__lk);
691227825Stheraven    if (this->__exception_ != nullptr)
692227825Stheraven        rethrow_exception(this->__exception_);
693227825Stheraven    return *__value_;
694227825Stheraven}
695227825Stheraven
696232950Stheraventemplate <class _Rp, class _Alloc>
697227825Stheravenclass __assoc_state_alloc
698232950Stheraven    : public __assoc_state<_Rp>
699227825Stheraven{
700232950Stheraven    typedef __assoc_state<_Rp> base;
701227825Stheraven    _Alloc __alloc_;
702227825Stheraven
703227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
704227825Stheravenpublic:
705227825Stheraven    _LIBCPP_INLINE_VISIBILITY
706227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
707227825Stheraven        : __alloc_(__a) {}
708227825Stheraven};
709227825Stheraven
710232950Stheraventemplate <class _Rp, class _Alloc>
711227825Stheravenvoid
712232950Stheraven__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
713227825Stheraven{
714227825Stheraven    if (this->__state_ & base::__constructed)
715232950Stheraven        reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
716227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
717227825Stheraven    this->~__assoc_state_alloc();
718227825Stheraven    __a.deallocate(this, 1);
719227825Stheraven}
720227825Stheraven
721232950Stheraventemplate <class _Rp, class _Alloc>
722232950Stheravenclass __assoc_state_alloc<_Rp&, _Alloc>
723232950Stheraven    : public __assoc_state<_Rp&>
724227825Stheraven{
725232950Stheraven    typedef __assoc_state<_Rp&> base;
726227825Stheraven    _Alloc __alloc_;
727227825Stheraven
728227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
729227825Stheravenpublic:
730227825Stheraven    _LIBCPP_INLINE_VISIBILITY
731227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
732227825Stheraven        : __alloc_(__a) {}
733227825Stheraven};
734227825Stheraven
735232950Stheraventemplate <class _Rp, class _Alloc>
736227825Stheravenvoid
737232950Stheraven__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
738227825Stheraven{
739227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
740227825Stheraven    this->~__assoc_state_alloc();
741227825Stheraven    __a.deallocate(this, 1);
742227825Stheraven}
743227825Stheraven
744227825Stheraventemplate <class _Alloc>
745227825Stheravenclass __assoc_sub_state_alloc
746227825Stheraven    : public __assoc_sub_state
747227825Stheraven{
748227825Stheraven    typedef __assoc_sub_state base;
749227825Stheraven    _Alloc __alloc_;
750227825Stheraven
751227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
752227825Stheravenpublic:
753227825Stheraven    _LIBCPP_INLINE_VISIBILITY
754227825Stheraven    explicit __assoc_sub_state_alloc(const _Alloc& __a)
755227825Stheraven        : __alloc_(__a) {}
756227825Stheraven};
757227825Stheraven
758227825Stheraventemplate <class _Alloc>
759227825Stheravenvoid
760227825Stheraven__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
761227825Stheraven{
762227825Stheraven    typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
763227825Stheraven    this->~__assoc_sub_state_alloc();
764227825Stheraven    __a.deallocate(this, 1);
765227825Stheraven}
766227825Stheraven
767232950Stheraventemplate <class _Rp, class _Fp>
768227825Stheravenclass __deferred_assoc_state
769232950Stheraven    : public __assoc_state<_Rp>
770227825Stheraven{
771232950Stheraven    typedef __assoc_state<_Rp> base;
772227825Stheraven
773232950Stheraven    _Fp __func_;
774227825Stheraven
775227825Stheravenpublic:
776227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
777232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
778227825Stheraven#endif
779227825Stheraven
780227825Stheraven    virtual void __execute();
781227825Stheraven};
782227825Stheraven
783227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
784227825Stheraven
785232950Stheraventemplate <class _Rp, class _Fp>
786227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
787232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
788232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
789227825Stheraven{
790227825Stheraven    this->__set_deferred();
791227825Stheraven}
792227825Stheraven
793227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
794227825Stheraven
795232950Stheraventemplate <class _Rp, class _Fp>
796227825Stheravenvoid
797232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__execute()
798227825Stheraven{
799227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
800227825Stheraven    try
801227825Stheraven    {
802227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
803227825Stheraven        this->set_value(__func_());
804227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
805227825Stheraven    }
806227825Stheraven    catch (...)
807227825Stheraven    {
808227825Stheraven        this->set_exception(current_exception());
809227825Stheraven    }
810227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
811227825Stheraven}
812227825Stheraven
813232950Stheraventemplate <class _Fp>
814232950Stheravenclass __deferred_assoc_state<void, _Fp>
815227825Stheraven    : public __assoc_sub_state
816227825Stheraven{
817227825Stheraven    typedef __assoc_sub_state base;
818227825Stheraven
819232950Stheraven    _Fp __func_;
820227825Stheraven
821227825Stheravenpublic:
822227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
823232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
824227825Stheraven#endif
825227825Stheraven
826227825Stheraven    virtual void __execute();
827227825Stheraven};
828227825Stheraven
829227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
830227825Stheraven
831232950Stheraventemplate <class _Fp>
832227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
833232950Stheraven__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
834232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
835227825Stheraven{
836227825Stheraven    this->__set_deferred();
837227825Stheraven}
838227825Stheraven
839227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
840227825Stheraven
841232950Stheraventemplate <class _Fp>
842227825Stheravenvoid
843232950Stheraven__deferred_assoc_state<void, _Fp>::__execute()
844227825Stheraven{
845227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
846227825Stheraven    try
847227825Stheraven    {
848227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
849227825Stheraven        __func_();
850227825Stheraven        this->set_value();
851227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
852227825Stheraven    }
853227825Stheraven    catch (...)
854227825Stheraven    {
855227825Stheraven        this->set_exception(current_exception());
856227825Stheraven    }
857227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
858227825Stheraven}
859227825Stheraven
860232950Stheraventemplate <class _Rp, class _Fp>
861227825Stheravenclass __async_assoc_state
862232950Stheraven    : public __assoc_state<_Rp>
863227825Stheraven{
864232950Stheraven    typedef __assoc_state<_Rp> base;
865227825Stheraven
866232950Stheraven    _Fp __func_;
867227825Stheraven
868227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
869227825Stheravenpublic:
870227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
871232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
872227825Stheraven#endif
873227825Stheraven
874227825Stheraven    virtual void __execute();
875227825Stheraven};
876227825Stheraven
877227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
878227825Stheraven
879232950Stheraventemplate <class _Rp, class _Fp>
880227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
881232950Stheraven__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
882232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
883227825Stheraven{
884227825Stheraven}
885227825Stheraven
886227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
887227825Stheraven
888232950Stheraventemplate <class _Rp, class _Fp>
889227825Stheravenvoid
890232950Stheraven__async_assoc_state<_Rp, _Fp>::__execute()
891227825Stheraven{
892227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
893227825Stheraven    try
894227825Stheraven    {
895227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
896227825Stheraven        this->set_value(__func_());
897227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
898227825Stheraven    }
899227825Stheraven    catch (...)
900227825Stheraven    {
901227825Stheraven        this->set_exception(current_exception());
902227825Stheraven    }
903227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
904227825Stheraven}
905227825Stheraven
906232950Stheraventemplate <class _Rp, class _Fp>
907227825Stheravenvoid
908232950Stheraven__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
909227825Stheraven{
910227825Stheraven    this->wait();
911227825Stheraven    base::__on_zero_shared();
912227825Stheraven}
913227825Stheraven
914232950Stheraventemplate <class _Fp>
915232950Stheravenclass __async_assoc_state<void, _Fp>
916227825Stheraven    : public __assoc_sub_state
917227825Stheraven{
918227825Stheraven    typedef __assoc_sub_state base;
919227825Stheraven
920232950Stheraven    _Fp __func_;
921227825Stheraven
922227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
923227825Stheravenpublic:
924227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
925232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
926227825Stheraven#endif
927227825Stheraven
928227825Stheraven    virtual void __execute();
929227825Stheraven};
930227825Stheraven
931227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
932227825Stheraven
933232950Stheraventemplate <class _Fp>
934227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
935232950Stheraven__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
936232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
937227825Stheraven{
938227825Stheraven}
939227825Stheraven
940227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
941227825Stheraven
942232950Stheraventemplate <class _Fp>
943227825Stheravenvoid
944232950Stheraven__async_assoc_state<void, _Fp>::__execute()
945227825Stheraven{
946227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
947227825Stheraven    try
948227825Stheraven    {
949227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
950227825Stheraven        __func_();
951227825Stheraven        this->set_value();
952227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
953227825Stheraven    }
954227825Stheraven    catch (...)
955227825Stheraven    {
956227825Stheraven        this->set_exception(current_exception());
957227825Stheraven    }
958227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
959227825Stheraven}
960227825Stheraven
961232950Stheraventemplate <class _Fp>
962227825Stheravenvoid
963232950Stheraven__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
964227825Stheraven{
965227825Stheraven    this->wait();
966227825Stheraven    base::__on_zero_shared();
967227825Stheraven}
968227825Stheraven
969241903Sdimtemplate <class _Rp> class _LIBCPP_VISIBLE promise;
970241903Sdimtemplate <class _Rp> class _LIBCPP_VISIBLE shared_future;
971227825Stheraven
972227825Stheraven// future
973227825Stheraven
974241903Sdimtemplate <class _Rp> class _LIBCPP_VISIBLE future;
975227825Stheraven
976232950Stheraventemplate <class _Rp, class _Fp>
977232950Stheravenfuture<_Rp>
978227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
979232950Stheraven__make_deferred_assoc_state(_Fp&& __f);
980227825Stheraven#else
981232950Stheraven__make_deferred_assoc_state(_Fp __f);
982227825Stheraven#endif
983227825Stheraven
984232950Stheraventemplate <class _Rp, class _Fp>
985232950Stheravenfuture<_Rp>
986227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
987232950Stheraven__make_async_assoc_state(_Fp&& __f);
988227825Stheraven#else
989232950Stheraven__make_async_assoc_state(_Fp __f);
990227825Stheraven#endif
991227825Stheraven
992232950Stheraventemplate <class _Rp>
993227825Stheravenclass _LIBCPP_VISIBLE future
994227825Stheraven{
995232950Stheraven    __assoc_state<_Rp>* __state_;
996227825Stheraven
997232950Stheraven    explicit future(__assoc_state<_Rp>* __state);
998227825Stheraven
999227825Stheraven    template <class> friend class promise;
1000227825Stheraven    template <class> friend class shared_future;
1001227825Stheraven
1002227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1003232950Stheraven    template <class _R1, class _Fp>
1004232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1005232950Stheraven    template <class _R1, class _Fp>
1006232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1007227825Stheraven#else
1008232950Stheraven    template <class _R1, class _Fp>
1009232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1010232950Stheraven    template <class _R1, class _Fp>
1011232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1012227825Stheraven#endif
1013227825Stheraven
1014227825Stheravenpublic:
1015227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1016241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1017227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1019241903Sdim    future(future&& __rhs) _NOEXCEPT
1020227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1021227825Stheraven    future(const future&) = delete;
1022227825Stheraven    future& operator=(const future&) = delete;
1023227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1024241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1025227825Stheraven        {
1026227825Stheraven            future(std::move(__rhs)).swap(*this);
1027227825Stheraven            return *this;
1028227825Stheraven        }
1029227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1030227825Stheravenprivate:
1031227825Stheraven    future(const future&);
1032227825Stheraven    future& operator=(const future&);
1033227825Stheravenpublic:
1034227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1035227825Stheraven    ~future();
1036232950Stheraven    shared_future<_Rp> share();
1037227825Stheraven
1038227825Stheraven    // retrieving the value
1039232950Stheraven    _Rp get();
1040227825Stheraven
1041227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1042241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1043227825Stheraven
1044227825Stheraven    // functions to check state
1045227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1046241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1047227825Stheraven
1048227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1049227825Stheraven    void wait() const {__state_->wait();}
1050227825Stheraven    template <class _Rep, class _Period>
1051227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1052227825Stheraven        future_status
1053227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1054227825Stheraven            {return __state_->wait_for(__rel_time);}
1055227825Stheraven    template <class _Clock, class _Duration>
1056227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1057227825Stheraven        future_status
1058227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1059227825Stheraven            {return __state_->wait_until(__abs_time);}
1060227825Stheraven};
1061227825Stheraven
1062232950Stheraventemplate <class _Rp>
1063232950Stheravenfuture<_Rp>::future(__assoc_state<_Rp>* __state)
1064227825Stheraven    : __state_(__state)
1065227825Stheraven{
1066227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1067227825Stheraven    if (__state_->__has_future_attached())
1068227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1069227825Stheraven#endif
1070227825Stheraven    __state_->__add_shared();
1071227825Stheraven    __state_->__set_future_attached();
1072227825Stheraven}
1073227825Stheraven
1074227825Stheravenstruct __release_shared_count
1075227825Stheraven{
1076227825Stheraven    void operator()(__shared_count* p) {p->__release_shared();}
1077227825Stheraven};
1078227825Stheraven
1079232950Stheraventemplate <class _Rp>
1080232950Stheravenfuture<_Rp>::~future()
1081227825Stheraven{
1082227825Stheraven    if (__state_)
1083227825Stheraven        __state_->__release_shared();
1084227825Stheraven}
1085227825Stheraven
1086232950Stheraventemplate <class _Rp>
1087232950Stheraven_Rp
1088232950Stheravenfuture<_Rp>::get()
1089227825Stheraven{
1090227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1091232950Stheraven    __assoc_state<_Rp>* __s = __state_;
1092227825Stheraven    __state_ = nullptr;
1093227825Stheraven    return __s->move();
1094227825Stheraven}
1095227825Stheraven
1096232950Stheraventemplate <class _Rp>
1097232950Stheravenclass _LIBCPP_VISIBLE future<_Rp&>
1098227825Stheraven{
1099232950Stheraven    __assoc_state<_Rp&>* __state_;
1100227825Stheraven
1101232950Stheraven    explicit future(__assoc_state<_Rp&>* __state);
1102227825Stheraven
1103227825Stheraven    template <class> friend class promise;
1104227825Stheraven    template <class> friend class shared_future;
1105227825Stheraven
1106227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1107232950Stheraven    template <class _R1, class _Fp>
1108232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1109232950Stheraven    template <class _R1, class _Fp>
1110232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1111227825Stheraven#else
1112232950Stheraven    template <class _R1, class _Fp>
1113232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1114232950Stheraven    template <class _R1, class _Fp>
1115232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1116227825Stheraven#endif
1117227825Stheraven
1118227825Stheravenpublic:
1119227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1120241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1121227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1122227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1123241903Sdim    future(future&& __rhs) _NOEXCEPT
1124227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1125227825Stheraven    future(const future&) = delete;
1126227825Stheraven    future& operator=(const future&) = delete;
1127227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1128241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1129227825Stheraven        {
1130227825Stheraven            future(std::move(__rhs)).swap(*this);
1131227825Stheraven            return *this;
1132227825Stheraven        }
1133227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1134227825Stheravenprivate:
1135227825Stheraven    future(const future&);
1136227825Stheraven    future& operator=(const future&);
1137227825Stheravenpublic:
1138227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1139227825Stheraven    ~future();
1140232950Stheraven    shared_future<_Rp&> share();
1141227825Stheraven
1142227825Stheraven    // retrieving the value
1143232950Stheraven    _Rp& get();
1144227825Stheraven
1145227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1146241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1147227825Stheraven
1148227825Stheraven    // functions to check state
1149227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1150241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1151227825Stheraven
1152227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1153227825Stheraven    void wait() const {__state_->wait();}
1154227825Stheraven    template <class _Rep, class _Period>
1155227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1156227825Stheraven        future_status
1157227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1158227825Stheraven            {return __state_->wait_for(__rel_time);}
1159227825Stheraven    template <class _Clock, class _Duration>
1160227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1161227825Stheraven        future_status
1162227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1163227825Stheraven            {return __state_->wait_until(__abs_time);}
1164227825Stheraven};
1165227825Stheraven
1166232950Stheraventemplate <class _Rp>
1167232950Stheravenfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
1168227825Stheraven    : __state_(__state)
1169227825Stheraven{
1170227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1171227825Stheraven    if (__state_->__has_future_attached())
1172227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1173227825Stheraven#endif
1174227825Stheraven    __state_->__add_shared();
1175227825Stheraven    __state_->__set_future_attached();
1176227825Stheraven}
1177227825Stheraven
1178232950Stheraventemplate <class _Rp>
1179232950Stheravenfuture<_Rp&>::~future()
1180227825Stheraven{
1181227825Stheraven    if (__state_)
1182227825Stheraven        __state_->__release_shared();
1183227825Stheraven}
1184227825Stheraven
1185232950Stheraventemplate <class _Rp>
1186232950Stheraven_Rp&
1187232950Stheravenfuture<_Rp&>::get()
1188227825Stheraven{
1189227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1190232950Stheraven    __assoc_state<_Rp&>* __s = __state_;
1191227825Stheraven    __state_ = nullptr;
1192227825Stheraven    return __s->copy();
1193227825Stheraven}
1194227825Stheraven
1195227825Stheraventemplate <>
1196227825Stheravenclass _LIBCPP_VISIBLE future<void>
1197227825Stheraven{
1198227825Stheraven    __assoc_sub_state* __state_;
1199227825Stheraven
1200227825Stheraven    explicit future(__assoc_sub_state* __state);
1201227825Stheraven
1202227825Stheraven    template <class> friend class promise;
1203227825Stheraven    template <class> friend class shared_future;
1204227825Stheraven
1205227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1206232950Stheraven    template <class _R1, class _Fp>
1207232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1208232950Stheraven    template <class _R1, class _Fp>
1209232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1210227825Stheraven#else
1211232950Stheraven    template <class _R1, class _Fp>
1212232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1213232950Stheraven    template <class _R1, class _Fp>
1214232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1215227825Stheraven#endif
1216227825Stheraven
1217227825Stheravenpublic:
1218227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1219241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1220227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1221227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1222241903Sdim    future(future&& __rhs) _NOEXCEPT
1223227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1224227825Stheraven    future(const future&) = delete;
1225227825Stheraven    future& operator=(const future&) = delete;
1226227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1227241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1228227825Stheraven        {
1229227825Stheraven            future(std::move(__rhs)).swap(*this);
1230227825Stheraven            return *this;
1231227825Stheraven        }
1232227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1233227825Stheravenprivate:
1234227825Stheraven    future(const future&);
1235227825Stheraven    future& operator=(const future&);
1236227825Stheravenpublic:
1237227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1238227825Stheraven    ~future();
1239227825Stheraven    shared_future<void> share();
1240227825Stheraven
1241227825Stheraven    // retrieving the value
1242227825Stheraven    void get();
1243227825Stheraven
1244227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1245241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1246227825Stheraven
1247227825Stheraven    // functions to check state
1248227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1249241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1250227825Stheraven
1251227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1252227825Stheraven    void wait() const {__state_->wait();}
1253227825Stheraven    template <class _Rep, class _Period>
1254227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1255227825Stheraven        future_status
1256227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1257227825Stheraven            {return __state_->wait_for(__rel_time);}
1258227825Stheraven    template <class _Clock, class _Duration>
1259227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1260227825Stheraven        future_status
1261227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1262227825Stheraven            {return __state_->wait_until(__abs_time);}
1263227825Stheraven};
1264227825Stheraven
1265232950Stheraventemplate <class _Rp>
1266227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1267227825Stheravenvoid
1268241903Sdimswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1269227825Stheraven{
1270227825Stheraven    __x.swap(__y);
1271227825Stheraven}
1272227825Stheraven
1273227825Stheraven// promise<R>
1274227825Stheraven
1275227825Stheraventemplate <class _Callable> class packaged_task;
1276227825Stheraven
1277232950Stheraventemplate <class _Rp>
1278227825Stheravenclass _LIBCPP_VISIBLE promise
1279227825Stheraven{
1280232950Stheraven    __assoc_state<_Rp>* __state_;
1281227825Stheraven
1282227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1283241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1284227825Stheraven
1285227825Stheraven    template <class> friend class packaged_task;
1286227825Stheravenpublic:
1287227825Stheraven    promise();
1288227825Stheraven    template <class _Alloc>
1289227825Stheraven        promise(allocator_arg_t, const _Alloc& __a);
1290227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1291227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1292241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1293227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1294227825Stheraven    promise(const promise& __rhs) = delete;
1295227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1296227825Stheravenprivate:
1297227825Stheraven    promise(const promise& __rhs);
1298227825Stheravenpublic:
1299227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1300227825Stheraven    ~promise();
1301227825Stheraven
1302227825Stheraven    // assignment
1303227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1304227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1305241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1306227825Stheraven        {
1307227825Stheraven            promise(std::move(__rhs)).swap(*this);
1308227825Stheraven            return *this;
1309227825Stheraven        }
1310227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1311227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1312227825Stheravenprivate:
1313227825Stheraven    promise& operator=(const promise& __rhs);
1314227825Stheravenpublic:
1315227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1316227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1317241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1318227825Stheraven
1319227825Stheraven    // retrieving the result
1320232950Stheraven    future<_Rp> get_future();
1321227825Stheraven
1322227825Stheraven    // setting the result
1323232950Stheraven    void set_value(const _Rp& __r);
1324227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1325232950Stheraven    void set_value(_Rp&& __r);
1326227825Stheraven#endif
1327227825Stheraven    void set_exception(exception_ptr __p);
1328227825Stheraven
1329227825Stheraven    // setting the result with deferred notification
1330232950Stheraven    void set_value_at_thread_exit(const _Rp& __r);
1331227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1332232950Stheraven    void set_value_at_thread_exit(_Rp&& __r);
1333227825Stheraven#endif
1334227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1335227825Stheraven};
1336227825Stheraven
1337232950Stheraventemplate <class _Rp>
1338232950Stheravenpromise<_Rp>::promise()
1339232950Stheraven    : __state_(new __assoc_state<_Rp>)
1340227825Stheraven{
1341227825Stheraven}
1342227825Stheraven
1343232950Stheraventemplate <class _Rp>
1344227825Stheraventemplate <class _Alloc>
1345232950Stheravenpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1346227825Stheraven{
1347232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
1348227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1349227825Stheraven    _A2 __a(__a0);
1350232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1351232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
1352227825Stheraven    __state_ = __hold.release();
1353227825Stheraven}
1354227825Stheraven
1355232950Stheraventemplate <class _Rp>
1356232950Stheravenpromise<_Rp>::~promise()
1357227825Stheraven{
1358227825Stheraven    if (__state_)
1359227825Stheraven    {
1360227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1361227825Stheraven            __state_->set_exception(make_exception_ptr(
1362227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1363227825Stheraven                                                      ));
1364227825Stheraven        __state_->__release_shared();
1365227825Stheraven    }
1366227825Stheraven}
1367227825Stheraven
1368232950Stheraventemplate <class _Rp>
1369232950Stheravenfuture<_Rp>
1370232950Stheravenpromise<_Rp>::get_future()
1371227825Stheraven{
1372227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1373227825Stheraven    if (__state_ == nullptr)
1374227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1375227825Stheraven#endif
1376232950Stheraven    return future<_Rp>(__state_);
1377227825Stheraven}
1378227825Stheraven
1379232950Stheraventemplate <class _Rp>
1380227825Stheravenvoid
1381232950Stheravenpromise<_Rp>::set_value(const _Rp& __r)
1382227825Stheraven{
1383227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1384227825Stheraven    if (__state_ == nullptr)
1385227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1386227825Stheraven#endif
1387227825Stheraven    __state_->set_value(__r);
1388227825Stheraven}
1389227825Stheraven
1390227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391227825Stheraven
1392232950Stheraventemplate <class _Rp>
1393227825Stheravenvoid
1394232950Stheravenpromise<_Rp>::set_value(_Rp&& __r)
1395227825Stheraven{
1396227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1397227825Stheraven    if (__state_ == nullptr)
1398227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1399227825Stheraven#endif
1400227825Stheraven    __state_->set_value(_VSTD::move(__r));
1401227825Stheraven}
1402227825Stheraven
1403227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1404227825Stheraven
1405232950Stheraventemplate <class _Rp>
1406227825Stheravenvoid
1407232950Stheravenpromise<_Rp>::set_exception(exception_ptr __p)
1408227825Stheraven{
1409227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1410227825Stheraven    if (__state_ == nullptr)
1411227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1412227825Stheraven#endif
1413227825Stheraven    __state_->set_exception(__p);
1414227825Stheraven}
1415227825Stheraven
1416232950Stheraventemplate <class _Rp>
1417227825Stheravenvoid
1418232950Stheravenpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1419227825Stheraven{
1420227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1421227825Stheraven    if (__state_ == nullptr)
1422227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1423227825Stheraven#endif
1424227825Stheraven    __state_->set_value_at_thread_exit(__r);
1425227825Stheraven}
1426227825Stheraven
1427227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1428227825Stheraven
1429232950Stheraventemplate <class _Rp>
1430227825Stheravenvoid
1431232950Stheravenpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1432227825Stheraven{
1433227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1434227825Stheraven    if (__state_ == nullptr)
1435227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1436227825Stheraven#endif
1437227825Stheraven    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1438227825Stheraven}
1439227825Stheraven
1440227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1441227825Stheraven
1442232950Stheraventemplate <class _Rp>
1443227825Stheravenvoid
1444232950Stheravenpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1445227825Stheraven{
1446227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1447227825Stheraven    if (__state_ == nullptr)
1448227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1449227825Stheraven#endif
1450227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1451227825Stheraven}
1452227825Stheraven
1453227825Stheraven// promise<R&>
1454227825Stheraven
1455232950Stheraventemplate <class _Rp>
1456232950Stheravenclass _LIBCPP_VISIBLE promise<_Rp&>
1457227825Stheraven{
1458232950Stheraven    __assoc_state<_Rp&>* __state_;
1459227825Stheraven
1460227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1461241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1462227825Stheraven
1463227825Stheraven    template <class> friend class packaged_task;
1464227825Stheraven
1465227825Stheravenpublic:
1466227825Stheraven    promise();
1467227825Stheraven    template <class _Allocator>
1468227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1469227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1470227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1471241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1472227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1473227825Stheraven    promise(const promise& __rhs) = delete;
1474227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1475227825Stheravenprivate:
1476227825Stheraven    promise(const promise& __rhs);
1477227825Stheravenpublic:
1478227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1479227825Stheraven    ~promise();
1480227825Stheraven
1481227825Stheraven    // assignment
1482227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1483227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1484241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1485227825Stheraven        {
1486227825Stheraven            promise(std::move(__rhs)).swap(*this);
1487227825Stheraven            return *this;
1488227825Stheraven        }
1489227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1490227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1491227825Stheravenprivate:
1492227825Stheraven    promise& operator=(const promise& __rhs);
1493227825Stheravenpublic:
1494227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1495227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1496241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1497227825Stheraven
1498227825Stheraven    // retrieving the result
1499232950Stheraven    future<_Rp&> get_future();
1500227825Stheraven
1501227825Stheraven    // setting the result
1502232950Stheraven    void set_value(_Rp& __r);
1503227825Stheraven    void set_exception(exception_ptr __p);
1504227825Stheraven
1505227825Stheraven    // setting the result with deferred notification
1506232950Stheraven    void set_value_at_thread_exit(_Rp&);
1507227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1508227825Stheraven};
1509227825Stheraven
1510232950Stheraventemplate <class _Rp>
1511232950Stheravenpromise<_Rp&>::promise()
1512232950Stheraven    : __state_(new __assoc_state<_Rp&>)
1513227825Stheraven{
1514227825Stheraven}
1515227825Stheraven
1516232950Stheraventemplate <class _Rp>
1517227825Stheraventemplate <class _Alloc>
1518232950Stheravenpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1519227825Stheraven{
1520232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
1521227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1522227825Stheraven    _A2 __a(__a0);
1523232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1524232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
1525227825Stheraven    __state_ = __hold.release();
1526227825Stheraven}
1527227825Stheraven
1528232950Stheraventemplate <class _Rp>
1529232950Stheravenpromise<_Rp&>::~promise()
1530227825Stheraven{
1531227825Stheraven    if (__state_)
1532227825Stheraven    {
1533227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1534227825Stheraven            __state_->set_exception(make_exception_ptr(
1535227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1536227825Stheraven                                                      ));
1537227825Stheraven        __state_->__release_shared();
1538227825Stheraven    }
1539227825Stheraven}
1540227825Stheraven
1541232950Stheraventemplate <class _Rp>
1542232950Stheravenfuture<_Rp&>
1543232950Stheravenpromise<_Rp&>::get_future()
1544227825Stheraven{
1545227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1546227825Stheraven    if (__state_ == nullptr)
1547227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1548227825Stheraven#endif
1549232950Stheraven    return future<_Rp&>(__state_);
1550227825Stheraven}
1551227825Stheraven
1552232950Stheraventemplate <class _Rp>
1553227825Stheravenvoid
1554232950Stheravenpromise<_Rp&>::set_value(_Rp& __r)
1555227825Stheraven{
1556227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1557227825Stheraven    if (__state_ == nullptr)
1558227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1559227825Stheraven#endif
1560227825Stheraven    __state_->set_value(__r);
1561227825Stheraven}
1562227825Stheraven
1563232950Stheraventemplate <class _Rp>
1564227825Stheravenvoid
1565232950Stheravenpromise<_Rp&>::set_exception(exception_ptr __p)
1566227825Stheraven{
1567227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1568227825Stheraven    if (__state_ == nullptr)
1569227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1570227825Stheraven#endif
1571227825Stheraven    __state_->set_exception(__p);
1572227825Stheraven}
1573227825Stheraven
1574232950Stheraventemplate <class _Rp>
1575227825Stheravenvoid
1576232950Stheravenpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1577227825Stheraven{
1578227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1579227825Stheraven    if (__state_ == nullptr)
1580227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1581227825Stheraven#endif
1582227825Stheraven    __state_->set_value_at_thread_exit(__r);
1583227825Stheraven}
1584227825Stheraven
1585232950Stheraventemplate <class _Rp>
1586227825Stheravenvoid
1587232950Stheravenpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1588227825Stheraven{
1589227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1590227825Stheraven    if (__state_ == nullptr)
1591227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1592227825Stheraven#endif
1593227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1594227825Stheraven}
1595227825Stheraven
1596227825Stheraven// promise<void>
1597227825Stheraven
1598227825Stheraventemplate <>
1599227825Stheravenclass _LIBCPP_VISIBLE promise<void>
1600227825Stheraven{
1601227825Stheraven    __assoc_sub_state* __state_;
1602227825Stheraven
1603227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1604241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1605227825Stheraven
1606227825Stheraven    template <class> friend class packaged_task;
1607227825Stheraven
1608227825Stheravenpublic:
1609227825Stheraven    promise();
1610227825Stheraven    template <class _Allocator>
1611227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1612227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1613227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1614241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1615227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1616227825Stheraven    promise(const promise& __rhs) = delete;
1617227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1618227825Stheravenprivate:
1619227825Stheraven    promise(const promise& __rhs);
1620227825Stheravenpublic:
1621227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1622227825Stheraven    ~promise();
1623227825Stheraven
1624227825Stheraven    // assignment
1625227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1626227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1627241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1628227825Stheraven        {
1629227825Stheraven            promise(std::move(__rhs)).swap(*this);
1630227825Stheraven            return *this;
1631227825Stheraven        }
1632227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1633227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1634227825Stheravenprivate:
1635227825Stheraven    promise& operator=(const promise& __rhs);
1636227825Stheravenpublic:
1637227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1638227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1639241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1640227825Stheraven
1641227825Stheraven    // retrieving the result
1642227825Stheraven    future<void> get_future();
1643227825Stheraven
1644227825Stheraven    // setting the result
1645227825Stheraven    void set_value();
1646227825Stheraven    void set_exception(exception_ptr __p);
1647227825Stheraven
1648227825Stheraven    // setting the result with deferred notification
1649227825Stheraven    void set_value_at_thread_exit();
1650227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1651227825Stheraven};
1652227825Stheraven
1653227825Stheraventemplate <class _Alloc>
1654227825Stheravenpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1655227825Stheraven{
1656227825Stheraven    typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1657227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1658227825Stheraven    _A2 __a(__a0);
1659227825Stheraven    unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1660227825Stheraven    ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1661227825Stheraven    __state_ = __hold.release();
1662227825Stheraven}
1663227825Stheraven
1664232950Stheraventemplate <class _Rp>
1665227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1666227825Stheravenvoid
1667241903Sdimswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1668227825Stheraven{
1669227825Stheraven    __x.swap(__y);
1670227825Stheraven}
1671227825Stheraven
1672232950Stheraventemplate <class _Rp, class _Alloc>
1673232950Stheraven    struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc>
1674227825Stheraven        : public true_type {};
1675227825Stheraven
1676227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
1677227825Stheraven
1678227825Stheraven// packaged_task
1679227825Stheraven
1680227825Stheraventemplate<class _Fp> class __packaged_task_base;
1681227825Stheraven
1682232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1683232950Stheravenclass __packaged_task_base<_Rp(_ArgTypes...)>
1684227825Stheraven{
1685227825Stheraven    __packaged_task_base(const __packaged_task_base&);
1686227825Stheraven    __packaged_task_base& operator=(const __packaged_task_base&);
1687227825Stheravenpublic:
1688227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1689227825Stheraven    __packaged_task_base() {}
1690227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1691227825Stheraven    virtual ~__packaged_task_base() {}
1692241903Sdim    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1693227825Stheraven    virtual void destroy() = 0;
1694227825Stheraven    virtual void destroy_deallocate() = 0;
1695232950Stheraven    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1696227825Stheraven};
1697227825Stheraven
1698227825Stheraventemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1699227825Stheraven
1700232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1701232950Stheravenclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1702232950Stheraven    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1703227825Stheraven{
1704232950Stheraven    __compressed_pair<_Fp, _Alloc> __f_;
1705227825Stheravenpublic:
1706227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1707232950Stheraven    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1708227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1709232950Stheraven    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1710227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1711232950Stheraven    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1712227825Stheraven        : __f_(__f, __a) {}
1713227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1714232950Stheraven    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1715227825Stheraven        : __f_(_VSTD::move(__f), __a) {}
1716241903Sdim    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1717227825Stheraven    virtual void destroy();
1718227825Stheraven    virtual void destroy_deallocate();
1719232950Stheraven    virtual _Rp operator()(_ArgTypes&& ... __args);
1720227825Stheraven};
1721227825Stheraven
1722232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1723227825Stheravenvoid
1724232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1725241903Sdim                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1726227825Stheraven{
1727227825Stheraven    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1728227825Stheraven}
1729227825Stheraven
1730232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1731227825Stheravenvoid
1732232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1733227825Stheraven{
1734232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1735227825Stheraven}
1736227825Stheraven
1737232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1738227825Stheravenvoid
1739232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1740227825Stheraven{
1741232950Stheraven    typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1742232950Stheraven    _Ap __a(__f_.second());
1743232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1744227825Stheraven    __a.deallocate(this, 1);
1745227825Stheraven}
1746227825Stheraven
1747232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1748232950Stheraven_Rp
1749232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1750227825Stheraven{
1751227825Stheraven    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1752227825Stheraven}
1753227825Stheraven
1754227825Stheraventemplate <class _Callable> class __packaged_task_function;
1755227825Stheraven
1756232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1757232950Stheravenclass __packaged_task_function<_Rp(_ArgTypes...)>
1758227825Stheraven{
1759232950Stheraven    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1760246487Stheraven    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1761227825Stheraven    __base* __f_;
1762227825Stheraven
1763227825Stheravenpublic:
1764232950Stheraven    typedef _Rp result_type;
1765227825Stheraven
1766227825Stheraven    // construct/copy/destroy:
1767227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1768241903Sdim    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1769232950Stheraven    template<class _Fp>
1770232950Stheraven      __packaged_task_function(_Fp&& __f);
1771232950Stheraven    template<class _Fp, class _Alloc>
1772232950Stheraven      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1773227825Stheraven
1774241903Sdim    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1775241903Sdim    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1776227825Stheraven
1777227825Stheraven    __packaged_task_function(const __packaged_task_function&) =  delete;
1778227825Stheraven    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1779227825Stheraven
1780227825Stheraven    ~__packaged_task_function();
1781227825Stheraven
1782241903Sdim    void swap(__packaged_task_function&) _NOEXCEPT;
1783227825Stheraven
1784232950Stheraven    _Rp operator()(_ArgTypes...) const;
1785227825Stheraven};
1786227825Stheraven
1787232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1788241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1789227825Stheraven{
1790227825Stheraven    if (__f.__f_ == nullptr)
1791227825Stheraven        __f_ = nullptr;
1792227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1793227825Stheraven    {
1794227825Stheraven        __f_ = (__base*)&__buf_;
1795227825Stheraven        __f.__f_->__move_to(__f_);
1796227825Stheraven    }
1797227825Stheraven    else
1798227825Stheraven    {
1799227825Stheraven        __f_ = __f.__f_;
1800227825Stheraven        __f.__f_ = nullptr;
1801227825Stheraven    }
1802227825Stheraven}
1803227825Stheraven
1804232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1805232950Stheraventemplate <class _Fp>
1806232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1807227825Stheraven    : __f_(nullptr)
1808227825Stheraven{
1809232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1810232950Stheraven    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1811227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1812227825Stheraven    {
1813227825Stheraven        __f_ = (__base*)&__buf_;
1814232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1815227825Stheraven    }
1816227825Stheraven    else
1817227825Stheraven    {
1818232950Stheraven        typedef allocator<_FF> _Ap;
1819232950Stheraven        _Ap __a;
1820232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1821232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1822232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1823227825Stheraven        __f_ = __hold.release();
1824227825Stheraven    }
1825227825Stheraven}
1826227825Stheraven
1827232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1828232950Stheraventemplate <class _Fp, class _Alloc>
1829232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1830232950Stheraven                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1831227825Stheraven    : __f_(nullptr)
1832227825Stheraven{
1833227825Stheraven    typedef allocator_traits<_Alloc> __alloc_traits;
1834232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1835232950Stheraven    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1836227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1837227825Stheraven    {
1838227825Stheraven        __f_ = (__base*)&__buf_;
1839232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1840227825Stheraven    }
1841227825Stheraven    else
1842227825Stheraven    {
1843227825Stheraven        typedef typename __alloc_traits::template
1844227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1845227825Stheraven            rebind_alloc<_FF>
1846227825Stheraven#else
1847227825Stheraven            rebind_alloc<_FF>::other
1848227825Stheraven#endif
1849232950Stheraven                                                     _Ap;
1850232950Stheraven        _Ap __a(__a0);
1851232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1852232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1853232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1854227825Stheraven        __f_ = __hold.release();
1855227825Stheraven    }
1856227825Stheraven}
1857227825Stheraven
1858232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1859232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>&
1860241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1861227825Stheraven{
1862227825Stheraven    if (__f_ == (__base*)&__buf_)
1863227825Stheraven        __f_->destroy();
1864227825Stheraven    else if (__f_)
1865227825Stheraven        __f_->destroy_deallocate();
1866227825Stheraven    __f_ = nullptr;
1867227825Stheraven    if (__f.__f_ == nullptr)
1868227825Stheraven        __f_ = nullptr;
1869227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1870227825Stheraven    {
1871227825Stheraven        __f_ = (__base*)&__buf_;
1872227825Stheraven        __f.__f_->__move_to(__f_);
1873227825Stheraven    }
1874227825Stheraven    else
1875227825Stheraven    {
1876227825Stheraven        __f_ = __f.__f_;
1877227825Stheraven        __f.__f_ = nullptr;
1878227825Stheraven    }
1879241903Sdim    return *this;
1880227825Stheraven}
1881227825Stheraven
1882232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1883232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1884227825Stheraven{
1885227825Stheraven    if (__f_ == (__base*)&__buf_)
1886227825Stheraven        __f_->destroy();
1887227825Stheraven    else if (__f_)
1888227825Stheraven        __f_->destroy_deallocate();
1889227825Stheraven}
1890227825Stheraven
1891232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1892227825Stheravenvoid
1893241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1894227825Stheraven{
1895227825Stheraven    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1896227825Stheraven    {
1897227825Stheraven        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1898227825Stheraven        __base* __t = (__base*)&__tempbuf;
1899227825Stheraven        __f_->__move_to(__t);
1900227825Stheraven        __f_->destroy();
1901227825Stheraven        __f_ = nullptr;
1902227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1903227825Stheraven        __f.__f_->destroy();
1904227825Stheraven        __f.__f_ = nullptr;
1905227825Stheraven        __f_ = (__base*)&__buf_;
1906227825Stheraven        __t->__move_to((__base*)&__f.__buf_);
1907227825Stheraven        __t->destroy();
1908227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1909227825Stheraven    }
1910227825Stheraven    else if (__f_ == (__base*)&__buf_)
1911227825Stheraven    {
1912227825Stheraven        __f_->__move_to((__base*)&__f.__buf_);
1913227825Stheraven        __f_->destroy();
1914227825Stheraven        __f_ = __f.__f_;
1915227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1916227825Stheraven    }
1917227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1918227825Stheraven    {
1919227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1920227825Stheraven        __f.__f_->destroy();
1921227825Stheraven        __f.__f_ = __f_;
1922227825Stheraven        __f_ = (__base*)&__buf_;
1923227825Stheraven    }
1924227825Stheraven    else
1925227825Stheraven        _VSTD::swap(__f_, __f.__f_);
1926227825Stheraven}
1927227825Stheraven
1928232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1929227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1930232950Stheraven_Rp
1931232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1932227825Stheraven{
1933227825Stheraven    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
1934227825Stheraven}
1935227825Stheraven
1936232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1937232950Stheravenclass _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)>
1938227825Stheraven{
1939227825Stheravenpublic:
1940232950Stheraven    typedef _Rp result_type;
1941227825Stheraven
1942227825Stheravenprivate:
1943227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
1944227825Stheraven    promise<result_type>                                __p_;
1945227825Stheraven
1946227825Stheravenpublic:
1947227825Stheraven    // construction and destruction
1948227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1949241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
1950232950Stheraven    template <class _Fp>
1951227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1952232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
1953232950Stheraven    template <class _Fp, class _Allocator>
1954227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1955232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1956232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1957227825Stheraven               __p_(allocator_arg, __a) {}
1958227825Stheraven    // ~packaged_task() = default;
1959227825Stheraven
1960227825Stheraven    // no copy
1961241903Sdim    packaged_task(const packaged_task&) = delete;
1962241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
1963227825Stheraven
1964227825Stheraven    // move support
1965227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1966241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
1967227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
1968227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1969241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
1970227825Stheraven    {
1971227825Stheraven        __f_ = _VSTD::move(__other.__f_);
1972227825Stheraven        __p_ = _VSTD::move(__other.__p_);
1973227825Stheraven        return *this;
1974227825Stheraven    }
1975227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1976241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
1977227825Stheraven    {
1978227825Stheraven        __f_.swap(__other.__f_);
1979227825Stheraven        __p_.swap(__other.__p_);
1980227825Stheraven    }
1981227825Stheraven
1982227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1983241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
1984227825Stheraven
1985227825Stheraven    // result retrieval
1986227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1987227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
1988227825Stheraven
1989227825Stheraven    // execution
1990227825Stheraven    void operator()(_ArgTypes... __args);
1991227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
1992227825Stheraven
1993227825Stheraven    void reset();
1994227825Stheraven};
1995227825Stheraven
1996232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1997227825Stheravenvoid
1998232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
1999227825Stheraven{
2000227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2001227825Stheraven    if (__p_.__state_ == nullptr)
2002227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2003227825Stheraven    if (__p_.__state_->__has_value())
2004227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2005227825Stheraven    try
2006227825Stheraven    {
2007227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2008227825Stheraven        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2009227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2010227825Stheraven    }
2011227825Stheraven    catch (...)
2012227825Stheraven    {
2013227825Stheraven        __p_.set_exception(current_exception());
2014227825Stheraven    }
2015227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2016227825Stheraven}
2017227825Stheraven
2018232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2019227825Stheravenvoid
2020232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2021227825Stheraven{
2022227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2023227825Stheraven    if (__p_.__state_ == nullptr)
2024227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2025227825Stheraven    if (__p_.__state_->__has_value())
2026227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2027227825Stheraven    try
2028227825Stheraven    {
2029227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2030227825Stheraven        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2031227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2032227825Stheraven    }
2033227825Stheraven    catch (...)
2034227825Stheraven    {
2035227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2036227825Stheraven    }
2037227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2038227825Stheraven}
2039227825Stheraven
2040232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2041227825Stheravenvoid
2042232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::reset()
2043227825Stheraven{
2044227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2045227825Stheraven    if (!valid())
2046227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2047227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2048227825Stheraven    __p_ = promise<result_type>();
2049227825Stheraven}
2050227825Stheraven
2051227825Stheraventemplate<class ..._ArgTypes>
2052227825Stheravenclass _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
2053227825Stheraven{
2054227825Stheravenpublic:
2055227825Stheraven    typedef void result_type;
2056227825Stheraven
2057227825Stheravenprivate:
2058227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2059227825Stheraven    promise<result_type>                                __p_;
2060227825Stheraven
2061227825Stheravenpublic:
2062227825Stheraven    // construction and destruction
2063227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2064241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2065232950Stheraven    template <class _Fp>
2066227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2067232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2068232950Stheraven    template <class _Fp, class _Allocator>
2069227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2070232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2071232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2072227825Stheraven               __p_(allocator_arg, __a) {}
2073227825Stheraven    // ~packaged_task() = default;
2074227825Stheraven
2075227825Stheraven    // no copy
2076241903Sdim    packaged_task(const packaged_task&) = delete;
2077241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2078227825Stheraven
2079227825Stheraven    // move support
2080227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2081241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2082227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2083227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2084241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2085227825Stheraven    {
2086227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2087227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2088227825Stheraven        return *this;
2089227825Stheraven    }
2090227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2091241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2092227825Stheraven    {
2093227825Stheraven        __f_.swap(__other.__f_);
2094227825Stheraven        __p_.swap(__other.__p_);
2095227825Stheraven    }
2096227825Stheraven
2097227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2098241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2099227825Stheraven
2100227825Stheraven    // result retrieval
2101227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2102227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2103227825Stheraven
2104227825Stheraven    // execution
2105227825Stheraven    void operator()(_ArgTypes... __args);
2106227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2107227825Stheraven
2108227825Stheraven    void reset();
2109227825Stheraven};
2110227825Stheraven
2111227825Stheraventemplate<class ..._ArgTypes>
2112227825Stheravenvoid
2113227825Stheravenpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2114227825Stheraven{
2115227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2116227825Stheraven    if (__p_.__state_ == nullptr)
2117227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2118227825Stheraven    if (__p_.__state_->__has_value())
2119227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2120227825Stheraven    try
2121227825Stheraven    {
2122227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2123227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2124227825Stheraven        __p_.set_value();
2125227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2126227825Stheraven    }
2127227825Stheraven    catch (...)
2128227825Stheraven    {
2129227825Stheraven        __p_.set_exception(current_exception());
2130227825Stheraven    }
2131227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2132227825Stheraven}
2133227825Stheraven
2134227825Stheraventemplate<class ..._ArgTypes>
2135227825Stheravenvoid
2136227825Stheravenpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2137227825Stheraven{
2138227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2139227825Stheraven    if (__p_.__state_ == nullptr)
2140227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2141227825Stheraven    if (__p_.__state_->__has_value())
2142227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2143227825Stheraven    try
2144227825Stheraven    {
2145227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2146227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2147227825Stheraven        __p_.set_value_at_thread_exit();
2148227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2149227825Stheraven    }
2150227825Stheraven    catch (...)
2151227825Stheraven    {
2152227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2153227825Stheraven    }
2154227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2155227825Stheraven}
2156227825Stheraven
2157227825Stheraventemplate<class ..._ArgTypes>
2158227825Stheravenvoid
2159227825Stheravenpackaged_task<void(_ArgTypes...)>::reset()
2160227825Stheraven{
2161227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2162227825Stheraven    if (!valid())
2163227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2164227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2165227825Stheraven    __p_ = promise<result_type>();
2166227825Stheraven}
2167227825Stheraven
2168227825Stheraventemplate <class _Callable>
2169227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2170227825Stheravenvoid
2171241903Sdimswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2172227825Stheraven{
2173227825Stheraven    __x.swap(__y);
2174227825Stheraven}
2175227825Stheraven
2176227825Stheraventemplate <class _Callable, class _Alloc>
2177227825Stheravenstruct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2178227825Stheraven    : public true_type {};
2179227825Stheraven
2180232950Stheraventemplate <class _Rp, class _Fp>
2181232950Stheravenfuture<_Rp>
2182227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2183232950Stheraven__make_deferred_assoc_state(_Fp&& __f)
2184227825Stheraven#else
2185232950Stheraven__make_deferred_assoc_state(_Fp __f)
2186227825Stheraven#endif
2187227825Stheraven{
2188232950Stheraven    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2189232950Stheraven        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2190232950Stheraven    return future<_Rp>(__h.get());
2191227825Stheraven}
2192227825Stheraven
2193232950Stheraventemplate <class _Rp, class _Fp>
2194232950Stheravenfuture<_Rp>
2195227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2196232950Stheraven__make_async_assoc_state(_Fp&& __f)
2197227825Stheraven#else
2198232950Stheraven__make_async_assoc_state(_Fp __f)
2199227825Stheraven#endif
2200227825Stheraven{
2201232950Stheraven    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2202232950Stheraven        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2203232950Stheraven    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2204232950Stheraven    return future<_Rp>(__h.get());
2205227825Stheraven}
2206227825Stheraven
2207232950Stheraventemplate <class _Fp, class... _Args>
2208227825Stheravenclass __async_func
2209227825Stheraven{
2210232950Stheraven    tuple<_Fp, _Args...> __f_;
2211227825Stheraven
2212227825Stheravenpublic:
2213232950Stheraven    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2214227825Stheraven
2215227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2216232950Stheraven    explicit __async_func(_Fp&& __f, _Args&&... __args)
2217227825Stheraven        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2218227825Stheraven
2219227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2220227825Stheraven    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2221227825Stheraven
2222232950Stheraven    _Rp operator()()
2223227825Stheraven    {
2224227825Stheraven        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2225227825Stheraven        return __execute(_Index());
2226227825Stheraven    }
2227227825Stheravenprivate:
2228227825Stheraven    template <size_t ..._Indices>
2229232950Stheraven    _Rp
2230227825Stheraven    __execute(__tuple_indices<_Indices...>)
2231227825Stheraven    {
2232227825Stheraven        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2233227825Stheraven    }
2234227825Stheraven};
2235227825Stheraven
2236232950Stheraventemplate <class _Fp, class... _Args>
2237232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2238232950Stheravenasync(launch __policy, _Fp&& __f, _Args&&... __args)
2239227825Stheraven{
2240232950Stheraven    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2241232950Stheraven    typedef typename _BF::_Rp _Rp;
2242232950Stheraven    future<_Rp> __r;
2243232950Stheraven    if (int(__policy) & int(launch::async))
2244232950Stheraven        __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2245227825Stheraven                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2246232950Stheraven    else if (int(__policy) & int(launch::deferred))
2247232950Stheraven        __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2248227825Stheraven                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2249227825Stheraven    return __r;
2250227825Stheraven}
2251227825Stheraven
2252232950Stheraventemplate <class _Fp, class... _Args>
2253227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2254232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2255232950Stheravenasync(_Fp&& __f, _Args&&... __args)
2256227825Stheraven{
2257232950Stheraven    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2258227825Stheraven                                    _VSTD::forward<_Args>(__args)...);
2259227825Stheraven}
2260227825Stheraven
2261227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
2262227825Stheraven
2263227825Stheraven// shared_future
2264227825Stheraven
2265232950Stheraventemplate <class _Rp>
2266227825Stheravenclass _LIBCPP_VISIBLE shared_future
2267227825Stheraven{
2268232950Stheraven    __assoc_state<_Rp>* __state_;
2269227825Stheraven
2270227825Stheravenpublic:
2271227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2272241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2273227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2274227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2275227825Stheraven        {if (__state_) __state_->__add_shared();}
2276227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2277227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2278241903Sdim    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2279227825Stheraven        {__f.__state_ = nullptr;}
2280227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2281241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2282227825Stheraven        {__rhs.__state_ = nullptr;}
2283227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2284227825Stheraven    ~shared_future();
2285227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2286227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2287227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2288241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2289227825Stheraven        {
2290227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2291227825Stheraven            return *this;
2292227825Stheraven        }
2293227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2294227825Stheraven
2295227825Stheraven    // retrieving the value
2296227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2297232950Stheraven    const _Rp& get() const {return __state_->copy();}
2298227825Stheraven
2299227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2300241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2301227825Stheraven
2302227825Stheraven    // functions to check state
2303227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2304241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2305227825Stheraven
2306227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2307227825Stheraven    void wait() const {__state_->wait();}
2308227825Stheraven    template <class _Rep, class _Period>
2309227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2310227825Stheraven        future_status
2311227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2312227825Stheraven            {return __state_->wait_for(__rel_time);}
2313227825Stheraven    template <class _Clock, class _Duration>
2314227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2315227825Stheraven        future_status
2316227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2317227825Stheraven            {return __state_->wait_until(__abs_time);}
2318227825Stheraven};
2319227825Stheraven
2320232950Stheraventemplate <class _Rp>
2321232950Stheravenshared_future<_Rp>::~shared_future()
2322227825Stheraven{
2323227825Stheraven    if (__state_)
2324227825Stheraven        __state_->__release_shared();
2325227825Stheraven}
2326227825Stheraven
2327232950Stheraventemplate <class _Rp>
2328232950Stheravenshared_future<_Rp>&
2329232950Stheravenshared_future<_Rp>::operator=(const shared_future& __rhs)
2330227825Stheraven{
2331227825Stheraven    if (__rhs.__state_)
2332227825Stheraven        __rhs.__state_->__add_shared();
2333227825Stheraven    if (__state_)
2334227825Stheraven        __state_->__release_shared();
2335227825Stheraven    __state_ = __rhs.__state_;
2336227825Stheraven    return *this;
2337227825Stheraven}
2338227825Stheraven
2339232950Stheraventemplate <class _Rp>
2340232950Stheravenclass _LIBCPP_VISIBLE shared_future<_Rp&>
2341227825Stheraven{
2342232950Stheraven    __assoc_state<_Rp&>* __state_;
2343227825Stheraven
2344227825Stheravenpublic:
2345227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2346241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2347227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2348227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2349227825Stheraven        {if (__state_) __state_->__add_shared();}
2350227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2351227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2352241903Sdim    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2353227825Stheraven        {__f.__state_ = nullptr;}
2354227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2355241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2356227825Stheraven        {__rhs.__state_ = nullptr;}
2357227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2358227825Stheraven    ~shared_future();
2359227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2360227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2361227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2362241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2363227825Stheraven        {
2364227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2365227825Stheraven            return *this;
2366227825Stheraven        }
2367227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2368227825Stheraven
2369227825Stheraven    // retrieving the value
2370227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2371232950Stheraven    _Rp& get() const {return __state_->copy();}
2372227825Stheraven
2373227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2374241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2375227825Stheraven
2376227825Stheraven    // functions to check state
2377227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2378241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2379227825Stheraven
2380227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2381227825Stheraven    void wait() const {__state_->wait();}
2382227825Stheraven    template <class _Rep, class _Period>
2383227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2384227825Stheraven        future_status
2385227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2386227825Stheraven            {return __state_->wait_for(__rel_time);}
2387227825Stheraven    template <class _Clock, class _Duration>
2388227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2389227825Stheraven        future_status
2390227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2391227825Stheraven            {return __state_->wait_until(__abs_time);}
2392227825Stheraven};
2393227825Stheraven
2394232950Stheraventemplate <class _Rp>
2395232950Stheravenshared_future<_Rp&>::~shared_future()
2396227825Stheraven{
2397227825Stheraven    if (__state_)
2398227825Stheraven        __state_->__release_shared();
2399227825Stheraven}
2400227825Stheraven
2401232950Stheraventemplate <class _Rp>
2402232950Stheravenshared_future<_Rp&>&
2403232950Stheravenshared_future<_Rp&>::operator=(const shared_future& __rhs)
2404227825Stheraven{
2405227825Stheraven    if (__rhs.__state_)
2406227825Stheraven        __rhs.__state_->__add_shared();
2407227825Stheraven    if (__state_)
2408227825Stheraven        __state_->__release_shared();
2409227825Stheraven    __state_ = __rhs.__state_;
2410227825Stheraven    return *this;
2411227825Stheraven}
2412227825Stheraven
2413227825Stheraventemplate <>
2414227825Stheravenclass _LIBCPP_VISIBLE shared_future<void>
2415227825Stheraven{
2416227825Stheraven    __assoc_sub_state* __state_;
2417227825Stheraven
2418227825Stheravenpublic:
2419227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2420241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2421227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2422227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2423227825Stheraven        {if (__state_) __state_->__add_shared();}
2424227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2425227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2426241903Sdim    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2427227825Stheraven        {__f.__state_ = nullptr;}
2428227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2429241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2430227825Stheraven        {__rhs.__state_ = nullptr;}
2431227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2432227825Stheraven    ~shared_future();
2433227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2434227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2435227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2436241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2437227825Stheraven        {
2438227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2439227825Stheraven            return *this;
2440227825Stheraven        }
2441227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2442227825Stheraven
2443227825Stheraven    // retrieving the value
2444227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2445227825Stheraven    void get() const {__state_->copy();}
2446227825Stheraven
2447227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2448241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2449227825Stheraven
2450227825Stheraven    // functions to check state
2451227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2452241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2453227825Stheraven
2454227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2455227825Stheraven    void wait() const {__state_->wait();}
2456227825Stheraven    template <class _Rep, class _Period>
2457227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2458227825Stheraven        future_status
2459227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2460227825Stheraven            {return __state_->wait_for(__rel_time);}
2461227825Stheraven    template <class _Clock, class _Duration>
2462227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2463227825Stheraven        future_status
2464227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2465227825Stheraven            {return __state_->wait_until(__abs_time);}
2466227825Stheraven};
2467227825Stheraven
2468232950Stheraventemplate <class _Rp>
2469227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2470227825Stheravenvoid
2471241903Sdimswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2472227825Stheraven{
2473227825Stheraven    __x.swap(__y);
2474227825Stheraven}
2475227825Stheraven
2476232950Stheraventemplate <class _Rp>
2477227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2478232950Stheravenshared_future<_Rp>
2479232950Stheravenfuture<_Rp>::share()
2480227825Stheraven{
2481232950Stheraven    return shared_future<_Rp>(_VSTD::move(*this));
2482227825Stheraven}
2483227825Stheraven
2484232950Stheraventemplate <class _Rp>
2485227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2486232950Stheravenshared_future<_Rp&>
2487232950Stheravenfuture<_Rp&>::share()
2488227825Stheraven{
2489232950Stheraven    return shared_future<_Rp&>(_VSTD::move(*this));
2490227825Stheraven}
2491227825Stheraven
2492227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2493227825Stheraven
2494227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2495227825Stheravenshared_future<void>
2496227825Stheravenfuture<void>::share()
2497227825Stheraven{
2498227825Stheraven    return shared_future<void>(_VSTD::move(*this));
2499227825Stheraven}
2500227825Stheraven
2501227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2502227825Stheraven
2503227825Stheraven_LIBCPP_END_NAMESPACE_STD
2504227825Stheraven
2505227825Stheraven#endif  // _LIBCPP_FUTURE
2506