future revision 262801
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{
22262801Sdim    future_already_retrieved = 1,
23227825Stheraven    promise_already_satisfied,
24262801Sdim    no_state,
25262801Sdim    broken_promise
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>
312262801Sdim  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
313227825Stheraven  async(F&& f, Args&&... args);
314227825Stheraven
315227825Stheraventemplate <class F, class... Args>
316262801Sdim  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::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{
382262801Sdim    future_already_retrieved = 1,
383227825Stheraven    promise_already_satisfied,
384262801Sdim    no_state,
385262801Sdim    broken_promise
386227825Stheraven};
387232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
388227825Stheraven
389227825Stheraventemplate <>
390262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
391227825Stheraven
392232950Stheraven#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
393232950Stheraventemplate <>
394262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY 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
406253159Stheraven#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
407253159Stheraven
408253159Stheraven#ifdef _LIBCXX_UNDERLYING_TYPE
409253159Stheraventypedef underlying_type<launch>::type __launch_underlying_type;
410253159Stheraven#else
411253159Stheraventypedef int __launch_underlying_type;
412253159Stheraven#endif
413253159Stheraven
414253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
415253159Stheraven_LIBCPP_CONSTEXPR
416253159Stheravenlaunch
417253159Stheravenoperator&(launch __x, launch __y)
418253159Stheraven{
419253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
420253159Stheraven                               static_cast<__launch_underlying_type>(__y));
421253159Stheraven}
422253159Stheraven
423253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
424253159Stheraven_LIBCPP_CONSTEXPR
425253159Stheravenlaunch
426253159Stheravenoperator|(launch __x, launch __y)
427253159Stheraven{
428253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
429253159Stheraven                               static_cast<__launch_underlying_type>(__y));
430253159Stheraven}
431253159Stheraven
432253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
433253159Stheraven_LIBCPP_CONSTEXPR
434253159Stheravenlaunch
435253159Stheravenoperator^(launch __x, launch __y)
436253159Stheraven{
437253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
438253159Stheraven                               static_cast<__launch_underlying_type>(__y));
439253159Stheraven}
440253159Stheraven
441253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
442253159Stheraven_LIBCPP_CONSTEXPR
443253159Stheravenlaunch
444253159Stheravenoperator~(launch __x)
445253159Stheraven{
446253159Stheraven    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
447253159Stheraven}
448253159Stheraven
449253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
450253159Stheravenlaunch&
451253159Stheravenoperator&=(launch& __x, launch __y)
452253159Stheraven{
453253159Stheraven    __x = __x & __y; return __x;
454253159Stheraven}
455253159Stheraven
456253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
457253159Stheravenlaunch&
458253159Stheravenoperator|=(launch& __x, launch __y)
459253159Stheraven{
460253159Stheraven    __x = __x | __y; return __x;
461253159Stheraven}
462253159Stheraven
463253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
464253159Stheravenlaunch&
465253159Stheravenoperator^=(launch& __x, launch __y)
466253159Stheraven{
467253159Stheraven    __x = __x ^ __y; return __x;
468253159Stheraven}
469253159Stheraven
470253159Stheraven#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
471253159Stheraven
472227825Stheraven//enum class future_status
473232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_status)
474227825Stheraven{
475227825Stheraven    ready,
476227825Stheraven    timeout,
477227825Stheraven    deferred
478227825Stheraven};
479232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
480227825Stheraven
481249998Sdim_LIBCPP_FUNC_VIS
482241903Sdimconst error_category& future_category() _NOEXCEPT;
483227825Stheraven
484227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
485227825Stheravenerror_code
486241903Sdimmake_error_code(future_errc __e) _NOEXCEPT
487227825Stheraven{
488227825Stheraven    return error_code(static_cast<int>(__e), future_category());
489227825Stheraven}
490227825Stheraven
491227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
492227825Stheravenerror_condition
493241903Sdimmake_error_condition(future_errc __e) _NOEXCEPT
494227825Stheraven{
495227825Stheraven    return error_condition(static_cast<int>(__e), future_category());
496227825Stheraven}
497227825Stheraven
498227825Stheravenclass _LIBCPP_EXCEPTION_ABI future_error
499227825Stheraven    : public logic_error
500227825Stheraven{
501227825Stheraven    error_code __ec_;
502227825Stheravenpublic:
503227825Stheraven    future_error(error_code __ec);
504227825Stheraven
505227825Stheraven    _LIBCPP_INLINE_VISIBILITY
506241903Sdim    const error_code& code() const _NOEXCEPT {return __ec_;}
507227825Stheraven
508227825Stheraven    virtual ~future_error() _NOEXCEPT;
509227825Stheraven};
510227825Stheraven
511262801Sdimclass _LIBCPP_TYPE_VIS __assoc_sub_state
512227825Stheraven    : public __shared_count
513227825Stheraven{
514227825Stheravenprotected:
515227825Stheraven    exception_ptr __exception_;
516227825Stheraven    mutable mutex __mut_;
517227825Stheraven    mutable condition_variable __cv_;
518227825Stheraven    unsigned __state_;
519227825Stheraven
520227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
521227825Stheraven    void __sub_wait(unique_lock<mutex>& __lk);
522227825Stheravenpublic:
523227825Stheraven    enum
524227825Stheraven    {
525227825Stheraven        __constructed = 1,
526227825Stheraven        __future_attached = 2,
527227825Stheraven        ready = 4,
528227825Stheraven        deferred = 8
529227825Stheraven    };
530227825Stheraven
531227825Stheraven    _LIBCPP_INLINE_VISIBILITY
532227825Stheraven    __assoc_sub_state() : __state_(0) {}
533227825Stheraven
534227825Stheraven    _LIBCPP_INLINE_VISIBILITY
535227825Stheraven    bool __has_value() const
536227825Stheraven        {return (__state_ & __constructed) || (__exception_ != nullptr);}
537227825Stheraven
538227825Stheraven    _LIBCPP_INLINE_VISIBILITY
539246487Stheraven    void __set_future_attached()
540246487Stheraven    {
541246487Stheraven        lock_guard<mutex> __lk(__mut_);
542246487Stheraven        __state_ |= __future_attached;
543246487Stheraven    }
544227825Stheraven    _LIBCPP_INLINE_VISIBILITY
545262801Sdim    bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
546227825Stheraven
547227825Stheraven    _LIBCPP_INLINE_VISIBILITY
548227825Stheraven    void __set_deferred() {__state_ |= deferred;}
549227825Stheraven
550227825Stheraven    void __make_ready();
551227825Stheraven    _LIBCPP_INLINE_VISIBILITY
552262801Sdim    bool __is_ready() const {return (__state_ & ready) != 0;}
553227825Stheraven
554227825Stheraven    void set_value();
555227825Stheraven    void set_value_at_thread_exit();
556227825Stheraven
557227825Stheraven    void set_exception(exception_ptr __p);
558227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
559227825Stheraven
560227825Stheraven    void copy();
561227825Stheraven
562227825Stheraven    void wait();
563227825Stheraven    template <class _Rep, class _Period>
564227825Stheraven        future_status
565227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
566227825Stheraven    template <class _Clock, class _Duration>
567227825Stheraven        future_status
568227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
569227825Stheraven
570227825Stheraven    virtual void __execute();
571227825Stheraven};
572227825Stheraven
573227825Stheraventemplate <class _Clock, class _Duration>
574227825Stheravenfuture_status
575227825Stheraven__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
576227825Stheraven{
577227825Stheraven    unique_lock<mutex> __lk(__mut_);
578227825Stheraven    if (__state_ & deferred)
579227825Stheraven        return future_status::deferred;
580227825Stheraven    while (!(__state_ & ready) && _Clock::now() < __abs_time)
581227825Stheraven        __cv_.wait_until(__lk, __abs_time);
582227825Stheraven    if (__state_ & ready)
583227825Stheraven        return future_status::ready;
584227825Stheraven    return future_status::timeout;
585227825Stheraven}
586227825Stheraven
587227825Stheraventemplate <class _Rep, class _Period>
588227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
589227825Stheravenfuture_status
590227825Stheraven__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
591227825Stheraven{
592227825Stheraven    return wait_until(chrono::steady_clock::now() + __rel_time);
593227825Stheraven}
594227825Stheraven
595232950Stheraventemplate <class _Rp>
596227825Stheravenclass __assoc_state
597227825Stheraven    : public __assoc_sub_state
598227825Stheraven{
599227825Stheraven    typedef __assoc_sub_state base;
600232950Stheraven    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
601227825Stheravenprotected:
602232950Stheraven    _Up __value_;
603227825Stheraven
604227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
605227825Stheravenpublic:
606227825Stheraven
607227825Stheraven    template <class _Arg>
608227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
609227825Stheraven        void set_value(_Arg&& __arg);
610227825Stheraven#else
611227825Stheraven        void set_value(_Arg& __arg);
612227825Stheraven#endif
613227825Stheraven
614227825Stheraven    template <class _Arg>
615227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
616227825Stheraven        void set_value_at_thread_exit(_Arg&& __arg);
617227825Stheraven#else
618227825Stheraven        void set_value_at_thread_exit(_Arg& __arg);
619227825Stheraven#endif
620227825Stheraven
621232950Stheraven    _Rp move();
622232950Stheraven    typename add_lvalue_reference<_Rp>::type copy();
623227825Stheraven};
624227825Stheraven
625232950Stheraventemplate <class _Rp>
626227825Stheravenvoid
627232950Stheraven__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
628227825Stheraven{
629227825Stheraven    if (this->__state_ & base::__constructed)
630232950Stheraven        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
631227825Stheraven    delete this;
632227825Stheraven}
633227825Stheraven
634232950Stheraventemplate <class _Rp>
635227825Stheraventemplate <class _Arg>
636227825Stheravenvoid
637227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
638232950Stheraven__assoc_state<_Rp>::set_value(_Arg&& __arg)
639227825Stheraven#else
640232950Stheraven__assoc_state<_Rp>::set_value(_Arg& __arg)
641227825Stheraven#endif
642227825Stheraven{
643227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
644227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
645227825Stheraven    if (this->__has_value())
646227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
647227825Stheraven#endif
648232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
649227825Stheraven    this->__state_ |= base::__constructed | base::ready;
650227825Stheraven    __lk.unlock();
651227825Stheraven    __cv_.notify_all();
652227825Stheraven}
653227825Stheraven
654232950Stheraventemplate <class _Rp>
655227825Stheraventemplate <class _Arg>
656227825Stheravenvoid
657227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
658232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
659227825Stheraven#else
660232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
661227825Stheraven#endif
662227825Stheraven{
663227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
664227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
665227825Stheraven    if (this->__has_value())
666227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
667227825Stheraven#endif
668232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
669227825Stheraven    this->__state_ |= base::__constructed;
670227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
671227825Stheraven    __lk.unlock();
672227825Stheraven}
673227825Stheraven
674232950Stheraventemplate <class _Rp>
675232950Stheraven_Rp
676232950Stheraven__assoc_state<_Rp>::move()
677227825Stheraven{
678227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
679227825Stheraven    this->__sub_wait(__lk);
680227825Stheraven    if (this->__exception_ != nullptr)
681227825Stheraven        rethrow_exception(this->__exception_);
682232950Stheraven    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
683227825Stheraven}
684227825Stheraven
685232950Stheraventemplate <class _Rp>
686232950Stheraventypename add_lvalue_reference<_Rp>::type
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_);
693232950Stheraven    return *reinterpret_cast<_Rp*>(&__value_);
694227825Stheraven}
695227825Stheraven
696232950Stheraventemplate <class _Rp>
697232950Stheravenclass __assoc_state<_Rp&>
698227825Stheraven    : public __assoc_sub_state
699227825Stheraven{
700227825Stheraven    typedef __assoc_sub_state base;
701232950Stheraven    typedef _Rp* _Up;
702227825Stheravenprotected:
703232950Stheraven    _Up __value_;
704227825Stheraven
705227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
706227825Stheravenpublic:
707227825Stheraven
708232950Stheraven    void set_value(_Rp& __arg);
709232950Stheraven    void set_value_at_thread_exit(_Rp& __arg);
710227825Stheraven
711232950Stheraven    _Rp& copy();
712227825Stheraven};
713227825Stheraven
714232950Stheraventemplate <class _Rp>
715227825Stheravenvoid
716232950Stheraven__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
717227825Stheraven{
718227825Stheraven    delete this;
719227825Stheraven}
720227825Stheraven
721232950Stheraventemplate <class _Rp>
722227825Stheravenvoid
723232950Stheraven__assoc_state<_Rp&>::set_value(_Rp& __arg)
724227825Stheraven{
725227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
726227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
727227825Stheraven    if (this->__has_value())
728227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
729227825Stheraven#endif
730262801Sdim    __value_ = _VSTD::addressof(__arg);
731227825Stheraven    this->__state_ |= base::__constructed | base::ready;
732227825Stheraven    __lk.unlock();
733227825Stheraven    __cv_.notify_all();
734227825Stheraven}
735227825Stheraven
736232950Stheraventemplate <class _Rp>
737227825Stheravenvoid
738232950Stheraven__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
739227825Stheraven{
740227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
741227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
742227825Stheraven    if (this->__has_value())
743227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
744227825Stheraven#endif
745262801Sdim    __value_ = _VSTD::addressof(__arg);
746227825Stheraven    this->__state_ |= base::__constructed;
747227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
748227825Stheraven    __lk.unlock();
749227825Stheraven}
750227825Stheraven
751232950Stheraventemplate <class _Rp>
752232950Stheraven_Rp&
753232950Stheraven__assoc_state<_Rp&>::copy()
754227825Stheraven{
755227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
756227825Stheraven    this->__sub_wait(__lk);
757227825Stheraven    if (this->__exception_ != nullptr)
758227825Stheraven        rethrow_exception(this->__exception_);
759227825Stheraven    return *__value_;
760227825Stheraven}
761227825Stheraven
762232950Stheraventemplate <class _Rp, class _Alloc>
763227825Stheravenclass __assoc_state_alloc
764232950Stheraven    : public __assoc_state<_Rp>
765227825Stheraven{
766232950Stheraven    typedef __assoc_state<_Rp> base;
767227825Stheraven    _Alloc __alloc_;
768227825Stheraven
769227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
770227825Stheravenpublic:
771227825Stheraven    _LIBCPP_INLINE_VISIBILITY
772227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
773227825Stheraven        : __alloc_(__a) {}
774227825Stheraven};
775227825Stheraven
776232950Stheraventemplate <class _Rp, class _Alloc>
777227825Stheravenvoid
778232950Stheraven__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
779227825Stheraven{
780227825Stheraven    if (this->__state_ & base::__constructed)
781262801Sdim        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
782227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
783227825Stheraven    this->~__assoc_state_alloc();
784227825Stheraven    __a.deallocate(this, 1);
785227825Stheraven}
786227825Stheraven
787232950Stheraventemplate <class _Rp, class _Alloc>
788232950Stheravenclass __assoc_state_alloc<_Rp&, _Alloc>
789232950Stheraven    : public __assoc_state<_Rp&>
790227825Stheraven{
791232950Stheraven    typedef __assoc_state<_Rp&> base;
792227825Stheraven    _Alloc __alloc_;
793227825Stheraven
794227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
795227825Stheravenpublic:
796227825Stheraven    _LIBCPP_INLINE_VISIBILITY
797227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
798227825Stheraven        : __alloc_(__a) {}
799227825Stheraven};
800227825Stheraven
801232950Stheraventemplate <class _Rp, class _Alloc>
802227825Stheravenvoid
803232950Stheraven__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
804227825Stheraven{
805227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
806227825Stheraven    this->~__assoc_state_alloc();
807227825Stheraven    __a.deallocate(this, 1);
808227825Stheraven}
809227825Stheraven
810227825Stheraventemplate <class _Alloc>
811227825Stheravenclass __assoc_sub_state_alloc
812227825Stheraven    : public __assoc_sub_state
813227825Stheraven{
814227825Stheraven    typedef __assoc_sub_state base;
815227825Stheraven    _Alloc __alloc_;
816227825Stheraven
817227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
818227825Stheravenpublic:
819227825Stheraven    _LIBCPP_INLINE_VISIBILITY
820227825Stheraven    explicit __assoc_sub_state_alloc(const _Alloc& __a)
821227825Stheraven        : __alloc_(__a) {}
822227825Stheraven};
823227825Stheraven
824227825Stheraventemplate <class _Alloc>
825227825Stheravenvoid
826227825Stheraven__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
827227825Stheraven{
828227825Stheraven    typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
829227825Stheraven    this->~__assoc_sub_state_alloc();
830227825Stheraven    __a.deallocate(this, 1);
831227825Stheraven}
832227825Stheraven
833232950Stheraventemplate <class _Rp, class _Fp>
834227825Stheravenclass __deferred_assoc_state
835232950Stheraven    : public __assoc_state<_Rp>
836227825Stheraven{
837232950Stheraven    typedef __assoc_state<_Rp> base;
838227825Stheraven
839232950Stheraven    _Fp __func_;
840227825Stheraven
841227825Stheravenpublic:
842227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
843232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
844227825Stheraven#endif
845227825Stheraven
846227825Stheraven    virtual void __execute();
847227825Stheraven};
848227825Stheraven
849227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
850227825Stheraven
851232950Stheraventemplate <class _Rp, class _Fp>
852227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
853232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
854232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
855227825Stheraven{
856227825Stheraven    this->__set_deferred();
857227825Stheraven}
858227825Stheraven
859227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
860227825Stheraven
861232950Stheraventemplate <class _Rp, class _Fp>
862227825Stheravenvoid
863232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__execute()
864227825Stheraven{
865227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
866227825Stheraven    try
867227825Stheraven    {
868227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
869227825Stheraven        this->set_value(__func_());
870227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
871227825Stheraven    }
872227825Stheraven    catch (...)
873227825Stheraven    {
874227825Stheraven        this->set_exception(current_exception());
875227825Stheraven    }
876227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
877227825Stheraven}
878227825Stheraven
879232950Stheraventemplate <class _Fp>
880232950Stheravenclass __deferred_assoc_state<void, _Fp>
881227825Stheraven    : public __assoc_sub_state
882227825Stheraven{
883227825Stheraven    typedef __assoc_sub_state base;
884227825Stheraven
885232950Stheraven    _Fp __func_;
886227825Stheraven
887227825Stheravenpublic:
888227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
889232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
890227825Stheraven#endif
891227825Stheraven
892227825Stheraven    virtual void __execute();
893227825Stheraven};
894227825Stheraven
895227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
896227825Stheraven
897232950Stheraventemplate <class _Fp>
898227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
899232950Stheraven__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
900232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
901227825Stheraven{
902227825Stheraven    this->__set_deferred();
903227825Stheraven}
904227825Stheraven
905227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
906227825Stheraven
907232950Stheraventemplate <class _Fp>
908227825Stheravenvoid
909232950Stheraven__deferred_assoc_state<void, _Fp>::__execute()
910227825Stheraven{
911227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
912227825Stheraven    try
913227825Stheraven    {
914227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
915227825Stheraven        __func_();
916227825Stheraven        this->set_value();
917227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
918227825Stheraven    }
919227825Stheraven    catch (...)
920227825Stheraven    {
921227825Stheraven        this->set_exception(current_exception());
922227825Stheraven    }
923227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
924227825Stheraven}
925227825Stheraven
926232950Stheraventemplate <class _Rp, class _Fp>
927227825Stheravenclass __async_assoc_state
928232950Stheraven    : public __assoc_state<_Rp>
929227825Stheraven{
930232950Stheraven    typedef __assoc_state<_Rp> base;
931227825Stheraven
932232950Stheraven    _Fp __func_;
933227825Stheraven
934227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
935227825Stheravenpublic:
936227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
937232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
938227825Stheraven#endif
939227825Stheraven
940227825Stheraven    virtual void __execute();
941227825Stheraven};
942227825Stheraven
943227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
944227825Stheraven
945232950Stheraventemplate <class _Rp, class _Fp>
946227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
947232950Stheraven__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
948232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
949227825Stheraven{
950227825Stheraven}
951227825Stheraven
952227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
953227825Stheraven
954232950Stheraventemplate <class _Rp, class _Fp>
955227825Stheravenvoid
956232950Stheraven__async_assoc_state<_Rp, _Fp>::__execute()
957227825Stheraven{
958227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
959227825Stheraven    try
960227825Stheraven    {
961227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
962227825Stheraven        this->set_value(__func_());
963227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
964227825Stheraven    }
965227825Stheraven    catch (...)
966227825Stheraven    {
967227825Stheraven        this->set_exception(current_exception());
968227825Stheraven    }
969227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
970227825Stheraven}
971227825Stheraven
972232950Stheraventemplate <class _Rp, class _Fp>
973227825Stheravenvoid
974232950Stheraven__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
975227825Stheraven{
976227825Stheraven    this->wait();
977227825Stheraven    base::__on_zero_shared();
978227825Stheraven}
979227825Stheraven
980232950Stheraventemplate <class _Fp>
981232950Stheravenclass __async_assoc_state<void, _Fp>
982227825Stheraven    : public __assoc_sub_state
983227825Stheraven{
984227825Stheraven    typedef __assoc_sub_state base;
985227825Stheraven
986232950Stheraven    _Fp __func_;
987227825Stheraven
988227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
989227825Stheravenpublic:
990227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
991232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
992227825Stheraven#endif
993227825Stheraven
994227825Stheraven    virtual void __execute();
995227825Stheraven};
996227825Stheraven
997227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
998227825Stheraven
999232950Stheraventemplate <class _Fp>
1000227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1001232950Stheraven__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1002232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
1003227825Stheraven{
1004227825Stheraven}
1005227825Stheraven
1006227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1007227825Stheraven
1008232950Stheraventemplate <class _Fp>
1009227825Stheravenvoid
1010232950Stheraven__async_assoc_state<void, _Fp>::__execute()
1011227825Stheraven{
1012227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1013227825Stheraven    try
1014227825Stheraven    {
1015227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
1016227825Stheraven        __func_();
1017227825Stheraven        this->set_value();
1018227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1019227825Stheraven    }
1020227825Stheraven    catch (...)
1021227825Stheraven    {
1022227825Stheraven        this->set_exception(current_exception());
1023227825Stheraven    }
1024227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
1025227825Stheraven}
1026227825Stheraven
1027232950Stheraventemplate <class _Fp>
1028227825Stheravenvoid
1029232950Stheraven__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
1030227825Stheraven{
1031227825Stheraven    this->wait();
1032227825Stheraven    base::__on_zero_shared();
1033227825Stheraven}
1034227825Stheraven
1035262801Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1036262801Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
1037227825Stheraven
1038227825Stheraven// future
1039227825Stheraven
1040262801Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
1041227825Stheraven
1042232950Stheraventemplate <class _Rp, class _Fp>
1043232950Stheravenfuture<_Rp>
1044227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1045232950Stheraven__make_deferred_assoc_state(_Fp&& __f);
1046227825Stheraven#else
1047232950Stheraven__make_deferred_assoc_state(_Fp __f);
1048227825Stheraven#endif
1049227825Stheraven
1050232950Stheraventemplate <class _Rp, class _Fp>
1051232950Stheravenfuture<_Rp>
1052227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1053232950Stheraven__make_async_assoc_state(_Fp&& __f);
1054227825Stheraven#else
1055232950Stheraven__make_async_assoc_state(_Fp __f);
1056227825Stheraven#endif
1057227825Stheraven
1058232950Stheraventemplate <class _Rp>
1059262801Sdimclass _LIBCPP_TYPE_VIS_ONLY future
1060227825Stheraven{
1061232950Stheraven    __assoc_state<_Rp>* __state_;
1062227825Stheraven
1063232950Stheraven    explicit future(__assoc_state<_Rp>* __state);
1064227825Stheraven
1065227825Stheraven    template <class> friend class promise;
1066227825Stheraven    template <class> friend class shared_future;
1067227825Stheraven
1068227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1069232950Stheraven    template <class _R1, class _Fp>
1070232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1071232950Stheraven    template <class _R1, class _Fp>
1072232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1073227825Stheraven#else
1074232950Stheraven    template <class _R1, class _Fp>
1075232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1076232950Stheraven    template <class _R1, class _Fp>
1077232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1078227825Stheraven#endif
1079227825Stheraven
1080227825Stheravenpublic:
1081227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1082241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1083227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1084227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1085241903Sdim    future(future&& __rhs) _NOEXCEPT
1086227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1087227825Stheraven    future(const future&) = delete;
1088227825Stheraven    future& operator=(const future&) = delete;
1089227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1090241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1091227825Stheraven        {
1092227825Stheraven            future(std::move(__rhs)).swap(*this);
1093227825Stheraven            return *this;
1094227825Stheraven        }
1095227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1096227825Stheravenprivate:
1097227825Stheraven    future(const future&);
1098227825Stheraven    future& operator=(const future&);
1099227825Stheravenpublic:
1100227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1101227825Stheraven    ~future();
1102232950Stheraven    shared_future<_Rp> share();
1103227825Stheraven
1104227825Stheraven    // retrieving the value
1105232950Stheraven    _Rp get();
1106227825Stheraven
1107227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1108241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1109227825Stheraven
1110227825Stheraven    // functions to check state
1111227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1112241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1113227825Stheraven
1114227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1115227825Stheraven    void wait() const {__state_->wait();}
1116227825Stheraven    template <class _Rep, class _Period>
1117227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1118227825Stheraven        future_status
1119227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1120227825Stheraven            {return __state_->wait_for(__rel_time);}
1121227825Stheraven    template <class _Clock, class _Duration>
1122227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1123227825Stheraven        future_status
1124227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1125227825Stheraven            {return __state_->wait_until(__abs_time);}
1126227825Stheraven};
1127227825Stheraven
1128232950Stheraventemplate <class _Rp>
1129232950Stheravenfuture<_Rp>::future(__assoc_state<_Rp>* __state)
1130227825Stheraven    : __state_(__state)
1131227825Stheraven{
1132227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1133227825Stheraven    if (__state_->__has_future_attached())
1134227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1135227825Stheraven#endif
1136227825Stheraven    __state_->__add_shared();
1137227825Stheraven    __state_->__set_future_attached();
1138227825Stheraven}
1139227825Stheraven
1140227825Stheravenstruct __release_shared_count
1141227825Stheraven{
1142227825Stheraven    void operator()(__shared_count* p) {p->__release_shared();}
1143227825Stheraven};
1144227825Stheraven
1145232950Stheraventemplate <class _Rp>
1146232950Stheravenfuture<_Rp>::~future()
1147227825Stheraven{
1148227825Stheraven    if (__state_)
1149227825Stheraven        __state_->__release_shared();
1150227825Stheraven}
1151227825Stheraven
1152232950Stheraventemplate <class _Rp>
1153232950Stheraven_Rp
1154232950Stheravenfuture<_Rp>::get()
1155227825Stheraven{
1156227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1157232950Stheraven    __assoc_state<_Rp>* __s = __state_;
1158227825Stheraven    __state_ = nullptr;
1159227825Stheraven    return __s->move();
1160227825Stheraven}
1161227825Stheraven
1162232950Stheraventemplate <class _Rp>
1163262801Sdimclass _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
1164227825Stheraven{
1165232950Stheraven    __assoc_state<_Rp&>* __state_;
1166227825Stheraven
1167232950Stheraven    explicit future(__assoc_state<_Rp&>* __state);
1168227825Stheraven
1169227825Stheraven    template <class> friend class promise;
1170227825Stheraven    template <class> friend class shared_future;
1171227825Stheraven
1172227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1173232950Stheraven    template <class _R1, class _Fp>
1174232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1175232950Stheraven    template <class _R1, class _Fp>
1176232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1177227825Stheraven#else
1178232950Stheraven    template <class _R1, class _Fp>
1179232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1180232950Stheraven    template <class _R1, class _Fp>
1181232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1182227825Stheraven#endif
1183227825Stheraven
1184227825Stheravenpublic:
1185227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1186241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1187227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1188227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1189241903Sdim    future(future&& __rhs) _NOEXCEPT
1190227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1191227825Stheraven    future(const future&) = delete;
1192227825Stheraven    future& operator=(const future&) = delete;
1193227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1194241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1195227825Stheraven        {
1196227825Stheraven            future(std::move(__rhs)).swap(*this);
1197227825Stheraven            return *this;
1198227825Stheraven        }
1199227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1200227825Stheravenprivate:
1201227825Stheraven    future(const future&);
1202227825Stheraven    future& operator=(const future&);
1203227825Stheravenpublic:
1204227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1205227825Stheraven    ~future();
1206232950Stheraven    shared_future<_Rp&> share();
1207227825Stheraven
1208227825Stheraven    // retrieving the value
1209232950Stheraven    _Rp& get();
1210227825Stheraven
1211227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1212241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1213227825Stheraven
1214227825Stheraven    // functions to check state
1215227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1216241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1217227825Stheraven
1218227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1219227825Stheraven    void wait() const {__state_->wait();}
1220227825Stheraven    template <class _Rep, class _Period>
1221227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1222227825Stheraven        future_status
1223227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1224227825Stheraven            {return __state_->wait_for(__rel_time);}
1225227825Stheraven    template <class _Clock, class _Duration>
1226227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1227227825Stheraven        future_status
1228227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1229227825Stheraven            {return __state_->wait_until(__abs_time);}
1230227825Stheraven};
1231227825Stheraven
1232232950Stheraventemplate <class _Rp>
1233232950Stheravenfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
1234227825Stheraven    : __state_(__state)
1235227825Stheraven{
1236227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1237227825Stheraven    if (__state_->__has_future_attached())
1238227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1239227825Stheraven#endif
1240227825Stheraven    __state_->__add_shared();
1241227825Stheraven    __state_->__set_future_attached();
1242227825Stheraven}
1243227825Stheraven
1244232950Stheraventemplate <class _Rp>
1245232950Stheravenfuture<_Rp&>::~future()
1246227825Stheraven{
1247227825Stheraven    if (__state_)
1248227825Stheraven        __state_->__release_shared();
1249227825Stheraven}
1250227825Stheraven
1251232950Stheraventemplate <class _Rp>
1252232950Stheraven_Rp&
1253232950Stheravenfuture<_Rp&>::get()
1254227825Stheraven{
1255227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1256232950Stheraven    __assoc_state<_Rp&>* __s = __state_;
1257227825Stheraven    __state_ = nullptr;
1258227825Stheraven    return __s->copy();
1259227825Stheraven}
1260227825Stheraven
1261227825Stheraventemplate <>
1262249998Sdimclass _LIBCPP_TYPE_VIS future<void>
1263227825Stheraven{
1264227825Stheraven    __assoc_sub_state* __state_;
1265227825Stheraven
1266227825Stheraven    explicit future(__assoc_sub_state* __state);
1267227825Stheraven
1268227825Stheraven    template <class> friend class promise;
1269227825Stheraven    template <class> friend class shared_future;
1270227825Stheraven
1271227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1272232950Stheraven    template <class _R1, class _Fp>
1273232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1274232950Stheraven    template <class _R1, class _Fp>
1275232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1276227825Stheraven#else
1277232950Stheraven    template <class _R1, class _Fp>
1278232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1279232950Stheraven    template <class _R1, class _Fp>
1280232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1281227825Stheraven#endif
1282227825Stheraven
1283227825Stheravenpublic:
1284227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1285241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1286227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1287227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1288241903Sdim    future(future&& __rhs) _NOEXCEPT
1289227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1290227825Stheraven    future(const future&) = delete;
1291227825Stheraven    future& operator=(const future&) = delete;
1292227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1293241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1294227825Stheraven        {
1295227825Stheraven            future(std::move(__rhs)).swap(*this);
1296227825Stheraven            return *this;
1297227825Stheraven        }
1298227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1299227825Stheravenprivate:
1300227825Stheraven    future(const future&);
1301227825Stheraven    future& operator=(const future&);
1302227825Stheravenpublic:
1303227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1304227825Stheraven    ~future();
1305227825Stheraven    shared_future<void> share();
1306227825Stheraven
1307227825Stheraven    // retrieving the value
1308227825Stheraven    void get();
1309227825Stheraven
1310227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1311241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1312227825Stheraven
1313227825Stheraven    // functions to check state
1314227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1315241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1316227825Stheraven
1317227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1318227825Stheraven    void wait() const {__state_->wait();}
1319227825Stheraven    template <class _Rep, class _Period>
1320227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1321227825Stheraven        future_status
1322227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1323227825Stheraven            {return __state_->wait_for(__rel_time);}
1324227825Stheraven    template <class _Clock, class _Duration>
1325227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1326227825Stheraven        future_status
1327227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1328227825Stheraven            {return __state_->wait_until(__abs_time);}
1329227825Stheraven};
1330227825Stheraven
1331232950Stheraventemplate <class _Rp>
1332227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1333227825Stheravenvoid
1334241903Sdimswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1335227825Stheraven{
1336227825Stheraven    __x.swap(__y);
1337227825Stheraven}
1338227825Stheraven
1339227825Stheraven// promise<R>
1340227825Stheraven
1341227825Stheraventemplate <class _Callable> class packaged_task;
1342227825Stheraven
1343232950Stheraventemplate <class _Rp>
1344262801Sdimclass _LIBCPP_TYPE_VIS_ONLY promise
1345227825Stheraven{
1346232950Stheraven    __assoc_state<_Rp>* __state_;
1347227825Stheraven
1348227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1349241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1350227825Stheraven
1351227825Stheraven    template <class> friend class packaged_task;
1352227825Stheravenpublic:
1353227825Stheraven    promise();
1354227825Stheraven    template <class _Alloc>
1355227825Stheraven        promise(allocator_arg_t, const _Alloc& __a);
1356227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1357227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1358241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1359227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1360227825Stheraven    promise(const promise& __rhs) = delete;
1361227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1362227825Stheravenprivate:
1363227825Stheraven    promise(const promise& __rhs);
1364227825Stheravenpublic:
1365227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1366227825Stheraven    ~promise();
1367227825Stheraven
1368227825Stheraven    // assignment
1369227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1370227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1371241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1372227825Stheraven        {
1373227825Stheraven            promise(std::move(__rhs)).swap(*this);
1374227825Stheraven            return *this;
1375227825Stheraven        }
1376227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1377227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1378227825Stheravenprivate:
1379227825Stheraven    promise& operator=(const promise& __rhs);
1380227825Stheravenpublic:
1381227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1382227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1383241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1384227825Stheraven
1385227825Stheraven    // retrieving the result
1386232950Stheraven    future<_Rp> get_future();
1387227825Stheraven
1388227825Stheraven    // setting the result
1389232950Stheraven    void set_value(const _Rp& __r);
1390227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391232950Stheraven    void set_value(_Rp&& __r);
1392227825Stheraven#endif
1393227825Stheraven    void set_exception(exception_ptr __p);
1394227825Stheraven
1395227825Stheraven    // setting the result with deferred notification
1396232950Stheraven    void set_value_at_thread_exit(const _Rp& __r);
1397227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1398232950Stheraven    void set_value_at_thread_exit(_Rp&& __r);
1399227825Stheraven#endif
1400227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1401227825Stheraven};
1402227825Stheraven
1403232950Stheraventemplate <class _Rp>
1404232950Stheravenpromise<_Rp>::promise()
1405232950Stheraven    : __state_(new __assoc_state<_Rp>)
1406227825Stheraven{
1407227825Stheraven}
1408227825Stheraven
1409232950Stheraventemplate <class _Rp>
1410227825Stheraventemplate <class _Alloc>
1411232950Stheravenpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1412227825Stheraven{
1413232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
1414227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1415227825Stheraven    _A2 __a(__a0);
1416232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1417232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
1418227825Stheraven    __state_ = __hold.release();
1419227825Stheraven}
1420227825Stheraven
1421232950Stheraventemplate <class _Rp>
1422232950Stheravenpromise<_Rp>::~promise()
1423227825Stheraven{
1424227825Stheraven    if (__state_)
1425227825Stheraven    {
1426227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1427227825Stheraven            __state_->set_exception(make_exception_ptr(
1428227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1429227825Stheraven                                                      ));
1430227825Stheraven        __state_->__release_shared();
1431227825Stheraven    }
1432227825Stheraven}
1433227825Stheraven
1434232950Stheraventemplate <class _Rp>
1435232950Stheravenfuture<_Rp>
1436232950Stheravenpromise<_Rp>::get_future()
1437227825Stheraven{
1438227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1439227825Stheraven    if (__state_ == nullptr)
1440227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1441227825Stheraven#endif
1442232950Stheraven    return future<_Rp>(__state_);
1443227825Stheraven}
1444227825Stheraven
1445232950Stheraventemplate <class _Rp>
1446227825Stheravenvoid
1447232950Stheravenpromise<_Rp>::set_value(const _Rp& __r)
1448227825Stheraven{
1449227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1450227825Stheraven    if (__state_ == nullptr)
1451227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1452227825Stheraven#endif
1453227825Stheraven    __state_->set_value(__r);
1454227825Stheraven}
1455227825Stheraven
1456227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1457227825Stheraven
1458232950Stheraventemplate <class _Rp>
1459227825Stheravenvoid
1460232950Stheravenpromise<_Rp>::set_value(_Rp&& __r)
1461227825Stheraven{
1462227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1463227825Stheraven    if (__state_ == nullptr)
1464227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1465227825Stheraven#endif
1466227825Stheraven    __state_->set_value(_VSTD::move(__r));
1467227825Stheraven}
1468227825Stheraven
1469227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1470227825Stheraven
1471232950Stheraventemplate <class _Rp>
1472227825Stheravenvoid
1473232950Stheravenpromise<_Rp>::set_exception(exception_ptr __p)
1474227825Stheraven{
1475227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1476227825Stheraven    if (__state_ == nullptr)
1477227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1478227825Stheraven#endif
1479227825Stheraven    __state_->set_exception(__p);
1480227825Stheraven}
1481227825Stheraven
1482232950Stheraventemplate <class _Rp>
1483227825Stheravenvoid
1484232950Stheravenpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1485227825Stheraven{
1486227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1487227825Stheraven    if (__state_ == nullptr)
1488227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1489227825Stheraven#endif
1490227825Stheraven    __state_->set_value_at_thread_exit(__r);
1491227825Stheraven}
1492227825Stheraven
1493227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1494227825Stheraven
1495232950Stheraventemplate <class _Rp>
1496227825Stheravenvoid
1497232950Stheravenpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1498227825Stheraven{
1499227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1500227825Stheraven    if (__state_ == nullptr)
1501227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1502227825Stheraven#endif
1503227825Stheraven    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1504227825Stheraven}
1505227825Stheraven
1506227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1507227825Stheraven
1508232950Stheraventemplate <class _Rp>
1509227825Stheravenvoid
1510232950Stheravenpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1511227825Stheraven{
1512227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1513227825Stheraven    if (__state_ == nullptr)
1514227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1515227825Stheraven#endif
1516227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1517227825Stheraven}
1518227825Stheraven
1519227825Stheraven// promise<R&>
1520227825Stheraven
1521232950Stheraventemplate <class _Rp>
1522262801Sdimclass _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
1523227825Stheraven{
1524232950Stheraven    __assoc_state<_Rp&>* __state_;
1525227825Stheraven
1526227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1527241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1528227825Stheraven
1529227825Stheraven    template <class> friend class packaged_task;
1530227825Stheraven
1531227825Stheravenpublic:
1532227825Stheraven    promise();
1533227825Stheraven    template <class _Allocator>
1534227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1535227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1536227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1537241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1538227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1539227825Stheraven    promise(const promise& __rhs) = delete;
1540227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1541227825Stheravenprivate:
1542227825Stheraven    promise(const promise& __rhs);
1543227825Stheravenpublic:
1544227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1545227825Stheraven    ~promise();
1546227825Stheraven
1547227825Stheraven    // assignment
1548227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1549227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1550241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1551227825Stheraven        {
1552227825Stheraven            promise(std::move(__rhs)).swap(*this);
1553227825Stheraven            return *this;
1554227825Stheraven        }
1555227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1556227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1557227825Stheravenprivate:
1558227825Stheraven    promise& operator=(const promise& __rhs);
1559227825Stheravenpublic:
1560227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1561227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1562241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1563227825Stheraven
1564227825Stheraven    // retrieving the result
1565232950Stheraven    future<_Rp&> get_future();
1566227825Stheraven
1567227825Stheraven    // setting the result
1568232950Stheraven    void set_value(_Rp& __r);
1569227825Stheraven    void set_exception(exception_ptr __p);
1570227825Stheraven
1571227825Stheraven    // setting the result with deferred notification
1572232950Stheraven    void set_value_at_thread_exit(_Rp&);
1573227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1574227825Stheraven};
1575227825Stheraven
1576232950Stheraventemplate <class _Rp>
1577232950Stheravenpromise<_Rp&>::promise()
1578232950Stheraven    : __state_(new __assoc_state<_Rp&>)
1579227825Stheraven{
1580227825Stheraven}
1581227825Stheraven
1582232950Stheraventemplate <class _Rp>
1583227825Stheraventemplate <class _Alloc>
1584232950Stheravenpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1585227825Stheraven{
1586232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
1587227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1588227825Stheraven    _A2 __a(__a0);
1589232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1590232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
1591227825Stheraven    __state_ = __hold.release();
1592227825Stheraven}
1593227825Stheraven
1594232950Stheraventemplate <class _Rp>
1595232950Stheravenpromise<_Rp&>::~promise()
1596227825Stheraven{
1597227825Stheraven    if (__state_)
1598227825Stheraven    {
1599227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1600227825Stheraven            __state_->set_exception(make_exception_ptr(
1601227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1602227825Stheraven                                                      ));
1603227825Stheraven        __state_->__release_shared();
1604227825Stheraven    }
1605227825Stheraven}
1606227825Stheraven
1607232950Stheraventemplate <class _Rp>
1608232950Stheravenfuture<_Rp&>
1609232950Stheravenpromise<_Rp&>::get_future()
1610227825Stheraven{
1611227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1612227825Stheraven    if (__state_ == nullptr)
1613227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1614227825Stheraven#endif
1615232950Stheraven    return future<_Rp&>(__state_);
1616227825Stheraven}
1617227825Stheraven
1618232950Stheraventemplate <class _Rp>
1619227825Stheravenvoid
1620232950Stheravenpromise<_Rp&>::set_value(_Rp& __r)
1621227825Stheraven{
1622227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1623227825Stheraven    if (__state_ == nullptr)
1624227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1625227825Stheraven#endif
1626227825Stheraven    __state_->set_value(__r);
1627227825Stheraven}
1628227825Stheraven
1629232950Stheraventemplate <class _Rp>
1630227825Stheravenvoid
1631232950Stheravenpromise<_Rp&>::set_exception(exception_ptr __p)
1632227825Stheraven{
1633227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1634227825Stheraven    if (__state_ == nullptr)
1635227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1636227825Stheraven#endif
1637227825Stheraven    __state_->set_exception(__p);
1638227825Stheraven}
1639227825Stheraven
1640232950Stheraventemplate <class _Rp>
1641227825Stheravenvoid
1642232950Stheravenpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1643227825Stheraven{
1644227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1645227825Stheraven    if (__state_ == nullptr)
1646227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1647227825Stheraven#endif
1648227825Stheraven    __state_->set_value_at_thread_exit(__r);
1649227825Stheraven}
1650227825Stheraven
1651232950Stheraventemplate <class _Rp>
1652227825Stheravenvoid
1653232950Stheravenpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1654227825Stheraven{
1655227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1656227825Stheraven    if (__state_ == nullptr)
1657227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1658227825Stheraven#endif
1659227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1660227825Stheraven}
1661227825Stheraven
1662227825Stheraven// promise<void>
1663227825Stheraven
1664227825Stheraventemplate <>
1665249998Sdimclass _LIBCPP_TYPE_VIS promise<void>
1666227825Stheraven{
1667227825Stheraven    __assoc_sub_state* __state_;
1668227825Stheraven
1669227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1670241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1671227825Stheraven
1672227825Stheraven    template <class> friend class packaged_task;
1673227825Stheraven
1674227825Stheravenpublic:
1675227825Stheraven    promise();
1676227825Stheraven    template <class _Allocator>
1677227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1678227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1679227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1680241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1681227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1682227825Stheraven    promise(const promise& __rhs) = delete;
1683227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1684227825Stheravenprivate:
1685227825Stheraven    promise(const promise& __rhs);
1686227825Stheravenpublic:
1687227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1688227825Stheraven    ~promise();
1689227825Stheraven
1690227825Stheraven    // assignment
1691227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1692227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1693241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1694227825Stheraven        {
1695227825Stheraven            promise(std::move(__rhs)).swap(*this);
1696227825Stheraven            return *this;
1697227825Stheraven        }
1698227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1699227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1700227825Stheravenprivate:
1701227825Stheraven    promise& operator=(const promise& __rhs);
1702227825Stheravenpublic:
1703227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1704227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1705241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1706227825Stheraven
1707227825Stheraven    // retrieving the result
1708227825Stheraven    future<void> get_future();
1709227825Stheraven
1710227825Stheraven    // setting the result
1711227825Stheraven    void set_value();
1712227825Stheraven    void set_exception(exception_ptr __p);
1713227825Stheraven
1714227825Stheraven    // setting the result with deferred notification
1715227825Stheraven    void set_value_at_thread_exit();
1716227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1717227825Stheraven};
1718227825Stheraven
1719227825Stheraventemplate <class _Alloc>
1720227825Stheravenpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1721227825Stheraven{
1722227825Stheraven    typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1723227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1724227825Stheraven    _A2 __a(__a0);
1725227825Stheraven    unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1726227825Stheraven    ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1727227825Stheraven    __state_ = __hold.release();
1728227825Stheraven}
1729227825Stheraven
1730232950Stheraventemplate <class _Rp>
1731227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1732227825Stheravenvoid
1733241903Sdimswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1734227825Stheraven{
1735227825Stheraven    __x.swap(__y);
1736227825Stheraven}
1737227825Stheraven
1738232950Stheraventemplate <class _Rp, class _Alloc>
1739262801Sdim    struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
1740227825Stheraven        : public true_type {};
1741227825Stheraven
1742227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
1743227825Stheraven
1744227825Stheraven// packaged_task
1745227825Stheraven
1746227825Stheraventemplate<class _Fp> class __packaged_task_base;
1747227825Stheraven
1748232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1749232950Stheravenclass __packaged_task_base<_Rp(_ArgTypes...)>
1750227825Stheraven{
1751227825Stheraven    __packaged_task_base(const __packaged_task_base&);
1752227825Stheraven    __packaged_task_base& operator=(const __packaged_task_base&);
1753227825Stheravenpublic:
1754227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1755227825Stheraven    __packaged_task_base() {}
1756227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1757227825Stheraven    virtual ~__packaged_task_base() {}
1758241903Sdim    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1759227825Stheraven    virtual void destroy() = 0;
1760227825Stheraven    virtual void destroy_deallocate() = 0;
1761232950Stheraven    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1762227825Stheraven};
1763227825Stheraven
1764227825Stheraventemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1765227825Stheraven
1766232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1767232950Stheravenclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1768232950Stheraven    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1769227825Stheraven{
1770232950Stheraven    __compressed_pair<_Fp, _Alloc> __f_;
1771227825Stheravenpublic:
1772227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1773232950Stheraven    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1774227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1775232950Stheraven    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1776227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1777232950Stheraven    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1778227825Stheraven        : __f_(__f, __a) {}
1779227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1780232950Stheraven    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1781227825Stheraven        : __f_(_VSTD::move(__f), __a) {}
1782241903Sdim    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1783227825Stheraven    virtual void destroy();
1784227825Stheraven    virtual void destroy_deallocate();
1785232950Stheraven    virtual _Rp operator()(_ArgTypes&& ... __args);
1786227825Stheraven};
1787227825Stheraven
1788232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1789227825Stheravenvoid
1790232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1791241903Sdim                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1792227825Stheraven{
1793227825Stheraven    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1794227825Stheraven}
1795227825Stheraven
1796232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1797227825Stheravenvoid
1798232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1799227825Stheraven{
1800232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1801227825Stheraven}
1802227825Stheraven
1803232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1804227825Stheravenvoid
1805232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1806227825Stheraven{
1807232950Stheraven    typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1808232950Stheraven    _Ap __a(__f_.second());
1809232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1810227825Stheraven    __a.deallocate(this, 1);
1811227825Stheraven}
1812227825Stheraven
1813232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1814232950Stheraven_Rp
1815232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1816227825Stheraven{
1817227825Stheraven    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1818227825Stheraven}
1819227825Stheraven
1820227825Stheraventemplate <class _Callable> class __packaged_task_function;
1821227825Stheraven
1822232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1823232950Stheravenclass __packaged_task_function<_Rp(_ArgTypes...)>
1824227825Stheraven{
1825232950Stheraven    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1826246487Stheraven    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1827227825Stheraven    __base* __f_;
1828227825Stheraven
1829227825Stheravenpublic:
1830232950Stheraven    typedef _Rp result_type;
1831227825Stheraven
1832227825Stheraven    // construct/copy/destroy:
1833227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1834241903Sdim    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1835232950Stheraven    template<class _Fp>
1836232950Stheraven      __packaged_task_function(_Fp&& __f);
1837232950Stheraven    template<class _Fp, class _Alloc>
1838232950Stheraven      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1839227825Stheraven
1840241903Sdim    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1841241903Sdim    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1842227825Stheraven
1843227825Stheraven    __packaged_task_function(const __packaged_task_function&) =  delete;
1844227825Stheraven    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1845227825Stheraven
1846227825Stheraven    ~__packaged_task_function();
1847227825Stheraven
1848241903Sdim    void swap(__packaged_task_function&) _NOEXCEPT;
1849227825Stheraven
1850232950Stheraven    _Rp operator()(_ArgTypes...) const;
1851227825Stheraven};
1852227825Stheraven
1853232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1854241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1855227825Stheraven{
1856227825Stheraven    if (__f.__f_ == nullptr)
1857227825Stheraven        __f_ = nullptr;
1858227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1859227825Stheraven    {
1860227825Stheraven        __f_ = (__base*)&__buf_;
1861227825Stheraven        __f.__f_->__move_to(__f_);
1862227825Stheraven    }
1863227825Stheraven    else
1864227825Stheraven    {
1865227825Stheraven        __f_ = __f.__f_;
1866227825Stheraven        __f.__f_ = nullptr;
1867227825Stheraven    }
1868227825Stheraven}
1869227825Stheraven
1870232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1871232950Stheraventemplate <class _Fp>
1872232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1873227825Stheraven    : __f_(nullptr)
1874227825Stheraven{
1875232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1876232950Stheraven    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1877227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1878227825Stheraven    {
1879227825Stheraven        __f_ = (__base*)&__buf_;
1880232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1881227825Stheraven    }
1882227825Stheraven    else
1883227825Stheraven    {
1884232950Stheraven        typedef allocator<_FF> _Ap;
1885232950Stheraven        _Ap __a;
1886232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1887232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1888232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1889227825Stheraven        __f_ = __hold.release();
1890227825Stheraven    }
1891227825Stheraven}
1892227825Stheraven
1893232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1894232950Stheraventemplate <class _Fp, class _Alloc>
1895232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1896232950Stheraven                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1897227825Stheraven    : __f_(nullptr)
1898227825Stheraven{
1899227825Stheraven    typedef allocator_traits<_Alloc> __alloc_traits;
1900232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1901232950Stheraven    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1902227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1903227825Stheraven    {
1904227825Stheraven        __f_ = (__base*)&__buf_;
1905232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1906227825Stheraven    }
1907227825Stheraven    else
1908227825Stheraven    {
1909227825Stheraven        typedef typename __alloc_traits::template
1910227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1911227825Stheraven            rebind_alloc<_FF>
1912227825Stheraven#else
1913227825Stheraven            rebind_alloc<_FF>::other
1914227825Stheraven#endif
1915232950Stheraven                                                     _Ap;
1916232950Stheraven        _Ap __a(__a0);
1917232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1918232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1919232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1920227825Stheraven        __f_ = __hold.release();
1921227825Stheraven    }
1922227825Stheraven}
1923227825Stheraven
1924232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1925232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>&
1926241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1927227825Stheraven{
1928227825Stheraven    if (__f_ == (__base*)&__buf_)
1929227825Stheraven        __f_->destroy();
1930227825Stheraven    else if (__f_)
1931227825Stheraven        __f_->destroy_deallocate();
1932227825Stheraven    __f_ = nullptr;
1933227825Stheraven    if (__f.__f_ == nullptr)
1934227825Stheraven        __f_ = nullptr;
1935227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1936227825Stheraven    {
1937227825Stheraven        __f_ = (__base*)&__buf_;
1938227825Stheraven        __f.__f_->__move_to(__f_);
1939227825Stheraven    }
1940227825Stheraven    else
1941227825Stheraven    {
1942227825Stheraven        __f_ = __f.__f_;
1943227825Stheraven        __f.__f_ = nullptr;
1944227825Stheraven    }
1945241903Sdim    return *this;
1946227825Stheraven}
1947227825Stheraven
1948232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1949232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1950227825Stheraven{
1951227825Stheraven    if (__f_ == (__base*)&__buf_)
1952227825Stheraven        __f_->destroy();
1953227825Stheraven    else if (__f_)
1954227825Stheraven        __f_->destroy_deallocate();
1955227825Stheraven}
1956227825Stheraven
1957232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1958227825Stheravenvoid
1959241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1960227825Stheraven{
1961227825Stheraven    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1962227825Stheraven    {
1963227825Stheraven        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1964227825Stheraven        __base* __t = (__base*)&__tempbuf;
1965227825Stheraven        __f_->__move_to(__t);
1966227825Stheraven        __f_->destroy();
1967227825Stheraven        __f_ = nullptr;
1968227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1969227825Stheraven        __f.__f_->destroy();
1970227825Stheraven        __f.__f_ = nullptr;
1971227825Stheraven        __f_ = (__base*)&__buf_;
1972227825Stheraven        __t->__move_to((__base*)&__f.__buf_);
1973227825Stheraven        __t->destroy();
1974227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1975227825Stheraven    }
1976227825Stheraven    else if (__f_ == (__base*)&__buf_)
1977227825Stheraven    {
1978227825Stheraven        __f_->__move_to((__base*)&__f.__buf_);
1979227825Stheraven        __f_->destroy();
1980227825Stheraven        __f_ = __f.__f_;
1981227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1982227825Stheraven    }
1983227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1984227825Stheraven    {
1985227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1986227825Stheraven        __f.__f_->destroy();
1987227825Stheraven        __f.__f_ = __f_;
1988227825Stheraven        __f_ = (__base*)&__buf_;
1989227825Stheraven    }
1990227825Stheraven    else
1991227825Stheraven        _VSTD::swap(__f_, __f.__f_);
1992227825Stheraven}
1993227825Stheraven
1994232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1995227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1996232950Stheraven_Rp
1997232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1998227825Stheraven{
1999227825Stheraven    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
2000227825Stheraven}
2001227825Stheraven
2002232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2003262801Sdimclass _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
2004227825Stheraven{
2005227825Stheravenpublic:
2006232950Stheraven    typedef _Rp result_type;
2007227825Stheraven
2008227825Stheravenprivate:
2009227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2010227825Stheraven    promise<result_type>                                __p_;
2011227825Stheraven
2012227825Stheravenpublic:
2013227825Stheraven    // construction and destruction
2014227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2015241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2016262801Sdim    template <class _Fp,
2017262801Sdim              class = typename enable_if
2018262801Sdim              <
2019262801Sdim                  !is_same<
2020262801Sdim                      typename decay<_Fp>::type, 
2021262801Sdim                      packaged_task
2022262801Sdim                      >::value
2023262801Sdim                  >::type
2024262801Sdim             >
2025227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2026232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2027262801Sdim    template <class _Fp, class _Allocator,
2028262801Sdim              class = typename enable_if
2029262801Sdim              <
2030262801Sdim                  !is_same<
2031262801Sdim                      typename decay<_Fp>::type, 
2032262801Sdim                      packaged_task
2033262801Sdim                      >::value
2034262801Sdim                  >::type
2035262801Sdim              >
2036227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2037232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2038232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2039227825Stheraven               __p_(allocator_arg, __a) {}
2040227825Stheraven    // ~packaged_task() = default;
2041227825Stheraven
2042227825Stheraven    // no copy
2043241903Sdim    packaged_task(const packaged_task&) = delete;
2044241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2045227825Stheraven
2046227825Stheraven    // move support
2047227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2048241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2049227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2050227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2051241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2052227825Stheraven    {
2053227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2054227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2055227825Stheraven        return *this;
2056227825Stheraven    }
2057227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2058241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2059227825Stheraven    {
2060227825Stheraven        __f_.swap(__other.__f_);
2061227825Stheraven        __p_.swap(__other.__p_);
2062227825Stheraven    }
2063227825Stheraven
2064227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2065241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2066227825Stheraven
2067227825Stheraven    // result retrieval
2068227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2069227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2070227825Stheraven
2071227825Stheraven    // execution
2072227825Stheraven    void operator()(_ArgTypes... __args);
2073227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2074227825Stheraven
2075227825Stheraven    void reset();
2076227825Stheraven};
2077227825Stheraven
2078232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2079227825Stheravenvoid
2080232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
2081227825Stheraven{
2082227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2083227825Stheraven    if (__p_.__state_ == nullptr)
2084227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2085227825Stheraven    if (__p_.__state_->__has_value())
2086227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2087227825Stheraven    try
2088227825Stheraven    {
2089227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2090227825Stheraven        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2091227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2092227825Stheraven    }
2093227825Stheraven    catch (...)
2094227825Stheraven    {
2095227825Stheraven        __p_.set_exception(current_exception());
2096227825Stheraven    }
2097227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2098227825Stheraven}
2099227825Stheraven
2100232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2101227825Stheravenvoid
2102232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2103227825Stheraven{
2104227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2105227825Stheraven    if (__p_.__state_ == nullptr)
2106227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2107227825Stheraven    if (__p_.__state_->__has_value())
2108227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2109227825Stheraven    try
2110227825Stheraven    {
2111227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2112227825Stheraven        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2113227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2114227825Stheraven    }
2115227825Stheraven    catch (...)
2116227825Stheraven    {
2117227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2118227825Stheraven    }
2119227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2120227825Stheraven}
2121227825Stheraven
2122232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2123227825Stheravenvoid
2124232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::reset()
2125227825Stheraven{
2126227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2127227825Stheraven    if (!valid())
2128227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2129227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2130227825Stheraven    __p_ = promise<result_type>();
2131227825Stheraven}
2132227825Stheraven
2133227825Stheraventemplate<class ..._ArgTypes>
2134262801Sdimclass _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
2135227825Stheraven{
2136227825Stheravenpublic:
2137227825Stheraven    typedef void result_type;
2138227825Stheraven
2139227825Stheravenprivate:
2140227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2141227825Stheraven    promise<result_type>                                __p_;
2142227825Stheraven
2143227825Stheravenpublic:
2144227825Stheraven    // construction and destruction
2145227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2146241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2147262801Sdim    template <class _Fp,
2148262801Sdim              class = typename enable_if
2149262801Sdim              <
2150262801Sdim                  !is_same<
2151262801Sdim                      typename decay<_Fp>::type, 
2152262801Sdim                      packaged_task
2153262801Sdim                      >::value
2154262801Sdim                  >::type
2155262801Sdim              >
2156227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2157232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2158262801Sdim    template <class _Fp, class _Allocator,
2159262801Sdim              class = typename enable_if
2160262801Sdim              <
2161262801Sdim                  !is_same<
2162262801Sdim                      typename decay<_Fp>::type, 
2163262801Sdim                      packaged_task
2164262801Sdim                      >::value
2165262801Sdim                  >::type
2166262801Sdim              >    
2167227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2168232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2169232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2170227825Stheraven               __p_(allocator_arg, __a) {}
2171227825Stheraven    // ~packaged_task() = default;
2172227825Stheraven
2173227825Stheraven    // no copy
2174241903Sdim    packaged_task(const packaged_task&) = delete;
2175241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2176227825Stheraven
2177227825Stheraven    // move support
2178227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2179241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2180227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2181227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2182241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2183227825Stheraven    {
2184227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2185227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2186227825Stheraven        return *this;
2187227825Stheraven    }
2188227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2189241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2190227825Stheraven    {
2191227825Stheraven        __f_.swap(__other.__f_);
2192227825Stheraven        __p_.swap(__other.__p_);
2193227825Stheraven    }
2194227825Stheraven
2195227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2196241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2197227825Stheraven
2198227825Stheraven    // result retrieval
2199227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2200227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2201227825Stheraven
2202227825Stheraven    // execution
2203227825Stheraven    void operator()(_ArgTypes... __args);
2204227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2205227825Stheraven
2206227825Stheraven    void reset();
2207227825Stheraven};
2208227825Stheraven
2209227825Stheraventemplate<class ..._ArgTypes>
2210227825Stheravenvoid
2211227825Stheravenpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2212227825Stheraven{
2213227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2214227825Stheraven    if (__p_.__state_ == nullptr)
2215227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2216227825Stheraven    if (__p_.__state_->__has_value())
2217227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2218227825Stheraven    try
2219227825Stheraven    {
2220227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2221227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2222227825Stheraven        __p_.set_value();
2223227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2224227825Stheraven    }
2225227825Stheraven    catch (...)
2226227825Stheraven    {
2227227825Stheraven        __p_.set_exception(current_exception());
2228227825Stheraven    }
2229227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2230227825Stheraven}
2231227825Stheraven
2232227825Stheraventemplate<class ..._ArgTypes>
2233227825Stheravenvoid
2234227825Stheravenpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2235227825Stheraven{
2236227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2237227825Stheraven    if (__p_.__state_ == nullptr)
2238227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2239227825Stheraven    if (__p_.__state_->__has_value())
2240227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2241227825Stheraven    try
2242227825Stheraven    {
2243227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2244227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2245227825Stheraven        __p_.set_value_at_thread_exit();
2246227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2247227825Stheraven    }
2248227825Stheraven    catch (...)
2249227825Stheraven    {
2250227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2251227825Stheraven    }
2252227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2253227825Stheraven}
2254227825Stheraven
2255227825Stheraventemplate<class ..._ArgTypes>
2256227825Stheravenvoid
2257227825Stheravenpackaged_task<void(_ArgTypes...)>::reset()
2258227825Stheraven{
2259227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2260227825Stheraven    if (!valid())
2261227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2262227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2263227825Stheraven    __p_ = promise<result_type>();
2264227825Stheraven}
2265227825Stheraven
2266227825Stheraventemplate <class _Callable>
2267227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2268227825Stheravenvoid
2269241903Sdimswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2270227825Stheraven{
2271227825Stheraven    __x.swap(__y);
2272227825Stheraven}
2273227825Stheraven
2274227825Stheraventemplate <class _Callable, class _Alloc>
2275262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
2276227825Stheraven    : public true_type {};
2277227825Stheraven
2278232950Stheraventemplate <class _Rp, class _Fp>
2279232950Stheravenfuture<_Rp>
2280227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2281232950Stheraven__make_deferred_assoc_state(_Fp&& __f)
2282227825Stheraven#else
2283232950Stheraven__make_deferred_assoc_state(_Fp __f)
2284227825Stheraven#endif
2285227825Stheraven{
2286232950Stheraven    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2287232950Stheraven        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2288232950Stheraven    return future<_Rp>(__h.get());
2289227825Stheraven}
2290227825Stheraven
2291232950Stheraventemplate <class _Rp, class _Fp>
2292232950Stheravenfuture<_Rp>
2293227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2294232950Stheraven__make_async_assoc_state(_Fp&& __f)
2295227825Stheraven#else
2296232950Stheraven__make_async_assoc_state(_Fp __f)
2297227825Stheraven#endif
2298227825Stheraven{
2299232950Stheraven    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2300232950Stheraven        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2301232950Stheraven    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2302232950Stheraven    return future<_Rp>(__h.get());
2303227825Stheraven}
2304227825Stheraven
2305232950Stheraventemplate <class _Fp, class... _Args>
2306227825Stheravenclass __async_func
2307227825Stheraven{
2308232950Stheraven    tuple<_Fp, _Args...> __f_;
2309227825Stheraven
2310227825Stheravenpublic:
2311232950Stheraven    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2312227825Stheraven
2313227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2314232950Stheraven    explicit __async_func(_Fp&& __f, _Args&&... __args)
2315227825Stheraven        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2316227825Stheraven
2317227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2318227825Stheraven    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2319227825Stheraven
2320232950Stheraven    _Rp operator()()
2321227825Stheraven    {
2322227825Stheraven        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2323227825Stheraven        return __execute(_Index());
2324227825Stheraven    }
2325227825Stheravenprivate:
2326227825Stheraven    template <size_t ..._Indices>
2327232950Stheraven    _Rp
2328227825Stheraven    __execute(__tuple_indices<_Indices...>)
2329227825Stheraven    {
2330227825Stheraven        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2331227825Stheraven    }
2332227825Stheraven};
2333227825Stheraven
2334262801Sdiminline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
2335262801Sdim{ return (int(__policy) & int(__value)) != 0; }
2336262801Sdim
2337232950Stheraventemplate <class _Fp, class... _Args>
2338232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2339232950Stheravenasync(launch __policy, _Fp&& __f, _Args&&... __args)
2340227825Stheraven{
2341232950Stheraven    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2342232950Stheraven    typedef typename _BF::_Rp _Rp;
2343262801Sdim
2344262801Sdim#ifndef _LIBCPP_NO_EXCEPTIONS
2345262801Sdim    try
2346262801Sdim    {
2347262801Sdim#endif
2348262801Sdim        if (__does_policy_contain(__policy, launch::async))
2349262801Sdim        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2350227825Stheraven                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2351262801Sdim#ifndef _LIBCPP_NO_EXCEPTIONS
2352262801Sdim    }
2353262801Sdim    catch ( ... ) { if (__policy == launch::async) throw ; }
2354262801Sdim#endif
2355262801Sdim
2356262801Sdim    if (__does_policy_contain(__policy, launch::deferred))
2357262801Sdim        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2358227825Stheraven                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2359262801Sdim    return future<_Rp>{};
2360227825Stheraven}
2361227825Stheraven
2362232950Stheraventemplate <class _Fp, class... _Args>
2363227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2364232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2365232950Stheravenasync(_Fp&& __f, _Args&&... __args)
2366227825Stheraven{
2367232950Stheraven    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2368227825Stheraven                                    _VSTD::forward<_Args>(__args)...);
2369227825Stheraven}
2370227825Stheraven
2371227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
2372227825Stheraven
2373227825Stheraven// shared_future
2374227825Stheraven
2375232950Stheraventemplate <class _Rp>
2376262801Sdimclass _LIBCPP_TYPE_VIS_ONLY shared_future
2377227825Stheraven{
2378232950Stheraven    __assoc_state<_Rp>* __state_;
2379227825Stheraven
2380227825Stheravenpublic:
2381227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2382241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2383227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2384227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2385227825Stheraven        {if (__state_) __state_->__add_shared();}
2386227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2387227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2388241903Sdim    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2389227825Stheraven        {__f.__state_ = nullptr;}
2390227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2391241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2392227825Stheraven        {__rhs.__state_ = nullptr;}
2393227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2394227825Stheraven    ~shared_future();
2395227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2396227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2397227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2398241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2399227825Stheraven        {
2400227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2401227825Stheraven            return *this;
2402227825Stheraven        }
2403227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2404227825Stheraven
2405227825Stheraven    // retrieving the value
2406227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2407232950Stheraven    const _Rp& get() const {return __state_->copy();}
2408227825Stheraven
2409227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2410241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2411227825Stheraven
2412227825Stheraven    // functions to check state
2413227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2414241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2415227825Stheraven
2416227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2417227825Stheraven    void wait() const {__state_->wait();}
2418227825Stheraven    template <class _Rep, class _Period>
2419227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2420227825Stheraven        future_status
2421227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2422227825Stheraven            {return __state_->wait_for(__rel_time);}
2423227825Stheraven    template <class _Clock, class _Duration>
2424227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2425227825Stheraven        future_status
2426227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2427227825Stheraven            {return __state_->wait_until(__abs_time);}
2428227825Stheraven};
2429227825Stheraven
2430232950Stheraventemplate <class _Rp>
2431232950Stheravenshared_future<_Rp>::~shared_future()
2432227825Stheraven{
2433227825Stheraven    if (__state_)
2434227825Stheraven        __state_->__release_shared();
2435227825Stheraven}
2436227825Stheraven
2437232950Stheraventemplate <class _Rp>
2438232950Stheravenshared_future<_Rp>&
2439232950Stheravenshared_future<_Rp>::operator=(const shared_future& __rhs)
2440227825Stheraven{
2441227825Stheraven    if (__rhs.__state_)
2442227825Stheraven        __rhs.__state_->__add_shared();
2443227825Stheraven    if (__state_)
2444227825Stheraven        __state_->__release_shared();
2445227825Stheraven    __state_ = __rhs.__state_;
2446227825Stheraven    return *this;
2447227825Stheraven}
2448227825Stheraven
2449232950Stheraventemplate <class _Rp>
2450262801Sdimclass _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
2451227825Stheraven{
2452232950Stheraven    __assoc_state<_Rp&>* __state_;
2453227825Stheraven
2454227825Stheravenpublic:
2455227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2456241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2457227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2458227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2459227825Stheraven        {if (__state_) __state_->__add_shared();}
2460227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2461227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2462241903Sdim    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2463227825Stheraven        {__f.__state_ = nullptr;}
2464227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2465241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2466227825Stheraven        {__rhs.__state_ = nullptr;}
2467227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2468227825Stheraven    ~shared_future();
2469227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2470227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2471227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2472241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2473227825Stheraven        {
2474227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2475227825Stheraven            return *this;
2476227825Stheraven        }
2477227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2478227825Stheraven
2479227825Stheraven    // retrieving the value
2480227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2481232950Stheraven    _Rp& get() const {return __state_->copy();}
2482227825Stheraven
2483227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2484241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2485227825Stheraven
2486227825Stheraven    // functions to check state
2487227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2488241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2489227825Stheraven
2490227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2491227825Stheraven    void wait() const {__state_->wait();}
2492227825Stheraven    template <class _Rep, class _Period>
2493227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2494227825Stheraven        future_status
2495227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2496227825Stheraven            {return __state_->wait_for(__rel_time);}
2497227825Stheraven    template <class _Clock, class _Duration>
2498227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2499227825Stheraven        future_status
2500227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2501227825Stheraven            {return __state_->wait_until(__abs_time);}
2502227825Stheraven};
2503227825Stheraven
2504232950Stheraventemplate <class _Rp>
2505232950Stheravenshared_future<_Rp&>::~shared_future()
2506227825Stheraven{
2507227825Stheraven    if (__state_)
2508227825Stheraven        __state_->__release_shared();
2509227825Stheraven}
2510227825Stheraven
2511232950Stheraventemplate <class _Rp>
2512232950Stheravenshared_future<_Rp&>&
2513232950Stheravenshared_future<_Rp&>::operator=(const shared_future& __rhs)
2514227825Stheraven{
2515227825Stheraven    if (__rhs.__state_)
2516227825Stheraven        __rhs.__state_->__add_shared();
2517227825Stheraven    if (__state_)
2518227825Stheraven        __state_->__release_shared();
2519227825Stheraven    __state_ = __rhs.__state_;
2520227825Stheraven    return *this;
2521227825Stheraven}
2522227825Stheraven
2523227825Stheraventemplate <>
2524249998Sdimclass _LIBCPP_TYPE_VIS shared_future<void>
2525227825Stheraven{
2526227825Stheraven    __assoc_sub_state* __state_;
2527227825Stheraven
2528227825Stheravenpublic:
2529227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2530241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2531227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2532227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2533227825Stheraven        {if (__state_) __state_->__add_shared();}
2534227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2535227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2536241903Sdim    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2537227825Stheraven        {__f.__state_ = nullptr;}
2538227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2539241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2540227825Stheraven        {__rhs.__state_ = nullptr;}
2541227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2542227825Stheraven    ~shared_future();
2543227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2544227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2545227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2546241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2547227825Stheraven        {
2548227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2549227825Stheraven            return *this;
2550227825Stheraven        }
2551227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2552227825Stheraven
2553227825Stheraven    // retrieving the value
2554227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2555227825Stheraven    void get() const {__state_->copy();}
2556227825Stheraven
2557227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2558241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2559227825Stheraven
2560227825Stheraven    // functions to check state
2561227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2562241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2563227825Stheraven
2564227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2565227825Stheraven    void wait() const {__state_->wait();}
2566227825Stheraven    template <class _Rep, class _Period>
2567227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2568227825Stheraven        future_status
2569227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2570227825Stheraven            {return __state_->wait_for(__rel_time);}
2571227825Stheraven    template <class _Clock, class _Duration>
2572227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2573227825Stheraven        future_status
2574227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2575227825Stheraven            {return __state_->wait_until(__abs_time);}
2576227825Stheraven};
2577227825Stheraven
2578232950Stheraventemplate <class _Rp>
2579227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2580227825Stheravenvoid
2581241903Sdimswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2582227825Stheraven{
2583227825Stheraven    __x.swap(__y);
2584227825Stheraven}
2585227825Stheraven
2586232950Stheraventemplate <class _Rp>
2587227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2588232950Stheravenshared_future<_Rp>
2589232950Stheravenfuture<_Rp>::share()
2590227825Stheraven{
2591232950Stheraven    return shared_future<_Rp>(_VSTD::move(*this));
2592227825Stheraven}
2593227825Stheraven
2594232950Stheraventemplate <class _Rp>
2595227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2596232950Stheravenshared_future<_Rp&>
2597232950Stheravenfuture<_Rp&>::share()
2598227825Stheraven{
2599232950Stheraven    return shared_future<_Rp&>(_VSTD::move(*this));
2600227825Stheraven}
2601227825Stheraven
2602227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2603227825Stheraven
2604227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2605227825Stheravenshared_future<void>
2606227825Stheravenfuture<void>::share()
2607227825Stheraven{
2608227825Stheraven    return shared_future<void>(_VSTD::move(*this));
2609227825Stheraven}
2610227825Stheraven
2611227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2612227825Stheraven
2613227825Stheraven_LIBCPP_END_NAMESPACE_STD
2614227825Stheraven
2615227825Stheraven#endif  // _LIBCPP_FUTURE
2616