xref: /freebsd/contrib/llvm-project/libcxx/include/future (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===--------------------------- future -----------------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_FUTURE
11*0b57cec5SDimitry Andric#define _LIBCPP_FUTURE
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric    future synopsis
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andricnamespace std
17*0b57cec5SDimitry Andric{
18*0b57cec5SDimitry Andric
19*0b57cec5SDimitry Andricenum class future_errc
20*0b57cec5SDimitry Andric{
21*0b57cec5SDimitry Andric    future_already_retrieved = 1,
22*0b57cec5SDimitry Andric    promise_already_satisfied,
23*0b57cec5SDimitry Andric    no_state,
24*0b57cec5SDimitry Andric    broken_promise
25*0b57cec5SDimitry Andric};
26*0b57cec5SDimitry Andric
27*0b57cec5SDimitry Andricenum class launch
28*0b57cec5SDimitry Andric{
29*0b57cec5SDimitry Andric    async = 1,
30*0b57cec5SDimitry Andric    deferred = 2,
31*0b57cec5SDimitry Andric    any = async | deferred
32*0b57cec5SDimitry Andric};
33*0b57cec5SDimitry Andric
34*0b57cec5SDimitry Andricenum class future_status
35*0b57cec5SDimitry Andric{
36*0b57cec5SDimitry Andric    ready,
37*0b57cec5SDimitry Andric    timeout,
38*0b57cec5SDimitry Andric    deferred
39*0b57cec5SDimitry Andric};
40*0b57cec5SDimitry Andric
41*0b57cec5SDimitry Andrictemplate <> struct is_error_code_enum<future_errc> : public true_type { };
42*0b57cec5SDimitry Andricerror_code make_error_code(future_errc e) noexcept;
43*0b57cec5SDimitry Andricerror_condition make_error_condition(future_errc e) noexcept;
44*0b57cec5SDimitry Andric
45*0b57cec5SDimitry Andricconst error_category& future_category() noexcept;
46*0b57cec5SDimitry Andric
47*0b57cec5SDimitry Andricclass future_error
48*0b57cec5SDimitry Andric    : public logic_error
49*0b57cec5SDimitry Andric{
50*0b57cec5SDimitry Andricpublic:
51*0b57cec5SDimitry Andric    future_error(error_code ec);  // exposition only
52*0b57cec5SDimitry Andric    explicit future_error(future_errc); // C++17
53*0b57cec5SDimitry Andric    const error_code& code() const noexcept;
54*0b57cec5SDimitry Andric    const char*       what() const noexcept;
55*0b57cec5SDimitry Andric};
56*0b57cec5SDimitry Andric
57*0b57cec5SDimitry Andrictemplate <class R>
58*0b57cec5SDimitry Andricclass promise
59*0b57cec5SDimitry Andric{
60*0b57cec5SDimitry Andricpublic:
61*0b57cec5SDimitry Andric    promise();
62*0b57cec5SDimitry Andric    template <class Allocator>
63*0b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
64*0b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
65*0b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
66*0b57cec5SDimitry Andric    ~promise();
67*0b57cec5SDimitry Andric
68*0b57cec5SDimitry Andric    // assignment
69*0b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
70*0b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
71*0b57cec5SDimitry Andric    void swap(promise& other) noexcept;
72*0b57cec5SDimitry Andric
73*0b57cec5SDimitry Andric    // retrieving the result
74*0b57cec5SDimitry Andric    future<R> get_future();
75*0b57cec5SDimitry Andric
76*0b57cec5SDimitry Andric    // setting the result
77*0b57cec5SDimitry Andric    void set_value(const R& r);
78*0b57cec5SDimitry Andric    void set_value(R&& r);
79*0b57cec5SDimitry Andric    void set_exception(exception_ptr p);
80*0b57cec5SDimitry Andric
81*0b57cec5SDimitry Andric    // setting the result with deferred notification
82*0b57cec5SDimitry Andric    void set_value_at_thread_exit(const R& r);
83*0b57cec5SDimitry Andric    void set_value_at_thread_exit(R&& r);
84*0b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
85*0b57cec5SDimitry Andric};
86*0b57cec5SDimitry Andric
87*0b57cec5SDimitry Andrictemplate <class R>
88*0b57cec5SDimitry Andricclass promise<R&>
89*0b57cec5SDimitry Andric{
90*0b57cec5SDimitry Andricpublic:
91*0b57cec5SDimitry Andric    promise();
92*0b57cec5SDimitry Andric    template <class Allocator>
93*0b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
94*0b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
95*0b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
96*0b57cec5SDimitry Andric    ~promise();
97*0b57cec5SDimitry Andric
98*0b57cec5SDimitry Andric    // assignment
99*0b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
100*0b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
101*0b57cec5SDimitry Andric    void swap(promise& other) noexcept;
102*0b57cec5SDimitry Andric
103*0b57cec5SDimitry Andric    // retrieving the result
104*0b57cec5SDimitry Andric    future<R&> get_future();
105*0b57cec5SDimitry Andric
106*0b57cec5SDimitry Andric    // setting the result
107*0b57cec5SDimitry Andric    void set_value(R& r);
108*0b57cec5SDimitry Andric    void set_exception(exception_ptr p);
109*0b57cec5SDimitry Andric
110*0b57cec5SDimitry Andric    // setting the result with deferred notification
111*0b57cec5SDimitry Andric    void set_value_at_thread_exit(R&);
112*0b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
113*0b57cec5SDimitry Andric};
114*0b57cec5SDimitry Andric
115*0b57cec5SDimitry Andrictemplate <>
116*0b57cec5SDimitry Andricclass promise<void>
117*0b57cec5SDimitry Andric{
118*0b57cec5SDimitry Andricpublic:
119*0b57cec5SDimitry Andric    promise();
120*0b57cec5SDimitry Andric    template <class Allocator>
121*0b57cec5SDimitry Andric        promise(allocator_arg_t, const Allocator& a);
122*0b57cec5SDimitry Andric    promise(promise&& rhs) noexcept;
123*0b57cec5SDimitry Andric    promise(const promise& rhs) = delete;
124*0b57cec5SDimitry Andric    ~promise();
125*0b57cec5SDimitry Andric
126*0b57cec5SDimitry Andric    // assignment
127*0b57cec5SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
128*0b57cec5SDimitry Andric    promise& operator=(const promise& rhs) = delete;
129*0b57cec5SDimitry Andric    void swap(promise& other) noexcept;
130*0b57cec5SDimitry Andric
131*0b57cec5SDimitry Andric    // retrieving the result
132*0b57cec5SDimitry Andric    future<void> get_future();
133*0b57cec5SDimitry Andric
134*0b57cec5SDimitry Andric    // setting the result
135*0b57cec5SDimitry Andric    void set_value();
136*0b57cec5SDimitry Andric    void set_exception(exception_ptr p);
137*0b57cec5SDimitry Andric
138*0b57cec5SDimitry Andric    // setting the result with deferred notification
139*0b57cec5SDimitry Andric    void set_value_at_thread_exit();
140*0b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
141*0b57cec5SDimitry Andric};
142*0b57cec5SDimitry Andric
143*0b57cec5SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
144*0b57cec5SDimitry Andric
145*0b57cec5SDimitry Andrictemplate <class R, class Alloc>
146*0b57cec5SDimitry Andric    struct uses_allocator<promise<R>, Alloc> : public true_type {};
147*0b57cec5SDimitry Andric
148*0b57cec5SDimitry Andrictemplate <class R>
149*0b57cec5SDimitry Andricclass future
150*0b57cec5SDimitry Andric{
151*0b57cec5SDimitry Andricpublic:
152*0b57cec5SDimitry Andric    future() noexcept;
153*0b57cec5SDimitry Andric    future(future&&) noexcept;
154*0b57cec5SDimitry Andric    future(const future& rhs) = delete;
155*0b57cec5SDimitry Andric    ~future();
156*0b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
157*0b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
158*0b57cec5SDimitry Andric    shared_future<R> share() noexcept;
159*0b57cec5SDimitry Andric
160*0b57cec5SDimitry Andric    // retrieving the value
161*0b57cec5SDimitry Andric    R get();
162*0b57cec5SDimitry Andric
163*0b57cec5SDimitry Andric    // functions to check state
164*0b57cec5SDimitry Andric    bool valid() const noexcept;
165*0b57cec5SDimitry Andric
166*0b57cec5SDimitry Andric    void wait() const;
167*0b57cec5SDimitry Andric    template <class Rep, class Period>
168*0b57cec5SDimitry Andric        future_status
169*0b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
170*0b57cec5SDimitry Andric    template <class Clock, class Duration>
171*0b57cec5SDimitry Andric        future_status
172*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
173*0b57cec5SDimitry Andric};
174*0b57cec5SDimitry Andric
175*0b57cec5SDimitry Andrictemplate <class R>
176*0b57cec5SDimitry Andricclass future<R&>
177*0b57cec5SDimitry Andric{
178*0b57cec5SDimitry Andricpublic:
179*0b57cec5SDimitry Andric    future() noexcept;
180*0b57cec5SDimitry Andric    future(future&&) noexcept;
181*0b57cec5SDimitry Andric    future(const future& rhs) = delete;
182*0b57cec5SDimitry Andric    ~future();
183*0b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
184*0b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
185*0b57cec5SDimitry Andric    shared_future<R&> share() noexcept;
186*0b57cec5SDimitry Andric
187*0b57cec5SDimitry Andric    // retrieving the value
188*0b57cec5SDimitry Andric    R& get();
189*0b57cec5SDimitry Andric
190*0b57cec5SDimitry Andric    // functions to check state
191*0b57cec5SDimitry Andric    bool valid() const noexcept;
192*0b57cec5SDimitry Andric
193*0b57cec5SDimitry Andric    void wait() const;
194*0b57cec5SDimitry Andric    template <class Rep, class Period>
195*0b57cec5SDimitry Andric        future_status
196*0b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
197*0b57cec5SDimitry Andric    template <class Clock, class Duration>
198*0b57cec5SDimitry Andric        future_status
199*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
200*0b57cec5SDimitry Andric};
201*0b57cec5SDimitry Andric
202*0b57cec5SDimitry Andrictemplate <>
203*0b57cec5SDimitry Andricclass future<void>
204*0b57cec5SDimitry Andric{
205*0b57cec5SDimitry Andricpublic:
206*0b57cec5SDimitry Andric    future() noexcept;
207*0b57cec5SDimitry Andric    future(future&&) noexcept;
208*0b57cec5SDimitry Andric    future(const future& rhs) = delete;
209*0b57cec5SDimitry Andric    ~future();
210*0b57cec5SDimitry Andric    future& operator=(const future& rhs) = delete;
211*0b57cec5SDimitry Andric    future& operator=(future&&) noexcept;
212*0b57cec5SDimitry Andric    shared_future<void> share() noexcept;
213*0b57cec5SDimitry Andric
214*0b57cec5SDimitry Andric    // retrieving the value
215*0b57cec5SDimitry Andric    void get();
216*0b57cec5SDimitry Andric
217*0b57cec5SDimitry Andric    // functions to check state
218*0b57cec5SDimitry Andric    bool valid() const noexcept;
219*0b57cec5SDimitry Andric
220*0b57cec5SDimitry Andric    void wait() const;
221*0b57cec5SDimitry Andric    template <class Rep, class Period>
222*0b57cec5SDimitry Andric        future_status
223*0b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
224*0b57cec5SDimitry Andric    template <class Clock, class Duration>
225*0b57cec5SDimitry Andric        future_status
226*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
227*0b57cec5SDimitry Andric};
228*0b57cec5SDimitry Andric
229*0b57cec5SDimitry Andrictemplate <class R>
230*0b57cec5SDimitry Andricclass shared_future
231*0b57cec5SDimitry Andric{
232*0b57cec5SDimitry Andricpublic:
233*0b57cec5SDimitry Andric    shared_future() noexcept;
234*0b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
235*0b57cec5SDimitry Andric    shared_future(future<R>&&) noexcept;
236*0b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
237*0b57cec5SDimitry Andric    ~shared_future();
238*0b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
239*0b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
240*0b57cec5SDimitry Andric
241*0b57cec5SDimitry Andric    // retrieving the value
242*0b57cec5SDimitry Andric    const R& get() const;
243*0b57cec5SDimitry Andric
244*0b57cec5SDimitry Andric    // functions to check state
245*0b57cec5SDimitry Andric    bool valid() const noexcept;
246*0b57cec5SDimitry Andric
247*0b57cec5SDimitry Andric    void wait() const;
248*0b57cec5SDimitry Andric    template <class Rep, class Period>
249*0b57cec5SDimitry Andric        future_status
250*0b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
251*0b57cec5SDimitry Andric    template <class Clock, class Duration>
252*0b57cec5SDimitry Andric        future_status
253*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
254*0b57cec5SDimitry Andric};
255*0b57cec5SDimitry Andric
256*0b57cec5SDimitry Andrictemplate <class R>
257*0b57cec5SDimitry Andricclass shared_future<R&>
258*0b57cec5SDimitry Andric{
259*0b57cec5SDimitry Andricpublic:
260*0b57cec5SDimitry Andric    shared_future() noexcept;
261*0b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
262*0b57cec5SDimitry Andric    shared_future(future<R&>&&) noexcept;
263*0b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
264*0b57cec5SDimitry Andric    ~shared_future();
265*0b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
266*0b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
267*0b57cec5SDimitry Andric
268*0b57cec5SDimitry Andric    // retrieving the value
269*0b57cec5SDimitry Andric    R& get() const;
270*0b57cec5SDimitry Andric
271*0b57cec5SDimitry Andric    // functions to check state
272*0b57cec5SDimitry Andric    bool valid() const noexcept;
273*0b57cec5SDimitry Andric
274*0b57cec5SDimitry Andric    void wait() const;
275*0b57cec5SDimitry Andric    template <class Rep, class Period>
276*0b57cec5SDimitry Andric        future_status
277*0b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
278*0b57cec5SDimitry Andric    template <class Clock, class Duration>
279*0b57cec5SDimitry Andric        future_status
280*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
281*0b57cec5SDimitry Andric};
282*0b57cec5SDimitry Andric
283*0b57cec5SDimitry Andrictemplate <>
284*0b57cec5SDimitry Andricclass shared_future<void>
285*0b57cec5SDimitry Andric{
286*0b57cec5SDimitry Andricpublic:
287*0b57cec5SDimitry Andric    shared_future() noexcept;
288*0b57cec5SDimitry Andric    shared_future(const shared_future& rhs);
289*0b57cec5SDimitry Andric    shared_future(future<void>&&) noexcept;
290*0b57cec5SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
291*0b57cec5SDimitry Andric    ~shared_future();
292*0b57cec5SDimitry Andric    shared_future& operator=(const shared_future& rhs);
293*0b57cec5SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
294*0b57cec5SDimitry Andric
295*0b57cec5SDimitry Andric    // retrieving the value
296*0b57cec5SDimitry Andric    void get() const;
297*0b57cec5SDimitry Andric
298*0b57cec5SDimitry Andric    // functions to check state
299*0b57cec5SDimitry Andric    bool valid() const noexcept;
300*0b57cec5SDimitry Andric
301*0b57cec5SDimitry Andric    void wait() const;
302*0b57cec5SDimitry Andric    template <class Rep, class Period>
303*0b57cec5SDimitry Andric        future_status
304*0b57cec5SDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
305*0b57cec5SDimitry Andric    template <class Clock, class Duration>
306*0b57cec5SDimitry Andric        future_status
307*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
308*0b57cec5SDimitry Andric};
309*0b57cec5SDimitry Andric
310*0b57cec5SDimitry Andrictemplate <class F, class... Args>
311*0b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
312*0b57cec5SDimitry Andric  async(F&& f, Args&&... args);
313*0b57cec5SDimitry Andric
314*0b57cec5SDimitry Andrictemplate <class F, class... Args>
315*0b57cec5SDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
316*0b57cec5SDimitry Andric  async(launch policy, F&& f, Args&&... args);
317*0b57cec5SDimitry Andric
318*0b57cec5SDimitry Andrictemplate <class> class packaged_task; // undefined
319*0b57cec5SDimitry Andric
320*0b57cec5SDimitry Andrictemplate <class R, class... ArgTypes>
321*0b57cec5SDimitry Andricclass packaged_task<R(ArgTypes...)>
322*0b57cec5SDimitry Andric{
323*0b57cec5SDimitry Andricpublic:
324*0b57cec5SDimitry Andric    typedef R result_type; // extension
325*0b57cec5SDimitry Andric
326*0b57cec5SDimitry Andric    // construction and destruction
327*0b57cec5SDimitry Andric    packaged_task() noexcept;
328*0b57cec5SDimitry Andric    template <class F>
329*0b57cec5SDimitry Andric        explicit packaged_task(F&& f);
330*0b57cec5SDimitry Andric    template <class F, class Allocator>
331*0b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
332*0b57cec5SDimitry Andric    ~packaged_task();
333*0b57cec5SDimitry Andric
334*0b57cec5SDimitry Andric    // no copy
335*0b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
336*0b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
337*0b57cec5SDimitry Andric
338*0b57cec5SDimitry Andric    // move support
339*0b57cec5SDimitry Andric    packaged_task(packaged_task&& other) noexcept;
340*0b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& other) noexcept;
341*0b57cec5SDimitry Andric    void swap(packaged_task& other) noexcept;
342*0b57cec5SDimitry Andric
343*0b57cec5SDimitry Andric    bool valid() const noexcept;
344*0b57cec5SDimitry Andric
345*0b57cec5SDimitry Andric    // result retrieval
346*0b57cec5SDimitry Andric    future<R> get_future();
347*0b57cec5SDimitry Andric
348*0b57cec5SDimitry Andric    // execution
349*0b57cec5SDimitry Andric    void operator()(ArgTypes... );
350*0b57cec5SDimitry Andric    void make_ready_at_thread_exit(ArgTypes...);
351*0b57cec5SDimitry Andric
352*0b57cec5SDimitry Andric    void reset();
353*0b57cec5SDimitry Andric};
354*0b57cec5SDimitry Andric
355*0b57cec5SDimitry Andrictemplate <class R>
356*0b57cec5SDimitry Andric  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
357*0b57cec5SDimitry Andric
358*0b57cec5SDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
359*0b57cec5SDimitry Andric
360*0b57cec5SDimitry Andric}  // std
361*0b57cec5SDimitry Andric
362*0b57cec5SDimitry Andric*/
363*0b57cec5SDimitry Andric
364*0b57cec5SDimitry Andric#include <__config>
365*0b57cec5SDimitry Andric#include <system_error>
366*0b57cec5SDimitry Andric#include <memory>
367*0b57cec5SDimitry Andric#include <chrono>
368*0b57cec5SDimitry Andric#include <exception>
369*0b57cec5SDimitry Andric#include <mutex>
370*0b57cec5SDimitry Andric#include <thread>
371*0b57cec5SDimitry Andric
372*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
373*0b57cec5SDimitry Andric#pragma GCC system_header
374*0b57cec5SDimitry Andric#endif
375*0b57cec5SDimitry Andric
376*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
377*0b57cec5SDimitry Andric#error <future> is not supported on this single threaded system
378*0b57cec5SDimitry Andric#else // !_LIBCPP_HAS_NO_THREADS
379*0b57cec5SDimitry Andric
380*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
381*0b57cec5SDimitry Andric
382*0b57cec5SDimitry Andric//enum class future_errc
383*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
384*0b57cec5SDimitry Andric{
385*0b57cec5SDimitry Andric    future_already_retrieved = 1,
386*0b57cec5SDimitry Andric    promise_already_satisfied,
387*0b57cec5SDimitry Andric    no_state,
388*0b57cec5SDimitry Andric    broken_promise
389*0b57cec5SDimitry Andric};
390*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
391*0b57cec5SDimitry Andric
392*0b57cec5SDimitry Andrictemplate <>
393*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
394*0b57cec5SDimitry Andric
395*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
396*0b57cec5SDimitry Andrictemplate <>
397*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
398*0b57cec5SDimitry Andric#endif
399*0b57cec5SDimitry Andric
400*0b57cec5SDimitry Andric//enum class launch
401*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch)
402*0b57cec5SDimitry Andric{
403*0b57cec5SDimitry Andric    async = 1,
404*0b57cec5SDimitry Andric    deferred = 2,
405*0b57cec5SDimitry Andric    any = async | deferred
406*0b57cec5SDimitry Andric};
407*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
408*0b57cec5SDimitry Andric
409*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
410*0b57cec5SDimitry Andric
411*0b57cec5SDimitry Andrictypedef underlying_type<launch>::type __launch_underlying_type;
412*0b57cec5SDimitry Andric
413*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
414*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
415*0b57cec5SDimitry Andriclaunch
416*0b57cec5SDimitry Andricoperator&(launch __x, launch __y)
417*0b57cec5SDimitry Andric{
418*0b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
419*0b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
420*0b57cec5SDimitry Andric}
421*0b57cec5SDimitry Andric
422*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
423*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
424*0b57cec5SDimitry Andriclaunch
425*0b57cec5SDimitry Andricoperator|(launch __x, launch __y)
426*0b57cec5SDimitry Andric{
427*0b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
428*0b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
429*0b57cec5SDimitry Andric}
430*0b57cec5SDimitry Andric
431*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
432*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
433*0b57cec5SDimitry Andriclaunch
434*0b57cec5SDimitry Andricoperator^(launch __x, launch __y)
435*0b57cec5SDimitry Andric{
436*0b57cec5SDimitry Andric    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
437*0b57cec5SDimitry Andric                               static_cast<__launch_underlying_type>(__y));
438*0b57cec5SDimitry Andric}
439*0b57cec5SDimitry Andric
440*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
441*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
442*0b57cec5SDimitry Andriclaunch
443*0b57cec5SDimitry Andricoperator~(launch __x)
444*0b57cec5SDimitry Andric{
445*0b57cec5SDimitry Andric    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
446*0b57cec5SDimitry Andric}
447*0b57cec5SDimitry Andric
448*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
449*0b57cec5SDimitry Andriclaunch&
450*0b57cec5SDimitry Andricoperator&=(launch& __x, launch __y)
451*0b57cec5SDimitry Andric{
452*0b57cec5SDimitry Andric    __x = __x & __y; return __x;
453*0b57cec5SDimitry Andric}
454*0b57cec5SDimitry Andric
455*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
456*0b57cec5SDimitry Andriclaunch&
457*0b57cec5SDimitry Andricoperator|=(launch& __x, launch __y)
458*0b57cec5SDimitry Andric{
459*0b57cec5SDimitry Andric    __x = __x | __y; return __x;
460*0b57cec5SDimitry Andric}
461*0b57cec5SDimitry Andric
462*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
463*0b57cec5SDimitry Andriclaunch&
464*0b57cec5SDimitry Andricoperator^=(launch& __x, launch __y)
465*0b57cec5SDimitry Andric{
466*0b57cec5SDimitry Andric    __x = __x ^ __y; return __x;
467*0b57cec5SDimitry Andric}
468*0b57cec5SDimitry Andric
469*0b57cec5SDimitry Andric#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
470*0b57cec5SDimitry Andric
471*0b57cec5SDimitry Andric//enum class future_status
472*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status)
473*0b57cec5SDimitry Andric{
474*0b57cec5SDimitry Andric    ready,
475*0b57cec5SDimitry Andric    timeout,
476*0b57cec5SDimitry Andric    deferred
477*0b57cec5SDimitry Andric};
478*0b57cec5SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
479*0b57cec5SDimitry Andric
480*0b57cec5SDimitry Andric_LIBCPP_FUNC_VIS
481*0b57cec5SDimitry Andricconst error_category& future_category() _NOEXCEPT;
482*0b57cec5SDimitry Andric
483*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
484*0b57cec5SDimitry Andricerror_code
485*0b57cec5SDimitry Andricmake_error_code(future_errc __e) _NOEXCEPT
486*0b57cec5SDimitry Andric{
487*0b57cec5SDimitry Andric    return error_code(static_cast<int>(__e), future_category());
488*0b57cec5SDimitry Andric}
489*0b57cec5SDimitry Andric
490*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
491*0b57cec5SDimitry Andricerror_condition
492*0b57cec5SDimitry Andricmake_error_condition(future_errc __e) _NOEXCEPT
493*0b57cec5SDimitry Andric{
494*0b57cec5SDimitry Andric    return error_condition(static_cast<int>(__e), future_category());
495*0b57cec5SDimitry Andric}
496*0b57cec5SDimitry Andric
497*0b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
498*0b57cec5SDimitry Andric    : public logic_error
499*0b57cec5SDimitry Andric{
500*0b57cec5SDimitry Andric    error_code __ec_;
501*0b57cec5SDimitry Andricpublic:
502*0b57cec5SDimitry Andric    future_error(error_code __ec);
503*0b57cec5SDimitry Andric#if _LIBCPP_STD_VERS > 14
504*0b57cec5SDimitry Andric    explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
505*0b57cec5SDimitry Andric#endif
506*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
507*0b57cec5SDimitry Andric    const error_code& code() const _NOEXCEPT {return __ec_;}
508*0b57cec5SDimitry Andric
509*0b57cec5SDimitry Andric    virtual ~future_error() _NOEXCEPT;
510*0b57cec5SDimitry Andric};
511*0b57cec5SDimitry Andric
512*0b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
513*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
514*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE_ERROR
515*0b57cec5SDimitry Andric#endif
516*0b57cec5SDimitry Andricvoid __throw_future_error(future_errc _Ev)
517*0b57cec5SDimitry Andric{
518*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
519*0b57cec5SDimitry Andric    throw future_error(make_error_code(_Ev));
520*0b57cec5SDimitry Andric#else
521*0b57cec5SDimitry Andric    ((void)_Ev);
522*0b57cec5SDimitry Andric    _VSTD::abort();
523*0b57cec5SDimitry Andric#endif
524*0b57cec5SDimitry Andric}
525*0b57cec5SDimitry Andric
526*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
527*0b57cec5SDimitry Andric    : public __shared_count
528*0b57cec5SDimitry Andric{
529*0b57cec5SDimitry Andricprotected:
530*0b57cec5SDimitry Andric    exception_ptr __exception_;
531*0b57cec5SDimitry Andric    mutable mutex __mut_;
532*0b57cec5SDimitry Andric    mutable condition_variable __cv_;
533*0b57cec5SDimitry Andric    unsigned __state_;
534*0b57cec5SDimitry Andric
535*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
536*0b57cec5SDimitry Andric    void __sub_wait(unique_lock<mutex>& __lk);
537*0b57cec5SDimitry Andricpublic:
538*0b57cec5SDimitry Andric    enum
539*0b57cec5SDimitry Andric    {
540*0b57cec5SDimitry Andric        __constructed = 1,
541*0b57cec5SDimitry Andric        __future_attached = 2,
542*0b57cec5SDimitry Andric        ready = 4,
543*0b57cec5SDimitry Andric        deferred = 8
544*0b57cec5SDimitry Andric    };
545*0b57cec5SDimitry Andric
546*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
547*0b57cec5SDimitry Andric    __assoc_sub_state() : __state_(0) {}
548*0b57cec5SDimitry Andric
549*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
550*0b57cec5SDimitry Andric    bool __has_value() const
551*0b57cec5SDimitry Andric        {return (__state_ & __constructed) || (__exception_ != nullptr);}
552*0b57cec5SDimitry Andric
553*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
554*0b57cec5SDimitry Andric    void __attach_future() {
555*0b57cec5SDimitry Andric        lock_guard<mutex> __lk(__mut_);
556*0b57cec5SDimitry Andric        bool __has_future_attached = (__state_ & __future_attached) != 0;
557*0b57cec5SDimitry Andric        if (__has_future_attached)
558*0b57cec5SDimitry Andric            __throw_future_error(future_errc::future_already_retrieved);
559*0b57cec5SDimitry Andric        this->__add_shared();
560*0b57cec5SDimitry Andric        __state_ |= __future_attached;
561*0b57cec5SDimitry Andric    }
562*0b57cec5SDimitry Andric
563*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
564*0b57cec5SDimitry Andric    void __set_deferred() {__state_ |= deferred;}
565*0b57cec5SDimitry Andric
566*0b57cec5SDimitry Andric    void __make_ready();
567*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
568*0b57cec5SDimitry Andric    bool __is_ready() const {return (__state_ & ready) != 0;}
569*0b57cec5SDimitry Andric
570*0b57cec5SDimitry Andric    void set_value();
571*0b57cec5SDimitry Andric    void set_value_at_thread_exit();
572*0b57cec5SDimitry Andric
573*0b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
574*0b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
575*0b57cec5SDimitry Andric
576*0b57cec5SDimitry Andric    void copy();
577*0b57cec5SDimitry Andric
578*0b57cec5SDimitry Andric    void wait();
579*0b57cec5SDimitry Andric    template <class _Rep, class _Period>
580*0b57cec5SDimitry Andric        future_status
581*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
582*0b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
583*0b57cec5SDimitry Andric    template <class _Clock, class _Duration>
584*0b57cec5SDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
585*0b57cec5SDimitry Andric        future_status
586*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
587*0b57cec5SDimitry Andric
588*0b57cec5SDimitry Andric    virtual void __execute();
589*0b57cec5SDimitry Andric};
590*0b57cec5SDimitry Andric
591*0b57cec5SDimitry Andrictemplate <class _Clock, class _Duration>
592*0b57cec5SDimitry Andricfuture_status
593*0b57cec5SDimitry Andric__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
594*0b57cec5SDimitry Andric{
595*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(__mut_);
596*0b57cec5SDimitry Andric    if (__state_ & deferred)
597*0b57cec5SDimitry Andric        return future_status::deferred;
598*0b57cec5SDimitry Andric    while (!(__state_ & ready) && _Clock::now() < __abs_time)
599*0b57cec5SDimitry Andric        __cv_.wait_until(__lk, __abs_time);
600*0b57cec5SDimitry Andric    if (__state_ & ready)
601*0b57cec5SDimitry Andric        return future_status::ready;
602*0b57cec5SDimitry Andric    return future_status::timeout;
603*0b57cec5SDimitry Andric}
604*0b57cec5SDimitry Andric
605*0b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
606*0b57cec5SDimitry Andricinline
607*0b57cec5SDimitry Andricfuture_status
608*0b57cec5SDimitry Andric__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
609*0b57cec5SDimitry Andric{
610*0b57cec5SDimitry Andric    return wait_until(chrono::steady_clock::now() + __rel_time);
611*0b57cec5SDimitry Andric}
612*0b57cec5SDimitry Andric
613*0b57cec5SDimitry Andrictemplate <class _Rp>
614*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state
615*0b57cec5SDimitry Andric    : public __assoc_sub_state
616*0b57cec5SDimitry Andric{
617*0b57cec5SDimitry Andric    typedef __assoc_sub_state base;
618*0b57cec5SDimitry Andric    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
619*0b57cec5SDimitry Andricprotected:
620*0b57cec5SDimitry Andric    _Up __value_;
621*0b57cec5SDimitry Andric
622*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
623*0b57cec5SDimitry Andricpublic:
624*0b57cec5SDimitry Andric
625*0b57cec5SDimitry Andric    template <class _Arg>
626*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
627*0b57cec5SDimitry Andric        void set_value(_Arg&& __arg);
628*0b57cec5SDimitry Andric#else
629*0b57cec5SDimitry Andric        void set_value(_Arg& __arg);
630*0b57cec5SDimitry Andric#endif
631*0b57cec5SDimitry Andric
632*0b57cec5SDimitry Andric    template <class _Arg>
633*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
634*0b57cec5SDimitry Andric        void set_value_at_thread_exit(_Arg&& __arg);
635*0b57cec5SDimitry Andric#else
636*0b57cec5SDimitry Andric        void set_value_at_thread_exit(_Arg& __arg);
637*0b57cec5SDimitry Andric#endif
638*0b57cec5SDimitry Andric
639*0b57cec5SDimitry Andric    _Rp move();
640*0b57cec5SDimitry Andric    typename add_lvalue_reference<_Rp>::type copy();
641*0b57cec5SDimitry Andric};
642*0b57cec5SDimitry Andric
643*0b57cec5SDimitry Andrictemplate <class _Rp>
644*0b57cec5SDimitry Andricvoid
645*0b57cec5SDimitry Andric__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
646*0b57cec5SDimitry Andric{
647*0b57cec5SDimitry Andric    if (this->__state_ & base::__constructed)
648*0b57cec5SDimitry Andric        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
649*0b57cec5SDimitry Andric    delete this;
650*0b57cec5SDimitry Andric}
651*0b57cec5SDimitry Andric
652*0b57cec5SDimitry Andrictemplate <class _Rp>
653*0b57cec5SDimitry Andrictemplate <class _Arg>
654*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE
655*0b57cec5SDimitry Andricvoid
656*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
657*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value(_Arg&& __arg)
658*0b57cec5SDimitry Andric#else
659*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value(_Arg& __arg)
660*0b57cec5SDimitry Andric#endif
661*0b57cec5SDimitry Andric{
662*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
663*0b57cec5SDimitry Andric    if (this->__has_value())
664*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
665*0b57cec5SDimitry Andric    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
666*0b57cec5SDimitry Andric    this->__state_ |= base::__constructed | base::ready;
667*0b57cec5SDimitry Andric    __cv_.notify_all();
668*0b57cec5SDimitry Andric}
669*0b57cec5SDimitry Andric
670*0b57cec5SDimitry Andrictemplate <class _Rp>
671*0b57cec5SDimitry Andrictemplate <class _Arg>
672*0b57cec5SDimitry Andricvoid
673*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
674*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
675*0b57cec5SDimitry Andric#else
676*0b57cec5SDimitry Andric__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
677*0b57cec5SDimitry Andric#endif
678*0b57cec5SDimitry Andric{
679*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
680*0b57cec5SDimitry Andric    if (this->__has_value())
681*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
682*0b57cec5SDimitry Andric    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
683*0b57cec5SDimitry Andric    this->__state_ |= base::__constructed;
684*0b57cec5SDimitry Andric    __thread_local_data()->__make_ready_at_thread_exit(this);
685*0b57cec5SDimitry Andric}
686*0b57cec5SDimitry Andric
687*0b57cec5SDimitry Andrictemplate <class _Rp>
688*0b57cec5SDimitry Andric_Rp
689*0b57cec5SDimitry Andric__assoc_state<_Rp>::move()
690*0b57cec5SDimitry Andric{
691*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
692*0b57cec5SDimitry Andric    this->__sub_wait(__lk);
693*0b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
694*0b57cec5SDimitry Andric        rethrow_exception(this->__exception_);
695*0b57cec5SDimitry Andric    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
696*0b57cec5SDimitry Andric}
697*0b57cec5SDimitry Andric
698*0b57cec5SDimitry Andrictemplate <class _Rp>
699*0b57cec5SDimitry Andrictypename add_lvalue_reference<_Rp>::type
700*0b57cec5SDimitry Andric__assoc_state<_Rp>::copy()
701*0b57cec5SDimitry Andric{
702*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
703*0b57cec5SDimitry Andric    this->__sub_wait(__lk);
704*0b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
705*0b57cec5SDimitry Andric        rethrow_exception(this->__exception_);
706*0b57cec5SDimitry Andric    return *reinterpret_cast<_Rp*>(&__value_);
707*0b57cec5SDimitry Andric}
708*0b57cec5SDimitry Andric
709*0b57cec5SDimitry Andrictemplate <class _Rp>
710*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
711*0b57cec5SDimitry Andric    : public __assoc_sub_state
712*0b57cec5SDimitry Andric{
713*0b57cec5SDimitry Andric    typedef __assoc_sub_state base;
714*0b57cec5SDimitry Andric    typedef _Rp* _Up;
715*0b57cec5SDimitry Andricprotected:
716*0b57cec5SDimitry Andric    _Up __value_;
717*0b57cec5SDimitry Andric
718*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
719*0b57cec5SDimitry Andricpublic:
720*0b57cec5SDimitry Andric
721*0b57cec5SDimitry Andric    void set_value(_Rp& __arg);
722*0b57cec5SDimitry Andric    void set_value_at_thread_exit(_Rp& __arg);
723*0b57cec5SDimitry Andric
724*0b57cec5SDimitry Andric    _Rp& copy();
725*0b57cec5SDimitry Andric};
726*0b57cec5SDimitry Andric
727*0b57cec5SDimitry Andrictemplate <class _Rp>
728*0b57cec5SDimitry Andricvoid
729*0b57cec5SDimitry Andric__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
730*0b57cec5SDimitry Andric{
731*0b57cec5SDimitry Andric    delete this;
732*0b57cec5SDimitry Andric}
733*0b57cec5SDimitry Andric
734*0b57cec5SDimitry Andrictemplate <class _Rp>
735*0b57cec5SDimitry Andricvoid
736*0b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value(_Rp& __arg)
737*0b57cec5SDimitry Andric{
738*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
739*0b57cec5SDimitry Andric    if (this->__has_value())
740*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
741*0b57cec5SDimitry Andric    __value_ = _VSTD::addressof(__arg);
742*0b57cec5SDimitry Andric    this->__state_ |= base::__constructed | base::ready;
743*0b57cec5SDimitry Andric    __cv_.notify_all();
744*0b57cec5SDimitry Andric}
745*0b57cec5SDimitry Andric
746*0b57cec5SDimitry Andrictemplate <class _Rp>
747*0b57cec5SDimitry Andricvoid
748*0b57cec5SDimitry Andric__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
749*0b57cec5SDimitry Andric{
750*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
751*0b57cec5SDimitry Andric    if (this->__has_value())
752*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
753*0b57cec5SDimitry Andric    __value_ = _VSTD::addressof(__arg);
754*0b57cec5SDimitry Andric    this->__state_ |= base::__constructed;
755*0b57cec5SDimitry Andric    __thread_local_data()->__make_ready_at_thread_exit(this);
756*0b57cec5SDimitry Andric}
757*0b57cec5SDimitry Andric
758*0b57cec5SDimitry Andrictemplate <class _Rp>
759*0b57cec5SDimitry Andric_Rp&
760*0b57cec5SDimitry Andric__assoc_state<_Rp&>::copy()
761*0b57cec5SDimitry Andric{
762*0b57cec5SDimitry Andric    unique_lock<mutex> __lk(this->__mut_);
763*0b57cec5SDimitry Andric    this->__sub_wait(__lk);
764*0b57cec5SDimitry Andric    if (this->__exception_ != nullptr)
765*0b57cec5SDimitry Andric        rethrow_exception(this->__exception_);
766*0b57cec5SDimitry Andric    return *__value_;
767*0b57cec5SDimitry Andric}
768*0b57cec5SDimitry Andric
769*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
770*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
771*0b57cec5SDimitry Andric    : public __assoc_state<_Rp>
772*0b57cec5SDimitry Andric{
773*0b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
774*0b57cec5SDimitry Andric    _Alloc __alloc_;
775*0b57cec5SDimitry Andric
776*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
777*0b57cec5SDimitry Andricpublic:
778*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
779*0b57cec5SDimitry Andric    explicit __assoc_state_alloc(const _Alloc& __a)
780*0b57cec5SDimitry Andric        : __alloc_(__a) {}
781*0b57cec5SDimitry Andric};
782*0b57cec5SDimitry Andric
783*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
784*0b57cec5SDimitry Andricvoid
785*0b57cec5SDimitry Andric__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
786*0b57cec5SDimitry Andric{
787*0b57cec5SDimitry Andric    if (this->__state_ & base::__constructed)
788*0b57cec5SDimitry Andric        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
789*0b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
790*0b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
791*0b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
792*0b57cec5SDimitry Andric    _Al __a(__alloc_);
793*0b57cec5SDimitry Andric    this->~__assoc_state_alloc();
794*0b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
795*0b57cec5SDimitry Andric}
796*0b57cec5SDimitry Andric
797*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
798*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
799*0b57cec5SDimitry Andric    : public __assoc_state<_Rp&>
800*0b57cec5SDimitry Andric{
801*0b57cec5SDimitry Andric    typedef __assoc_state<_Rp&> base;
802*0b57cec5SDimitry Andric    _Alloc __alloc_;
803*0b57cec5SDimitry Andric
804*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
805*0b57cec5SDimitry Andricpublic:
806*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
807*0b57cec5SDimitry Andric    explicit __assoc_state_alloc(const _Alloc& __a)
808*0b57cec5SDimitry Andric        : __alloc_(__a) {}
809*0b57cec5SDimitry Andric};
810*0b57cec5SDimitry Andric
811*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
812*0b57cec5SDimitry Andricvoid
813*0b57cec5SDimitry Andric__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
814*0b57cec5SDimitry Andric{
815*0b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
816*0b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
817*0b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
818*0b57cec5SDimitry Andric    _Al __a(__alloc_);
819*0b57cec5SDimitry Andric    this->~__assoc_state_alloc();
820*0b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
821*0b57cec5SDimitry Andric}
822*0b57cec5SDimitry Andric
823*0b57cec5SDimitry Andrictemplate <class _Alloc>
824*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
825*0b57cec5SDimitry Andric    : public __assoc_sub_state
826*0b57cec5SDimitry Andric{
827*0b57cec5SDimitry Andric    typedef __assoc_sub_state base;
828*0b57cec5SDimitry Andric    _Alloc __alloc_;
829*0b57cec5SDimitry Andric
830*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
831*0b57cec5SDimitry Andricpublic:
832*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
833*0b57cec5SDimitry Andric    explicit __assoc_sub_state_alloc(const _Alloc& __a)
834*0b57cec5SDimitry Andric        : __alloc_(__a) {}
835*0b57cec5SDimitry Andric};
836*0b57cec5SDimitry Andric
837*0b57cec5SDimitry Andrictemplate <class _Alloc>
838*0b57cec5SDimitry Andricvoid
839*0b57cec5SDimitry Andric__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
840*0b57cec5SDimitry Andric{
841*0b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
842*0b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
843*0b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
844*0b57cec5SDimitry Andric    _Al __a(__alloc_);
845*0b57cec5SDimitry Andric    this->~__assoc_sub_state_alloc();
846*0b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
847*0b57cec5SDimitry Andric}
848*0b57cec5SDimitry Andric
849*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
850*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
851*0b57cec5SDimitry Andric    : public __assoc_state<_Rp>
852*0b57cec5SDimitry Andric{
853*0b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
854*0b57cec5SDimitry Andric
855*0b57cec5SDimitry Andric    _Fp __func_;
856*0b57cec5SDimitry Andric
857*0b57cec5SDimitry Andricpublic:
858*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
859*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
860*0b57cec5SDimitry Andric    explicit __deferred_assoc_state(_Fp&& __f);
861*0b57cec5SDimitry Andric#endif
862*0b57cec5SDimitry Andric
863*0b57cec5SDimitry Andric    virtual void __execute();
864*0b57cec5SDimitry Andric};
865*0b57cec5SDimitry Andric
866*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
867*0b57cec5SDimitry Andric
868*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
869*0b57cec5SDimitry Andricinline
870*0b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
871*0b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
872*0b57cec5SDimitry Andric{
873*0b57cec5SDimitry Andric    this->__set_deferred();
874*0b57cec5SDimitry Andric}
875*0b57cec5SDimitry Andric
876*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
877*0b57cec5SDimitry Andric
878*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
879*0b57cec5SDimitry Andricvoid
880*0b57cec5SDimitry Andric__deferred_assoc_state<_Rp, _Fp>::__execute()
881*0b57cec5SDimitry Andric{
882*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
883*0b57cec5SDimitry Andric    try
884*0b57cec5SDimitry Andric    {
885*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
886*0b57cec5SDimitry Andric        this->set_value(__func_());
887*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
888*0b57cec5SDimitry Andric    }
889*0b57cec5SDimitry Andric    catch (...)
890*0b57cec5SDimitry Andric    {
891*0b57cec5SDimitry Andric        this->set_exception(current_exception());
892*0b57cec5SDimitry Andric    }
893*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
894*0b57cec5SDimitry Andric}
895*0b57cec5SDimitry Andric
896*0b57cec5SDimitry Andrictemplate <class _Fp>
897*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
898*0b57cec5SDimitry Andric    : public __assoc_sub_state
899*0b57cec5SDimitry Andric{
900*0b57cec5SDimitry Andric    typedef __assoc_sub_state base;
901*0b57cec5SDimitry Andric
902*0b57cec5SDimitry Andric    _Fp __func_;
903*0b57cec5SDimitry Andric
904*0b57cec5SDimitry Andricpublic:
905*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
906*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
907*0b57cec5SDimitry Andric    explicit __deferred_assoc_state(_Fp&& __f);
908*0b57cec5SDimitry Andric#endif
909*0b57cec5SDimitry Andric
910*0b57cec5SDimitry Andric    virtual void __execute();
911*0b57cec5SDimitry Andric};
912*0b57cec5SDimitry Andric
913*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
914*0b57cec5SDimitry Andric
915*0b57cec5SDimitry Andrictemplate <class _Fp>
916*0b57cec5SDimitry Andricinline
917*0b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
918*0b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
919*0b57cec5SDimitry Andric{
920*0b57cec5SDimitry Andric    this->__set_deferred();
921*0b57cec5SDimitry Andric}
922*0b57cec5SDimitry Andric
923*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
924*0b57cec5SDimitry Andric
925*0b57cec5SDimitry Andrictemplate <class _Fp>
926*0b57cec5SDimitry Andricvoid
927*0b57cec5SDimitry Andric__deferred_assoc_state<void, _Fp>::__execute()
928*0b57cec5SDimitry Andric{
929*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
930*0b57cec5SDimitry Andric    try
931*0b57cec5SDimitry Andric    {
932*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
933*0b57cec5SDimitry Andric        __func_();
934*0b57cec5SDimitry Andric        this->set_value();
935*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
936*0b57cec5SDimitry Andric    }
937*0b57cec5SDimitry Andric    catch (...)
938*0b57cec5SDimitry Andric    {
939*0b57cec5SDimitry Andric        this->set_exception(current_exception());
940*0b57cec5SDimitry Andric    }
941*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
942*0b57cec5SDimitry Andric}
943*0b57cec5SDimitry Andric
944*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
945*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
946*0b57cec5SDimitry Andric    : public __assoc_state<_Rp>
947*0b57cec5SDimitry Andric{
948*0b57cec5SDimitry Andric    typedef __assoc_state<_Rp> base;
949*0b57cec5SDimitry Andric
950*0b57cec5SDimitry Andric    _Fp __func_;
951*0b57cec5SDimitry Andric
952*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
953*0b57cec5SDimitry Andricpublic:
954*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
955*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
956*0b57cec5SDimitry Andric    explicit __async_assoc_state(_Fp&& __f);
957*0b57cec5SDimitry Andric#endif
958*0b57cec5SDimitry Andric
959*0b57cec5SDimitry Andric    virtual void __execute();
960*0b57cec5SDimitry Andric};
961*0b57cec5SDimitry Andric
962*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
963*0b57cec5SDimitry Andric
964*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
965*0b57cec5SDimitry Andricinline
966*0b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
967*0b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
968*0b57cec5SDimitry Andric{
969*0b57cec5SDimitry Andric}
970*0b57cec5SDimitry Andric
971*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
972*0b57cec5SDimitry Andric
973*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
974*0b57cec5SDimitry Andricvoid
975*0b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__execute()
976*0b57cec5SDimitry Andric{
977*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
978*0b57cec5SDimitry Andric    try
979*0b57cec5SDimitry Andric    {
980*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
981*0b57cec5SDimitry Andric        this->set_value(__func_());
982*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
983*0b57cec5SDimitry Andric    }
984*0b57cec5SDimitry Andric    catch (...)
985*0b57cec5SDimitry Andric    {
986*0b57cec5SDimitry Andric        this->set_exception(current_exception());
987*0b57cec5SDimitry Andric    }
988*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
989*0b57cec5SDimitry Andric}
990*0b57cec5SDimitry Andric
991*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
992*0b57cec5SDimitry Andricvoid
993*0b57cec5SDimitry Andric__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
994*0b57cec5SDimitry Andric{
995*0b57cec5SDimitry Andric    this->wait();
996*0b57cec5SDimitry Andric    base::__on_zero_shared();
997*0b57cec5SDimitry Andric}
998*0b57cec5SDimitry Andric
999*0b57cec5SDimitry Andrictemplate <class _Fp>
1000*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
1001*0b57cec5SDimitry Andric    : public __assoc_sub_state
1002*0b57cec5SDimitry Andric{
1003*0b57cec5SDimitry Andric    typedef __assoc_sub_state base;
1004*0b57cec5SDimitry Andric
1005*0b57cec5SDimitry Andric    _Fp __func_;
1006*0b57cec5SDimitry Andric
1007*0b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
1008*0b57cec5SDimitry Andricpublic:
1009*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1010*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1011*0b57cec5SDimitry Andric    explicit __async_assoc_state(_Fp&& __f);
1012*0b57cec5SDimitry Andric#endif
1013*0b57cec5SDimitry Andric
1014*0b57cec5SDimitry Andric    virtual void __execute();
1015*0b57cec5SDimitry Andric};
1016*0b57cec5SDimitry Andric
1017*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018*0b57cec5SDimitry Andric
1019*0b57cec5SDimitry Andrictemplate <class _Fp>
1020*0b57cec5SDimitry Andricinline
1021*0b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1022*0b57cec5SDimitry Andric    : __func_(_VSTD::forward<_Fp>(__f))
1023*0b57cec5SDimitry Andric{
1024*0b57cec5SDimitry Andric}
1025*0b57cec5SDimitry Andric
1026*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1027*0b57cec5SDimitry Andric
1028*0b57cec5SDimitry Andrictemplate <class _Fp>
1029*0b57cec5SDimitry Andricvoid
1030*0b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__execute()
1031*0b57cec5SDimitry Andric{
1032*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
1033*0b57cec5SDimitry Andric    try
1034*0b57cec5SDimitry Andric    {
1035*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
1036*0b57cec5SDimitry Andric        __func_();
1037*0b57cec5SDimitry Andric        this->set_value();
1038*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
1039*0b57cec5SDimitry Andric    }
1040*0b57cec5SDimitry Andric    catch (...)
1041*0b57cec5SDimitry Andric    {
1042*0b57cec5SDimitry Andric        this->set_exception(current_exception());
1043*0b57cec5SDimitry Andric    }
1044*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
1045*0b57cec5SDimitry Andric}
1046*0b57cec5SDimitry Andric
1047*0b57cec5SDimitry Andrictemplate <class _Fp>
1048*0b57cec5SDimitry Andricvoid
1049*0b57cec5SDimitry Andric__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
1050*0b57cec5SDimitry Andric{
1051*0b57cec5SDimitry Andric    this->wait();
1052*0b57cec5SDimitry Andric    base::__on_zero_shared();
1053*0b57cec5SDimitry Andric}
1054*0b57cec5SDimitry Andric
1055*0b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1056*0b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
1057*0b57cec5SDimitry Andric
1058*0b57cec5SDimitry Andric// future
1059*0b57cec5SDimitry Andric
1060*0b57cec5SDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
1061*0b57cec5SDimitry Andric
1062*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1063*0b57cec5SDimitry Andricfuture<_Rp>
1064*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1065*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f);
1066*0b57cec5SDimitry Andric#else
1067*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp __f);
1068*0b57cec5SDimitry Andric#endif
1069*0b57cec5SDimitry Andric
1070*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
1071*0b57cec5SDimitry Andricfuture<_Rp>
1072*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1073*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f);
1074*0b57cec5SDimitry Andric#else
1075*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp __f);
1076*0b57cec5SDimitry Andric#endif
1077*0b57cec5SDimitry Andric
1078*0b57cec5SDimitry Andrictemplate <class _Rp>
1079*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
1080*0b57cec5SDimitry Andric{
1081*0b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
1082*0b57cec5SDimitry Andric
1083*0b57cec5SDimitry Andric    explicit future(__assoc_state<_Rp>* __state);
1084*0b57cec5SDimitry Andric
1085*0b57cec5SDimitry Andric    template <class> friend class promise;
1086*0b57cec5SDimitry Andric    template <class> friend class shared_future;
1087*0b57cec5SDimitry Andric
1088*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1089*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1090*0b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1091*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1092*0b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1093*0b57cec5SDimitry Andric#else
1094*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1095*0b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1096*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1097*0b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp __f);
1098*0b57cec5SDimitry Andric#endif
1099*0b57cec5SDimitry Andric
1100*0b57cec5SDimitry Andricpublic:
1101*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1102*0b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
1103*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1104*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1105*0b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
1106*0b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1107*0b57cec5SDimitry Andric    future(const future&) = delete;
1108*0b57cec5SDimitry Andric    future& operator=(const future&) = delete;
1109*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1110*0b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
1111*0b57cec5SDimitry Andric        {
1112*0b57cec5SDimitry Andric            future(std::move(__rhs)).swap(*this);
1113*0b57cec5SDimitry Andric            return *this;
1114*0b57cec5SDimitry Andric        }
1115*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1116*0b57cec5SDimitry Andricprivate:
1117*0b57cec5SDimitry Andric    future(const future&);
1118*0b57cec5SDimitry Andric    future& operator=(const future&);
1119*0b57cec5SDimitry Andricpublic:
1120*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1121*0b57cec5SDimitry Andric    ~future();
1122*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1123*0b57cec5SDimitry Andric    shared_future<_Rp> share() _NOEXCEPT;
1124*0b57cec5SDimitry Andric
1125*0b57cec5SDimitry Andric    // retrieving the value
1126*0b57cec5SDimitry Andric    _Rp get();
1127*0b57cec5SDimitry Andric
1128*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1129*0b57cec5SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1130*0b57cec5SDimitry Andric
1131*0b57cec5SDimitry Andric    // functions to check state
1132*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1133*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1134*0b57cec5SDimitry Andric
1135*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1136*0b57cec5SDimitry Andric    void wait() const {__state_->wait();}
1137*0b57cec5SDimitry Andric    template <class _Rep, class _Period>
1138*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1139*0b57cec5SDimitry Andric        future_status
1140*0b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1141*0b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
1142*0b57cec5SDimitry Andric    template <class _Clock, class _Duration>
1143*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1144*0b57cec5SDimitry Andric        future_status
1145*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1146*0b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
1147*0b57cec5SDimitry Andric};
1148*0b57cec5SDimitry Andric
1149*0b57cec5SDimitry Andrictemplate <class _Rp>
1150*0b57cec5SDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state)
1151*0b57cec5SDimitry Andric    : __state_(__state)
1152*0b57cec5SDimitry Andric{
1153*0b57cec5SDimitry Andric    __state_->__attach_future();
1154*0b57cec5SDimitry Andric}
1155*0b57cec5SDimitry Andric
1156*0b57cec5SDimitry Andricstruct __release_shared_count
1157*0b57cec5SDimitry Andric{
1158*0b57cec5SDimitry Andric    void operator()(__shared_count* p) {p->__release_shared();}
1159*0b57cec5SDimitry Andric};
1160*0b57cec5SDimitry Andric
1161*0b57cec5SDimitry Andrictemplate <class _Rp>
1162*0b57cec5SDimitry Andricfuture<_Rp>::~future()
1163*0b57cec5SDimitry Andric{
1164*0b57cec5SDimitry Andric    if (__state_)
1165*0b57cec5SDimitry Andric        __state_->__release_shared();
1166*0b57cec5SDimitry Andric}
1167*0b57cec5SDimitry Andric
1168*0b57cec5SDimitry Andrictemplate <class _Rp>
1169*0b57cec5SDimitry Andric_Rp
1170*0b57cec5SDimitry Andricfuture<_Rp>::get()
1171*0b57cec5SDimitry Andric{
1172*0b57cec5SDimitry Andric    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1173*0b57cec5SDimitry Andric    __assoc_state<_Rp>* __s = __state_;
1174*0b57cec5SDimitry Andric    __state_ = nullptr;
1175*0b57cec5SDimitry Andric    return __s->move();
1176*0b57cec5SDimitry Andric}
1177*0b57cec5SDimitry Andric
1178*0b57cec5SDimitry Andrictemplate <class _Rp>
1179*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
1180*0b57cec5SDimitry Andric{
1181*0b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
1182*0b57cec5SDimitry Andric
1183*0b57cec5SDimitry Andric    explicit future(__assoc_state<_Rp&>* __state);
1184*0b57cec5SDimitry Andric
1185*0b57cec5SDimitry Andric    template <class> friend class promise;
1186*0b57cec5SDimitry Andric    template <class> friend class shared_future;
1187*0b57cec5SDimitry Andric
1188*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1189*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1190*0b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1191*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1192*0b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1193*0b57cec5SDimitry Andric#else
1194*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1195*0b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1196*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1197*0b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp __f);
1198*0b57cec5SDimitry Andric#endif
1199*0b57cec5SDimitry Andric
1200*0b57cec5SDimitry Andricpublic:
1201*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1202*0b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
1203*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1204*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1205*0b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
1206*0b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1207*0b57cec5SDimitry Andric    future(const future&) = delete;
1208*0b57cec5SDimitry Andric    future& operator=(const future&) = delete;
1209*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1210*0b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
1211*0b57cec5SDimitry Andric        {
1212*0b57cec5SDimitry Andric            future(std::move(__rhs)).swap(*this);
1213*0b57cec5SDimitry Andric            return *this;
1214*0b57cec5SDimitry Andric        }
1215*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1216*0b57cec5SDimitry Andricprivate:
1217*0b57cec5SDimitry Andric    future(const future&);
1218*0b57cec5SDimitry Andric    future& operator=(const future&);
1219*0b57cec5SDimitry Andricpublic:
1220*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1221*0b57cec5SDimitry Andric    ~future();
1222*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1223*0b57cec5SDimitry Andric    shared_future<_Rp&> share() _NOEXCEPT;
1224*0b57cec5SDimitry Andric
1225*0b57cec5SDimitry Andric    // retrieving the value
1226*0b57cec5SDimitry Andric    _Rp& get();
1227*0b57cec5SDimitry Andric
1228*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1229*0b57cec5SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1230*0b57cec5SDimitry Andric
1231*0b57cec5SDimitry Andric    // functions to check state
1232*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1233*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1234*0b57cec5SDimitry Andric
1235*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1236*0b57cec5SDimitry Andric    void wait() const {__state_->wait();}
1237*0b57cec5SDimitry Andric    template <class _Rep, class _Period>
1238*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1239*0b57cec5SDimitry Andric        future_status
1240*0b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1241*0b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
1242*0b57cec5SDimitry Andric    template <class _Clock, class _Duration>
1243*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1244*0b57cec5SDimitry Andric        future_status
1245*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1246*0b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
1247*0b57cec5SDimitry Andric};
1248*0b57cec5SDimitry Andric
1249*0b57cec5SDimitry Andrictemplate <class _Rp>
1250*0b57cec5SDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
1251*0b57cec5SDimitry Andric    : __state_(__state)
1252*0b57cec5SDimitry Andric{
1253*0b57cec5SDimitry Andric    __state_->__attach_future();
1254*0b57cec5SDimitry Andric}
1255*0b57cec5SDimitry Andric
1256*0b57cec5SDimitry Andrictemplate <class _Rp>
1257*0b57cec5SDimitry Andricfuture<_Rp&>::~future()
1258*0b57cec5SDimitry Andric{
1259*0b57cec5SDimitry Andric    if (__state_)
1260*0b57cec5SDimitry Andric        __state_->__release_shared();
1261*0b57cec5SDimitry Andric}
1262*0b57cec5SDimitry Andric
1263*0b57cec5SDimitry Andrictemplate <class _Rp>
1264*0b57cec5SDimitry Andric_Rp&
1265*0b57cec5SDimitry Andricfuture<_Rp&>::get()
1266*0b57cec5SDimitry Andric{
1267*0b57cec5SDimitry Andric    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1268*0b57cec5SDimitry Andric    __assoc_state<_Rp&>* __s = __state_;
1269*0b57cec5SDimitry Andric    __state_ = nullptr;
1270*0b57cec5SDimitry Andric    return __s->copy();
1271*0b57cec5SDimitry Andric}
1272*0b57cec5SDimitry Andric
1273*0b57cec5SDimitry Andrictemplate <>
1274*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
1275*0b57cec5SDimitry Andric{
1276*0b57cec5SDimitry Andric    __assoc_sub_state* __state_;
1277*0b57cec5SDimitry Andric
1278*0b57cec5SDimitry Andric    explicit future(__assoc_sub_state* __state);
1279*0b57cec5SDimitry Andric
1280*0b57cec5SDimitry Andric    template <class> friend class promise;
1281*0b57cec5SDimitry Andric    template <class> friend class shared_future;
1282*0b57cec5SDimitry Andric
1283*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1284*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1285*0b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1286*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1287*0b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1288*0b57cec5SDimitry Andric#else
1289*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1290*0b57cec5SDimitry Andric        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1291*0b57cec5SDimitry Andric    template <class _R1, class _Fp>
1292*0b57cec5SDimitry Andric        friend future<_R1> __make_async_assoc_state(_Fp __f);
1293*0b57cec5SDimitry Andric#endif
1294*0b57cec5SDimitry Andric
1295*0b57cec5SDimitry Andricpublic:
1296*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1297*0b57cec5SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
1298*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1299*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1300*0b57cec5SDimitry Andric    future(future&& __rhs) _NOEXCEPT
1301*0b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1302*0b57cec5SDimitry Andric    future(const future&) = delete;
1303*0b57cec5SDimitry Andric    future& operator=(const future&) = delete;
1304*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1305*0b57cec5SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
1306*0b57cec5SDimitry Andric        {
1307*0b57cec5SDimitry Andric            future(std::move(__rhs)).swap(*this);
1308*0b57cec5SDimitry Andric            return *this;
1309*0b57cec5SDimitry Andric        }
1310*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1311*0b57cec5SDimitry Andricprivate:
1312*0b57cec5SDimitry Andric    future(const future&);
1313*0b57cec5SDimitry Andric    future& operator=(const future&);
1314*0b57cec5SDimitry Andricpublic:
1315*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1316*0b57cec5SDimitry Andric    ~future();
1317*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1318*0b57cec5SDimitry Andric    shared_future<void> share() _NOEXCEPT;
1319*0b57cec5SDimitry Andric
1320*0b57cec5SDimitry Andric    // retrieving the value
1321*0b57cec5SDimitry Andric    void get();
1322*0b57cec5SDimitry Andric
1323*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1324*0b57cec5SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1325*0b57cec5SDimitry Andric
1326*0b57cec5SDimitry Andric    // functions to check state
1327*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1328*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1329*0b57cec5SDimitry Andric
1330*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1331*0b57cec5SDimitry Andric    void wait() const {__state_->wait();}
1332*0b57cec5SDimitry Andric    template <class _Rep, class _Period>
1333*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1334*0b57cec5SDimitry Andric        future_status
1335*0b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1336*0b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
1337*0b57cec5SDimitry Andric    template <class _Clock, class _Duration>
1338*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1339*0b57cec5SDimitry Andric        future_status
1340*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1341*0b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
1342*0b57cec5SDimitry Andric};
1343*0b57cec5SDimitry Andric
1344*0b57cec5SDimitry Andrictemplate <class _Rp>
1345*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1346*0b57cec5SDimitry Andricvoid
1347*0b57cec5SDimitry Andricswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1348*0b57cec5SDimitry Andric{
1349*0b57cec5SDimitry Andric    __x.swap(__y);
1350*0b57cec5SDimitry Andric}
1351*0b57cec5SDimitry Andric
1352*0b57cec5SDimitry Andric// promise<R>
1353*0b57cec5SDimitry Andric
1354*0b57cec5SDimitry Andrictemplate <class _Callable> class packaged_task;
1355*0b57cec5SDimitry Andric
1356*0b57cec5SDimitry Andrictemplate <class _Rp>
1357*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
1358*0b57cec5SDimitry Andric{
1359*0b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
1360*0b57cec5SDimitry Andric
1361*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1362*0b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1363*0b57cec5SDimitry Andric
1364*0b57cec5SDimitry Andric    template <class> friend class packaged_task;
1365*0b57cec5SDimitry Andricpublic:
1366*0b57cec5SDimitry Andric    promise();
1367*0b57cec5SDimitry Andric    template <class _Alloc>
1368*0b57cec5SDimitry Andric        promise(allocator_arg_t, const _Alloc& __a);
1369*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1370*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1371*0b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
1372*0b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1373*0b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
1374*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1375*0b57cec5SDimitry Andricprivate:
1376*0b57cec5SDimitry Andric    promise(const promise& __rhs);
1377*0b57cec5SDimitry Andricpublic:
1378*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1379*0b57cec5SDimitry Andric    ~promise();
1380*0b57cec5SDimitry Andric
1381*0b57cec5SDimitry Andric    // assignment
1382*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1383*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1384*0b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
1385*0b57cec5SDimitry Andric        {
1386*0b57cec5SDimitry Andric            promise(std::move(__rhs)).swap(*this);
1387*0b57cec5SDimitry Andric            return *this;
1388*0b57cec5SDimitry Andric        }
1389*0b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
1390*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391*0b57cec5SDimitry Andricprivate:
1392*0b57cec5SDimitry Andric    promise& operator=(const promise& __rhs);
1393*0b57cec5SDimitry Andricpublic:
1394*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1395*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1396*0b57cec5SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1397*0b57cec5SDimitry Andric
1398*0b57cec5SDimitry Andric    // retrieving the result
1399*0b57cec5SDimitry Andric    future<_Rp> get_future();
1400*0b57cec5SDimitry Andric
1401*0b57cec5SDimitry Andric    // setting the result
1402*0b57cec5SDimitry Andric    void set_value(const _Rp& __r);
1403*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1404*0b57cec5SDimitry Andric    void set_value(_Rp&& __r);
1405*0b57cec5SDimitry Andric#endif
1406*0b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
1407*0b57cec5SDimitry Andric
1408*0b57cec5SDimitry Andric    // setting the result with deferred notification
1409*0b57cec5SDimitry Andric    void set_value_at_thread_exit(const _Rp& __r);
1410*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1411*0b57cec5SDimitry Andric    void set_value_at_thread_exit(_Rp&& __r);
1412*0b57cec5SDimitry Andric#endif
1413*0b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
1414*0b57cec5SDimitry Andric};
1415*0b57cec5SDimitry Andric
1416*0b57cec5SDimitry Andrictemplate <class _Rp>
1417*0b57cec5SDimitry Andricpromise<_Rp>::promise()
1418*0b57cec5SDimitry Andric    : __state_(new __assoc_state<_Rp>)
1419*0b57cec5SDimitry Andric{
1420*0b57cec5SDimitry Andric}
1421*0b57cec5SDimitry Andric
1422*0b57cec5SDimitry Andrictemplate <class _Rp>
1423*0b57cec5SDimitry Andrictemplate <class _Alloc>
1424*0b57cec5SDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1425*0b57cec5SDimitry Andric{
1426*0b57cec5SDimitry Andric    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1427*0b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1428*0b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
1429*0b57cec5SDimitry Andric    _A2 __a(__a0);
1430*0b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1431*0b57cec5SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1432*0b57cec5SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
1433*0b57cec5SDimitry Andric}
1434*0b57cec5SDimitry Andric
1435*0b57cec5SDimitry Andrictemplate <class _Rp>
1436*0b57cec5SDimitry Andricpromise<_Rp>::~promise()
1437*0b57cec5SDimitry Andric{
1438*0b57cec5SDimitry Andric    if (__state_)
1439*0b57cec5SDimitry Andric    {
1440*0b57cec5SDimitry Andric        if (!__state_->__has_value() && __state_->use_count() > 1)
1441*0b57cec5SDimitry Andric            __state_->set_exception(make_exception_ptr(
1442*0b57cec5SDimitry Andric                      future_error(make_error_code(future_errc::broken_promise))
1443*0b57cec5SDimitry Andric                                                      ));
1444*0b57cec5SDimitry Andric        __state_->__release_shared();
1445*0b57cec5SDimitry Andric    }
1446*0b57cec5SDimitry Andric}
1447*0b57cec5SDimitry Andric
1448*0b57cec5SDimitry Andrictemplate <class _Rp>
1449*0b57cec5SDimitry Andricfuture<_Rp>
1450*0b57cec5SDimitry Andricpromise<_Rp>::get_future()
1451*0b57cec5SDimitry Andric{
1452*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1453*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1454*0b57cec5SDimitry Andric    return future<_Rp>(__state_);
1455*0b57cec5SDimitry Andric}
1456*0b57cec5SDimitry Andric
1457*0b57cec5SDimitry Andrictemplate <class _Rp>
1458*0b57cec5SDimitry Andricvoid
1459*0b57cec5SDimitry Andricpromise<_Rp>::set_value(const _Rp& __r)
1460*0b57cec5SDimitry Andric{
1461*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1462*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1463*0b57cec5SDimitry Andric    __state_->set_value(__r);
1464*0b57cec5SDimitry Andric}
1465*0b57cec5SDimitry Andric
1466*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1467*0b57cec5SDimitry Andric
1468*0b57cec5SDimitry Andrictemplate <class _Rp>
1469*0b57cec5SDimitry Andricvoid
1470*0b57cec5SDimitry Andricpromise<_Rp>::set_value(_Rp&& __r)
1471*0b57cec5SDimitry Andric{
1472*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1473*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1474*0b57cec5SDimitry Andric    __state_->set_value(_VSTD::move(__r));
1475*0b57cec5SDimitry Andric}
1476*0b57cec5SDimitry Andric
1477*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1478*0b57cec5SDimitry Andric
1479*0b57cec5SDimitry Andrictemplate <class _Rp>
1480*0b57cec5SDimitry Andricvoid
1481*0b57cec5SDimitry Andricpromise<_Rp>::set_exception(exception_ptr __p)
1482*0b57cec5SDimitry Andric{
1483*0b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1484*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1485*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1486*0b57cec5SDimitry Andric    __state_->set_exception(__p);
1487*0b57cec5SDimitry Andric}
1488*0b57cec5SDimitry Andric
1489*0b57cec5SDimitry Andrictemplate <class _Rp>
1490*0b57cec5SDimitry Andricvoid
1491*0b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1492*0b57cec5SDimitry Andric{
1493*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1494*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1495*0b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(__r);
1496*0b57cec5SDimitry Andric}
1497*0b57cec5SDimitry Andric
1498*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1499*0b57cec5SDimitry Andric
1500*0b57cec5SDimitry Andrictemplate <class _Rp>
1501*0b57cec5SDimitry Andricvoid
1502*0b57cec5SDimitry Andricpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1503*0b57cec5SDimitry Andric{
1504*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1505*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1506*0b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1507*0b57cec5SDimitry Andric}
1508*0b57cec5SDimitry Andric
1509*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1510*0b57cec5SDimitry Andric
1511*0b57cec5SDimitry Andrictemplate <class _Rp>
1512*0b57cec5SDimitry Andricvoid
1513*0b57cec5SDimitry Andricpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1514*0b57cec5SDimitry Andric{
1515*0b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1516*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1517*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1518*0b57cec5SDimitry Andric    __state_->set_exception_at_thread_exit(__p);
1519*0b57cec5SDimitry Andric}
1520*0b57cec5SDimitry Andric
1521*0b57cec5SDimitry Andric// promise<R&>
1522*0b57cec5SDimitry Andric
1523*0b57cec5SDimitry Andrictemplate <class _Rp>
1524*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
1525*0b57cec5SDimitry Andric{
1526*0b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
1527*0b57cec5SDimitry Andric
1528*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1529*0b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1530*0b57cec5SDimitry Andric
1531*0b57cec5SDimitry Andric    template <class> friend class packaged_task;
1532*0b57cec5SDimitry Andric
1533*0b57cec5SDimitry Andricpublic:
1534*0b57cec5SDimitry Andric    promise();
1535*0b57cec5SDimitry Andric    template <class _Allocator>
1536*0b57cec5SDimitry Andric        promise(allocator_arg_t, const _Allocator& __a);
1537*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1538*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1539*0b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
1540*0b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1541*0b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
1542*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1543*0b57cec5SDimitry Andricprivate:
1544*0b57cec5SDimitry Andric    promise(const promise& __rhs);
1545*0b57cec5SDimitry Andricpublic:
1546*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1547*0b57cec5SDimitry Andric    ~promise();
1548*0b57cec5SDimitry Andric
1549*0b57cec5SDimitry Andric    // assignment
1550*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1551*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1552*0b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
1553*0b57cec5SDimitry Andric        {
1554*0b57cec5SDimitry Andric            promise(std::move(__rhs)).swap(*this);
1555*0b57cec5SDimitry Andric            return *this;
1556*0b57cec5SDimitry Andric        }
1557*0b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
1558*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1559*0b57cec5SDimitry Andricprivate:
1560*0b57cec5SDimitry Andric    promise& operator=(const promise& __rhs);
1561*0b57cec5SDimitry Andricpublic:
1562*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1563*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1564*0b57cec5SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1565*0b57cec5SDimitry Andric
1566*0b57cec5SDimitry Andric    // retrieving the result
1567*0b57cec5SDimitry Andric    future<_Rp&> get_future();
1568*0b57cec5SDimitry Andric
1569*0b57cec5SDimitry Andric    // setting the result
1570*0b57cec5SDimitry Andric    void set_value(_Rp& __r);
1571*0b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
1572*0b57cec5SDimitry Andric
1573*0b57cec5SDimitry Andric    // setting the result with deferred notification
1574*0b57cec5SDimitry Andric    void set_value_at_thread_exit(_Rp&);
1575*0b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
1576*0b57cec5SDimitry Andric};
1577*0b57cec5SDimitry Andric
1578*0b57cec5SDimitry Andrictemplate <class _Rp>
1579*0b57cec5SDimitry Andricpromise<_Rp&>::promise()
1580*0b57cec5SDimitry Andric    : __state_(new __assoc_state<_Rp&>)
1581*0b57cec5SDimitry Andric{
1582*0b57cec5SDimitry Andric}
1583*0b57cec5SDimitry Andric
1584*0b57cec5SDimitry Andrictemplate <class _Rp>
1585*0b57cec5SDimitry Andrictemplate <class _Alloc>
1586*0b57cec5SDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1587*0b57cec5SDimitry Andric{
1588*0b57cec5SDimitry Andric    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1589*0b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1590*0b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
1591*0b57cec5SDimitry Andric    _A2 __a(__a0);
1592*0b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1593*0b57cec5SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1594*0b57cec5SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
1595*0b57cec5SDimitry Andric}
1596*0b57cec5SDimitry Andric
1597*0b57cec5SDimitry Andrictemplate <class _Rp>
1598*0b57cec5SDimitry Andricpromise<_Rp&>::~promise()
1599*0b57cec5SDimitry Andric{
1600*0b57cec5SDimitry Andric    if (__state_)
1601*0b57cec5SDimitry Andric    {
1602*0b57cec5SDimitry Andric        if (!__state_->__has_value() && __state_->use_count() > 1)
1603*0b57cec5SDimitry Andric            __state_->set_exception(make_exception_ptr(
1604*0b57cec5SDimitry Andric                      future_error(make_error_code(future_errc::broken_promise))
1605*0b57cec5SDimitry Andric                                                      ));
1606*0b57cec5SDimitry Andric        __state_->__release_shared();
1607*0b57cec5SDimitry Andric    }
1608*0b57cec5SDimitry Andric}
1609*0b57cec5SDimitry Andric
1610*0b57cec5SDimitry Andrictemplate <class _Rp>
1611*0b57cec5SDimitry Andricfuture<_Rp&>
1612*0b57cec5SDimitry Andricpromise<_Rp&>::get_future()
1613*0b57cec5SDimitry Andric{
1614*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1615*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1616*0b57cec5SDimitry Andric    return future<_Rp&>(__state_);
1617*0b57cec5SDimitry Andric}
1618*0b57cec5SDimitry Andric
1619*0b57cec5SDimitry Andrictemplate <class _Rp>
1620*0b57cec5SDimitry Andricvoid
1621*0b57cec5SDimitry Andricpromise<_Rp&>::set_value(_Rp& __r)
1622*0b57cec5SDimitry Andric{
1623*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1624*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1625*0b57cec5SDimitry Andric    __state_->set_value(__r);
1626*0b57cec5SDimitry Andric}
1627*0b57cec5SDimitry Andric
1628*0b57cec5SDimitry Andrictemplate <class _Rp>
1629*0b57cec5SDimitry Andricvoid
1630*0b57cec5SDimitry Andricpromise<_Rp&>::set_exception(exception_ptr __p)
1631*0b57cec5SDimitry Andric{
1632*0b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
1633*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1634*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1635*0b57cec5SDimitry Andric    __state_->set_exception(__p);
1636*0b57cec5SDimitry Andric}
1637*0b57cec5SDimitry Andric
1638*0b57cec5SDimitry Andrictemplate <class _Rp>
1639*0b57cec5SDimitry Andricvoid
1640*0b57cec5SDimitry Andricpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1641*0b57cec5SDimitry Andric{
1642*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1643*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1644*0b57cec5SDimitry Andric    __state_->set_value_at_thread_exit(__r);
1645*0b57cec5SDimitry Andric}
1646*0b57cec5SDimitry Andric
1647*0b57cec5SDimitry Andrictemplate <class _Rp>
1648*0b57cec5SDimitry Andricvoid
1649*0b57cec5SDimitry Andricpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1650*0b57cec5SDimitry Andric{
1651*0b57cec5SDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
1652*0b57cec5SDimitry Andric    if (__state_ == nullptr)
1653*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
1654*0b57cec5SDimitry Andric    __state_->set_exception_at_thread_exit(__p);
1655*0b57cec5SDimitry Andric}
1656*0b57cec5SDimitry Andric
1657*0b57cec5SDimitry Andric// promise<void>
1658*0b57cec5SDimitry Andric
1659*0b57cec5SDimitry Andrictemplate <>
1660*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
1661*0b57cec5SDimitry Andric{
1662*0b57cec5SDimitry Andric    __assoc_sub_state* __state_;
1663*0b57cec5SDimitry Andric
1664*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1665*0b57cec5SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1666*0b57cec5SDimitry Andric
1667*0b57cec5SDimitry Andric    template <class> friend class packaged_task;
1668*0b57cec5SDimitry Andric
1669*0b57cec5SDimitry Andricpublic:
1670*0b57cec5SDimitry Andric    promise();
1671*0b57cec5SDimitry Andric    template <class _Allocator>
1672*0b57cec5SDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
1673*0b57cec5SDimitry Andric        promise(allocator_arg_t, const _Allocator& __a);
1674*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1675*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1676*0b57cec5SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
1677*0b57cec5SDimitry Andric        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1678*0b57cec5SDimitry Andric    promise(const promise& __rhs) = delete;
1679*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1680*0b57cec5SDimitry Andricprivate:
1681*0b57cec5SDimitry Andric    promise(const promise& __rhs);
1682*0b57cec5SDimitry Andricpublic:
1683*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1684*0b57cec5SDimitry Andric    ~promise();
1685*0b57cec5SDimitry Andric
1686*0b57cec5SDimitry Andric    // assignment
1687*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1688*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1689*0b57cec5SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
1690*0b57cec5SDimitry Andric        {
1691*0b57cec5SDimitry Andric            promise(std::move(__rhs)).swap(*this);
1692*0b57cec5SDimitry Andric            return *this;
1693*0b57cec5SDimitry Andric        }
1694*0b57cec5SDimitry Andric    promise& operator=(const promise& __rhs) = delete;
1695*0b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1696*0b57cec5SDimitry Andricprivate:
1697*0b57cec5SDimitry Andric    promise& operator=(const promise& __rhs);
1698*0b57cec5SDimitry Andricpublic:
1699*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1700*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1701*0b57cec5SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1702*0b57cec5SDimitry Andric
1703*0b57cec5SDimitry Andric    // retrieving the result
1704*0b57cec5SDimitry Andric    future<void> get_future();
1705*0b57cec5SDimitry Andric
1706*0b57cec5SDimitry Andric    // setting the result
1707*0b57cec5SDimitry Andric    void set_value();
1708*0b57cec5SDimitry Andric    void set_exception(exception_ptr __p);
1709*0b57cec5SDimitry Andric
1710*0b57cec5SDimitry Andric    // setting the result with deferred notification
1711*0b57cec5SDimitry Andric    void set_value_at_thread_exit();
1712*0b57cec5SDimitry Andric    void set_exception_at_thread_exit(exception_ptr __p);
1713*0b57cec5SDimitry Andric};
1714*0b57cec5SDimitry Andric
1715*0b57cec5SDimitry Andrictemplate <class _Alloc>
1716*0b57cec5SDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1717*0b57cec5SDimitry Andric{
1718*0b57cec5SDimitry Andric    typedef __assoc_sub_state_alloc<_Alloc> _State;
1719*0b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1720*0b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
1721*0b57cec5SDimitry Andric    _A2 __a(__a0);
1722*0b57cec5SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1723*0b57cec5SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1724*0b57cec5SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
1725*0b57cec5SDimitry Andric}
1726*0b57cec5SDimitry Andric
1727*0b57cec5SDimitry Andrictemplate <class _Rp>
1728*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1729*0b57cec5SDimitry Andricvoid
1730*0b57cec5SDimitry Andricswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1731*0b57cec5SDimitry Andric{
1732*0b57cec5SDimitry Andric    __x.swap(__y);
1733*0b57cec5SDimitry Andric}
1734*0b57cec5SDimitry Andric
1735*0b57cec5SDimitry Andrictemplate <class _Rp, class _Alloc>
1736*0b57cec5SDimitry Andric    struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
1737*0b57cec5SDimitry Andric        : public true_type {};
1738*0b57cec5SDimitry Andric
1739*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
1740*0b57cec5SDimitry Andric
1741*0b57cec5SDimitry Andric// packaged_task
1742*0b57cec5SDimitry Andric
1743*0b57cec5SDimitry Andrictemplate<class _Fp> class __packaged_task_base;
1744*0b57cec5SDimitry Andric
1745*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1746*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
1747*0b57cec5SDimitry Andric{
1748*0b57cec5SDimitry Andric    __packaged_task_base(const __packaged_task_base&);
1749*0b57cec5SDimitry Andric    __packaged_task_base& operator=(const __packaged_task_base&);
1750*0b57cec5SDimitry Andricpublic:
1751*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1752*0b57cec5SDimitry Andric    __packaged_task_base() {}
1753*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1754*0b57cec5SDimitry Andric    virtual ~__packaged_task_base() {}
1755*0b57cec5SDimitry Andric    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1756*0b57cec5SDimitry Andric    virtual void destroy() = 0;
1757*0b57cec5SDimitry Andric    virtual void destroy_deallocate() = 0;
1758*0b57cec5SDimitry Andric    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1759*0b57cec5SDimitry Andric};
1760*0b57cec5SDimitry Andric
1761*0b57cec5SDimitry Andrictemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1762*0b57cec5SDimitry Andric
1763*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1764*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1765*0b57cec5SDimitry Andric    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1766*0b57cec5SDimitry Andric{
1767*0b57cec5SDimitry Andric    __compressed_pair<_Fp, _Alloc> __f_;
1768*0b57cec5SDimitry Andricpublic:
1769*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1770*0b57cec5SDimitry Andric    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1771*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1772*0b57cec5SDimitry Andric    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1773*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1774*0b57cec5SDimitry Andric    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1775*0b57cec5SDimitry Andric        : __f_(__f, __a) {}
1776*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1777*0b57cec5SDimitry Andric    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1778*0b57cec5SDimitry Andric        : __f_(_VSTD::move(__f), __a) {}
1779*0b57cec5SDimitry Andric    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1780*0b57cec5SDimitry Andric    virtual void destroy();
1781*0b57cec5SDimitry Andric    virtual void destroy_deallocate();
1782*0b57cec5SDimitry Andric    virtual _Rp operator()(_ArgTypes&& ... __args);
1783*0b57cec5SDimitry Andric};
1784*0b57cec5SDimitry Andric
1785*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1786*0b57cec5SDimitry Andricvoid
1787*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1788*0b57cec5SDimitry Andric                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1789*0b57cec5SDimitry Andric{
1790*0b57cec5SDimitry Andric    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1791*0b57cec5SDimitry Andric}
1792*0b57cec5SDimitry Andric
1793*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1794*0b57cec5SDimitry Andricvoid
1795*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1796*0b57cec5SDimitry Andric{
1797*0b57cec5SDimitry Andric    __f_.~__compressed_pair<_Fp, _Alloc>();
1798*0b57cec5SDimitry Andric}
1799*0b57cec5SDimitry Andric
1800*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1801*0b57cec5SDimitry Andricvoid
1802*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1803*0b57cec5SDimitry Andric{
1804*0b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1805*0b57cec5SDimitry Andric    typedef allocator_traits<_Ap> _ATraits;
1806*0b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
1807*0b57cec5SDimitry Andric    _Ap __a(__f_.second());
1808*0b57cec5SDimitry Andric    __f_.~__compressed_pair<_Fp, _Alloc>();
1809*0b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
1810*0b57cec5SDimitry Andric}
1811*0b57cec5SDimitry Andric
1812*0b57cec5SDimitry Andrictemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1813*0b57cec5SDimitry Andric_Rp
1814*0b57cec5SDimitry Andric__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1815*0b57cec5SDimitry Andric{
1816*0b57cec5SDimitry Andric    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1817*0b57cec5SDimitry Andric}
1818*0b57cec5SDimitry Andric
1819*0b57cec5SDimitry Andrictemplate <class _Callable> class __packaged_task_function;
1820*0b57cec5SDimitry Andric
1821*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1822*0b57cec5SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
1823*0b57cec5SDimitry Andric{
1824*0b57cec5SDimitry Andric    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1825*0b57cec5SDimitry Andric    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1826*0b57cec5SDimitry Andric    __base* __f_;
1827*0b57cec5SDimitry Andric
1828*0b57cec5SDimitry Andricpublic:
1829*0b57cec5SDimitry Andric    typedef _Rp result_type;
1830*0b57cec5SDimitry Andric
1831*0b57cec5SDimitry Andric    // construct/copy/destroy:
1832*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1833*0b57cec5SDimitry Andric    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1834*0b57cec5SDimitry Andric    template<class _Fp>
1835*0b57cec5SDimitry Andric      __packaged_task_function(_Fp&& __f);
1836*0b57cec5SDimitry Andric    template<class _Fp, class _Alloc>
1837*0b57cec5SDimitry Andric      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1838*0b57cec5SDimitry Andric
1839*0b57cec5SDimitry Andric    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1840*0b57cec5SDimitry Andric    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1841*0b57cec5SDimitry Andric
1842*0b57cec5SDimitry Andric    __packaged_task_function(const __packaged_task_function&) =  delete;
1843*0b57cec5SDimitry Andric    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1844*0b57cec5SDimitry Andric
1845*0b57cec5SDimitry Andric    ~__packaged_task_function();
1846*0b57cec5SDimitry Andric
1847*0b57cec5SDimitry Andric    void swap(__packaged_task_function&) _NOEXCEPT;
1848*0b57cec5SDimitry Andric
1849*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1850*0b57cec5SDimitry Andric    _Rp operator()(_ArgTypes...) const;
1851*0b57cec5SDimitry Andric};
1852*0b57cec5SDimitry Andric
1853*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1854*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1855*0b57cec5SDimitry Andric{
1856*0b57cec5SDimitry Andric    if (__f.__f_ == nullptr)
1857*0b57cec5SDimitry Andric        __f_ = nullptr;
1858*0b57cec5SDimitry Andric    else if (__f.__f_ == (__base*)&__f.__buf_)
1859*0b57cec5SDimitry Andric    {
1860*0b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
1861*0b57cec5SDimitry Andric        __f.__f_->__move_to(__f_);
1862*0b57cec5SDimitry Andric    }
1863*0b57cec5SDimitry Andric    else
1864*0b57cec5SDimitry Andric    {
1865*0b57cec5SDimitry Andric        __f_ = __f.__f_;
1866*0b57cec5SDimitry Andric        __f.__f_ = nullptr;
1867*0b57cec5SDimitry Andric    }
1868*0b57cec5SDimitry Andric}
1869*0b57cec5SDimitry Andric
1870*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1871*0b57cec5SDimitry Andrictemplate <class _Fp>
1872*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1873*0b57cec5SDimitry Andric    : __f_(nullptr)
1874*0b57cec5SDimitry Andric{
1875*0b57cec5SDimitry Andric    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1876*0b57cec5SDimitry Andric    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1877*0b57cec5SDimitry Andric    if (sizeof(_FF) <= sizeof(__buf_))
1878*0b57cec5SDimitry Andric    {
1879*0b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
1880*0b57cec5SDimitry Andric        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1881*0b57cec5SDimitry Andric    }
1882*0b57cec5SDimitry Andric    else
1883*0b57cec5SDimitry Andric    {
1884*0b57cec5SDimitry Andric        typedef allocator<_FF> _Ap;
1885*0b57cec5SDimitry Andric        _Ap __a;
1886*0b57cec5SDimitry Andric        typedef __allocator_destructor<_Ap> _Dp;
1887*0b57cec5SDimitry Andric        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1888*0b57cec5SDimitry Andric        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1889*0b57cec5SDimitry Andric        __f_ = __hold.release();
1890*0b57cec5SDimitry Andric    }
1891*0b57cec5SDimitry Andric}
1892*0b57cec5SDimitry Andric
1893*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1894*0b57cec5SDimitry Andrictemplate <class _Fp, class _Alloc>
1895*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1896*0b57cec5SDimitry Andric                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1897*0b57cec5SDimitry Andric    : __f_(nullptr)
1898*0b57cec5SDimitry Andric{
1899*0b57cec5SDimitry Andric    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
1900*0b57cec5SDimitry Andric    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1901*0b57cec5SDimitry Andric    if (sizeof(_FF) <= sizeof(__buf_))
1902*0b57cec5SDimitry Andric    {
1903*0b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
1904*0b57cec5SDimitry Andric        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1905*0b57cec5SDimitry Andric    }
1906*0b57cec5SDimitry Andric    else
1907*0b57cec5SDimitry Andric    {
1908*0b57cec5SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
1909*0b57cec5SDimitry Andric        _Ap __a(__a0);
1910*0b57cec5SDimitry Andric        typedef __allocator_destructor<_Ap> _Dp;
1911*0b57cec5SDimitry Andric        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1912*0b57cec5SDimitry Andric        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1913*0b57cec5SDimitry Andric            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1914*0b57cec5SDimitry Andric        __f_ = _VSTD::addressof(*__hold.release());
1915*0b57cec5SDimitry Andric    }
1916*0b57cec5SDimitry Andric}
1917*0b57cec5SDimitry Andric
1918*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1919*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>&
1920*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1921*0b57cec5SDimitry Andric{
1922*0b57cec5SDimitry Andric    if (__f_ == (__base*)&__buf_)
1923*0b57cec5SDimitry Andric        __f_->destroy();
1924*0b57cec5SDimitry Andric    else if (__f_)
1925*0b57cec5SDimitry Andric        __f_->destroy_deallocate();
1926*0b57cec5SDimitry Andric    __f_ = nullptr;
1927*0b57cec5SDimitry Andric    if (__f.__f_ == nullptr)
1928*0b57cec5SDimitry Andric        __f_ = nullptr;
1929*0b57cec5SDimitry Andric    else if (__f.__f_ == (__base*)&__f.__buf_)
1930*0b57cec5SDimitry Andric    {
1931*0b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
1932*0b57cec5SDimitry Andric        __f.__f_->__move_to(__f_);
1933*0b57cec5SDimitry Andric    }
1934*0b57cec5SDimitry Andric    else
1935*0b57cec5SDimitry Andric    {
1936*0b57cec5SDimitry Andric        __f_ = __f.__f_;
1937*0b57cec5SDimitry Andric        __f.__f_ = nullptr;
1938*0b57cec5SDimitry Andric    }
1939*0b57cec5SDimitry Andric    return *this;
1940*0b57cec5SDimitry Andric}
1941*0b57cec5SDimitry Andric
1942*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1943*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1944*0b57cec5SDimitry Andric{
1945*0b57cec5SDimitry Andric    if (__f_ == (__base*)&__buf_)
1946*0b57cec5SDimitry Andric        __f_->destroy();
1947*0b57cec5SDimitry Andric    else if (__f_)
1948*0b57cec5SDimitry Andric        __f_->destroy_deallocate();
1949*0b57cec5SDimitry Andric}
1950*0b57cec5SDimitry Andric
1951*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1952*0b57cec5SDimitry Andricvoid
1953*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1954*0b57cec5SDimitry Andric{
1955*0b57cec5SDimitry Andric    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1956*0b57cec5SDimitry Andric    {
1957*0b57cec5SDimitry Andric        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1958*0b57cec5SDimitry Andric        __base* __t = (__base*)&__tempbuf;
1959*0b57cec5SDimitry Andric        __f_->__move_to(__t);
1960*0b57cec5SDimitry Andric        __f_->destroy();
1961*0b57cec5SDimitry Andric        __f_ = nullptr;
1962*0b57cec5SDimitry Andric        __f.__f_->__move_to((__base*)&__buf_);
1963*0b57cec5SDimitry Andric        __f.__f_->destroy();
1964*0b57cec5SDimitry Andric        __f.__f_ = nullptr;
1965*0b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
1966*0b57cec5SDimitry Andric        __t->__move_to((__base*)&__f.__buf_);
1967*0b57cec5SDimitry Andric        __t->destroy();
1968*0b57cec5SDimitry Andric        __f.__f_ = (__base*)&__f.__buf_;
1969*0b57cec5SDimitry Andric    }
1970*0b57cec5SDimitry Andric    else if (__f_ == (__base*)&__buf_)
1971*0b57cec5SDimitry Andric    {
1972*0b57cec5SDimitry Andric        __f_->__move_to((__base*)&__f.__buf_);
1973*0b57cec5SDimitry Andric        __f_->destroy();
1974*0b57cec5SDimitry Andric        __f_ = __f.__f_;
1975*0b57cec5SDimitry Andric        __f.__f_ = (__base*)&__f.__buf_;
1976*0b57cec5SDimitry Andric    }
1977*0b57cec5SDimitry Andric    else if (__f.__f_ == (__base*)&__f.__buf_)
1978*0b57cec5SDimitry Andric    {
1979*0b57cec5SDimitry Andric        __f.__f_->__move_to((__base*)&__buf_);
1980*0b57cec5SDimitry Andric        __f.__f_->destroy();
1981*0b57cec5SDimitry Andric        __f.__f_ = __f_;
1982*0b57cec5SDimitry Andric        __f_ = (__base*)&__buf_;
1983*0b57cec5SDimitry Andric    }
1984*0b57cec5SDimitry Andric    else
1985*0b57cec5SDimitry Andric        _VSTD::swap(__f_, __f.__f_);
1986*0b57cec5SDimitry Andric}
1987*0b57cec5SDimitry Andric
1988*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1989*0b57cec5SDimitry Andricinline
1990*0b57cec5SDimitry Andric_Rp
1991*0b57cec5SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1992*0b57cec5SDimitry Andric{
1993*0b57cec5SDimitry Andric    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
1994*0b57cec5SDimitry Andric}
1995*0b57cec5SDimitry Andric
1996*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
1997*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
1998*0b57cec5SDimitry Andric{
1999*0b57cec5SDimitry Andricpublic:
2000*0b57cec5SDimitry Andric    typedef _Rp result_type; // extension
2001*0b57cec5SDimitry Andric
2002*0b57cec5SDimitry Andricprivate:
2003*0b57cec5SDimitry Andric    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2004*0b57cec5SDimitry Andric    promise<result_type>                                __p_;
2005*0b57cec5SDimitry Andric
2006*0b57cec5SDimitry Andricpublic:
2007*0b57cec5SDimitry Andric    // construction and destruction
2008*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2009*0b57cec5SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2010*0b57cec5SDimitry Andric    template <class _Fp,
2011*0b57cec5SDimitry Andric              class = typename enable_if
2012*0b57cec5SDimitry Andric              <
2013*0b57cec5SDimitry Andric                  !is_same<
2014*0b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
2015*0b57cec5SDimitry Andric                      packaged_task
2016*0b57cec5SDimitry Andric                      >::value
2017*0b57cec5SDimitry Andric                  >::type
2018*0b57cec5SDimitry Andric             >
2019*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2020*0b57cec5SDimitry Andric        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2021*0b57cec5SDimitry Andric    template <class _Fp, class _Allocator,
2022*0b57cec5SDimitry Andric              class = typename enable_if
2023*0b57cec5SDimitry Andric              <
2024*0b57cec5SDimitry Andric                  !is_same<
2025*0b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
2026*0b57cec5SDimitry Andric                      packaged_task
2027*0b57cec5SDimitry Andric                      >::value
2028*0b57cec5SDimitry Andric                  >::type
2029*0b57cec5SDimitry Andric              >
2030*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2031*0b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2032*0b57cec5SDimitry Andric             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2033*0b57cec5SDimitry Andric               __p_(allocator_arg, __a) {}
2034*0b57cec5SDimitry Andric    // ~packaged_task() = default;
2035*0b57cec5SDimitry Andric
2036*0b57cec5SDimitry Andric    // no copy
2037*0b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
2038*0b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
2039*0b57cec5SDimitry Andric
2040*0b57cec5SDimitry Andric    // move support
2041*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2042*0b57cec5SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
2043*0b57cec5SDimitry Andric        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2044*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2045*0b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2046*0b57cec5SDimitry Andric    {
2047*0b57cec5SDimitry Andric        __f_ = _VSTD::move(__other.__f_);
2048*0b57cec5SDimitry Andric        __p_ = _VSTD::move(__other.__p_);
2049*0b57cec5SDimitry Andric        return *this;
2050*0b57cec5SDimitry Andric    }
2051*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2052*0b57cec5SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
2053*0b57cec5SDimitry Andric    {
2054*0b57cec5SDimitry Andric        __f_.swap(__other.__f_);
2055*0b57cec5SDimitry Andric        __p_.swap(__other.__p_);
2056*0b57cec5SDimitry Andric    }
2057*0b57cec5SDimitry Andric
2058*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2059*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2060*0b57cec5SDimitry Andric
2061*0b57cec5SDimitry Andric    // result retrieval
2062*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2063*0b57cec5SDimitry Andric    future<result_type> get_future() {return __p_.get_future();}
2064*0b57cec5SDimitry Andric
2065*0b57cec5SDimitry Andric    // execution
2066*0b57cec5SDimitry Andric    void operator()(_ArgTypes... __args);
2067*0b57cec5SDimitry Andric    void make_ready_at_thread_exit(_ArgTypes... __args);
2068*0b57cec5SDimitry Andric
2069*0b57cec5SDimitry Andric    void reset();
2070*0b57cec5SDimitry Andric};
2071*0b57cec5SDimitry Andric
2072*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2073*0b57cec5SDimitry Andricvoid
2074*0b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
2075*0b57cec5SDimitry Andric{
2076*0b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
2077*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
2078*0b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
2079*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
2080*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2081*0b57cec5SDimitry Andric    try
2082*0b57cec5SDimitry Andric    {
2083*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2084*0b57cec5SDimitry Andric        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2085*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2086*0b57cec5SDimitry Andric    }
2087*0b57cec5SDimitry Andric    catch (...)
2088*0b57cec5SDimitry Andric    {
2089*0b57cec5SDimitry Andric        __p_.set_exception(current_exception());
2090*0b57cec5SDimitry Andric    }
2091*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2092*0b57cec5SDimitry Andric}
2093*0b57cec5SDimitry Andric
2094*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2095*0b57cec5SDimitry Andricvoid
2096*0b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2097*0b57cec5SDimitry Andric{
2098*0b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
2099*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
2100*0b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
2101*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
2102*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2103*0b57cec5SDimitry Andric    try
2104*0b57cec5SDimitry Andric    {
2105*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2106*0b57cec5SDimitry Andric        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2107*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2108*0b57cec5SDimitry Andric    }
2109*0b57cec5SDimitry Andric    catch (...)
2110*0b57cec5SDimitry Andric    {
2111*0b57cec5SDimitry Andric        __p_.set_exception_at_thread_exit(current_exception());
2112*0b57cec5SDimitry Andric    }
2113*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2114*0b57cec5SDimitry Andric}
2115*0b57cec5SDimitry Andric
2116*0b57cec5SDimitry Andrictemplate<class _Rp, class ..._ArgTypes>
2117*0b57cec5SDimitry Andricvoid
2118*0b57cec5SDimitry Andricpackaged_task<_Rp(_ArgTypes...)>::reset()
2119*0b57cec5SDimitry Andric{
2120*0b57cec5SDimitry Andric    if (!valid())
2121*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
2122*0b57cec5SDimitry Andric    __p_ = promise<result_type>();
2123*0b57cec5SDimitry Andric}
2124*0b57cec5SDimitry Andric
2125*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
2126*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
2127*0b57cec5SDimitry Andric{
2128*0b57cec5SDimitry Andricpublic:
2129*0b57cec5SDimitry Andric    typedef void result_type; // extension
2130*0b57cec5SDimitry Andric
2131*0b57cec5SDimitry Andricprivate:
2132*0b57cec5SDimitry Andric    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2133*0b57cec5SDimitry Andric    promise<result_type>                                __p_;
2134*0b57cec5SDimitry Andric
2135*0b57cec5SDimitry Andricpublic:
2136*0b57cec5SDimitry Andric    // construction and destruction
2137*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2138*0b57cec5SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2139*0b57cec5SDimitry Andric    template <class _Fp,
2140*0b57cec5SDimitry Andric              class = typename enable_if
2141*0b57cec5SDimitry Andric              <
2142*0b57cec5SDimitry Andric                  !is_same<
2143*0b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
2144*0b57cec5SDimitry Andric                      packaged_task
2145*0b57cec5SDimitry Andric                      >::value
2146*0b57cec5SDimitry Andric                  >::type
2147*0b57cec5SDimitry Andric              >
2148*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2149*0b57cec5SDimitry Andric        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2150*0b57cec5SDimitry Andric    template <class _Fp, class _Allocator,
2151*0b57cec5SDimitry Andric              class = typename enable_if
2152*0b57cec5SDimitry Andric              <
2153*0b57cec5SDimitry Andric                  !is_same<
2154*0b57cec5SDimitry Andric                      typename __uncvref<_Fp>::type,
2155*0b57cec5SDimitry Andric                      packaged_task
2156*0b57cec5SDimitry Andric                      >::value
2157*0b57cec5SDimitry Andric                  >::type
2158*0b57cec5SDimitry Andric              >
2159*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2160*0b57cec5SDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2161*0b57cec5SDimitry Andric             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2162*0b57cec5SDimitry Andric               __p_(allocator_arg, __a) {}
2163*0b57cec5SDimitry Andric    // ~packaged_task() = default;
2164*0b57cec5SDimitry Andric
2165*0b57cec5SDimitry Andric    // no copy
2166*0b57cec5SDimitry Andric    packaged_task(const packaged_task&) = delete;
2167*0b57cec5SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
2168*0b57cec5SDimitry Andric
2169*0b57cec5SDimitry Andric    // move support
2170*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2171*0b57cec5SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
2172*0b57cec5SDimitry Andric        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2173*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2174*0b57cec5SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2175*0b57cec5SDimitry Andric    {
2176*0b57cec5SDimitry Andric        __f_ = _VSTD::move(__other.__f_);
2177*0b57cec5SDimitry Andric        __p_ = _VSTD::move(__other.__p_);
2178*0b57cec5SDimitry Andric        return *this;
2179*0b57cec5SDimitry Andric    }
2180*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2181*0b57cec5SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
2182*0b57cec5SDimitry Andric    {
2183*0b57cec5SDimitry Andric        __f_.swap(__other.__f_);
2184*0b57cec5SDimitry Andric        __p_.swap(__other.__p_);
2185*0b57cec5SDimitry Andric    }
2186*0b57cec5SDimitry Andric
2187*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2188*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2189*0b57cec5SDimitry Andric
2190*0b57cec5SDimitry Andric    // result retrieval
2191*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2192*0b57cec5SDimitry Andric    future<result_type> get_future() {return __p_.get_future();}
2193*0b57cec5SDimitry Andric
2194*0b57cec5SDimitry Andric    // execution
2195*0b57cec5SDimitry Andric    void operator()(_ArgTypes... __args);
2196*0b57cec5SDimitry Andric    void make_ready_at_thread_exit(_ArgTypes... __args);
2197*0b57cec5SDimitry Andric
2198*0b57cec5SDimitry Andric    void reset();
2199*0b57cec5SDimitry Andric};
2200*0b57cec5SDimitry Andric
2201*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
2202*0b57cec5SDimitry Andricvoid
2203*0b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2204*0b57cec5SDimitry Andric{
2205*0b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
2206*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
2207*0b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
2208*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
2209*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2210*0b57cec5SDimitry Andric    try
2211*0b57cec5SDimitry Andric    {
2212*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2213*0b57cec5SDimitry Andric        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2214*0b57cec5SDimitry Andric        __p_.set_value();
2215*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2216*0b57cec5SDimitry Andric    }
2217*0b57cec5SDimitry Andric    catch (...)
2218*0b57cec5SDimitry Andric    {
2219*0b57cec5SDimitry Andric        __p_.set_exception(current_exception());
2220*0b57cec5SDimitry Andric    }
2221*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2222*0b57cec5SDimitry Andric}
2223*0b57cec5SDimitry Andric
2224*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
2225*0b57cec5SDimitry Andricvoid
2226*0b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2227*0b57cec5SDimitry Andric{
2228*0b57cec5SDimitry Andric    if (__p_.__state_ == nullptr)
2229*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
2230*0b57cec5SDimitry Andric    if (__p_.__state_->__has_value())
2231*0b57cec5SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
2232*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2233*0b57cec5SDimitry Andric    try
2234*0b57cec5SDimitry Andric    {
2235*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2236*0b57cec5SDimitry Andric        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2237*0b57cec5SDimitry Andric        __p_.set_value_at_thread_exit();
2238*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2239*0b57cec5SDimitry Andric    }
2240*0b57cec5SDimitry Andric    catch (...)
2241*0b57cec5SDimitry Andric    {
2242*0b57cec5SDimitry Andric        __p_.set_exception_at_thread_exit(current_exception());
2243*0b57cec5SDimitry Andric    }
2244*0b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
2245*0b57cec5SDimitry Andric}
2246*0b57cec5SDimitry Andric
2247*0b57cec5SDimitry Andrictemplate<class ..._ArgTypes>
2248*0b57cec5SDimitry Andricvoid
2249*0b57cec5SDimitry Andricpackaged_task<void(_ArgTypes...)>::reset()
2250*0b57cec5SDimitry Andric{
2251*0b57cec5SDimitry Andric    if (!valid())
2252*0b57cec5SDimitry Andric        __throw_future_error(future_errc::no_state);
2253*0b57cec5SDimitry Andric    __p_ = promise<result_type>();
2254*0b57cec5SDimitry Andric}
2255*0b57cec5SDimitry Andric
2256*0b57cec5SDimitry Andrictemplate <class _Callable>
2257*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2258*0b57cec5SDimitry Andricvoid
2259*0b57cec5SDimitry Andricswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2260*0b57cec5SDimitry Andric{
2261*0b57cec5SDimitry Andric    __x.swap(__y);
2262*0b57cec5SDimitry Andric}
2263*0b57cec5SDimitry Andric
2264*0b57cec5SDimitry Andrictemplate <class _Callable, class _Alloc>
2265*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2266*0b57cec5SDimitry Andric    : public true_type {};
2267*0b57cec5SDimitry Andric
2268*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
2269*0b57cec5SDimitry Andricfuture<_Rp>
2270*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2271*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp&& __f)
2272*0b57cec5SDimitry Andric#else
2273*0b57cec5SDimitry Andric__make_deferred_assoc_state(_Fp __f)
2274*0b57cec5SDimitry Andric#endif
2275*0b57cec5SDimitry Andric{
2276*0b57cec5SDimitry Andric    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2277*0b57cec5SDimitry Andric        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2278*0b57cec5SDimitry Andric    return future<_Rp>(__h.get());
2279*0b57cec5SDimitry Andric}
2280*0b57cec5SDimitry Andric
2281*0b57cec5SDimitry Andrictemplate <class _Rp, class _Fp>
2282*0b57cec5SDimitry Andricfuture<_Rp>
2283*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2284*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp&& __f)
2285*0b57cec5SDimitry Andric#else
2286*0b57cec5SDimitry Andric__make_async_assoc_state(_Fp __f)
2287*0b57cec5SDimitry Andric#endif
2288*0b57cec5SDimitry Andric{
2289*0b57cec5SDimitry Andric    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2290*0b57cec5SDimitry Andric        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2291*0b57cec5SDimitry Andric    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2292*0b57cec5SDimitry Andric    return future<_Rp>(__h.get());
2293*0b57cec5SDimitry Andric}
2294*0b57cec5SDimitry Andric
2295*0b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
2296*0b57cec5SDimitry Andricclass __async_func
2297*0b57cec5SDimitry Andric{
2298*0b57cec5SDimitry Andric    tuple<_Fp, _Args...> __f_;
2299*0b57cec5SDimitry Andric
2300*0b57cec5SDimitry Andricpublic:
2301*0b57cec5SDimitry Andric    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2302*0b57cec5SDimitry Andric
2303*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2304*0b57cec5SDimitry Andric    explicit __async_func(_Fp&& __f, _Args&&... __args)
2305*0b57cec5SDimitry Andric        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2306*0b57cec5SDimitry Andric
2307*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2308*0b57cec5SDimitry Andric    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2309*0b57cec5SDimitry Andric
2310*0b57cec5SDimitry Andric    _Rp operator()()
2311*0b57cec5SDimitry Andric    {
2312*0b57cec5SDimitry Andric        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2313*0b57cec5SDimitry Andric        return __execute(_Index());
2314*0b57cec5SDimitry Andric    }
2315*0b57cec5SDimitry Andricprivate:
2316*0b57cec5SDimitry Andric    template <size_t ..._Indices>
2317*0b57cec5SDimitry Andric    _Rp
2318*0b57cec5SDimitry Andric    __execute(__tuple_indices<_Indices...>)
2319*0b57cec5SDimitry Andric    {
2320*0b57cec5SDimitry Andric        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2321*0b57cec5SDimitry Andric    }
2322*0b57cec5SDimitry Andric};
2323*0b57cec5SDimitry Andric
2324*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
2325*0b57cec5SDimitry Andric{ return (int(__policy) & int(__value)) != 0; }
2326*0b57cec5SDimitry Andric
2327*0b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
2328*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17
2329*0b57cec5SDimitry Andricfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2330*0b57cec5SDimitry Andricasync(launch __policy, _Fp&& __f, _Args&&... __args)
2331*0b57cec5SDimitry Andric{
2332*0b57cec5SDimitry Andric    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2333*0b57cec5SDimitry Andric    typedef typename _BF::_Rp _Rp;
2334*0b57cec5SDimitry Andric
2335*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2336*0b57cec5SDimitry Andric    try
2337*0b57cec5SDimitry Andric    {
2338*0b57cec5SDimitry Andric#endif
2339*0b57cec5SDimitry Andric        if (__does_policy_contain(__policy, launch::async))
2340*0b57cec5SDimitry Andric        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2341*0b57cec5SDimitry Andric                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2342*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
2343*0b57cec5SDimitry Andric    }
2344*0b57cec5SDimitry Andric    catch ( ... ) { if (__policy == launch::async) throw ; }
2345*0b57cec5SDimitry Andric#endif
2346*0b57cec5SDimitry Andric
2347*0b57cec5SDimitry Andric    if (__does_policy_contain(__policy, launch::deferred))
2348*0b57cec5SDimitry Andric        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2349*0b57cec5SDimitry Andric                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2350*0b57cec5SDimitry Andric    return future<_Rp>{};
2351*0b57cec5SDimitry Andric}
2352*0b57cec5SDimitry Andric
2353*0b57cec5SDimitry Andrictemplate <class _Fp, class... _Args>
2354*0b57cec5SDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
2355*0b57cec5SDimitry Andricfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2356*0b57cec5SDimitry Andricasync(_Fp&& __f, _Args&&... __args)
2357*0b57cec5SDimitry Andric{
2358*0b57cec5SDimitry Andric    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2359*0b57cec5SDimitry Andric                                    _VSTD::forward<_Args>(__args)...);
2360*0b57cec5SDimitry Andric}
2361*0b57cec5SDimitry Andric
2362*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
2363*0b57cec5SDimitry Andric
2364*0b57cec5SDimitry Andric// shared_future
2365*0b57cec5SDimitry Andric
2366*0b57cec5SDimitry Andrictemplate <class _Rp>
2367*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future
2368*0b57cec5SDimitry Andric{
2369*0b57cec5SDimitry Andric    __assoc_state<_Rp>* __state_;
2370*0b57cec5SDimitry Andric
2371*0b57cec5SDimitry Andricpublic:
2372*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2373*0b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
2374*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2375*0b57cec5SDimitry Andric    shared_future(const shared_future& __rhs)  _NOEXCEPT : __state_(__rhs.__state_)
2376*0b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
2377*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2378*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2379*0b57cec5SDimitry Andric    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2380*0b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
2381*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2382*0b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2383*0b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
2384*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2385*0b57cec5SDimitry Andric    ~shared_future();
2386*0b57cec5SDimitry Andric    shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
2387*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2388*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2389*0b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2390*0b57cec5SDimitry Andric        {
2391*0b57cec5SDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
2392*0b57cec5SDimitry Andric            return *this;
2393*0b57cec5SDimitry Andric        }
2394*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2395*0b57cec5SDimitry Andric
2396*0b57cec5SDimitry Andric    // retrieving the value
2397*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2398*0b57cec5SDimitry Andric    const _Rp& get() const {return __state_->copy();}
2399*0b57cec5SDimitry Andric
2400*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2401*0b57cec5SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2402*0b57cec5SDimitry Andric
2403*0b57cec5SDimitry Andric    // functions to check state
2404*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2405*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2406*0b57cec5SDimitry Andric
2407*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2408*0b57cec5SDimitry Andric    void wait() const {__state_->wait();}
2409*0b57cec5SDimitry Andric    template <class _Rep, class _Period>
2410*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2411*0b57cec5SDimitry Andric        future_status
2412*0b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2413*0b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
2414*0b57cec5SDimitry Andric    template <class _Clock, class _Duration>
2415*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2416*0b57cec5SDimitry Andric        future_status
2417*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2418*0b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
2419*0b57cec5SDimitry Andric};
2420*0b57cec5SDimitry Andric
2421*0b57cec5SDimitry Andrictemplate <class _Rp>
2422*0b57cec5SDimitry Andricshared_future<_Rp>::~shared_future()
2423*0b57cec5SDimitry Andric{
2424*0b57cec5SDimitry Andric    if (__state_)
2425*0b57cec5SDimitry Andric        __state_->__release_shared();
2426*0b57cec5SDimitry Andric}
2427*0b57cec5SDimitry Andric
2428*0b57cec5SDimitry Andrictemplate <class _Rp>
2429*0b57cec5SDimitry Andricshared_future<_Rp>&
2430*0b57cec5SDimitry Andricshared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
2431*0b57cec5SDimitry Andric{
2432*0b57cec5SDimitry Andric    if (__rhs.__state_)
2433*0b57cec5SDimitry Andric        __rhs.__state_->__add_shared();
2434*0b57cec5SDimitry Andric    if (__state_)
2435*0b57cec5SDimitry Andric        __state_->__release_shared();
2436*0b57cec5SDimitry Andric    __state_ = __rhs.__state_;
2437*0b57cec5SDimitry Andric    return *this;
2438*0b57cec5SDimitry Andric}
2439*0b57cec5SDimitry Andric
2440*0b57cec5SDimitry Andrictemplate <class _Rp>
2441*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
2442*0b57cec5SDimitry Andric{
2443*0b57cec5SDimitry Andric    __assoc_state<_Rp&>* __state_;
2444*0b57cec5SDimitry Andric
2445*0b57cec5SDimitry Andricpublic:
2446*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2447*0b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
2448*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2449*0b57cec5SDimitry Andric    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2450*0b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
2451*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2452*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2453*0b57cec5SDimitry Andric    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2454*0b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
2455*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2456*0b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2457*0b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
2458*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2459*0b57cec5SDimitry Andric    ~shared_future();
2460*0b57cec5SDimitry Andric    shared_future& operator=(const shared_future& __rhs);
2461*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2462*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2463*0b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2464*0b57cec5SDimitry Andric        {
2465*0b57cec5SDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
2466*0b57cec5SDimitry Andric            return *this;
2467*0b57cec5SDimitry Andric        }
2468*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2469*0b57cec5SDimitry Andric
2470*0b57cec5SDimitry Andric    // retrieving the value
2471*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2472*0b57cec5SDimitry Andric    _Rp& get() const {return __state_->copy();}
2473*0b57cec5SDimitry Andric
2474*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2475*0b57cec5SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2476*0b57cec5SDimitry Andric
2477*0b57cec5SDimitry Andric    // functions to check state
2478*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2479*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2480*0b57cec5SDimitry Andric
2481*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2482*0b57cec5SDimitry Andric    void wait() const {__state_->wait();}
2483*0b57cec5SDimitry Andric    template <class _Rep, class _Period>
2484*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2485*0b57cec5SDimitry Andric        future_status
2486*0b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2487*0b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
2488*0b57cec5SDimitry Andric    template <class _Clock, class _Duration>
2489*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2490*0b57cec5SDimitry Andric        future_status
2491*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2492*0b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
2493*0b57cec5SDimitry Andric};
2494*0b57cec5SDimitry Andric
2495*0b57cec5SDimitry Andrictemplate <class _Rp>
2496*0b57cec5SDimitry Andricshared_future<_Rp&>::~shared_future()
2497*0b57cec5SDimitry Andric{
2498*0b57cec5SDimitry Andric    if (__state_)
2499*0b57cec5SDimitry Andric        __state_->__release_shared();
2500*0b57cec5SDimitry Andric}
2501*0b57cec5SDimitry Andric
2502*0b57cec5SDimitry Andrictemplate <class _Rp>
2503*0b57cec5SDimitry Andricshared_future<_Rp&>&
2504*0b57cec5SDimitry Andricshared_future<_Rp&>::operator=(const shared_future& __rhs)
2505*0b57cec5SDimitry Andric{
2506*0b57cec5SDimitry Andric    if (__rhs.__state_)
2507*0b57cec5SDimitry Andric        __rhs.__state_->__add_shared();
2508*0b57cec5SDimitry Andric    if (__state_)
2509*0b57cec5SDimitry Andric        __state_->__release_shared();
2510*0b57cec5SDimitry Andric    __state_ = __rhs.__state_;
2511*0b57cec5SDimitry Andric    return *this;
2512*0b57cec5SDimitry Andric}
2513*0b57cec5SDimitry Andric
2514*0b57cec5SDimitry Andrictemplate <>
2515*0b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
2516*0b57cec5SDimitry Andric{
2517*0b57cec5SDimitry Andric    __assoc_sub_state* __state_;
2518*0b57cec5SDimitry Andric
2519*0b57cec5SDimitry Andricpublic:
2520*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2521*0b57cec5SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
2522*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2523*0b57cec5SDimitry Andric    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2524*0b57cec5SDimitry Andric        {if (__state_) __state_->__add_shared();}
2525*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2526*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2527*0b57cec5SDimitry Andric    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2528*0b57cec5SDimitry Andric        {__f.__state_ = nullptr;}
2529*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2530*0b57cec5SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2531*0b57cec5SDimitry Andric        {__rhs.__state_ = nullptr;}
2532*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2533*0b57cec5SDimitry Andric    ~shared_future();
2534*0b57cec5SDimitry Andric    shared_future& operator=(const shared_future& __rhs);
2535*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2536*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2537*0b57cec5SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2538*0b57cec5SDimitry Andric        {
2539*0b57cec5SDimitry Andric            shared_future(std::move(__rhs)).swap(*this);
2540*0b57cec5SDimitry Andric            return *this;
2541*0b57cec5SDimitry Andric        }
2542*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2543*0b57cec5SDimitry Andric
2544*0b57cec5SDimitry Andric    // retrieving the value
2545*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2546*0b57cec5SDimitry Andric    void get() const {__state_->copy();}
2547*0b57cec5SDimitry Andric
2548*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2549*0b57cec5SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2550*0b57cec5SDimitry Andric
2551*0b57cec5SDimitry Andric    // functions to check state
2552*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2553*0b57cec5SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2554*0b57cec5SDimitry Andric
2555*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2556*0b57cec5SDimitry Andric    void wait() const {__state_->wait();}
2557*0b57cec5SDimitry Andric    template <class _Rep, class _Period>
2558*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2559*0b57cec5SDimitry Andric        future_status
2560*0b57cec5SDimitry Andric        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2561*0b57cec5SDimitry Andric            {return __state_->wait_for(__rel_time);}
2562*0b57cec5SDimitry Andric    template <class _Clock, class _Duration>
2563*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
2564*0b57cec5SDimitry Andric        future_status
2565*0b57cec5SDimitry Andric        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2566*0b57cec5SDimitry Andric            {return __state_->wait_until(__abs_time);}
2567*0b57cec5SDimitry Andric};
2568*0b57cec5SDimitry Andric
2569*0b57cec5SDimitry Andrictemplate <class _Rp>
2570*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2571*0b57cec5SDimitry Andricvoid
2572*0b57cec5SDimitry Andricswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2573*0b57cec5SDimitry Andric{
2574*0b57cec5SDimitry Andric    __x.swap(__y);
2575*0b57cec5SDimitry Andric}
2576*0b57cec5SDimitry Andric
2577*0b57cec5SDimitry Andrictemplate <class _Rp>
2578*0b57cec5SDimitry Andricinline
2579*0b57cec5SDimitry Andricshared_future<_Rp>
2580*0b57cec5SDimitry Andricfuture<_Rp>::share() _NOEXCEPT
2581*0b57cec5SDimitry Andric{
2582*0b57cec5SDimitry Andric    return shared_future<_Rp>(_VSTD::move(*this));
2583*0b57cec5SDimitry Andric}
2584*0b57cec5SDimitry Andric
2585*0b57cec5SDimitry Andrictemplate <class _Rp>
2586*0b57cec5SDimitry Andricinline
2587*0b57cec5SDimitry Andricshared_future<_Rp&>
2588*0b57cec5SDimitry Andricfuture<_Rp&>::share() _NOEXCEPT
2589*0b57cec5SDimitry Andric{
2590*0b57cec5SDimitry Andric    return shared_future<_Rp&>(_VSTD::move(*this));
2591*0b57cec5SDimitry Andric}
2592*0b57cec5SDimitry Andric
2593*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2594*0b57cec5SDimitry Andric
2595*0b57cec5SDimitry Andricinline
2596*0b57cec5SDimitry Andricshared_future<void>
2597*0b57cec5SDimitry Andricfuture<void>::share() _NOEXCEPT
2598*0b57cec5SDimitry Andric{
2599*0b57cec5SDimitry Andric    return shared_future<void>(_VSTD::move(*this));
2600*0b57cec5SDimitry Andric}
2601*0b57cec5SDimitry Andric
2602*0b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2603*0b57cec5SDimitry Andric
2604*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
2605*0b57cec5SDimitry Andric
2606*0b57cec5SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS
2607*0b57cec5SDimitry Andric
2608*0b57cec5SDimitry Andric#endif  // _LIBCPP_FUTURE
2609