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
377278724Sdim#ifdef _LIBCPP_HAS_NO_THREADS
378278724Sdim#error <future> is not supported on this single threaded system
379278724Sdim#else // !_LIBCPP_HAS_NO_THREADS
380278724Sdim
381227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
382227825Stheraven
383227825Stheraven//enum class future_errc
384232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
385227825Stheraven{
386262801Sdim    future_already_retrieved = 1,
387227825Stheraven    promise_already_satisfied,
388262801Sdim    no_state,
389262801Sdim    broken_promise
390227825Stheraven};
391232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
392227825Stheraven
393227825Stheraventemplate <>
394262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
395227825Stheraven
396232950Stheraven#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397232950Stheraventemplate <>
398262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
399232950Stheraven#endif
400232950Stheraven
401227825Stheraven//enum class launch
402232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(launch)
403227825Stheraven{
404227825Stheraven    async = 1,
405227825Stheraven    deferred = 2,
406227825Stheraven    any = async | deferred
407227825Stheraven};
408232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
409227825Stheraven
410253159Stheraven#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411253159Stheraven
412253159Stheraven#ifdef _LIBCXX_UNDERLYING_TYPE
413253159Stheraventypedef underlying_type<launch>::type __launch_underlying_type;
414253159Stheraven#else
415253159Stheraventypedef int __launch_underlying_type;
416253159Stheraven#endif
417253159Stheraven
418253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
419253159Stheraven_LIBCPP_CONSTEXPR
420253159Stheravenlaunch
421253159Stheravenoperator&(launch __x, launch __y)
422253159Stheraven{
423253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
424253159Stheraven                               static_cast<__launch_underlying_type>(__y));
425253159Stheraven}
426253159Stheraven
427253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
428253159Stheraven_LIBCPP_CONSTEXPR
429253159Stheravenlaunch
430253159Stheravenoperator|(launch __x, launch __y)
431253159Stheraven{
432253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
433253159Stheraven                               static_cast<__launch_underlying_type>(__y));
434253159Stheraven}
435253159Stheraven
436253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
437253159Stheraven_LIBCPP_CONSTEXPR
438253159Stheravenlaunch
439253159Stheravenoperator^(launch __x, launch __y)
440253159Stheraven{
441253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
442253159Stheraven                               static_cast<__launch_underlying_type>(__y));
443253159Stheraven}
444253159Stheraven
445253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
446253159Stheraven_LIBCPP_CONSTEXPR
447253159Stheravenlaunch
448253159Stheravenoperator~(launch __x)
449253159Stheraven{
450253159Stheraven    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
451253159Stheraven}
452253159Stheraven
453253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
454253159Stheravenlaunch&
455253159Stheravenoperator&=(launch& __x, launch __y)
456253159Stheraven{
457253159Stheraven    __x = __x & __y; return __x;
458253159Stheraven}
459253159Stheraven
460253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
461253159Stheravenlaunch&
462253159Stheravenoperator|=(launch& __x, launch __y)
463253159Stheraven{
464253159Stheraven    __x = __x | __y; return __x;
465253159Stheraven}
466253159Stheraven
467253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
468253159Stheravenlaunch&
469253159Stheravenoperator^=(launch& __x, launch __y)
470253159Stheraven{
471253159Stheraven    __x = __x ^ __y; return __x;
472253159Stheraven}
473253159Stheraven
474253159Stheraven#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
475253159Stheraven
476227825Stheraven//enum class future_status
477232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_status)
478227825Stheraven{
479227825Stheraven    ready,
480227825Stheraven    timeout,
481227825Stheraven    deferred
482227825Stheraven};
483232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
484227825Stheraven
485249998Sdim_LIBCPP_FUNC_VIS
486241903Sdimconst error_category& future_category() _NOEXCEPT;
487227825Stheraven
488227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
489227825Stheravenerror_code
490241903Sdimmake_error_code(future_errc __e) _NOEXCEPT
491227825Stheraven{
492227825Stheraven    return error_code(static_cast<int>(__e), future_category());
493227825Stheraven}
494227825Stheraven
495227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
496227825Stheravenerror_condition
497241903Sdimmake_error_condition(future_errc __e) _NOEXCEPT
498227825Stheraven{
499227825Stheraven    return error_condition(static_cast<int>(__e), future_category());
500227825Stheraven}
501227825Stheraven
502227825Stheravenclass _LIBCPP_EXCEPTION_ABI future_error
503227825Stheraven    : public logic_error
504227825Stheraven{
505227825Stheraven    error_code __ec_;
506227825Stheravenpublic:
507227825Stheraven    future_error(error_code __ec);
508227825Stheraven
509227825Stheraven    _LIBCPP_INLINE_VISIBILITY
510241903Sdim    const error_code& code() const _NOEXCEPT {return __ec_;}
511227825Stheraven
512227825Stheraven    virtual ~future_error() _NOEXCEPT;
513227825Stheraven};
514227825Stheraven
515262801Sdimclass _LIBCPP_TYPE_VIS __assoc_sub_state
516227825Stheraven    : public __shared_count
517227825Stheraven{
518227825Stheravenprotected:
519227825Stheraven    exception_ptr __exception_;
520227825Stheraven    mutable mutex __mut_;
521227825Stheraven    mutable condition_variable __cv_;
522227825Stheraven    unsigned __state_;
523227825Stheraven
524227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
525227825Stheraven    void __sub_wait(unique_lock<mutex>& __lk);
526227825Stheravenpublic:
527227825Stheraven    enum
528227825Stheraven    {
529227825Stheraven        __constructed = 1,
530227825Stheraven        __future_attached = 2,
531227825Stheraven        ready = 4,
532227825Stheraven        deferred = 8
533227825Stheraven    };
534227825Stheraven
535227825Stheraven    _LIBCPP_INLINE_VISIBILITY
536227825Stheraven    __assoc_sub_state() : __state_(0) {}
537227825Stheraven
538227825Stheraven    _LIBCPP_INLINE_VISIBILITY
539227825Stheraven    bool __has_value() const
540227825Stheraven        {return (__state_ & __constructed) || (__exception_ != nullptr);}
541227825Stheraven
542227825Stheraven    _LIBCPP_INLINE_VISIBILITY
543246487Stheraven    void __set_future_attached()
544246487Stheraven    {
545246487Stheraven        lock_guard<mutex> __lk(__mut_);
546246487Stheraven        __state_ |= __future_attached;
547246487Stheraven    }
548227825Stheraven    _LIBCPP_INLINE_VISIBILITY
549262801Sdim    bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
550227825Stheraven
551227825Stheraven    _LIBCPP_INLINE_VISIBILITY
552227825Stheraven    void __set_deferred() {__state_ |= deferred;}
553227825Stheraven
554227825Stheraven    void __make_ready();
555227825Stheraven    _LIBCPP_INLINE_VISIBILITY
556262801Sdim    bool __is_ready() const {return (__state_ & ready) != 0;}
557227825Stheraven
558227825Stheraven    void set_value();
559227825Stheraven    void set_value_at_thread_exit();
560227825Stheraven
561227825Stheraven    void set_exception(exception_ptr __p);
562227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
563227825Stheraven
564227825Stheraven    void copy();
565227825Stheraven
566227825Stheraven    void wait();
567227825Stheraven    template <class _Rep, class _Period>
568227825Stheraven        future_status
569227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
570227825Stheraven    template <class _Clock, class _Duration>
571227825Stheraven        future_status
572227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
573227825Stheraven
574227825Stheraven    virtual void __execute();
575227825Stheraven};
576227825Stheraven
577227825Stheraventemplate <class _Clock, class _Duration>
578227825Stheravenfuture_status
579227825Stheraven__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
580227825Stheraven{
581227825Stheraven    unique_lock<mutex> __lk(__mut_);
582227825Stheraven    if (__state_ & deferred)
583227825Stheraven        return future_status::deferred;
584227825Stheraven    while (!(__state_ & ready) && _Clock::now() < __abs_time)
585227825Stheraven        __cv_.wait_until(__lk, __abs_time);
586227825Stheraven    if (__state_ & ready)
587227825Stheraven        return future_status::ready;
588227825Stheraven    return future_status::timeout;
589227825Stheraven}
590227825Stheraven
591227825Stheraventemplate <class _Rep, class _Period>
592227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
593227825Stheravenfuture_status
594227825Stheraven__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
595227825Stheraven{
596227825Stheraven    return wait_until(chrono::steady_clock::now() + __rel_time);
597227825Stheraven}
598227825Stheraven
599232950Stheraventemplate <class _Rp>
600227825Stheravenclass __assoc_state
601227825Stheraven    : public __assoc_sub_state
602227825Stheraven{
603227825Stheraven    typedef __assoc_sub_state base;
604232950Stheraven    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
605227825Stheravenprotected:
606232950Stheraven    _Up __value_;
607227825Stheraven
608227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
609227825Stheravenpublic:
610227825Stheraven
611227825Stheraven    template <class _Arg>
612227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
613227825Stheraven        void set_value(_Arg&& __arg);
614227825Stheraven#else
615227825Stheraven        void set_value(_Arg& __arg);
616227825Stheraven#endif
617227825Stheraven
618227825Stheraven    template <class _Arg>
619227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
620227825Stheraven        void set_value_at_thread_exit(_Arg&& __arg);
621227825Stheraven#else
622227825Stheraven        void set_value_at_thread_exit(_Arg& __arg);
623227825Stheraven#endif
624227825Stheraven
625232950Stheraven    _Rp move();
626232950Stheraven    typename add_lvalue_reference<_Rp>::type copy();
627227825Stheraven};
628227825Stheraven
629232950Stheraventemplate <class _Rp>
630227825Stheravenvoid
631232950Stheraven__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
632227825Stheraven{
633227825Stheraven    if (this->__state_ & base::__constructed)
634232950Stheraven        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
635227825Stheraven    delete this;
636227825Stheraven}
637227825Stheraven
638232950Stheraventemplate <class _Rp>
639227825Stheraventemplate <class _Arg>
640227825Stheravenvoid
641227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
642232950Stheraven__assoc_state<_Rp>::set_value(_Arg&& __arg)
643227825Stheraven#else
644232950Stheraven__assoc_state<_Rp>::set_value(_Arg& __arg)
645227825Stheraven#endif
646227825Stheraven{
647227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
648227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
649227825Stheraven    if (this->__has_value())
650227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
651227825Stheraven#endif
652232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
653227825Stheraven    this->__state_ |= base::__constructed | base::ready;
654227825Stheraven    __lk.unlock();
655227825Stheraven    __cv_.notify_all();
656227825Stheraven}
657227825Stheraven
658232950Stheraventemplate <class _Rp>
659227825Stheraventemplate <class _Arg>
660227825Stheravenvoid
661227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
662232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
663227825Stheraven#else
664232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
665227825Stheraven#endif
666227825Stheraven{
667227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
668227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
669227825Stheraven    if (this->__has_value())
670227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
671227825Stheraven#endif
672232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
673227825Stheraven    this->__state_ |= base::__constructed;
674227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
675227825Stheraven    __lk.unlock();
676227825Stheraven}
677227825Stheraven
678232950Stheraventemplate <class _Rp>
679232950Stheraven_Rp
680232950Stheraven__assoc_state<_Rp>::move()
681227825Stheraven{
682227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
683227825Stheraven    this->__sub_wait(__lk);
684227825Stheraven    if (this->__exception_ != nullptr)
685227825Stheraven        rethrow_exception(this->__exception_);
686232950Stheraven    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
687227825Stheraven}
688227825Stheraven
689232950Stheraventemplate <class _Rp>
690232950Stheraventypename add_lvalue_reference<_Rp>::type
691232950Stheraven__assoc_state<_Rp>::copy()
692227825Stheraven{
693227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
694227825Stheraven    this->__sub_wait(__lk);
695227825Stheraven    if (this->__exception_ != nullptr)
696227825Stheraven        rethrow_exception(this->__exception_);
697232950Stheraven    return *reinterpret_cast<_Rp*>(&__value_);
698227825Stheraven}
699227825Stheraven
700232950Stheraventemplate <class _Rp>
701232950Stheravenclass __assoc_state<_Rp&>
702227825Stheraven    : public __assoc_sub_state
703227825Stheraven{
704227825Stheraven    typedef __assoc_sub_state base;
705232950Stheraven    typedef _Rp* _Up;
706227825Stheravenprotected:
707232950Stheraven    _Up __value_;
708227825Stheraven
709227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
710227825Stheravenpublic:
711227825Stheraven
712232950Stheraven    void set_value(_Rp& __arg);
713232950Stheraven    void set_value_at_thread_exit(_Rp& __arg);
714227825Stheraven
715232950Stheraven    _Rp& copy();
716227825Stheraven};
717227825Stheraven
718232950Stheraventemplate <class _Rp>
719227825Stheravenvoid
720232950Stheraven__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
721227825Stheraven{
722227825Stheraven    delete this;
723227825Stheraven}
724227825Stheraven
725232950Stheraventemplate <class _Rp>
726227825Stheravenvoid
727232950Stheraven__assoc_state<_Rp&>::set_value(_Rp& __arg)
728227825Stheraven{
729227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
730227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
731227825Stheraven    if (this->__has_value())
732227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
733227825Stheraven#endif
734262801Sdim    __value_ = _VSTD::addressof(__arg);
735227825Stheraven    this->__state_ |= base::__constructed | base::ready;
736227825Stheraven    __lk.unlock();
737227825Stheraven    __cv_.notify_all();
738227825Stheraven}
739227825Stheraven
740232950Stheraventemplate <class _Rp>
741227825Stheravenvoid
742232950Stheraven__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
743227825Stheraven{
744227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
745227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
746227825Stheraven    if (this->__has_value())
747227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
748227825Stheraven#endif
749262801Sdim    __value_ = _VSTD::addressof(__arg);
750227825Stheraven    this->__state_ |= base::__constructed;
751227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
752227825Stheraven    __lk.unlock();
753227825Stheraven}
754227825Stheraven
755232950Stheraventemplate <class _Rp>
756232950Stheraven_Rp&
757232950Stheraven__assoc_state<_Rp&>::copy()
758227825Stheraven{
759227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
760227825Stheraven    this->__sub_wait(__lk);
761227825Stheraven    if (this->__exception_ != nullptr)
762227825Stheraven        rethrow_exception(this->__exception_);
763227825Stheraven    return *__value_;
764227825Stheraven}
765227825Stheraven
766232950Stheraventemplate <class _Rp, class _Alloc>
767227825Stheravenclass __assoc_state_alloc
768232950Stheraven    : public __assoc_state<_Rp>
769227825Stheraven{
770232950Stheraven    typedef __assoc_state<_Rp> base;
771227825Stheraven    _Alloc __alloc_;
772227825Stheraven
773227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
774227825Stheravenpublic:
775227825Stheraven    _LIBCPP_INLINE_VISIBILITY
776227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
777227825Stheraven        : __alloc_(__a) {}
778227825Stheraven};
779227825Stheraven
780232950Stheraventemplate <class _Rp, class _Alloc>
781227825Stheravenvoid
782232950Stheraven__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
783227825Stheraven{
784227825Stheraven    if (this->__state_ & base::__constructed)
785262801Sdim        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
786278724Sdim    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _A;
787278724Sdim    typedef allocator_traits<_A> _ATraits;
788278724Sdim    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
789278724Sdim    _A __a(__alloc_);
790227825Stheraven    this->~__assoc_state_alloc();
791278724Sdim    __a.deallocate(_PTraits::pointer_to(*this), 1);
792227825Stheraven}
793227825Stheraven
794232950Stheraventemplate <class _Rp, class _Alloc>
795232950Stheravenclass __assoc_state_alloc<_Rp&, _Alloc>
796232950Stheraven    : public __assoc_state<_Rp&>
797227825Stheraven{
798232950Stheraven    typedef __assoc_state<_Rp&> base;
799227825Stheraven    _Alloc __alloc_;
800227825Stheraven
801227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
802227825Stheravenpublic:
803227825Stheraven    _LIBCPP_INLINE_VISIBILITY
804227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
805227825Stheraven        : __alloc_(__a) {}
806227825Stheraven};
807227825Stheraven
808232950Stheraventemplate <class _Rp, class _Alloc>
809227825Stheravenvoid
810232950Stheraven__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
811227825Stheraven{
812278724Sdim    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _A;
813278724Sdim    typedef allocator_traits<_A> _ATraits;
814278724Sdim    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
815278724Sdim    _A __a(__alloc_);
816227825Stheraven    this->~__assoc_state_alloc();
817278724Sdim    __a.deallocate(_PTraits::pointer_to(*this), 1);
818227825Stheraven}
819227825Stheraven
820227825Stheraventemplate <class _Alloc>
821227825Stheravenclass __assoc_sub_state_alloc
822227825Stheraven    : public __assoc_sub_state
823227825Stheraven{
824227825Stheraven    typedef __assoc_sub_state base;
825227825Stheraven    _Alloc __alloc_;
826227825Stheraven
827227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
828227825Stheravenpublic:
829227825Stheraven    _LIBCPP_INLINE_VISIBILITY
830227825Stheraven    explicit __assoc_sub_state_alloc(const _Alloc& __a)
831227825Stheraven        : __alloc_(__a) {}
832227825Stheraven};
833227825Stheraven
834227825Stheraventemplate <class _Alloc>
835227825Stheravenvoid
836227825Stheraven__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
837227825Stheraven{
838278724Sdim    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _A;
839278724Sdim    typedef allocator_traits<_A> _ATraits;
840278724Sdim    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
841278724Sdim    _A __a(__alloc_);
842227825Stheraven    this->~__assoc_sub_state_alloc();
843278724Sdim    __a.deallocate(_PTraits::pointer_to(*this), 1);
844227825Stheraven}
845227825Stheraven
846232950Stheraventemplate <class _Rp, class _Fp>
847227825Stheravenclass __deferred_assoc_state
848232950Stheraven    : public __assoc_state<_Rp>
849227825Stheraven{
850232950Stheraven    typedef __assoc_state<_Rp> base;
851227825Stheraven
852232950Stheraven    _Fp __func_;
853227825Stheraven
854227825Stheravenpublic:
855227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
856232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
857227825Stheraven#endif
858227825Stheraven
859227825Stheraven    virtual void __execute();
860227825Stheraven};
861227825Stheraven
862227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
863227825Stheraven
864232950Stheraventemplate <class _Rp, class _Fp>
865227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
866232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
867232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
868227825Stheraven{
869227825Stheraven    this->__set_deferred();
870227825Stheraven}
871227825Stheraven
872227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
873227825Stheraven
874232950Stheraventemplate <class _Rp, class _Fp>
875227825Stheravenvoid
876232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__execute()
877227825Stheraven{
878227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
879227825Stheraven    try
880227825Stheraven    {
881227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
882227825Stheraven        this->set_value(__func_());
883227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
884227825Stheraven    }
885227825Stheraven    catch (...)
886227825Stheraven    {
887227825Stheraven        this->set_exception(current_exception());
888227825Stheraven    }
889227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
890227825Stheraven}
891227825Stheraven
892232950Stheraventemplate <class _Fp>
893232950Stheravenclass __deferred_assoc_state<void, _Fp>
894227825Stheraven    : public __assoc_sub_state
895227825Stheraven{
896227825Stheraven    typedef __assoc_sub_state base;
897227825Stheraven
898232950Stheraven    _Fp __func_;
899227825Stheraven
900227825Stheravenpublic:
901227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
902232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
903227825Stheraven#endif
904227825Stheraven
905227825Stheraven    virtual void __execute();
906227825Stheraven};
907227825Stheraven
908227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
909227825Stheraven
910232950Stheraventemplate <class _Fp>
911227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
912232950Stheraven__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
913232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
914227825Stheraven{
915227825Stheraven    this->__set_deferred();
916227825Stheraven}
917227825Stheraven
918227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
919227825Stheraven
920232950Stheraventemplate <class _Fp>
921227825Stheravenvoid
922232950Stheraven__deferred_assoc_state<void, _Fp>::__execute()
923227825Stheraven{
924227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
925227825Stheraven    try
926227825Stheraven    {
927227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
928227825Stheraven        __func_();
929227825Stheraven        this->set_value();
930227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
931227825Stheraven    }
932227825Stheraven    catch (...)
933227825Stheraven    {
934227825Stheraven        this->set_exception(current_exception());
935227825Stheraven    }
936227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
937227825Stheraven}
938227825Stheraven
939232950Stheraventemplate <class _Rp, class _Fp>
940227825Stheravenclass __async_assoc_state
941232950Stheraven    : public __assoc_state<_Rp>
942227825Stheraven{
943232950Stheraven    typedef __assoc_state<_Rp> base;
944227825Stheraven
945232950Stheraven    _Fp __func_;
946227825Stheraven
947227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
948227825Stheravenpublic:
949227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
950232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
951227825Stheraven#endif
952227825Stheraven
953227825Stheraven    virtual void __execute();
954227825Stheraven};
955227825Stheraven
956227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
957227825Stheraven
958232950Stheraventemplate <class _Rp, class _Fp>
959227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
960232950Stheraven__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
961232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
962227825Stheraven{
963227825Stheraven}
964227825Stheraven
965227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
966227825Stheraven
967232950Stheraventemplate <class _Rp, class _Fp>
968227825Stheravenvoid
969232950Stheraven__async_assoc_state<_Rp, _Fp>::__execute()
970227825Stheraven{
971227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
972227825Stheraven    try
973227825Stheraven    {
974227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
975227825Stheraven        this->set_value(__func_());
976227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
977227825Stheraven    }
978227825Stheraven    catch (...)
979227825Stheraven    {
980227825Stheraven        this->set_exception(current_exception());
981227825Stheraven    }
982227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
983227825Stheraven}
984227825Stheraven
985232950Stheraventemplate <class _Rp, class _Fp>
986227825Stheravenvoid
987232950Stheraven__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
988227825Stheraven{
989227825Stheraven    this->wait();
990227825Stheraven    base::__on_zero_shared();
991227825Stheraven}
992227825Stheraven
993232950Stheraventemplate <class _Fp>
994232950Stheravenclass __async_assoc_state<void, _Fp>
995227825Stheraven    : public __assoc_sub_state
996227825Stheraven{
997227825Stheraven    typedef __assoc_sub_state base;
998227825Stheraven
999232950Stheraven    _Fp __func_;
1000227825Stheraven
1001227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
1002227825Stheravenpublic:
1003227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1004232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
1005227825Stheraven#endif
1006227825Stheraven
1007227825Stheraven    virtual void __execute();
1008227825Stheraven};
1009227825Stheraven
1010227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1011227825Stheraven
1012232950Stheraventemplate <class _Fp>
1013227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1014232950Stheraven__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1015232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
1016227825Stheraven{
1017227825Stheraven}
1018227825Stheraven
1019227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1020227825Stheraven
1021232950Stheraventemplate <class _Fp>
1022227825Stheravenvoid
1023232950Stheraven__async_assoc_state<void, _Fp>::__execute()
1024227825Stheraven{
1025227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1026227825Stheraven    try
1027227825Stheraven    {
1028227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
1029227825Stheraven        __func_();
1030227825Stheraven        this->set_value();
1031227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1032227825Stheraven    }
1033227825Stheraven    catch (...)
1034227825Stheraven    {
1035227825Stheraven        this->set_exception(current_exception());
1036227825Stheraven    }
1037227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
1038227825Stheraven}
1039227825Stheraven
1040232950Stheraventemplate <class _Fp>
1041227825Stheravenvoid
1042232950Stheraven__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
1043227825Stheraven{
1044227825Stheraven    this->wait();
1045227825Stheraven    base::__on_zero_shared();
1046227825Stheraven}
1047227825Stheraven
1048262801Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1049262801Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
1050227825Stheraven
1051227825Stheraven// future
1052227825Stheraven
1053262801Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
1054227825Stheraven
1055232950Stheraventemplate <class _Rp, class _Fp>
1056232950Stheravenfuture<_Rp>
1057227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1058232950Stheraven__make_deferred_assoc_state(_Fp&& __f);
1059227825Stheraven#else
1060232950Stheraven__make_deferred_assoc_state(_Fp __f);
1061227825Stheraven#endif
1062227825Stheraven
1063232950Stheraventemplate <class _Rp, class _Fp>
1064232950Stheravenfuture<_Rp>
1065227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1066232950Stheraven__make_async_assoc_state(_Fp&& __f);
1067227825Stheraven#else
1068232950Stheraven__make_async_assoc_state(_Fp __f);
1069227825Stheraven#endif
1070227825Stheraven
1071232950Stheraventemplate <class _Rp>
1072262801Sdimclass _LIBCPP_TYPE_VIS_ONLY future
1073227825Stheraven{
1074232950Stheraven    __assoc_state<_Rp>* __state_;
1075227825Stheraven
1076232950Stheraven    explicit future(__assoc_state<_Rp>* __state);
1077227825Stheraven
1078227825Stheraven    template <class> friend class promise;
1079227825Stheraven    template <class> friend class shared_future;
1080227825Stheraven
1081227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1082232950Stheraven    template <class _R1, class _Fp>
1083232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1084232950Stheraven    template <class _R1, class _Fp>
1085232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1086227825Stheraven#else
1087232950Stheraven    template <class _R1, class _Fp>
1088232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1089232950Stheraven    template <class _R1, class _Fp>
1090232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1091227825Stheraven#endif
1092227825Stheraven
1093227825Stheravenpublic:
1094227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1095241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1096227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1097227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1098241903Sdim    future(future&& __rhs) _NOEXCEPT
1099227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1100227825Stheraven    future(const future&) = delete;
1101227825Stheraven    future& operator=(const future&) = delete;
1102227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1103241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1104227825Stheraven        {
1105227825Stheraven            future(std::move(__rhs)).swap(*this);
1106227825Stheraven            return *this;
1107227825Stheraven        }
1108227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1109227825Stheravenprivate:
1110227825Stheraven    future(const future&);
1111227825Stheraven    future& operator=(const future&);
1112227825Stheravenpublic:
1113227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1114227825Stheraven    ~future();
1115232950Stheraven    shared_future<_Rp> share();
1116227825Stheraven
1117227825Stheraven    // retrieving the value
1118232950Stheraven    _Rp get();
1119227825Stheraven
1120227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1121241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1122227825Stheraven
1123227825Stheraven    // functions to check state
1124227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1125241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1126227825Stheraven
1127227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1128227825Stheraven    void wait() const {__state_->wait();}
1129227825Stheraven    template <class _Rep, class _Period>
1130227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1131227825Stheraven        future_status
1132227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1133227825Stheraven            {return __state_->wait_for(__rel_time);}
1134227825Stheraven    template <class _Clock, class _Duration>
1135227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1136227825Stheraven        future_status
1137227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1138227825Stheraven            {return __state_->wait_until(__abs_time);}
1139227825Stheraven};
1140227825Stheraven
1141232950Stheraventemplate <class _Rp>
1142232950Stheravenfuture<_Rp>::future(__assoc_state<_Rp>* __state)
1143227825Stheraven    : __state_(__state)
1144227825Stheraven{
1145227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1146227825Stheraven    if (__state_->__has_future_attached())
1147227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1148227825Stheraven#endif
1149227825Stheraven    __state_->__add_shared();
1150227825Stheraven    __state_->__set_future_attached();
1151227825Stheraven}
1152227825Stheraven
1153227825Stheravenstruct __release_shared_count
1154227825Stheraven{
1155227825Stheraven    void operator()(__shared_count* p) {p->__release_shared();}
1156227825Stheraven};
1157227825Stheraven
1158232950Stheraventemplate <class _Rp>
1159232950Stheravenfuture<_Rp>::~future()
1160227825Stheraven{
1161227825Stheraven    if (__state_)
1162227825Stheraven        __state_->__release_shared();
1163227825Stheraven}
1164227825Stheraven
1165232950Stheraventemplate <class _Rp>
1166232950Stheraven_Rp
1167232950Stheravenfuture<_Rp>::get()
1168227825Stheraven{
1169227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1170232950Stheraven    __assoc_state<_Rp>* __s = __state_;
1171227825Stheraven    __state_ = nullptr;
1172227825Stheraven    return __s->move();
1173227825Stheraven}
1174227825Stheraven
1175232950Stheraventemplate <class _Rp>
1176262801Sdimclass _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
1177227825Stheraven{
1178232950Stheraven    __assoc_state<_Rp&>* __state_;
1179227825Stheraven
1180232950Stheraven    explicit future(__assoc_state<_Rp&>* __state);
1181227825Stheraven
1182227825Stheraven    template <class> friend class promise;
1183227825Stheraven    template <class> friend class shared_future;
1184227825Stheraven
1185227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1186232950Stheraven    template <class _R1, class _Fp>
1187232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1188232950Stheraven    template <class _R1, class _Fp>
1189232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1190227825Stheraven#else
1191232950Stheraven    template <class _R1, class _Fp>
1192232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1193232950Stheraven    template <class _R1, class _Fp>
1194232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1195227825Stheraven#endif
1196227825Stheraven
1197227825Stheravenpublic:
1198227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1199241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1200227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1201227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1202241903Sdim    future(future&& __rhs) _NOEXCEPT
1203227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1204227825Stheraven    future(const future&) = delete;
1205227825Stheraven    future& operator=(const future&) = delete;
1206227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1207241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1208227825Stheraven        {
1209227825Stheraven            future(std::move(__rhs)).swap(*this);
1210227825Stheraven            return *this;
1211227825Stheraven        }
1212227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1213227825Stheravenprivate:
1214227825Stheraven    future(const future&);
1215227825Stheraven    future& operator=(const future&);
1216227825Stheravenpublic:
1217227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1218227825Stheraven    ~future();
1219232950Stheraven    shared_future<_Rp&> share();
1220227825Stheraven
1221227825Stheraven    // retrieving the value
1222232950Stheraven    _Rp& get();
1223227825Stheraven
1224227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1225241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1226227825Stheraven
1227227825Stheraven    // functions to check state
1228227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1229241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1230227825Stheraven
1231227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1232227825Stheraven    void wait() const {__state_->wait();}
1233227825Stheraven    template <class _Rep, class _Period>
1234227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1235227825Stheraven        future_status
1236227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1237227825Stheraven            {return __state_->wait_for(__rel_time);}
1238227825Stheraven    template <class _Clock, class _Duration>
1239227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1240227825Stheraven        future_status
1241227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1242227825Stheraven            {return __state_->wait_until(__abs_time);}
1243227825Stheraven};
1244227825Stheraven
1245232950Stheraventemplate <class _Rp>
1246232950Stheravenfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
1247227825Stheraven    : __state_(__state)
1248227825Stheraven{
1249227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1250227825Stheraven    if (__state_->__has_future_attached())
1251227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1252227825Stheraven#endif
1253227825Stheraven    __state_->__add_shared();
1254227825Stheraven    __state_->__set_future_attached();
1255227825Stheraven}
1256227825Stheraven
1257232950Stheraventemplate <class _Rp>
1258232950Stheravenfuture<_Rp&>::~future()
1259227825Stheraven{
1260227825Stheraven    if (__state_)
1261227825Stheraven        __state_->__release_shared();
1262227825Stheraven}
1263227825Stheraven
1264232950Stheraventemplate <class _Rp>
1265232950Stheraven_Rp&
1266232950Stheravenfuture<_Rp&>::get()
1267227825Stheraven{
1268227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1269232950Stheraven    __assoc_state<_Rp&>* __s = __state_;
1270227825Stheraven    __state_ = nullptr;
1271227825Stheraven    return __s->copy();
1272227825Stheraven}
1273227825Stheraven
1274227825Stheraventemplate <>
1275249998Sdimclass _LIBCPP_TYPE_VIS future<void>
1276227825Stheraven{
1277227825Stheraven    __assoc_sub_state* __state_;
1278227825Stheraven
1279227825Stheraven    explicit future(__assoc_sub_state* __state);
1280227825Stheraven
1281227825Stheraven    template <class> friend class promise;
1282227825Stheraven    template <class> friend class shared_future;
1283227825Stheraven
1284227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1285232950Stheraven    template <class _R1, class _Fp>
1286232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1287232950Stheraven    template <class _R1, class _Fp>
1288232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1289227825Stheraven#else
1290232950Stheraven    template <class _R1, class _Fp>
1291232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1292232950Stheraven    template <class _R1, class _Fp>
1293232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1294227825Stheraven#endif
1295227825Stheraven
1296227825Stheravenpublic:
1297227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1298241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1299227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1300227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1301241903Sdim    future(future&& __rhs) _NOEXCEPT
1302227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1303227825Stheraven    future(const future&) = delete;
1304227825Stheraven    future& operator=(const future&) = delete;
1305227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1306241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1307227825Stheraven        {
1308227825Stheraven            future(std::move(__rhs)).swap(*this);
1309227825Stheraven            return *this;
1310227825Stheraven        }
1311227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1312227825Stheravenprivate:
1313227825Stheraven    future(const future&);
1314227825Stheraven    future& operator=(const future&);
1315227825Stheravenpublic:
1316227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1317227825Stheraven    ~future();
1318227825Stheraven    shared_future<void> share();
1319227825Stheraven
1320227825Stheraven    // retrieving the value
1321227825Stheraven    void get();
1322227825Stheraven
1323227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1324241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1325227825Stheraven
1326227825Stheraven    // functions to check state
1327227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1328241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1329227825Stheraven
1330227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1331227825Stheraven    void wait() const {__state_->wait();}
1332227825Stheraven    template <class _Rep, class _Period>
1333227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1334227825Stheraven        future_status
1335227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1336227825Stheraven            {return __state_->wait_for(__rel_time);}
1337227825Stheraven    template <class _Clock, class _Duration>
1338227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1339227825Stheraven        future_status
1340227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1341227825Stheraven            {return __state_->wait_until(__abs_time);}
1342227825Stheraven};
1343227825Stheraven
1344232950Stheraventemplate <class _Rp>
1345227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1346227825Stheravenvoid
1347241903Sdimswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1348227825Stheraven{
1349227825Stheraven    __x.swap(__y);
1350227825Stheraven}
1351227825Stheraven
1352227825Stheraven// promise<R>
1353227825Stheraven
1354227825Stheraventemplate <class _Callable> class packaged_task;
1355227825Stheraven
1356232950Stheraventemplate <class _Rp>
1357262801Sdimclass _LIBCPP_TYPE_VIS_ONLY promise
1358227825Stheraven{
1359232950Stheraven    __assoc_state<_Rp>* __state_;
1360227825Stheraven
1361227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1362241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1363227825Stheraven
1364227825Stheraven    template <class> friend class packaged_task;
1365227825Stheravenpublic:
1366227825Stheraven    promise();
1367227825Stheraven    template <class _Alloc>
1368227825Stheraven        promise(allocator_arg_t, const _Alloc& __a);
1369227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1370227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1371241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1372227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1373227825Stheraven    promise(const promise& __rhs) = delete;
1374227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1375227825Stheravenprivate:
1376227825Stheraven    promise(const promise& __rhs);
1377227825Stheravenpublic:
1378227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1379227825Stheraven    ~promise();
1380227825Stheraven
1381227825Stheraven    // assignment
1382227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1383227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1384241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1385227825Stheraven        {
1386227825Stheraven            promise(std::move(__rhs)).swap(*this);
1387227825Stheraven            return *this;
1388227825Stheraven        }
1389227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1390227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391227825Stheravenprivate:
1392227825Stheraven    promise& operator=(const promise& __rhs);
1393227825Stheravenpublic:
1394227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1395227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1396241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1397227825Stheraven
1398227825Stheraven    // retrieving the result
1399232950Stheraven    future<_Rp> get_future();
1400227825Stheraven
1401227825Stheraven    // setting the result
1402232950Stheraven    void set_value(const _Rp& __r);
1403227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1404232950Stheraven    void set_value(_Rp&& __r);
1405227825Stheraven#endif
1406227825Stheraven    void set_exception(exception_ptr __p);
1407227825Stheraven
1408227825Stheraven    // setting the result with deferred notification
1409232950Stheraven    void set_value_at_thread_exit(const _Rp& __r);
1410227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1411232950Stheraven    void set_value_at_thread_exit(_Rp&& __r);
1412227825Stheraven#endif
1413227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1414227825Stheraven};
1415227825Stheraven
1416232950Stheraventemplate <class _Rp>
1417232950Stheravenpromise<_Rp>::promise()
1418232950Stheraven    : __state_(new __assoc_state<_Rp>)
1419227825Stheraven{
1420227825Stheraven}
1421227825Stheraven
1422232950Stheraventemplate <class _Rp>
1423227825Stheraventemplate <class _Alloc>
1424232950Stheravenpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1425227825Stheraven{
1426278724Sdim    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1427278724Sdim    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1428227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1429227825Stheraven    _A2 __a(__a0);
1430278724Sdim    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1431278724Sdim    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1432278724Sdim    __state_ = _VSTD::addressof(*__hold.release());
1433227825Stheraven}
1434227825Stheraven
1435232950Stheraventemplate <class _Rp>
1436232950Stheravenpromise<_Rp>::~promise()
1437227825Stheraven{
1438227825Stheraven    if (__state_)
1439227825Stheraven    {
1440227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1441227825Stheraven            __state_->set_exception(make_exception_ptr(
1442227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1443227825Stheraven                                                      ));
1444227825Stheraven        __state_->__release_shared();
1445227825Stheraven    }
1446227825Stheraven}
1447227825Stheraven
1448232950Stheraventemplate <class _Rp>
1449232950Stheravenfuture<_Rp>
1450232950Stheravenpromise<_Rp>::get_future()
1451227825Stheraven{
1452227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1453227825Stheraven    if (__state_ == nullptr)
1454227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1455227825Stheraven#endif
1456232950Stheraven    return future<_Rp>(__state_);
1457227825Stheraven}
1458227825Stheraven
1459232950Stheraventemplate <class _Rp>
1460227825Stheravenvoid
1461232950Stheravenpromise<_Rp>::set_value(const _Rp& __r)
1462227825Stheraven{
1463227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1464227825Stheraven    if (__state_ == nullptr)
1465227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1466227825Stheraven#endif
1467227825Stheraven    __state_->set_value(__r);
1468227825Stheraven}
1469227825Stheraven
1470227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1471227825Stheraven
1472232950Stheraventemplate <class _Rp>
1473227825Stheravenvoid
1474232950Stheravenpromise<_Rp>::set_value(_Rp&& __r)
1475227825Stheraven{
1476227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1477227825Stheraven    if (__state_ == nullptr)
1478227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1479227825Stheraven#endif
1480227825Stheraven    __state_->set_value(_VSTD::move(__r));
1481227825Stheraven}
1482227825Stheraven
1483227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1484227825Stheraven
1485232950Stheraventemplate <class _Rp>
1486227825Stheravenvoid
1487232950Stheravenpromise<_Rp>::set_exception(exception_ptr __p)
1488227825Stheraven{
1489227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1490227825Stheraven    if (__state_ == nullptr)
1491227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1492227825Stheraven#endif
1493227825Stheraven    __state_->set_exception(__p);
1494227825Stheraven}
1495227825Stheraven
1496232950Stheraventemplate <class _Rp>
1497227825Stheravenvoid
1498232950Stheravenpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1499227825Stheraven{
1500227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1501227825Stheraven    if (__state_ == nullptr)
1502227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1503227825Stheraven#endif
1504227825Stheraven    __state_->set_value_at_thread_exit(__r);
1505227825Stheraven}
1506227825Stheraven
1507227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1508227825Stheraven
1509232950Stheraventemplate <class _Rp>
1510227825Stheravenvoid
1511232950Stheravenpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1512227825Stheraven{
1513227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1514227825Stheraven    if (__state_ == nullptr)
1515227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1516227825Stheraven#endif
1517227825Stheraven    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1518227825Stheraven}
1519227825Stheraven
1520227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1521227825Stheraven
1522232950Stheraventemplate <class _Rp>
1523227825Stheravenvoid
1524232950Stheravenpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1525227825Stheraven{
1526227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1527227825Stheraven    if (__state_ == nullptr)
1528227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1529227825Stheraven#endif
1530227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1531227825Stheraven}
1532227825Stheraven
1533227825Stheraven// promise<R&>
1534227825Stheraven
1535232950Stheraventemplate <class _Rp>
1536262801Sdimclass _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
1537227825Stheraven{
1538232950Stheraven    __assoc_state<_Rp&>* __state_;
1539227825Stheraven
1540227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1541241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1542227825Stheraven
1543227825Stheraven    template <class> friend class packaged_task;
1544227825Stheraven
1545227825Stheravenpublic:
1546227825Stheraven    promise();
1547227825Stheraven    template <class _Allocator>
1548227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1549227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1550227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1551241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1552227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1553227825Stheraven    promise(const promise& __rhs) = delete;
1554227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1555227825Stheravenprivate:
1556227825Stheraven    promise(const promise& __rhs);
1557227825Stheravenpublic:
1558227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1559227825Stheraven    ~promise();
1560227825Stheraven
1561227825Stheraven    // assignment
1562227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1563227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1564241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1565227825Stheraven        {
1566227825Stheraven            promise(std::move(__rhs)).swap(*this);
1567227825Stheraven            return *this;
1568227825Stheraven        }
1569227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1570227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1571227825Stheravenprivate:
1572227825Stheraven    promise& operator=(const promise& __rhs);
1573227825Stheravenpublic:
1574227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1575227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1576241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1577227825Stheraven
1578227825Stheraven    // retrieving the result
1579232950Stheraven    future<_Rp&> get_future();
1580227825Stheraven
1581227825Stheraven    // setting the result
1582232950Stheraven    void set_value(_Rp& __r);
1583227825Stheraven    void set_exception(exception_ptr __p);
1584227825Stheraven
1585227825Stheraven    // setting the result with deferred notification
1586232950Stheraven    void set_value_at_thread_exit(_Rp&);
1587227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1588227825Stheraven};
1589227825Stheraven
1590232950Stheraventemplate <class _Rp>
1591232950Stheravenpromise<_Rp&>::promise()
1592232950Stheraven    : __state_(new __assoc_state<_Rp&>)
1593227825Stheraven{
1594227825Stheraven}
1595227825Stheraven
1596232950Stheraventemplate <class _Rp>
1597227825Stheraventemplate <class _Alloc>
1598232950Stheravenpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1599227825Stheraven{
1600278724Sdim    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1601278724Sdim    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1602227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1603227825Stheraven    _A2 __a(__a0);
1604278724Sdim    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1605278724Sdim    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1606278724Sdim    __state_ = _VSTD::addressof(*__hold.release());
1607227825Stheraven}
1608227825Stheraven
1609232950Stheraventemplate <class _Rp>
1610232950Stheravenpromise<_Rp&>::~promise()
1611227825Stheraven{
1612227825Stheraven    if (__state_)
1613227825Stheraven    {
1614227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1615227825Stheraven            __state_->set_exception(make_exception_ptr(
1616227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1617227825Stheraven                                                      ));
1618227825Stheraven        __state_->__release_shared();
1619227825Stheraven    }
1620227825Stheraven}
1621227825Stheraven
1622232950Stheraventemplate <class _Rp>
1623232950Stheravenfuture<_Rp&>
1624232950Stheravenpromise<_Rp&>::get_future()
1625227825Stheraven{
1626227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1627227825Stheraven    if (__state_ == nullptr)
1628227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1629227825Stheraven#endif
1630232950Stheraven    return future<_Rp&>(__state_);
1631227825Stheraven}
1632227825Stheraven
1633232950Stheraventemplate <class _Rp>
1634227825Stheravenvoid
1635232950Stheravenpromise<_Rp&>::set_value(_Rp& __r)
1636227825Stheraven{
1637227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1638227825Stheraven    if (__state_ == nullptr)
1639227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1640227825Stheraven#endif
1641227825Stheraven    __state_->set_value(__r);
1642227825Stheraven}
1643227825Stheraven
1644232950Stheraventemplate <class _Rp>
1645227825Stheravenvoid
1646232950Stheravenpromise<_Rp&>::set_exception(exception_ptr __p)
1647227825Stheraven{
1648227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1649227825Stheraven    if (__state_ == nullptr)
1650227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1651227825Stheraven#endif
1652227825Stheraven    __state_->set_exception(__p);
1653227825Stheraven}
1654227825Stheraven
1655232950Stheraventemplate <class _Rp>
1656227825Stheravenvoid
1657232950Stheravenpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1658227825Stheraven{
1659227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1660227825Stheraven    if (__state_ == nullptr)
1661227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1662227825Stheraven#endif
1663227825Stheraven    __state_->set_value_at_thread_exit(__r);
1664227825Stheraven}
1665227825Stheraven
1666232950Stheraventemplate <class _Rp>
1667227825Stheravenvoid
1668232950Stheravenpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1669227825Stheraven{
1670227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1671227825Stheraven    if (__state_ == nullptr)
1672227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1673227825Stheraven#endif
1674227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1675227825Stheraven}
1676227825Stheraven
1677227825Stheraven// promise<void>
1678227825Stheraven
1679227825Stheraventemplate <>
1680249998Sdimclass _LIBCPP_TYPE_VIS promise<void>
1681227825Stheraven{
1682227825Stheraven    __assoc_sub_state* __state_;
1683227825Stheraven
1684227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1685241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1686227825Stheraven
1687227825Stheraven    template <class> friend class packaged_task;
1688227825Stheraven
1689227825Stheravenpublic:
1690227825Stheraven    promise();
1691227825Stheraven    template <class _Allocator>
1692227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1693227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1694227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1695241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1696227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1697227825Stheraven    promise(const promise& __rhs) = delete;
1698227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1699227825Stheravenprivate:
1700227825Stheraven    promise(const promise& __rhs);
1701227825Stheravenpublic:
1702227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1703227825Stheraven    ~promise();
1704227825Stheraven
1705227825Stheraven    // assignment
1706227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1707227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1708241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1709227825Stheraven        {
1710227825Stheraven            promise(std::move(__rhs)).swap(*this);
1711227825Stheraven            return *this;
1712227825Stheraven        }
1713227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1714227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1715227825Stheravenprivate:
1716227825Stheraven    promise& operator=(const promise& __rhs);
1717227825Stheravenpublic:
1718227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1719227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1720241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1721227825Stheraven
1722227825Stheraven    // retrieving the result
1723227825Stheraven    future<void> get_future();
1724227825Stheraven
1725227825Stheraven    // setting the result
1726227825Stheraven    void set_value();
1727227825Stheraven    void set_exception(exception_ptr __p);
1728227825Stheraven
1729227825Stheraven    // setting the result with deferred notification
1730227825Stheraven    void set_value_at_thread_exit();
1731227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1732227825Stheraven};
1733227825Stheraven
1734227825Stheraventemplate <class _Alloc>
1735227825Stheravenpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1736227825Stheraven{
1737278724Sdim    typedef __assoc_sub_state_alloc<_Alloc> _State;
1738278724Sdim    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1739227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1740227825Stheraven    _A2 __a(__a0);
1741278724Sdim    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1742278724Sdim    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1743278724Sdim    __state_ = _VSTD::addressof(*__hold.release());
1744227825Stheraven}
1745227825Stheraven
1746232950Stheraventemplate <class _Rp>
1747227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1748227825Stheravenvoid
1749241903Sdimswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1750227825Stheraven{
1751227825Stheraven    __x.swap(__y);
1752227825Stheraven}
1753227825Stheraven
1754232950Stheraventemplate <class _Rp, class _Alloc>
1755262801Sdim    struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
1756227825Stheraven        : public true_type {};
1757227825Stheraven
1758227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
1759227825Stheraven
1760227825Stheraven// packaged_task
1761227825Stheraven
1762227825Stheraventemplate<class _Fp> class __packaged_task_base;
1763227825Stheraven
1764232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1765232950Stheravenclass __packaged_task_base<_Rp(_ArgTypes...)>
1766227825Stheraven{
1767227825Stheraven    __packaged_task_base(const __packaged_task_base&);
1768227825Stheraven    __packaged_task_base& operator=(const __packaged_task_base&);
1769227825Stheravenpublic:
1770227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1771227825Stheraven    __packaged_task_base() {}
1772227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1773227825Stheraven    virtual ~__packaged_task_base() {}
1774241903Sdim    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1775227825Stheraven    virtual void destroy() = 0;
1776227825Stheraven    virtual void destroy_deallocate() = 0;
1777232950Stheraven    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1778227825Stheraven};
1779227825Stheraven
1780227825Stheraventemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1781227825Stheraven
1782232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1783232950Stheravenclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1784232950Stheraven    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1785227825Stheraven{
1786232950Stheraven    __compressed_pair<_Fp, _Alloc> __f_;
1787227825Stheravenpublic:
1788227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1789232950Stheraven    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1790227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1791232950Stheraven    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1792227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1793232950Stheraven    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1794227825Stheraven        : __f_(__f, __a) {}
1795227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1796232950Stheraven    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1797227825Stheraven        : __f_(_VSTD::move(__f), __a) {}
1798241903Sdim    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1799227825Stheraven    virtual void destroy();
1800227825Stheraven    virtual void destroy_deallocate();
1801232950Stheraven    virtual _Rp operator()(_ArgTypes&& ... __args);
1802227825Stheraven};
1803227825Stheraven
1804232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1805227825Stheravenvoid
1806232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1807241903Sdim                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1808227825Stheraven{
1809227825Stheraven    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1810227825Stheraven}
1811227825Stheraven
1812232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1813227825Stheravenvoid
1814232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1815227825Stheraven{
1816232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1817227825Stheraven}
1818227825Stheraven
1819232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1820227825Stheravenvoid
1821232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1822227825Stheraven{
1823278724Sdim    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1824278724Sdim    typedef allocator_traits<_Ap> _ATraits;
1825278724Sdim    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
1826232950Stheraven    _Ap __a(__f_.second());
1827232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1828278724Sdim    __a.deallocate(_PTraits::pointer_to(*this), 1);
1829227825Stheraven}
1830227825Stheraven
1831232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1832232950Stheraven_Rp
1833232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1834227825Stheraven{
1835227825Stheraven    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1836227825Stheraven}
1837227825Stheraven
1838227825Stheraventemplate <class _Callable> class __packaged_task_function;
1839227825Stheraven
1840232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1841232950Stheravenclass __packaged_task_function<_Rp(_ArgTypes...)>
1842227825Stheraven{
1843232950Stheraven    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1844246487Stheraven    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1845227825Stheraven    __base* __f_;
1846227825Stheraven
1847227825Stheravenpublic:
1848232950Stheraven    typedef _Rp result_type;
1849227825Stheraven
1850227825Stheraven    // construct/copy/destroy:
1851227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1852241903Sdim    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1853232950Stheraven    template<class _Fp>
1854232950Stheraven      __packaged_task_function(_Fp&& __f);
1855232950Stheraven    template<class _Fp, class _Alloc>
1856232950Stheraven      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1857227825Stheraven
1858241903Sdim    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1859241903Sdim    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1860227825Stheraven
1861227825Stheraven    __packaged_task_function(const __packaged_task_function&) =  delete;
1862227825Stheraven    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1863227825Stheraven
1864227825Stheraven    ~__packaged_task_function();
1865227825Stheraven
1866241903Sdim    void swap(__packaged_task_function&) _NOEXCEPT;
1867227825Stheraven
1868232950Stheraven    _Rp operator()(_ArgTypes...) const;
1869227825Stheraven};
1870227825Stheraven
1871232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1872241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1873227825Stheraven{
1874227825Stheraven    if (__f.__f_ == nullptr)
1875227825Stheraven        __f_ = nullptr;
1876227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1877227825Stheraven    {
1878227825Stheraven        __f_ = (__base*)&__buf_;
1879227825Stheraven        __f.__f_->__move_to(__f_);
1880227825Stheraven    }
1881227825Stheraven    else
1882227825Stheraven    {
1883227825Stheraven        __f_ = __f.__f_;
1884227825Stheraven        __f.__f_ = nullptr;
1885227825Stheraven    }
1886227825Stheraven}
1887227825Stheraven
1888232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1889232950Stheraventemplate <class _Fp>
1890232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1891227825Stheraven    : __f_(nullptr)
1892227825Stheraven{
1893278724Sdim    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1894232950Stheraven    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1895227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1896227825Stheraven    {
1897227825Stheraven        __f_ = (__base*)&__buf_;
1898232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1899227825Stheraven    }
1900227825Stheraven    else
1901227825Stheraven    {
1902232950Stheraven        typedef allocator<_FF> _Ap;
1903232950Stheraven        _Ap __a;
1904232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1905232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1906232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1907227825Stheraven        __f_ = __hold.release();
1908227825Stheraven    }
1909227825Stheraven}
1910227825Stheraven
1911232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1912232950Stheraventemplate <class _Fp, class _Alloc>
1913232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1914232950Stheraven                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1915227825Stheraven    : __f_(nullptr)
1916227825Stheraven{
1917278724Sdim    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1918232950Stheraven    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1919227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1920227825Stheraven    {
1921227825Stheraven        __f_ = (__base*)&__buf_;
1922232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1923227825Stheraven    }
1924227825Stheraven    else
1925227825Stheraven    {
1926278724Sdim        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
1927232950Stheraven        _Ap __a(__a0);
1928232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1929232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1930278724Sdim        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1931278724Sdim            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1932278724Sdim        __f_ = _VSTD::addressof(*__hold.release());
1933227825Stheraven    }
1934227825Stheraven}
1935227825Stheraven
1936232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1937232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>&
1938241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1939227825Stheraven{
1940227825Stheraven    if (__f_ == (__base*)&__buf_)
1941227825Stheraven        __f_->destroy();
1942227825Stheraven    else if (__f_)
1943227825Stheraven        __f_->destroy_deallocate();
1944227825Stheraven    __f_ = nullptr;
1945227825Stheraven    if (__f.__f_ == nullptr)
1946227825Stheraven        __f_ = nullptr;
1947227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1948227825Stheraven    {
1949227825Stheraven        __f_ = (__base*)&__buf_;
1950227825Stheraven        __f.__f_->__move_to(__f_);
1951227825Stheraven    }
1952227825Stheraven    else
1953227825Stheraven    {
1954227825Stheraven        __f_ = __f.__f_;
1955227825Stheraven        __f.__f_ = nullptr;
1956227825Stheraven    }
1957241903Sdim    return *this;
1958227825Stheraven}
1959227825Stheraven
1960232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1961232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1962227825Stheraven{
1963227825Stheraven    if (__f_ == (__base*)&__buf_)
1964227825Stheraven        __f_->destroy();
1965227825Stheraven    else if (__f_)
1966227825Stheraven        __f_->destroy_deallocate();
1967227825Stheraven}
1968227825Stheraven
1969232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1970227825Stheravenvoid
1971241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1972227825Stheraven{
1973227825Stheraven    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1974227825Stheraven    {
1975227825Stheraven        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1976227825Stheraven        __base* __t = (__base*)&__tempbuf;
1977227825Stheraven        __f_->__move_to(__t);
1978227825Stheraven        __f_->destroy();
1979227825Stheraven        __f_ = nullptr;
1980227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1981227825Stheraven        __f.__f_->destroy();
1982227825Stheraven        __f.__f_ = nullptr;
1983227825Stheraven        __f_ = (__base*)&__buf_;
1984227825Stheraven        __t->__move_to((__base*)&__f.__buf_);
1985227825Stheraven        __t->destroy();
1986227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1987227825Stheraven    }
1988227825Stheraven    else if (__f_ == (__base*)&__buf_)
1989227825Stheraven    {
1990227825Stheraven        __f_->__move_to((__base*)&__f.__buf_);
1991227825Stheraven        __f_->destroy();
1992227825Stheraven        __f_ = __f.__f_;
1993227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1994227825Stheraven    }
1995227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1996227825Stheraven    {
1997227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1998227825Stheraven        __f.__f_->destroy();
1999227825Stheraven        __f.__f_ = __f_;
2000227825Stheraven        __f_ = (__base*)&__buf_;
2001227825Stheraven    }
2002227825Stheraven    else
2003227825Stheraven        _VSTD::swap(__f_, __f.__f_);
2004227825Stheraven}
2005227825Stheraven
2006232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2007227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2008232950Stheraven_Rp
2009232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
2010227825Stheraven{
2011227825Stheraven    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
2012227825Stheraven}
2013227825Stheraven
2014232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2015262801Sdimclass _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
2016227825Stheraven{
2017227825Stheravenpublic:
2018232950Stheraven    typedef _Rp result_type;
2019227825Stheraven
2020227825Stheravenprivate:
2021227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2022227825Stheraven    promise<result_type>                                __p_;
2023227825Stheraven
2024227825Stheravenpublic:
2025227825Stheraven    // construction and destruction
2026227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2027241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2028262801Sdim    template <class _Fp,
2029262801Sdim              class = typename enable_if
2030262801Sdim              <
2031262801Sdim                  !is_same<
2032262801Sdim                      typename decay<_Fp>::type, 
2033262801Sdim                      packaged_task
2034262801Sdim                      >::value
2035262801Sdim                  >::type
2036262801Sdim             >
2037227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2038232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2039262801Sdim    template <class _Fp, class _Allocator,
2040262801Sdim              class = typename enable_if
2041262801Sdim              <
2042262801Sdim                  !is_same<
2043262801Sdim                      typename decay<_Fp>::type, 
2044262801Sdim                      packaged_task
2045262801Sdim                      >::value
2046262801Sdim                  >::type
2047262801Sdim              >
2048227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2049232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2050232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2051227825Stheraven               __p_(allocator_arg, __a) {}
2052227825Stheraven    // ~packaged_task() = default;
2053227825Stheraven
2054227825Stheraven    // no copy
2055241903Sdim    packaged_task(const packaged_task&) = delete;
2056241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2057227825Stheraven
2058227825Stheraven    // move support
2059227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2060241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2061227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2062227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2063241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2064227825Stheraven    {
2065227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2066227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2067227825Stheraven        return *this;
2068227825Stheraven    }
2069227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2070241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2071227825Stheraven    {
2072227825Stheraven        __f_.swap(__other.__f_);
2073227825Stheraven        __p_.swap(__other.__p_);
2074227825Stheraven    }
2075227825Stheraven
2076227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2077241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2078227825Stheraven
2079227825Stheraven    // result retrieval
2080227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2081227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2082227825Stheraven
2083227825Stheraven    // execution
2084227825Stheraven    void operator()(_ArgTypes... __args);
2085227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2086227825Stheraven
2087227825Stheraven    void reset();
2088227825Stheraven};
2089227825Stheraven
2090232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2091227825Stheravenvoid
2092232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
2093227825Stheraven{
2094227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2095227825Stheraven    if (__p_.__state_ == nullptr)
2096227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2097227825Stheraven    if (__p_.__state_->__has_value())
2098227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2099227825Stheraven    try
2100227825Stheraven    {
2101227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2102227825Stheraven        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2103227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2104227825Stheraven    }
2105227825Stheraven    catch (...)
2106227825Stheraven    {
2107227825Stheraven        __p_.set_exception(current_exception());
2108227825Stheraven    }
2109227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2110227825Stheraven}
2111227825Stheraven
2112232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2113227825Stheravenvoid
2114232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2115227825Stheraven{
2116227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2117227825Stheraven    if (__p_.__state_ == nullptr)
2118227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2119227825Stheraven    if (__p_.__state_->__has_value())
2120227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2121227825Stheraven    try
2122227825Stheraven    {
2123227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2124227825Stheraven        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2125227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2126227825Stheraven    }
2127227825Stheraven    catch (...)
2128227825Stheraven    {
2129227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2130227825Stheraven    }
2131227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2132227825Stheraven}
2133227825Stheraven
2134232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2135227825Stheravenvoid
2136232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::reset()
2137227825Stheraven{
2138227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2139227825Stheraven    if (!valid())
2140227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2141227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2142227825Stheraven    __p_ = promise<result_type>();
2143227825Stheraven}
2144227825Stheraven
2145227825Stheraventemplate<class ..._ArgTypes>
2146262801Sdimclass _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
2147227825Stheraven{
2148227825Stheravenpublic:
2149227825Stheraven    typedef void result_type;
2150227825Stheraven
2151227825Stheravenprivate:
2152227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2153227825Stheraven    promise<result_type>                                __p_;
2154227825Stheraven
2155227825Stheravenpublic:
2156227825Stheraven    // construction and destruction
2157227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2158241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2159262801Sdim    template <class _Fp,
2160262801Sdim              class = typename enable_if
2161262801Sdim              <
2162262801Sdim                  !is_same<
2163262801Sdim                      typename decay<_Fp>::type, 
2164262801Sdim                      packaged_task
2165262801Sdim                      >::value
2166262801Sdim                  >::type
2167262801Sdim              >
2168227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2169232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2170262801Sdim    template <class _Fp, class _Allocator,
2171262801Sdim              class = typename enable_if
2172262801Sdim              <
2173262801Sdim                  !is_same<
2174262801Sdim                      typename decay<_Fp>::type, 
2175262801Sdim                      packaged_task
2176262801Sdim                      >::value
2177262801Sdim                  >::type
2178262801Sdim              >    
2179227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2180232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2181232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2182227825Stheraven               __p_(allocator_arg, __a) {}
2183227825Stheraven    // ~packaged_task() = default;
2184227825Stheraven
2185227825Stheraven    // no copy
2186241903Sdim    packaged_task(const packaged_task&) = delete;
2187241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2188227825Stheraven
2189227825Stheraven    // move support
2190227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2191241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2192227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2193227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2194241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2195227825Stheraven    {
2196227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2197227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2198227825Stheraven        return *this;
2199227825Stheraven    }
2200227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2201241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2202227825Stheraven    {
2203227825Stheraven        __f_.swap(__other.__f_);
2204227825Stheraven        __p_.swap(__other.__p_);
2205227825Stheraven    }
2206227825Stheraven
2207227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2208241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2209227825Stheraven
2210227825Stheraven    // result retrieval
2211227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2212227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2213227825Stheraven
2214227825Stheraven    // execution
2215227825Stheraven    void operator()(_ArgTypes... __args);
2216227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2217227825Stheraven
2218227825Stheraven    void reset();
2219227825Stheraven};
2220227825Stheraven
2221227825Stheraventemplate<class ..._ArgTypes>
2222227825Stheravenvoid
2223227825Stheravenpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2224227825Stheraven{
2225227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2226227825Stheraven    if (__p_.__state_ == nullptr)
2227227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2228227825Stheraven    if (__p_.__state_->__has_value())
2229227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2230227825Stheraven    try
2231227825Stheraven    {
2232227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2233227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2234227825Stheraven        __p_.set_value();
2235227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2236227825Stheraven    }
2237227825Stheraven    catch (...)
2238227825Stheraven    {
2239227825Stheraven        __p_.set_exception(current_exception());
2240227825Stheraven    }
2241227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2242227825Stheraven}
2243227825Stheraven
2244227825Stheraventemplate<class ..._ArgTypes>
2245227825Stheravenvoid
2246227825Stheravenpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2247227825Stheraven{
2248227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2249227825Stheraven    if (__p_.__state_ == nullptr)
2250227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2251227825Stheraven    if (__p_.__state_->__has_value())
2252227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2253227825Stheraven    try
2254227825Stheraven    {
2255227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2256227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2257227825Stheraven        __p_.set_value_at_thread_exit();
2258227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2259227825Stheraven    }
2260227825Stheraven    catch (...)
2261227825Stheraven    {
2262227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2263227825Stheraven    }
2264227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2265227825Stheraven}
2266227825Stheraven
2267227825Stheraventemplate<class ..._ArgTypes>
2268227825Stheravenvoid
2269227825Stheravenpackaged_task<void(_ArgTypes...)>::reset()
2270227825Stheraven{
2271227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2272227825Stheraven    if (!valid())
2273227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2274227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2275227825Stheraven    __p_ = promise<result_type>();
2276227825Stheraven}
2277227825Stheraven
2278227825Stheraventemplate <class _Callable>
2279227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2280227825Stheravenvoid
2281241903Sdimswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2282227825Stheraven{
2283227825Stheraven    __x.swap(__y);
2284227825Stheraven}
2285227825Stheraven
2286227825Stheraventemplate <class _Callable, class _Alloc>
2287262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
2288227825Stheraven    : public true_type {};
2289227825Stheraven
2290232950Stheraventemplate <class _Rp, class _Fp>
2291232950Stheravenfuture<_Rp>
2292227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2293232950Stheraven__make_deferred_assoc_state(_Fp&& __f)
2294227825Stheraven#else
2295232950Stheraven__make_deferred_assoc_state(_Fp __f)
2296227825Stheraven#endif
2297227825Stheraven{
2298232950Stheraven    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2299232950Stheraven        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2300232950Stheraven    return future<_Rp>(__h.get());
2301227825Stheraven}
2302227825Stheraven
2303232950Stheraventemplate <class _Rp, class _Fp>
2304232950Stheravenfuture<_Rp>
2305227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2306232950Stheraven__make_async_assoc_state(_Fp&& __f)
2307227825Stheraven#else
2308232950Stheraven__make_async_assoc_state(_Fp __f)
2309227825Stheraven#endif
2310227825Stheraven{
2311232950Stheraven    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2312232950Stheraven        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2313232950Stheraven    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2314232950Stheraven    return future<_Rp>(__h.get());
2315227825Stheraven}
2316227825Stheraven
2317232950Stheraventemplate <class _Fp, class... _Args>
2318227825Stheravenclass __async_func
2319227825Stheraven{
2320232950Stheraven    tuple<_Fp, _Args...> __f_;
2321227825Stheraven
2322227825Stheravenpublic:
2323232950Stheraven    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2324227825Stheraven
2325227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2326232950Stheraven    explicit __async_func(_Fp&& __f, _Args&&... __args)
2327227825Stheraven        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2328227825Stheraven
2329227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2330227825Stheraven    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2331227825Stheraven
2332232950Stheraven    _Rp operator()()
2333227825Stheraven    {
2334227825Stheraven        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2335227825Stheraven        return __execute(_Index());
2336227825Stheraven    }
2337227825Stheravenprivate:
2338227825Stheraven    template <size_t ..._Indices>
2339232950Stheraven    _Rp
2340227825Stheraven    __execute(__tuple_indices<_Indices...>)
2341227825Stheraven    {
2342227825Stheraven        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2343227825Stheraven    }
2344227825Stheraven};
2345227825Stheraven
2346262801Sdiminline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
2347262801Sdim{ return (int(__policy) & int(__value)) != 0; }
2348262801Sdim
2349232950Stheraventemplate <class _Fp, class... _Args>
2350232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2351232950Stheravenasync(launch __policy, _Fp&& __f, _Args&&... __args)
2352227825Stheraven{
2353232950Stheraven    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2354232950Stheraven    typedef typename _BF::_Rp _Rp;
2355262801Sdim
2356262801Sdim#ifndef _LIBCPP_NO_EXCEPTIONS
2357262801Sdim    try
2358262801Sdim    {
2359262801Sdim#endif
2360262801Sdim        if (__does_policy_contain(__policy, launch::async))
2361262801Sdim        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2362227825Stheraven                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2363262801Sdim#ifndef _LIBCPP_NO_EXCEPTIONS
2364262801Sdim    }
2365262801Sdim    catch ( ... ) { if (__policy == launch::async) throw ; }
2366262801Sdim#endif
2367262801Sdim
2368262801Sdim    if (__does_policy_contain(__policy, launch::deferred))
2369262801Sdim        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2370227825Stheraven                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2371262801Sdim    return future<_Rp>{};
2372227825Stheraven}
2373227825Stheraven
2374232950Stheraventemplate <class _Fp, class... _Args>
2375227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2376232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2377232950Stheravenasync(_Fp&& __f, _Args&&... __args)
2378227825Stheraven{
2379232950Stheraven    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2380227825Stheraven                                    _VSTD::forward<_Args>(__args)...);
2381227825Stheraven}
2382227825Stheraven
2383227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
2384227825Stheraven
2385227825Stheraven// shared_future
2386227825Stheraven
2387232950Stheraventemplate <class _Rp>
2388262801Sdimclass _LIBCPP_TYPE_VIS_ONLY shared_future
2389227825Stheraven{
2390232950Stheraven    __assoc_state<_Rp>* __state_;
2391227825Stheraven
2392227825Stheravenpublic:
2393227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2394241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2395227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2396227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2397227825Stheraven        {if (__state_) __state_->__add_shared();}
2398227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2399227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2400241903Sdim    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2401227825Stheraven        {__f.__state_ = nullptr;}
2402227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2403241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2404227825Stheraven        {__rhs.__state_ = nullptr;}
2405227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2406227825Stheraven    ~shared_future();
2407227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2408227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2409227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2410241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2411227825Stheraven        {
2412227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2413227825Stheraven            return *this;
2414227825Stheraven        }
2415227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2416227825Stheraven
2417227825Stheraven    // retrieving the value
2418227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2419232950Stheraven    const _Rp& get() const {return __state_->copy();}
2420227825Stheraven
2421227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2422241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2423227825Stheraven
2424227825Stheraven    // functions to check state
2425227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2426241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2427227825Stheraven
2428227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2429227825Stheraven    void wait() const {__state_->wait();}
2430227825Stheraven    template <class _Rep, class _Period>
2431227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2432227825Stheraven        future_status
2433227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2434227825Stheraven            {return __state_->wait_for(__rel_time);}
2435227825Stheraven    template <class _Clock, class _Duration>
2436227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2437227825Stheraven        future_status
2438227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2439227825Stheraven            {return __state_->wait_until(__abs_time);}
2440227825Stheraven};
2441227825Stheraven
2442232950Stheraventemplate <class _Rp>
2443232950Stheravenshared_future<_Rp>::~shared_future()
2444227825Stheraven{
2445227825Stheraven    if (__state_)
2446227825Stheraven        __state_->__release_shared();
2447227825Stheraven}
2448227825Stheraven
2449232950Stheraventemplate <class _Rp>
2450232950Stheravenshared_future<_Rp>&
2451232950Stheravenshared_future<_Rp>::operator=(const shared_future& __rhs)
2452227825Stheraven{
2453227825Stheraven    if (__rhs.__state_)
2454227825Stheraven        __rhs.__state_->__add_shared();
2455227825Stheraven    if (__state_)
2456227825Stheraven        __state_->__release_shared();
2457227825Stheraven    __state_ = __rhs.__state_;
2458227825Stheraven    return *this;
2459227825Stheraven}
2460227825Stheraven
2461232950Stheraventemplate <class _Rp>
2462262801Sdimclass _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
2463227825Stheraven{
2464232950Stheraven    __assoc_state<_Rp&>* __state_;
2465227825Stheraven
2466227825Stheravenpublic:
2467227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2468241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2469227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2470227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2471227825Stheraven        {if (__state_) __state_->__add_shared();}
2472227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2473227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2474241903Sdim    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2475227825Stheraven        {__f.__state_ = nullptr;}
2476227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2477241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2478227825Stheraven        {__rhs.__state_ = nullptr;}
2479227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2480227825Stheraven    ~shared_future();
2481227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2482227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2483227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2484241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2485227825Stheraven        {
2486227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2487227825Stheraven            return *this;
2488227825Stheraven        }
2489227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2490227825Stheraven
2491227825Stheraven    // retrieving the value
2492227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2493232950Stheraven    _Rp& get() const {return __state_->copy();}
2494227825Stheraven
2495227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2496241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2497227825Stheraven
2498227825Stheraven    // functions to check state
2499227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2500241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2501227825Stheraven
2502227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2503227825Stheraven    void wait() const {__state_->wait();}
2504227825Stheraven    template <class _Rep, class _Period>
2505227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2506227825Stheraven        future_status
2507227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2508227825Stheraven            {return __state_->wait_for(__rel_time);}
2509227825Stheraven    template <class _Clock, class _Duration>
2510227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2511227825Stheraven        future_status
2512227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2513227825Stheraven            {return __state_->wait_until(__abs_time);}
2514227825Stheraven};
2515227825Stheraven
2516232950Stheraventemplate <class _Rp>
2517232950Stheravenshared_future<_Rp&>::~shared_future()
2518227825Stheraven{
2519227825Stheraven    if (__state_)
2520227825Stheraven        __state_->__release_shared();
2521227825Stheraven}
2522227825Stheraven
2523232950Stheraventemplate <class _Rp>
2524232950Stheravenshared_future<_Rp&>&
2525232950Stheravenshared_future<_Rp&>::operator=(const shared_future& __rhs)
2526227825Stheraven{
2527227825Stheraven    if (__rhs.__state_)
2528227825Stheraven        __rhs.__state_->__add_shared();
2529227825Stheraven    if (__state_)
2530227825Stheraven        __state_->__release_shared();
2531227825Stheraven    __state_ = __rhs.__state_;
2532227825Stheraven    return *this;
2533227825Stheraven}
2534227825Stheraven
2535227825Stheraventemplate <>
2536249998Sdimclass _LIBCPP_TYPE_VIS shared_future<void>
2537227825Stheraven{
2538227825Stheraven    __assoc_sub_state* __state_;
2539227825Stheraven
2540227825Stheravenpublic:
2541227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2542241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2543227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2544227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2545227825Stheraven        {if (__state_) __state_->__add_shared();}
2546227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2547227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2548241903Sdim    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2549227825Stheraven        {__f.__state_ = nullptr;}
2550227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2551241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2552227825Stheraven        {__rhs.__state_ = nullptr;}
2553227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2554227825Stheraven    ~shared_future();
2555227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2556227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2557227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2558241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2559227825Stheraven        {
2560227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2561227825Stheraven            return *this;
2562227825Stheraven        }
2563227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2564227825Stheraven
2565227825Stheraven    // retrieving the value
2566227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2567227825Stheraven    void get() const {__state_->copy();}
2568227825Stheraven
2569227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2570241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2571227825Stheraven
2572227825Stheraven    // functions to check state
2573227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2574241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2575227825Stheraven
2576227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2577227825Stheraven    void wait() const {__state_->wait();}
2578227825Stheraven    template <class _Rep, class _Period>
2579227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2580227825Stheraven        future_status
2581227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2582227825Stheraven            {return __state_->wait_for(__rel_time);}
2583227825Stheraven    template <class _Clock, class _Duration>
2584227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2585227825Stheraven        future_status
2586227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2587227825Stheraven            {return __state_->wait_until(__abs_time);}
2588227825Stheraven};
2589227825Stheraven
2590232950Stheraventemplate <class _Rp>
2591227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2592227825Stheravenvoid
2593241903Sdimswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2594227825Stheraven{
2595227825Stheraven    __x.swap(__y);
2596227825Stheraven}
2597227825Stheraven
2598232950Stheraventemplate <class _Rp>
2599227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2600232950Stheravenshared_future<_Rp>
2601232950Stheravenfuture<_Rp>::share()
2602227825Stheraven{
2603232950Stheraven    return shared_future<_Rp>(_VSTD::move(*this));
2604227825Stheraven}
2605227825Stheraven
2606232950Stheraventemplate <class _Rp>
2607227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2608232950Stheravenshared_future<_Rp&>
2609232950Stheravenfuture<_Rp&>::share()
2610227825Stheraven{
2611232950Stheraven    return shared_future<_Rp&>(_VSTD::move(*this));
2612227825Stheraven}
2613227825Stheraven
2614227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2615227825Stheraven
2616227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2617227825Stheravenshared_future<void>
2618227825Stheravenfuture<void>::share()
2619227825Stheraven{
2620227825Stheraven    return shared_future<void>(_VSTD::move(*this));
2621227825Stheraven}
2622227825Stheraven
2623227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2624227825Stheraven
2625227825Stheraven_LIBCPP_END_NAMESPACE_STD
2626227825Stheraven
2627278724Sdim#endif // !_LIBCPP_HAS_NO_THREADS
2628278724Sdim
2629227825Stheraven#endif  // _LIBCPP_FUTURE
2630