xref: /freebsd/contrib/llvm-project/libcxx/include/__cxx03/future (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric// -*- C++ -*-
2*700637cbSDimitry Andric//===----------------------------------------------------------------------===//
3*700637cbSDimitry Andric//
4*700637cbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*700637cbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*700637cbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*700637cbSDimitry Andric//
8*700637cbSDimitry Andric//===----------------------------------------------------------------------===//
9*700637cbSDimitry Andric
10*700637cbSDimitry Andric#ifndef _LIBCPP___CXX03_FUTURE
11*700637cbSDimitry Andric#define _LIBCPP___CXX03_FUTURE
12*700637cbSDimitry Andric
13*700637cbSDimitry Andric/*
14*700637cbSDimitry Andric    future synopsis
15*700637cbSDimitry Andric
16*700637cbSDimitry Andricnamespace std
17*700637cbSDimitry Andric{
18*700637cbSDimitry Andric
19*700637cbSDimitry Andricenum class future_errc
20*700637cbSDimitry Andric{
21*700637cbSDimitry Andric    future_already_retrieved = 1,
22*700637cbSDimitry Andric    promise_already_satisfied,
23*700637cbSDimitry Andric    no_state,
24*700637cbSDimitry Andric    broken_promise
25*700637cbSDimitry Andric};
26*700637cbSDimitry Andric
27*700637cbSDimitry Andricenum class launch
28*700637cbSDimitry Andric{
29*700637cbSDimitry Andric    async = 1,
30*700637cbSDimitry Andric    deferred = 2,
31*700637cbSDimitry Andric    any = async | deferred
32*700637cbSDimitry Andric};
33*700637cbSDimitry Andric
34*700637cbSDimitry Andricenum class future_status
35*700637cbSDimitry Andric{
36*700637cbSDimitry Andric    ready,
37*700637cbSDimitry Andric    timeout,
38*700637cbSDimitry Andric    deferred
39*700637cbSDimitry Andric};
40*700637cbSDimitry Andric
41*700637cbSDimitry Andrictemplate <> struct is_error_code_enum<future_errc> : public true_type { };
42*700637cbSDimitry Andricerror_code make_error_code(future_errc e) noexcept;
43*700637cbSDimitry Andricerror_condition make_error_condition(future_errc e) noexcept;
44*700637cbSDimitry Andric
45*700637cbSDimitry Andricconst error_category& future_category() noexcept;
46*700637cbSDimitry Andric
47*700637cbSDimitry Andricclass future_error : public logic_error {
48*700637cbSDimitry Andricpublic:
49*700637cbSDimitry Andric    explicit future_error(future_errc e); // since C++17
50*700637cbSDimitry Andric
51*700637cbSDimitry Andric    const error_code& code() const noexcept;
52*700637cbSDimitry Andric    const char*       what() const noexcept;
53*700637cbSDimitry Andric
54*700637cbSDimitry Andricprivate:
55*700637cbSDimitry Andric    error_code ec_;             // exposition only
56*700637cbSDimitry Andric};
57*700637cbSDimitry Andric
58*700637cbSDimitry Andrictemplate <class R>
59*700637cbSDimitry Andricclass promise
60*700637cbSDimitry Andric{
61*700637cbSDimitry Andricpublic:
62*700637cbSDimitry Andric    promise();
63*700637cbSDimitry Andric    template <class Allocator>
64*700637cbSDimitry Andric        promise(allocator_arg_t, const Allocator& a);
65*700637cbSDimitry Andric    promise(promise&& rhs) noexcept;
66*700637cbSDimitry Andric    promise(const promise& rhs) = delete;
67*700637cbSDimitry Andric    ~promise();
68*700637cbSDimitry Andric
69*700637cbSDimitry Andric    // assignment
70*700637cbSDimitry Andric    promise& operator=(promise&& rhs) noexcept;
71*700637cbSDimitry Andric    promise& operator=(const promise& rhs) = delete;
72*700637cbSDimitry Andric    void swap(promise& other) noexcept;
73*700637cbSDimitry Andric
74*700637cbSDimitry Andric    // retrieving the result
75*700637cbSDimitry Andric    future<R> get_future();
76*700637cbSDimitry Andric
77*700637cbSDimitry Andric    // setting the result
78*700637cbSDimitry Andric    void set_value(const R& r);
79*700637cbSDimitry Andric    void set_value(R&& r);
80*700637cbSDimitry Andric    void set_exception(exception_ptr p);
81*700637cbSDimitry Andric
82*700637cbSDimitry Andric    // setting the result with deferred notification
83*700637cbSDimitry Andric    void set_value_at_thread_exit(const R& r);
84*700637cbSDimitry Andric    void set_value_at_thread_exit(R&& r);
85*700637cbSDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
86*700637cbSDimitry Andric};
87*700637cbSDimitry Andric
88*700637cbSDimitry Andrictemplate <class R>
89*700637cbSDimitry Andricclass promise<R&>
90*700637cbSDimitry Andric{
91*700637cbSDimitry Andricpublic:
92*700637cbSDimitry Andric    promise();
93*700637cbSDimitry Andric    template <class Allocator>
94*700637cbSDimitry Andric        promise(allocator_arg_t, const Allocator& a);
95*700637cbSDimitry Andric    promise(promise&& rhs) noexcept;
96*700637cbSDimitry Andric    promise(const promise& rhs) = delete;
97*700637cbSDimitry Andric    ~promise();
98*700637cbSDimitry Andric
99*700637cbSDimitry Andric    // assignment
100*700637cbSDimitry Andric    promise& operator=(promise&& rhs) noexcept;
101*700637cbSDimitry Andric    promise& operator=(const promise& rhs) = delete;
102*700637cbSDimitry Andric    void swap(promise& other) noexcept;
103*700637cbSDimitry Andric
104*700637cbSDimitry Andric    // retrieving the result
105*700637cbSDimitry Andric    future<R&> get_future();
106*700637cbSDimitry Andric
107*700637cbSDimitry Andric    // setting the result
108*700637cbSDimitry Andric    void set_value(R& r);
109*700637cbSDimitry Andric    void set_exception(exception_ptr p);
110*700637cbSDimitry Andric
111*700637cbSDimitry Andric    // setting the result with deferred notification
112*700637cbSDimitry Andric    void set_value_at_thread_exit(R&);
113*700637cbSDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
114*700637cbSDimitry Andric};
115*700637cbSDimitry Andric
116*700637cbSDimitry Andrictemplate <>
117*700637cbSDimitry Andricclass promise<void>
118*700637cbSDimitry Andric{
119*700637cbSDimitry Andricpublic:
120*700637cbSDimitry Andric    promise();
121*700637cbSDimitry Andric    template <class Allocator>
122*700637cbSDimitry Andric        promise(allocator_arg_t, const Allocator& a);
123*700637cbSDimitry Andric    promise(promise&& rhs) noexcept;
124*700637cbSDimitry Andric    promise(const promise& rhs) = delete;
125*700637cbSDimitry Andric    ~promise();
126*700637cbSDimitry Andric
127*700637cbSDimitry Andric    // assignment
128*700637cbSDimitry Andric    promise& operator=(promise&& rhs) noexcept;
129*700637cbSDimitry Andric    promise& operator=(const promise& rhs) = delete;
130*700637cbSDimitry Andric    void swap(promise& other) noexcept;
131*700637cbSDimitry Andric
132*700637cbSDimitry Andric    // retrieving the result
133*700637cbSDimitry Andric    future<void> get_future();
134*700637cbSDimitry Andric
135*700637cbSDimitry Andric    // setting the result
136*700637cbSDimitry Andric    void set_value();
137*700637cbSDimitry Andric    void set_exception(exception_ptr p);
138*700637cbSDimitry Andric
139*700637cbSDimitry Andric    // setting the result with deferred notification
140*700637cbSDimitry Andric    void set_value_at_thread_exit();
141*700637cbSDimitry Andric    void set_exception_at_thread_exit(exception_ptr p);
142*700637cbSDimitry Andric};
143*700637cbSDimitry Andric
144*700637cbSDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
145*700637cbSDimitry Andric
146*700637cbSDimitry Andrictemplate <class R, class Alloc>
147*700637cbSDimitry Andric    struct uses_allocator<promise<R>, Alloc> : public true_type {};
148*700637cbSDimitry Andric
149*700637cbSDimitry Andrictemplate <class R>
150*700637cbSDimitry Andricclass future
151*700637cbSDimitry Andric{
152*700637cbSDimitry Andricpublic:
153*700637cbSDimitry Andric    future() noexcept;
154*700637cbSDimitry Andric    future(future&&) noexcept;
155*700637cbSDimitry Andric    future(const future& rhs) = delete;
156*700637cbSDimitry Andric    ~future();
157*700637cbSDimitry Andric    future& operator=(const future& rhs) = delete;
158*700637cbSDimitry Andric    future& operator=(future&&) noexcept;
159*700637cbSDimitry Andric    shared_future<R> share() noexcept;
160*700637cbSDimitry Andric
161*700637cbSDimitry Andric    // retrieving the value
162*700637cbSDimitry Andric    R get();
163*700637cbSDimitry Andric
164*700637cbSDimitry Andric    // functions to check state
165*700637cbSDimitry Andric    bool valid() const noexcept;
166*700637cbSDimitry Andric
167*700637cbSDimitry Andric    void wait() const;
168*700637cbSDimitry Andric    template <class Rep, class Period>
169*700637cbSDimitry Andric        future_status
170*700637cbSDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171*700637cbSDimitry Andric    template <class Clock, class Duration>
172*700637cbSDimitry Andric        future_status
173*700637cbSDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174*700637cbSDimitry Andric};
175*700637cbSDimitry Andric
176*700637cbSDimitry Andrictemplate <class R>
177*700637cbSDimitry Andricclass future<R&>
178*700637cbSDimitry Andric{
179*700637cbSDimitry Andricpublic:
180*700637cbSDimitry Andric    future() noexcept;
181*700637cbSDimitry Andric    future(future&&) noexcept;
182*700637cbSDimitry Andric    future(const future& rhs) = delete;
183*700637cbSDimitry Andric    ~future();
184*700637cbSDimitry Andric    future& operator=(const future& rhs) = delete;
185*700637cbSDimitry Andric    future& operator=(future&&) noexcept;
186*700637cbSDimitry Andric    shared_future<R&> share() noexcept;
187*700637cbSDimitry Andric
188*700637cbSDimitry Andric    // retrieving the value
189*700637cbSDimitry Andric    R& get();
190*700637cbSDimitry Andric
191*700637cbSDimitry Andric    // functions to check state
192*700637cbSDimitry Andric    bool valid() const noexcept;
193*700637cbSDimitry Andric
194*700637cbSDimitry Andric    void wait() const;
195*700637cbSDimitry Andric    template <class Rep, class Period>
196*700637cbSDimitry Andric        future_status
197*700637cbSDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198*700637cbSDimitry Andric    template <class Clock, class Duration>
199*700637cbSDimitry Andric        future_status
200*700637cbSDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201*700637cbSDimitry Andric};
202*700637cbSDimitry Andric
203*700637cbSDimitry Andrictemplate <>
204*700637cbSDimitry Andricclass future<void>
205*700637cbSDimitry Andric{
206*700637cbSDimitry Andricpublic:
207*700637cbSDimitry Andric    future() noexcept;
208*700637cbSDimitry Andric    future(future&&) noexcept;
209*700637cbSDimitry Andric    future(const future& rhs) = delete;
210*700637cbSDimitry Andric    ~future();
211*700637cbSDimitry Andric    future& operator=(const future& rhs) = delete;
212*700637cbSDimitry Andric    future& operator=(future&&) noexcept;
213*700637cbSDimitry Andric    shared_future<void> share() noexcept;
214*700637cbSDimitry Andric
215*700637cbSDimitry Andric    // retrieving the value
216*700637cbSDimitry Andric    void get();
217*700637cbSDimitry Andric
218*700637cbSDimitry Andric    // functions to check state
219*700637cbSDimitry Andric    bool valid() const noexcept;
220*700637cbSDimitry Andric
221*700637cbSDimitry Andric    void wait() const;
222*700637cbSDimitry Andric    template <class Rep, class Period>
223*700637cbSDimitry Andric        future_status
224*700637cbSDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225*700637cbSDimitry Andric    template <class Clock, class Duration>
226*700637cbSDimitry Andric        future_status
227*700637cbSDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228*700637cbSDimitry Andric};
229*700637cbSDimitry Andric
230*700637cbSDimitry Andrictemplate <class R>
231*700637cbSDimitry Andricclass shared_future
232*700637cbSDimitry Andric{
233*700637cbSDimitry Andricpublic:
234*700637cbSDimitry Andric    shared_future() noexcept;
235*700637cbSDimitry Andric    shared_future(const shared_future& rhs);
236*700637cbSDimitry Andric    shared_future(future<R>&&) noexcept;
237*700637cbSDimitry Andric    shared_future(shared_future&& rhs) noexcept;
238*700637cbSDimitry Andric    ~shared_future();
239*700637cbSDimitry Andric    shared_future& operator=(const shared_future& rhs);
240*700637cbSDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
241*700637cbSDimitry Andric
242*700637cbSDimitry Andric    // retrieving the value
243*700637cbSDimitry Andric    const R& get() const;
244*700637cbSDimitry Andric
245*700637cbSDimitry Andric    // functions to check state
246*700637cbSDimitry Andric    bool valid() const noexcept;
247*700637cbSDimitry Andric
248*700637cbSDimitry Andric    void wait() const;
249*700637cbSDimitry Andric    template <class Rep, class Period>
250*700637cbSDimitry Andric        future_status
251*700637cbSDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252*700637cbSDimitry Andric    template <class Clock, class Duration>
253*700637cbSDimitry Andric        future_status
254*700637cbSDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255*700637cbSDimitry Andric};
256*700637cbSDimitry Andric
257*700637cbSDimitry Andrictemplate <class R>
258*700637cbSDimitry Andricclass shared_future<R&>
259*700637cbSDimitry Andric{
260*700637cbSDimitry Andricpublic:
261*700637cbSDimitry Andric    shared_future() noexcept;
262*700637cbSDimitry Andric    shared_future(const shared_future& rhs);
263*700637cbSDimitry Andric    shared_future(future<R&>&&) noexcept;
264*700637cbSDimitry Andric    shared_future(shared_future&& rhs) noexcept;
265*700637cbSDimitry Andric    ~shared_future();
266*700637cbSDimitry Andric    shared_future& operator=(const shared_future& rhs);
267*700637cbSDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
268*700637cbSDimitry Andric
269*700637cbSDimitry Andric    // retrieving the value
270*700637cbSDimitry Andric    R& get() const;
271*700637cbSDimitry Andric
272*700637cbSDimitry Andric    // functions to check state
273*700637cbSDimitry Andric    bool valid() const noexcept;
274*700637cbSDimitry Andric
275*700637cbSDimitry Andric    void wait() const;
276*700637cbSDimitry Andric    template <class Rep, class Period>
277*700637cbSDimitry Andric        future_status
278*700637cbSDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279*700637cbSDimitry Andric    template <class Clock, class Duration>
280*700637cbSDimitry Andric        future_status
281*700637cbSDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282*700637cbSDimitry Andric};
283*700637cbSDimitry Andric
284*700637cbSDimitry Andrictemplate <>
285*700637cbSDimitry Andricclass shared_future<void>
286*700637cbSDimitry Andric{
287*700637cbSDimitry Andricpublic:
288*700637cbSDimitry Andric    shared_future() noexcept;
289*700637cbSDimitry Andric    shared_future(const shared_future& rhs);
290*700637cbSDimitry Andric    shared_future(future<void>&&) noexcept;
291*700637cbSDimitry Andric    shared_future(shared_future&& rhs) noexcept;
292*700637cbSDimitry Andric    ~shared_future();
293*700637cbSDimitry Andric    shared_future& operator=(const shared_future& rhs);
294*700637cbSDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
295*700637cbSDimitry Andric
296*700637cbSDimitry Andric    // retrieving the value
297*700637cbSDimitry Andric    void get() const;
298*700637cbSDimitry Andric
299*700637cbSDimitry Andric    // functions to check state
300*700637cbSDimitry Andric    bool valid() const noexcept;
301*700637cbSDimitry Andric
302*700637cbSDimitry Andric    void wait() const;
303*700637cbSDimitry Andric    template <class Rep, class Period>
304*700637cbSDimitry Andric        future_status
305*700637cbSDimitry Andric        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306*700637cbSDimitry Andric    template <class Clock, class Duration>
307*700637cbSDimitry Andric        future_status
308*700637cbSDimitry Andric        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309*700637cbSDimitry Andric};
310*700637cbSDimitry Andric
311*700637cbSDimitry Andrictemplate <class F, class... Args>
312*700637cbSDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
313*700637cbSDimitry Andric  async(F&& f, Args&&... args);
314*700637cbSDimitry Andric
315*700637cbSDimitry Andrictemplate <class F, class... Args>
316*700637cbSDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
317*700637cbSDimitry Andric  async(launch policy, F&& f, Args&&... args);
318*700637cbSDimitry Andric
319*700637cbSDimitry Andrictemplate <class> class packaged_task; // undefined
320*700637cbSDimitry Andric
321*700637cbSDimitry Andrictemplate <class R, class... ArgTypes>
322*700637cbSDimitry Andricclass packaged_task<R(ArgTypes...)>
323*700637cbSDimitry Andric{
324*700637cbSDimitry Andricpublic:
325*700637cbSDimitry Andric    typedef R result_type; // extension
326*700637cbSDimitry Andric
327*700637cbSDimitry Andric    // construction and destruction
328*700637cbSDimitry Andric    packaged_task() noexcept;
329*700637cbSDimitry Andric    template <class F>
330*700637cbSDimitry Andric        explicit packaged_task(F&& f);
331*700637cbSDimitry Andric    template <class F, class Allocator>
332*700637cbSDimitry Andric        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333*700637cbSDimitry Andric    ~packaged_task();
334*700637cbSDimitry Andric
335*700637cbSDimitry Andric    // no copy
336*700637cbSDimitry Andric    packaged_task(const packaged_task&) = delete;
337*700637cbSDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
338*700637cbSDimitry Andric
339*700637cbSDimitry Andric    // move support
340*700637cbSDimitry Andric    packaged_task(packaged_task&& other) noexcept;
341*700637cbSDimitry Andric    packaged_task& operator=(packaged_task&& other) noexcept;
342*700637cbSDimitry Andric    void swap(packaged_task& other) noexcept;
343*700637cbSDimitry Andric
344*700637cbSDimitry Andric    bool valid() const noexcept;
345*700637cbSDimitry Andric
346*700637cbSDimitry Andric    // result retrieval
347*700637cbSDimitry Andric    future<R> get_future();
348*700637cbSDimitry Andric
349*700637cbSDimitry Andric    // execution
350*700637cbSDimitry Andric    void operator()(ArgTypes... );
351*700637cbSDimitry Andric    void make_ready_at_thread_exit(ArgTypes...);
352*700637cbSDimitry Andric
353*700637cbSDimitry Andric    void reset();
354*700637cbSDimitry Andric};
355*700637cbSDimitry Andric
356*700637cbSDimitry Andrictemplate <class R>
357*700637cbSDimitry Andric  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
358*700637cbSDimitry Andric
359*700637cbSDimitry Andrictemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360*700637cbSDimitry Andric
361*700637cbSDimitry Andric}  // std
362*700637cbSDimitry Andric
363*700637cbSDimitry Andric*/
364*700637cbSDimitry Andric
365*700637cbSDimitry Andric#include <__cxx03/__config>
366*700637cbSDimitry Andric
367*700637cbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS)
368*700637cbSDimitry Andric
369*700637cbSDimitry Andric#  include <__cxx03/__assert>
370*700637cbSDimitry Andric#  include <__cxx03/__chrono/duration.h>
371*700637cbSDimitry Andric#  include <__cxx03/__chrono/time_point.h>
372*700637cbSDimitry Andric#  include <__cxx03/__exception/exception_ptr.h>
373*700637cbSDimitry Andric#  include <__cxx03/__memory/addressof.h>
374*700637cbSDimitry Andric#  include <__cxx03/__memory/allocator.h>
375*700637cbSDimitry Andric#  include <__cxx03/__memory/allocator_arg_t.h>
376*700637cbSDimitry Andric#  include <__cxx03/__memory/allocator_destructor.h>
377*700637cbSDimitry Andric#  include <__cxx03/__memory/allocator_traits.h>
378*700637cbSDimitry Andric#  include <__cxx03/__memory/compressed_pair.h>
379*700637cbSDimitry Andric#  include <__cxx03/__memory/pointer_traits.h>
380*700637cbSDimitry Andric#  include <__cxx03/__memory/shared_ptr.h>
381*700637cbSDimitry Andric#  include <__cxx03/__memory/unique_ptr.h>
382*700637cbSDimitry Andric#  include <__cxx03/__memory/uses_allocator.h>
383*700637cbSDimitry Andric#  include <__cxx03/__system_error/error_category.h>
384*700637cbSDimitry Andric#  include <__cxx03/__system_error/error_code.h>
385*700637cbSDimitry Andric#  include <__cxx03/__system_error/error_condition.h>
386*700637cbSDimitry Andric#  include <__cxx03/__type_traits/aligned_storage.h>
387*700637cbSDimitry Andric#  include <__cxx03/__type_traits/strip_signature.h>
388*700637cbSDimitry Andric#  include <__cxx03/__utility/auto_cast.h>
389*700637cbSDimitry Andric#  include <__cxx03/__utility/forward.h>
390*700637cbSDimitry Andric#  include <__cxx03/__utility/move.h>
391*700637cbSDimitry Andric#  include <__cxx03/mutex>
392*700637cbSDimitry Andric#  include <__cxx03/new>
393*700637cbSDimitry Andric#  include <__cxx03/stdexcept>
394*700637cbSDimitry Andric#  include <__cxx03/thread>
395*700637cbSDimitry Andric#  include <__cxx03/version>
396*700637cbSDimitry Andric
397*700637cbSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
398*700637cbSDimitry Andric#    pragma GCC system_header
399*700637cbSDimitry Andric#  endif
400*700637cbSDimitry Andric
401*700637cbSDimitry Andric_LIBCPP_PUSH_MACROS
402*700637cbSDimitry Andric#  include <__cxx03/__undef_macros>
403*700637cbSDimitry Andric
404*700637cbSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
405*700637cbSDimitry Andric
406*700637cbSDimitry Andric// enum class future_errc
407*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_errc){
408*700637cbSDimitry Andric    future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise};
409*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
410*700637cbSDimitry Andric
411*700637cbSDimitry Andrictemplate <>
412*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
413*700637cbSDimitry Andric
414*700637cbSDimitry Andrictemplate <>
415*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type {};
416*700637cbSDimitry Andric
417*700637cbSDimitry Andric// enum class launch
418*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(launch){async = 1, deferred = 2, any = async | deferred};
419*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
420*700637cbSDimitry Andric
421*700637cbSDimitry Andric// enum class future_status
422*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(future_status){ready, timeout, deferred};
423*700637cbSDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
424*700637cbSDimitry Andric
425*700637cbSDimitry Andric_LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT;
426*700637cbSDimitry Andric
427*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(future_errc __e) _NOEXCEPT {
428*700637cbSDimitry Andric  return error_code(static_cast<int>(__e), future_category());
429*700637cbSDimitry Andric}
430*700637cbSDimitry Andric
431*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(future_errc __e) _NOEXCEPT {
432*700637cbSDimitry Andric  return error_condition(static_cast<int>(__e), future_category());
433*700637cbSDimitry Andric}
434*700637cbSDimitry Andric
435*700637cbSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_future_error(future_errc __ev);
436*700637cbSDimitry Andric
437*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future_error : public logic_error {
438*700637cbSDimitry Andric  error_code __ec_;
439*700637cbSDimitry Andric
440*700637cbSDimitry Andric  future_error(error_code);
441*700637cbSDimitry Andric  friend void __throw_future_error(future_errc);
442*700637cbSDimitry Andric  template <class>
443*700637cbSDimitry Andric  friend class promise;
444*700637cbSDimitry Andric
445*700637cbSDimitry Andricpublic:
446*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
447*700637cbSDimitry Andric
448*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default;
449*700637cbSDimitry Andric  ~future_error() _NOEXCEPT override;
450*700637cbSDimitry Andric};
451*700637cbSDimitry Andric
452*700637cbSDimitry Andric// Declared above std::future_error
453*700637cbSDimitry Andricvoid __throw_future_error(future_errc __ev) {
454*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
455*700637cbSDimitry Andric  throw future_error(make_error_code(__ev));
456*700637cbSDimitry Andric#  else
457*700637cbSDimitry Andric  (void)__ev;
458*700637cbSDimitry Andric  _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode");
459*700637cbSDimitry Andric#  endif
460*700637cbSDimitry Andric}
461*700637cbSDimitry Andric
462*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI __assoc_sub_state : public __shared_count {
463*700637cbSDimitry Andricprotected:
464*700637cbSDimitry Andric  exception_ptr __exception_;
465*700637cbSDimitry Andric  mutable mutex __mut_;
466*700637cbSDimitry Andric  mutable condition_variable __cv_;
467*700637cbSDimitry Andric  unsigned __state_;
468*700637cbSDimitry Andric
469*700637cbSDimitry Andric  void __on_zero_shared() _NOEXCEPT override;
470*700637cbSDimitry Andric  void __sub_wait(unique_lock<mutex>& __lk);
471*700637cbSDimitry Andric
472*700637cbSDimitry Andricpublic:
473*700637cbSDimitry Andric  enum { __constructed = 1, __future_attached = 2, ready = 4, deferred = 8 };
474*700637cbSDimitry Andric
475*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __assoc_sub_state() : __state_(0) {}
476*700637cbSDimitry Andric
477*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __has_value() const { return (__state_ & __constructed) || (__exception_ != nullptr); }
478*700637cbSDimitry Andric
479*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __attach_future() {
480*700637cbSDimitry Andric    lock_guard<mutex> __lk(__mut_);
481*700637cbSDimitry Andric    bool __has_future_attached = (__state_ & __future_attached) != 0;
482*700637cbSDimitry Andric    if (__has_future_attached)
483*700637cbSDimitry Andric      __throw_future_error(future_errc::future_already_retrieved);
484*700637cbSDimitry Andric    this->__add_shared();
485*700637cbSDimitry Andric    __state_ |= __future_attached;
486*700637cbSDimitry Andric  }
487*700637cbSDimitry Andric
488*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __set_deferred() { __state_ |= deferred; }
489*700637cbSDimitry Andric
490*700637cbSDimitry Andric  void __make_ready();
491*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool __is_ready() const { return (__state_ & ready) != 0; }
492*700637cbSDimitry Andric
493*700637cbSDimitry Andric  void set_value();
494*700637cbSDimitry Andric  void set_value_at_thread_exit();
495*700637cbSDimitry Andric
496*700637cbSDimitry Andric  void set_exception(exception_ptr __p);
497*700637cbSDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
498*700637cbSDimitry Andric
499*700637cbSDimitry Andric  void copy();
500*700637cbSDimitry Andric
501*700637cbSDimitry Andric  void wait();
502*700637cbSDimitry Andric  template <class _Rep, class _Period>
503*700637cbSDimitry Andric  future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
504*700637cbSDimitry Andric  template <class _Clock, class _Duration>
505*700637cbSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS future_status
506*700637cbSDimitry Andric  wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
507*700637cbSDimitry Andric
508*700637cbSDimitry Andric  virtual void __execute();
509*700637cbSDimitry Andric};
510*700637cbSDimitry Andric
511*700637cbSDimitry Andrictemplate <class _Clock, class _Duration>
512*700637cbSDimitry Andricfuture_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
513*700637cbSDimitry Andric  unique_lock<mutex> __lk(__mut_);
514*700637cbSDimitry Andric  if (__state_ & deferred)
515*700637cbSDimitry Andric    return future_status::deferred;
516*700637cbSDimitry Andric  while (!(__state_ & ready) && _Clock::now() < __abs_time)
517*700637cbSDimitry Andric    __cv_.wait_until(__lk, __abs_time);
518*700637cbSDimitry Andric  if (__state_ & ready)
519*700637cbSDimitry Andric    return future_status::ready;
520*700637cbSDimitry Andric  return future_status::timeout;
521*700637cbSDimitry Andric}
522*700637cbSDimitry Andric
523*700637cbSDimitry Andrictemplate <class _Rep, class _Period>
524*700637cbSDimitry Andricinline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
525*700637cbSDimitry Andric  return wait_until(chrono::steady_clock::now() + __rel_time);
526*700637cbSDimitry Andric}
527*700637cbSDimitry Andric
528*700637cbSDimitry Andrictemplate <class _Rp>
529*700637cbSDimitry Andricclass _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state {
530*700637cbSDimitry Andric  typedef __assoc_sub_state base;
531*700637cbSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
532*700637cbSDimitry Andric  typedef typename aligned_storage<sizeof(_Rp), _LIBCPP_ALIGNOF(_Rp)>::type _Up;
533*700637cbSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_POP
534*700637cbSDimitry Andric
535*700637cbSDimitry Andricprotected:
536*700637cbSDimitry Andric  _Up __value_;
537*700637cbSDimitry Andric
538*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
539*700637cbSDimitry Andric
540*700637cbSDimitry Andricpublic:
541*700637cbSDimitry Andric  template <class _Arg>
542*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg);
543*700637cbSDimitry Andric
544*700637cbSDimitry Andric  template <class _Arg>
545*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg);
546*700637cbSDimitry Andric
547*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp move();
548*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy();
549*700637cbSDimitry Andric};
550*700637cbSDimitry Andric
551*700637cbSDimitry Andrictemplate <class _Rp>
552*700637cbSDimitry Andricvoid __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT {
553*700637cbSDimitry Andric  if (this->__state_ & base::__constructed)
554*700637cbSDimitry Andric    reinterpret_cast<_Rp*>(&__value_)->~_Rp();
555*700637cbSDimitry Andric  delete this;
556*700637cbSDimitry Andric}
557*700637cbSDimitry Andric
558*700637cbSDimitry Andrictemplate <class _Rp>
559*700637cbSDimitry Andrictemplate <class _Arg>
560*700637cbSDimitry Andricvoid __assoc_state<_Rp>::set_value(_Arg&& __arg) {
561*700637cbSDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
562*700637cbSDimitry Andric  if (this->__has_value())
563*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
564*700637cbSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
565*700637cbSDimitry Andric  this->__state_ |= base::__constructed | base::ready;
566*700637cbSDimitry Andric  __cv_.notify_all();
567*700637cbSDimitry Andric}
568*700637cbSDimitry Andric
569*700637cbSDimitry Andrictemplate <class _Rp>
570*700637cbSDimitry Andrictemplate <class _Arg>
571*700637cbSDimitry Andricvoid __assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg) {
572*700637cbSDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
573*700637cbSDimitry Andric  if (this->__has_value())
574*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
575*700637cbSDimitry Andric  ::new ((void*)&__value_) _Rp(std::forward<_Arg>(__arg));
576*700637cbSDimitry Andric  this->__state_ |= base::__constructed;
577*700637cbSDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
578*700637cbSDimitry Andric}
579*700637cbSDimitry Andric
580*700637cbSDimitry Andrictemplate <class _Rp>
581*700637cbSDimitry Andric_Rp __assoc_state<_Rp>::move() {
582*700637cbSDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
583*700637cbSDimitry Andric  this->__sub_wait(__lk);
584*700637cbSDimitry Andric  if (this->__exception_ != nullptr)
585*700637cbSDimitry Andric    std::rethrow_exception(this->__exception_);
586*700637cbSDimitry Andric  return std::move(*reinterpret_cast<_Rp*>(&__value_));
587*700637cbSDimitry Andric}
588*700637cbSDimitry Andric
589*700637cbSDimitry Andrictemplate <class _Rp>
590*700637cbSDimitry Andric__add_lvalue_reference_t<_Rp> __assoc_state<_Rp>::copy() {
591*700637cbSDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
592*700637cbSDimitry Andric  this->__sub_wait(__lk);
593*700637cbSDimitry Andric  if (this->__exception_ != nullptr)
594*700637cbSDimitry Andric    std::rethrow_exception(this->__exception_);
595*700637cbSDimitry Andric  return *reinterpret_cast<_Rp*>(&__value_);
596*700637cbSDimitry Andric}
597*700637cbSDimitry Andric
598*700637cbSDimitry Andrictemplate <class _Rp>
599*700637cbSDimitry Andricclass __assoc_state<_Rp&> : public __assoc_sub_state {
600*700637cbSDimitry Andric  typedef __assoc_sub_state base;
601*700637cbSDimitry Andric  typedef _Rp* _Up;
602*700637cbSDimitry Andric
603*700637cbSDimitry Andricprotected:
604*700637cbSDimitry Andric  _Up __value_;
605*700637cbSDimitry Andric
606*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
607*700637cbSDimitry Andric
608*700637cbSDimitry Andricpublic:
609*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg);
610*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg);
611*700637cbSDimitry Andric
612*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& copy();
613*700637cbSDimitry Andric};
614*700637cbSDimitry Andric
615*700637cbSDimitry Andrictemplate <class _Rp>
616*700637cbSDimitry Andricvoid __assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT {
617*700637cbSDimitry Andric  delete this;
618*700637cbSDimitry Andric}
619*700637cbSDimitry Andric
620*700637cbSDimitry Andrictemplate <class _Rp>
621*700637cbSDimitry Andricvoid __assoc_state<_Rp&>::set_value(_Rp& __arg) {
622*700637cbSDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
623*700637cbSDimitry Andric  if (this->__has_value())
624*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
625*700637cbSDimitry Andric  __value_ = std::addressof(__arg);
626*700637cbSDimitry Andric  this->__state_ |= base::__constructed | base::ready;
627*700637cbSDimitry Andric  __cv_.notify_all();
628*700637cbSDimitry Andric}
629*700637cbSDimitry Andric
630*700637cbSDimitry Andrictemplate <class _Rp>
631*700637cbSDimitry Andricvoid __assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg) {
632*700637cbSDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
633*700637cbSDimitry Andric  if (this->__has_value())
634*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
635*700637cbSDimitry Andric  __value_ = std::addressof(__arg);
636*700637cbSDimitry Andric  this->__state_ |= base::__constructed;
637*700637cbSDimitry Andric  __thread_local_data()->__make_ready_at_thread_exit(this);
638*700637cbSDimitry Andric}
639*700637cbSDimitry Andric
640*700637cbSDimitry Andrictemplate <class _Rp>
641*700637cbSDimitry Andric_Rp& __assoc_state<_Rp&>::copy() {
642*700637cbSDimitry Andric  unique_lock<mutex> __lk(this->__mut_);
643*700637cbSDimitry Andric  this->__sub_wait(__lk);
644*700637cbSDimitry Andric  if (this->__exception_ != nullptr)
645*700637cbSDimitry Andric    std::rethrow_exception(this->__exception_);
646*700637cbSDimitry Andric  return *__value_;
647*700637cbSDimitry Andric}
648*700637cbSDimitry Andric
649*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc>
650*700637cbSDimitry Andricclass __assoc_state_alloc : public __assoc_state<_Rp> {
651*700637cbSDimitry Andric  typedef __assoc_state<_Rp> base;
652*700637cbSDimitry Andric  _Alloc __alloc_;
653*700637cbSDimitry Andric
654*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
655*700637cbSDimitry Andric
656*700637cbSDimitry Andricpublic:
657*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
658*700637cbSDimitry Andric};
659*700637cbSDimitry Andric
660*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc>
661*700637cbSDimitry Andricvoid __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT {
662*700637cbSDimitry Andric  if (this->__state_ & base::__constructed)
663*700637cbSDimitry Andric    reinterpret_cast<_Rp*>(std::addressof(this->__value_))->~_Rp();
664*700637cbSDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
665*700637cbSDimitry Andric  typedef allocator_traits<_Al> _ATraits;
666*700637cbSDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
667*700637cbSDimitry Andric  _Al __a(__alloc_);
668*700637cbSDimitry Andric  this->~__assoc_state_alloc();
669*700637cbSDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
670*700637cbSDimitry Andric}
671*700637cbSDimitry Andric
672*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc>
673*700637cbSDimitry Andricclass __assoc_state_alloc<_Rp&, _Alloc> : public __assoc_state<_Rp&> {
674*700637cbSDimitry Andric  typedef __assoc_state<_Rp&> base;
675*700637cbSDimitry Andric  _Alloc __alloc_;
676*700637cbSDimitry Andric
677*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
678*700637cbSDimitry Andric
679*700637cbSDimitry Andricpublic:
680*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
681*700637cbSDimitry Andric};
682*700637cbSDimitry Andric
683*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc>
684*700637cbSDimitry Andricvoid __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT {
685*700637cbSDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
686*700637cbSDimitry Andric  typedef allocator_traits<_Al> _ATraits;
687*700637cbSDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
688*700637cbSDimitry Andric  _Al __a(__alloc_);
689*700637cbSDimitry Andric  this->~__assoc_state_alloc();
690*700637cbSDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
691*700637cbSDimitry Andric}
692*700637cbSDimitry Andric
693*700637cbSDimitry Andrictemplate <class _Alloc>
694*700637cbSDimitry Andricclass __assoc_sub_state_alloc : public __assoc_sub_state {
695*700637cbSDimitry Andric  typedef __assoc_sub_state base;
696*700637cbSDimitry Andric  _Alloc __alloc_;
697*700637cbSDimitry Andric
698*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
699*700637cbSDimitry Andric
700*700637cbSDimitry Andricpublic:
701*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __assoc_sub_state_alloc(const _Alloc& __a) : __alloc_(__a) {}
702*700637cbSDimitry Andric};
703*700637cbSDimitry Andric
704*700637cbSDimitry Andrictemplate <class _Alloc>
705*700637cbSDimitry Andricvoid __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT {
706*700637cbSDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
707*700637cbSDimitry Andric  typedef allocator_traits<_Al> _ATraits;
708*700637cbSDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
709*700637cbSDimitry Andric  _Al __a(__alloc_);
710*700637cbSDimitry Andric  this->~__assoc_sub_state_alloc();
711*700637cbSDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
712*700637cbSDimitry Andric}
713*700637cbSDimitry Andric
714*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
715*700637cbSDimitry Andricclass __deferred_assoc_state : public __assoc_state<_Rp> {
716*700637cbSDimitry Andric  typedef __assoc_state<_Rp> base;
717*700637cbSDimitry Andric
718*700637cbSDimitry Andric  _Fp __func_;
719*700637cbSDimitry Andric
720*700637cbSDimitry Andricpublic:
721*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
722*700637cbSDimitry Andric
723*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
724*700637cbSDimitry Andric};
725*700637cbSDimitry Andric
726*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
727*700637cbSDimitry Andricinline __deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
728*700637cbSDimitry Andric  this->__set_deferred();
729*700637cbSDimitry Andric}
730*700637cbSDimitry Andric
731*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
732*700637cbSDimitry Andricvoid __deferred_assoc_state<_Rp, _Fp>::__execute() {
733*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
734*700637cbSDimitry Andric  try {
735*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
736*700637cbSDimitry Andric    this->set_value(__func_());
737*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
738*700637cbSDimitry Andric  } catch (...) {
739*700637cbSDimitry Andric    this->set_exception(current_exception());
740*700637cbSDimitry Andric  }
741*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
742*700637cbSDimitry Andric}
743*700637cbSDimitry Andric
744*700637cbSDimitry Andrictemplate <class _Fp>
745*700637cbSDimitry Andricclass __deferred_assoc_state<void, _Fp> : public __assoc_sub_state {
746*700637cbSDimitry Andric  typedef __assoc_sub_state base;
747*700637cbSDimitry Andric
748*700637cbSDimitry Andric  _Fp __func_;
749*700637cbSDimitry Andric
750*700637cbSDimitry Andricpublic:
751*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __deferred_assoc_state(_Fp&& __f);
752*700637cbSDimitry Andric
753*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
754*700637cbSDimitry Andric};
755*700637cbSDimitry Andric
756*700637cbSDimitry Andrictemplate <class _Fp>
757*700637cbSDimitry Andricinline __deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {
758*700637cbSDimitry Andric  this->__set_deferred();
759*700637cbSDimitry Andric}
760*700637cbSDimitry Andric
761*700637cbSDimitry Andrictemplate <class _Fp>
762*700637cbSDimitry Andricvoid __deferred_assoc_state<void, _Fp>::__execute() {
763*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
764*700637cbSDimitry Andric  try {
765*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
766*700637cbSDimitry Andric    __func_();
767*700637cbSDimitry Andric    this->set_value();
768*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
769*700637cbSDimitry Andric  } catch (...) {
770*700637cbSDimitry Andric    this->set_exception(current_exception());
771*700637cbSDimitry Andric  }
772*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
773*700637cbSDimitry Andric}
774*700637cbSDimitry Andric
775*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
776*700637cbSDimitry Andricclass __async_assoc_state : public __assoc_state<_Rp> {
777*700637cbSDimitry Andric  typedef __assoc_state<_Rp> base;
778*700637cbSDimitry Andric
779*700637cbSDimitry Andric  _Fp __func_;
780*700637cbSDimitry Andric
781*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT;
782*700637cbSDimitry Andric
783*700637cbSDimitry Andricpublic:
784*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
785*700637cbSDimitry Andric
786*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute();
787*700637cbSDimitry Andric};
788*700637cbSDimitry Andric
789*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
790*700637cbSDimitry Andricinline __async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
791*700637cbSDimitry Andric
792*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
793*700637cbSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__execute() {
794*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
795*700637cbSDimitry Andric  try {
796*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
797*700637cbSDimitry Andric    this->set_value(__func_());
798*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
799*700637cbSDimitry Andric  } catch (...) {
800*700637cbSDimitry Andric    this->set_exception(current_exception());
801*700637cbSDimitry Andric  }
802*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
803*700637cbSDimitry Andric}
804*700637cbSDimitry Andric
805*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
806*700637cbSDimitry Andricvoid __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT {
807*700637cbSDimitry Andric  this->wait();
808*700637cbSDimitry Andric  base::__on_zero_shared();
809*700637cbSDimitry Andric}
810*700637cbSDimitry Andric
811*700637cbSDimitry Andrictemplate <class _Fp>
812*700637cbSDimitry Andricclass __async_assoc_state<void, _Fp> : public __assoc_sub_state {
813*700637cbSDimitry Andric  typedef __assoc_sub_state base;
814*700637cbSDimitry Andric
815*700637cbSDimitry Andric  _Fp __func_;
816*700637cbSDimitry Andric
817*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
818*700637cbSDimitry Andric
819*700637cbSDimitry Andricpublic:
820*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __async_assoc_state(_Fp&& __f);
821*700637cbSDimitry Andric
822*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override;
823*700637cbSDimitry Andric};
824*700637cbSDimitry Andric
825*700637cbSDimitry Andrictemplate <class _Fp>
826*700637cbSDimitry Andricinline __async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f) : __func_(std::forward<_Fp>(__f)) {}
827*700637cbSDimitry Andric
828*700637cbSDimitry Andrictemplate <class _Fp>
829*700637cbSDimitry Andricvoid __async_assoc_state<void, _Fp>::__execute() {
830*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
831*700637cbSDimitry Andric  try {
832*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
833*700637cbSDimitry Andric    __func_();
834*700637cbSDimitry Andric    this->set_value();
835*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
836*700637cbSDimitry Andric  } catch (...) {
837*700637cbSDimitry Andric    this->set_exception(current_exception());
838*700637cbSDimitry Andric  }
839*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
840*700637cbSDimitry Andric}
841*700637cbSDimitry Andric
842*700637cbSDimitry Andrictemplate <class _Fp>
843*700637cbSDimitry Andricvoid __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT {
844*700637cbSDimitry Andric  this->wait();
845*700637cbSDimitry Andric  base::__on_zero_shared();
846*700637cbSDimitry Andric}
847*700637cbSDimitry Andric
848*700637cbSDimitry Andrictemplate <class _Rp>
849*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise;
850*700637cbSDimitry Andrictemplate <class _Rp>
851*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future;
852*700637cbSDimitry Andric
853*700637cbSDimitry Andric// future
854*700637cbSDimitry Andric
855*700637cbSDimitry Andrictemplate <class _Rp>
856*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future;
857*700637cbSDimitry Andric
858*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
859*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f);
860*700637cbSDimitry Andric
861*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
862*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f);
863*700637cbSDimitry Andric
864*700637cbSDimitry Andrictemplate <class _Rp>
865*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future {
866*700637cbSDimitry Andric  __assoc_state<_Rp>* __state_;
867*700637cbSDimitry Andric
868*700637cbSDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state);
869*700637cbSDimitry Andric
870*700637cbSDimitry Andric  template <class>
871*700637cbSDimitry Andric  friend class promise;
872*700637cbSDimitry Andric  template <class>
873*700637cbSDimitry Andric  friend class shared_future;
874*700637cbSDimitry Andric
875*700637cbSDimitry Andric  template <class _R1, class _Fp>
876*700637cbSDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
877*700637cbSDimitry Andric  template <class _R1, class _Fp>
878*700637cbSDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
879*700637cbSDimitry Andric
880*700637cbSDimitry Andricpublic:
881*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
882*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
883*700637cbSDimitry Andric  future(const future&)            = delete;
884*700637cbSDimitry Andric  future& operator=(const future&) = delete;
885*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
886*700637cbSDimitry Andric    future(std::move(__rhs)).swap(*this);
887*700637cbSDimitry Andric    return *this;
888*700637cbSDimitry Andric  }
889*700637cbSDimitry Andric
890*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
891*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp> share() _NOEXCEPT;
892*700637cbSDimitry Andric
893*700637cbSDimitry Andric  // retrieving the value
894*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp get();
895*700637cbSDimitry Andric
896*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
897*700637cbSDimitry Andric
898*700637cbSDimitry Andric  // functions to check state
899*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
900*700637cbSDimitry Andric
901*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
902*700637cbSDimitry Andric  template <class _Rep, class _Period>
903*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
904*700637cbSDimitry Andric    return __state_->wait_for(__rel_time);
905*700637cbSDimitry Andric  }
906*700637cbSDimitry Andric  template <class _Clock, class _Duration>
907*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
908*700637cbSDimitry Andric    return __state_->wait_until(__abs_time);
909*700637cbSDimitry Andric  }
910*700637cbSDimitry Andric};
911*700637cbSDimitry Andric
912*700637cbSDimitry Andrictemplate <class _Rp>
913*700637cbSDimitry Andricfuture<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) {
914*700637cbSDimitry Andric  __state_->__attach_future();
915*700637cbSDimitry Andric}
916*700637cbSDimitry Andric
917*700637cbSDimitry Andricstruct __release_shared_count {
918*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) { __p->__release_shared(); }
919*700637cbSDimitry Andric};
920*700637cbSDimitry Andric
921*700637cbSDimitry Andrictemplate <class _Rp>
922*700637cbSDimitry Andricfuture<_Rp>::~future() {
923*700637cbSDimitry Andric  if (__state_)
924*700637cbSDimitry Andric    __state_->__release_shared();
925*700637cbSDimitry Andric}
926*700637cbSDimitry Andric
927*700637cbSDimitry Andrictemplate <class _Rp>
928*700637cbSDimitry Andric_Rp future<_Rp>::get() {
929*700637cbSDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
930*700637cbSDimitry Andric  __assoc_state<_Rp>* __s = __state_;
931*700637cbSDimitry Andric  __state_                = nullptr;
932*700637cbSDimitry Andric  return __s->move();
933*700637cbSDimitry Andric}
934*700637cbSDimitry Andric
935*700637cbSDimitry Andrictemplate <class _Rp>
936*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS future<_Rp&> {
937*700637cbSDimitry Andric  __assoc_state<_Rp&>* __state_;
938*700637cbSDimitry Andric
939*700637cbSDimitry Andric  explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state);
940*700637cbSDimitry Andric
941*700637cbSDimitry Andric  template <class>
942*700637cbSDimitry Andric  friend class promise;
943*700637cbSDimitry Andric  template <class>
944*700637cbSDimitry Andric  friend class shared_future;
945*700637cbSDimitry Andric
946*700637cbSDimitry Andric  template <class _R1, class _Fp>
947*700637cbSDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
948*700637cbSDimitry Andric  template <class _R1, class _Fp>
949*700637cbSDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
950*700637cbSDimitry Andric
951*700637cbSDimitry Andricpublic:
952*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
953*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
954*700637cbSDimitry Andric  future(const future&)            = delete;
955*700637cbSDimitry Andric  future& operator=(const future&) = delete;
956*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
957*700637cbSDimitry Andric    future(std::move(__rhs)).swap(*this);
958*700637cbSDimitry Andric    return *this;
959*700637cbSDimitry Andric  }
960*700637cbSDimitry Andric
961*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~future();
962*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<_Rp&> share() _NOEXCEPT;
963*700637cbSDimitry Andric
964*700637cbSDimitry Andric  // retrieving the value
965*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get();
966*700637cbSDimitry Andric
967*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
968*700637cbSDimitry Andric
969*700637cbSDimitry Andric  // functions to check state
970*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
971*700637cbSDimitry Andric
972*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
973*700637cbSDimitry Andric  template <class _Rep, class _Period>
974*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
975*700637cbSDimitry Andric    return __state_->wait_for(__rel_time);
976*700637cbSDimitry Andric  }
977*700637cbSDimitry Andric  template <class _Clock, class _Duration>
978*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
979*700637cbSDimitry Andric    return __state_->wait_until(__abs_time);
980*700637cbSDimitry Andric  }
981*700637cbSDimitry Andric};
982*700637cbSDimitry Andric
983*700637cbSDimitry Andrictemplate <class _Rp>
984*700637cbSDimitry Andricfuture<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) {
985*700637cbSDimitry Andric  __state_->__attach_future();
986*700637cbSDimitry Andric}
987*700637cbSDimitry Andric
988*700637cbSDimitry Andrictemplate <class _Rp>
989*700637cbSDimitry Andricfuture<_Rp&>::~future() {
990*700637cbSDimitry Andric  if (__state_)
991*700637cbSDimitry Andric    __state_->__release_shared();
992*700637cbSDimitry Andric}
993*700637cbSDimitry Andric
994*700637cbSDimitry Andrictemplate <class _Rp>
995*700637cbSDimitry Andric_Rp& future<_Rp&>::get() {
996*700637cbSDimitry Andric  unique_ptr<__shared_count, __release_shared_count> __guard(__state_);
997*700637cbSDimitry Andric  __assoc_state<_Rp&>* __s = __state_;
998*700637cbSDimitry Andric  __state_                 = nullptr;
999*700637cbSDimitry Andric  return __s->copy();
1000*700637cbSDimitry Andric}
1001*700637cbSDimitry Andric
1002*700637cbSDimitry Andrictemplate <>
1003*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI future<void> {
1004*700637cbSDimitry Andric  __assoc_sub_state* __state_;
1005*700637cbSDimitry Andric
1006*700637cbSDimitry Andric  explicit future(__assoc_sub_state* __state);
1007*700637cbSDimitry Andric
1008*700637cbSDimitry Andric  template <class>
1009*700637cbSDimitry Andric  friend class promise;
1010*700637cbSDimitry Andric  template <class>
1011*700637cbSDimitry Andric  friend class shared_future;
1012*700637cbSDimitry Andric
1013*700637cbSDimitry Andric  template <class _R1, class _Fp>
1014*700637cbSDimitry Andric  friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1015*700637cbSDimitry Andric  template <class _R1, class _Fp>
1016*700637cbSDimitry Andric  friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1017*700637cbSDimitry Andric
1018*700637cbSDimitry Andricpublic:
1019*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future() _NOEXCEPT : __state_(nullptr) {}
1020*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future(future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
1021*700637cbSDimitry Andric  future(const future&)            = delete;
1022*700637cbSDimitry Andric  future& operator=(const future&) = delete;
1023*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future& operator=(future&& __rhs) _NOEXCEPT {
1024*700637cbSDimitry Andric    future(std::move(__rhs)).swap(*this);
1025*700637cbSDimitry Andric    return *this;
1026*700637cbSDimitry Andric  }
1027*700637cbSDimitry Andric
1028*700637cbSDimitry Andric  ~future();
1029*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future<void> share() _NOEXCEPT;
1030*700637cbSDimitry Andric
1031*700637cbSDimitry Andric  // retrieving the value
1032*700637cbSDimitry Andric  void get();
1033*700637cbSDimitry Andric
1034*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
1035*700637cbSDimitry Andric
1036*700637cbSDimitry Andric  // functions to check state
1037*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1038*700637cbSDimitry Andric
1039*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
1040*700637cbSDimitry Andric  template <class _Rep, class _Period>
1041*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1042*700637cbSDimitry Andric    return __state_->wait_for(__rel_time);
1043*700637cbSDimitry Andric  }
1044*700637cbSDimitry Andric  template <class _Clock, class _Duration>
1045*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1046*700637cbSDimitry Andric    return __state_->wait_until(__abs_time);
1047*700637cbSDimitry Andric  }
1048*700637cbSDimitry Andric};
1049*700637cbSDimitry Andric
1050*700637cbSDimitry Andrictemplate <class _Rp>
1051*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT {
1052*700637cbSDimitry Andric  __x.swap(__y);
1053*700637cbSDimitry Andric}
1054*700637cbSDimitry Andric
1055*700637cbSDimitry Andric// promise<R>
1056*700637cbSDimitry Andric
1057*700637cbSDimitry Andrictemplate <class _Callable>
1058*700637cbSDimitry Andricclass packaged_task;
1059*700637cbSDimitry Andric
1060*700637cbSDimitry Andrictemplate <class _Rp>
1061*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise {
1062*700637cbSDimitry Andric  __assoc_state<_Rp>* __state_;
1063*700637cbSDimitry Andric
1064*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1065*700637cbSDimitry Andric
1066*700637cbSDimitry Andric  template <class>
1067*700637cbSDimitry Andric  friend class packaged_task;
1068*700637cbSDimitry Andric
1069*700637cbSDimitry Andricpublic:
1070*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
1071*700637cbSDimitry Andric  template <class _Alloc>
1072*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a);
1073*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
1074*700637cbSDimitry Andric  promise(const promise& __rhs) = delete;
1075*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
1076*700637cbSDimitry Andric
1077*700637cbSDimitry Andric  // assignment
1078*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
1079*700637cbSDimitry Andric    promise(std::move(__rhs)).swap(*this);
1080*700637cbSDimitry Andric    return *this;
1081*700637cbSDimitry Andric  }
1082*700637cbSDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1083*700637cbSDimitry Andric
1084*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
1085*700637cbSDimitry Andric
1086*700637cbSDimitry Andric  // retrieving the result
1087*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future();
1088*700637cbSDimitry Andric
1089*700637cbSDimitry Andric  // setting the result
1090*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r);
1091*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r);
1092*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
1093*700637cbSDimitry Andric
1094*700637cbSDimitry Andric  // setting the result with deferred notification
1095*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r);
1096*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r);
1097*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
1098*700637cbSDimitry Andric};
1099*700637cbSDimitry Andric
1100*700637cbSDimitry Andrictemplate <class _Rp>
1101*700637cbSDimitry Andricpromise<_Rp>::promise() : __state_(new __assoc_state<_Rp>) {}
1102*700637cbSDimitry Andric
1103*700637cbSDimitry Andrictemplate <class _Rp>
1104*700637cbSDimitry Andrictemplate <class _Alloc>
1105*700637cbSDimitry Andricpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0) {
1106*700637cbSDimitry Andric  typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1107*700637cbSDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1108*700637cbSDimitry Andric  typedef __allocator_destructor<_A2> _D2;
1109*700637cbSDimitry Andric  _A2 __a(__a0);
1110*700637cbSDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1111*700637cbSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
1112*700637cbSDimitry Andric  __state_ = std::addressof(*__hold.release());
1113*700637cbSDimitry Andric}
1114*700637cbSDimitry Andric
1115*700637cbSDimitry Andrictemplate <class _Rp>
1116*700637cbSDimitry Andricpromise<_Rp>::~promise() {
1117*700637cbSDimitry Andric  if (__state_) {
1118*700637cbSDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
1119*700637cbSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
1120*700637cbSDimitry Andric    __state_->__release_shared();
1121*700637cbSDimitry Andric  }
1122*700637cbSDimitry Andric}
1123*700637cbSDimitry Andric
1124*700637cbSDimitry Andrictemplate <class _Rp>
1125*700637cbSDimitry Andricfuture<_Rp> promise<_Rp>::get_future() {
1126*700637cbSDimitry Andric  if (__state_ == nullptr)
1127*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1128*700637cbSDimitry Andric  return future<_Rp>(__state_);
1129*700637cbSDimitry Andric}
1130*700637cbSDimitry Andric
1131*700637cbSDimitry Andrictemplate <class _Rp>
1132*700637cbSDimitry Andricvoid promise<_Rp>::set_value(const _Rp& __r) {
1133*700637cbSDimitry Andric  if (__state_ == nullptr)
1134*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1135*700637cbSDimitry Andric  __state_->set_value(__r);
1136*700637cbSDimitry Andric}
1137*700637cbSDimitry Andric
1138*700637cbSDimitry Andrictemplate <class _Rp>
1139*700637cbSDimitry Andricvoid promise<_Rp>::set_value(_Rp&& __r) {
1140*700637cbSDimitry Andric  if (__state_ == nullptr)
1141*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1142*700637cbSDimitry Andric  __state_->set_value(std::move(__r));
1143*700637cbSDimitry Andric}
1144*700637cbSDimitry Andric
1145*700637cbSDimitry Andrictemplate <class _Rp>
1146*700637cbSDimitry Andricvoid promise<_Rp>::set_exception(exception_ptr __p) {
1147*700637cbSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
1148*700637cbSDimitry Andric  if (__state_ == nullptr)
1149*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1150*700637cbSDimitry Andric  __state_->set_exception(__p);
1151*700637cbSDimitry Andric}
1152*700637cbSDimitry Andric
1153*700637cbSDimitry Andrictemplate <class _Rp>
1154*700637cbSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(const _Rp& __r) {
1155*700637cbSDimitry Andric  if (__state_ == nullptr)
1156*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1157*700637cbSDimitry Andric  __state_->set_value_at_thread_exit(__r);
1158*700637cbSDimitry Andric}
1159*700637cbSDimitry Andric
1160*700637cbSDimitry Andrictemplate <class _Rp>
1161*700637cbSDimitry Andricvoid promise<_Rp>::set_value_at_thread_exit(_Rp&& __r) {
1162*700637cbSDimitry Andric  if (__state_ == nullptr)
1163*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1164*700637cbSDimitry Andric  __state_->set_value_at_thread_exit(std::move(__r));
1165*700637cbSDimitry Andric}
1166*700637cbSDimitry Andric
1167*700637cbSDimitry Andrictemplate <class _Rp>
1168*700637cbSDimitry Andricvoid promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) {
1169*700637cbSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
1170*700637cbSDimitry Andric  if (__state_ == nullptr)
1171*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1172*700637cbSDimitry Andric  __state_->set_exception_at_thread_exit(__p);
1173*700637cbSDimitry Andric}
1174*700637cbSDimitry Andric
1175*700637cbSDimitry Andric// promise<R&>
1176*700637cbSDimitry Andric
1177*700637cbSDimitry Andrictemplate <class _Rp>
1178*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS promise<_Rp&> {
1179*700637cbSDimitry Andric  __assoc_state<_Rp&>* __state_;
1180*700637cbSDimitry Andric
1181*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1182*700637cbSDimitry Andric
1183*700637cbSDimitry Andric  template <class>
1184*700637cbSDimitry Andric  friend class packaged_task;
1185*700637cbSDimitry Andric
1186*700637cbSDimitry Andricpublic:
1187*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise();
1188*700637cbSDimitry Andric  template <class _Allocator>
1189*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a);
1190*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
1191*700637cbSDimitry Andric  promise(const promise& __rhs) = delete;
1192*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~promise();
1193*700637cbSDimitry Andric
1194*700637cbSDimitry Andric  // assignment
1195*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
1196*700637cbSDimitry Andric    promise(std::move(__rhs)).swap(*this);
1197*700637cbSDimitry Andric    return *this;
1198*700637cbSDimitry Andric  }
1199*700637cbSDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1200*700637cbSDimitry Andric
1201*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
1202*700637cbSDimitry Andric
1203*700637cbSDimitry Andric  // retrieving the result
1204*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future();
1205*700637cbSDimitry Andric
1206*700637cbSDimitry Andric  // setting the result
1207*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r);
1208*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p);
1209*700637cbSDimitry Andric
1210*700637cbSDimitry Andric  // setting the result with deferred notification
1211*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&);
1212*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p);
1213*700637cbSDimitry Andric};
1214*700637cbSDimitry Andric
1215*700637cbSDimitry Andrictemplate <class _Rp>
1216*700637cbSDimitry Andricpromise<_Rp&>::promise() : __state_(new __assoc_state<_Rp&>) {}
1217*700637cbSDimitry Andric
1218*700637cbSDimitry Andrictemplate <class _Rp>
1219*700637cbSDimitry Andrictemplate <class _Alloc>
1220*700637cbSDimitry Andricpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0) {
1221*700637cbSDimitry Andric  typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1222*700637cbSDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1223*700637cbSDimitry Andric  typedef __allocator_destructor<_A2> _D2;
1224*700637cbSDimitry Andric  _A2 __a(__a0);
1225*700637cbSDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1226*700637cbSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
1227*700637cbSDimitry Andric  __state_ = std::addressof(*__hold.release());
1228*700637cbSDimitry Andric}
1229*700637cbSDimitry Andric
1230*700637cbSDimitry Andrictemplate <class _Rp>
1231*700637cbSDimitry Andricpromise<_Rp&>::~promise() {
1232*700637cbSDimitry Andric  if (__state_) {
1233*700637cbSDimitry Andric    if (!__state_->__has_value() && __state_->use_count() > 1)
1234*700637cbSDimitry Andric      __state_->set_exception(make_exception_ptr(future_error(make_error_code(future_errc::broken_promise))));
1235*700637cbSDimitry Andric    __state_->__release_shared();
1236*700637cbSDimitry Andric  }
1237*700637cbSDimitry Andric}
1238*700637cbSDimitry Andric
1239*700637cbSDimitry Andrictemplate <class _Rp>
1240*700637cbSDimitry Andricfuture<_Rp&> promise<_Rp&>::get_future() {
1241*700637cbSDimitry Andric  if (__state_ == nullptr)
1242*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1243*700637cbSDimitry Andric  return future<_Rp&>(__state_);
1244*700637cbSDimitry Andric}
1245*700637cbSDimitry Andric
1246*700637cbSDimitry Andrictemplate <class _Rp>
1247*700637cbSDimitry Andricvoid promise<_Rp&>::set_value(_Rp& __r) {
1248*700637cbSDimitry Andric  if (__state_ == nullptr)
1249*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1250*700637cbSDimitry Andric  __state_->set_value(__r);
1251*700637cbSDimitry Andric}
1252*700637cbSDimitry Andric
1253*700637cbSDimitry Andrictemplate <class _Rp>
1254*700637cbSDimitry Andricvoid promise<_Rp&>::set_exception(exception_ptr __p) {
1255*700637cbSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception: received nullptr");
1256*700637cbSDimitry Andric  if (__state_ == nullptr)
1257*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1258*700637cbSDimitry Andric  __state_->set_exception(__p);
1259*700637cbSDimitry Andric}
1260*700637cbSDimitry Andric
1261*700637cbSDimitry Andrictemplate <class _Rp>
1262*700637cbSDimitry Andricvoid promise<_Rp&>::set_value_at_thread_exit(_Rp& __r) {
1263*700637cbSDimitry Andric  if (__state_ == nullptr)
1264*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1265*700637cbSDimitry Andric  __state_->set_value_at_thread_exit(__r);
1266*700637cbSDimitry Andric}
1267*700637cbSDimitry Andric
1268*700637cbSDimitry Andrictemplate <class _Rp>
1269*700637cbSDimitry Andricvoid promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) {
1270*700637cbSDimitry Andric  _LIBCPP_ASSERT_NON_NULL(__p != nullptr, "promise::set_exception_at_thread_exit: received nullptr");
1271*700637cbSDimitry Andric  if (__state_ == nullptr)
1272*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1273*700637cbSDimitry Andric  __state_->set_exception_at_thread_exit(__p);
1274*700637cbSDimitry Andric}
1275*700637cbSDimitry Andric
1276*700637cbSDimitry Andric// promise<void>
1277*700637cbSDimitry Andric
1278*700637cbSDimitry Andrictemplate <>
1279*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI promise<void> {
1280*700637cbSDimitry Andric  __assoc_sub_state* __state_;
1281*700637cbSDimitry Andric
1282*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1283*700637cbSDimitry Andric
1284*700637cbSDimitry Andric  template <class>
1285*700637cbSDimitry Andric  friend class packaged_task;
1286*700637cbSDimitry Andric
1287*700637cbSDimitry Andricpublic:
1288*700637cbSDimitry Andric  promise();
1289*700637cbSDimitry Andric  template <class _Allocator>
1290*700637cbSDimitry Andric  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a);
1291*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
1292*700637cbSDimitry Andric  promise(const promise& __rhs) = delete;
1293*700637cbSDimitry Andric  ~promise();
1294*700637cbSDimitry Andric
1295*700637cbSDimitry Andric  // assignment
1296*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI promise& operator=(promise&& __rhs) _NOEXCEPT {
1297*700637cbSDimitry Andric    promise(std::move(__rhs)).swap(*this);
1298*700637cbSDimitry Andric    return *this;
1299*700637cbSDimitry Andric  }
1300*700637cbSDimitry Andric  promise& operator=(const promise& __rhs) = delete;
1301*700637cbSDimitry Andric
1302*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(promise& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
1303*700637cbSDimitry Andric
1304*700637cbSDimitry Andric  // retrieving the result
1305*700637cbSDimitry Andric  future<void> get_future();
1306*700637cbSDimitry Andric
1307*700637cbSDimitry Andric  // setting the result
1308*700637cbSDimitry Andric  void set_value();
1309*700637cbSDimitry Andric  void set_exception(exception_ptr __p);
1310*700637cbSDimitry Andric
1311*700637cbSDimitry Andric  // setting the result with deferred notification
1312*700637cbSDimitry Andric  void set_value_at_thread_exit();
1313*700637cbSDimitry Andric  void set_exception_at_thread_exit(exception_ptr __p);
1314*700637cbSDimitry Andric};
1315*700637cbSDimitry Andric
1316*700637cbSDimitry Andrictemplate <class _Alloc>
1317*700637cbSDimitry Andricpromise<void>::promise(allocator_arg_t, const _Alloc& __a0) {
1318*700637cbSDimitry Andric  typedef __assoc_sub_state_alloc<_Alloc> _State;
1319*700637cbSDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
1320*700637cbSDimitry Andric  typedef __allocator_destructor<_A2> _D2;
1321*700637cbSDimitry Andric  _A2 __a(__a0);
1322*700637cbSDimitry Andric  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1323*700637cbSDimitry Andric  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
1324*700637cbSDimitry Andric  __state_ = std::addressof(*__hold.release());
1325*700637cbSDimitry Andric}
1326*700637cbSDimitry Andric
1327*700637cbSDimitry Andrictemplate <class _Rp>
1328*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT {
1329*700637cbSDimitry Andric  __x.swap(__y);
1330*700637cbSDimitry Andric}
1331*700637cbSDimitry Andric
1332*700637cbSDimitry Andrictemplate <class _Rp, class _Alloc>
1333*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc> : public true_type {};
1334*700637cbSDimitry Andric
1335*700637cbSDimitry Andric// packaged_task
1336*700637cbSDimitry Andric
1337*700637cbSDimitry Andrictemplate <class _Fp>
1338*700637cbSDimitry Andricclass __packaged_task_base;
1339*700637cbSDimitry Andric
1340*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1341*700637cbSDimitry Andricclass __packaged_task_base<_Rp(_ArgTypes...)> {
1342*700637cbSDimitry Andricpublic:
1343*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_base() {}
1344*700637cbSDimitry Andric  __packaged_task_base(const __packaged_task_base&)            = delete;
1345*700637cbSDimitry Andric  __packaged_task_base& operator=(const __packaged_task_base&) = delete;
1346*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1347*700637cbSDimitry Andric  virtual ~__packaged_task_base() {}
1348*700637cbSDimitry Andric  virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1349*700637cbSDimitry Andric  virtual void destroy()                                  = 0;
1350*700637cbSDimitry Andric  virtual void destroy_deallocate()                       = 0;
1351*700637cbSDimitry Andric  virtual _Rp operator()(_ArgTypes&&...)                  = 0;
1352*700637cbSDimitry Andric};
1353*700637cbSDimitry Andric
1354*700637cbSDimitry Andrictemplate <class _FD, class _Alloc, class _FB>
1355*700637cbSDimitry Andricclass __packaged_task_func;
1356*700637cbSDimitry Andric
1357*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1358*700637cbSDimitry Andricclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __packaged_task_base<_Rp(_ArgTypes...)> {
1359*700637cbSDimitry Andric  __compressed_pair<_Fp, _Alloc> __f_;
1360*700637cbSDimitry Andric
1361*700637cbSDimitry Andricpublic:
1362*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
1363*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __packaged_task_func(_Fp&& __f) : __f_(std::move(__f), __default_init_tag()) {}
1364*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {}
1365*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_func(_Fp&& __f, const _Alloc& __a) : __f_(std::move(__f), __a) {}
1366*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1367*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy();
1368*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate();
1369*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __args);
1370*700637cbSDimitry Andric};
1371*700637cbSDimitry Andric
1372*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1373*700637cbSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1374*700637cbSDimitry Andric    __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT {
1375*700637cbSDimitry Andric  ::new ((void*)__p) __packaged_task_func(std::move(__f_.first()), std::move(__f_.second()));
1376*700637cbSDimitry Andric}
1377*700637cbSDimitry Andric
1378*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1379*700637cbSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() {
1380*700637cbSDimitry Andric  __f_.~__compressed_pair<_Fp, _Alloc>();
1381*700637cbSDimitry Andric}
1382*700637cbSDimitry Andric
1383*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1384*700637cbSDimitry Andricvoid __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() {
1385*700637cbSDimitry Andric  typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1386*700637cbSDimitry Andric  typedef allocator_traits<_Ap> _ATraits;
1387*700637cbSDimitry Andric  typedef pointer_traits<typename _ATraits::pointer> _PTraits;
1388*700637cbSDimitry Andric  _Ap __a(__f_.second());
1389*700637cbSDimitry Andric  __f_.~__compressed_pair<_Fp, _Alloc>();
1390*700637cbSDimitry Andric  __a.deallocate(_PTraits::pointer_to(*this), 1);
1391*700637cbSDimitry Andric}
1392*700637cbSDimitry Andric
1393*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc, class _Rp, class... _ArgTypes>
1394*700637cbSDimitry Andric_Rp __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) {
1395*700637cbSDimitry Andric  return std::__invoke(__f_.first(), std::forward<_ArgTypes>(__arg)...);
1396*700637cbSDimitry Andric}
1397*700637cbSDimitry Andric
1398*700637cbSDimitry Andrictemplate <class _Callable>
1399*700637cbSDimitry Andricclass __packaged_task_function;
1400*700637cbSDimitry Andric
1401*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1402*700637cbSDimitry Andricclass __packaged_task_function<_Rp(_ArgTypes...)> {
1403*700637cbSDimitry Andric  typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1404*700637cbSDimitry Andric
1405*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __base* __get_buf() { return (__base*)&__buf_; }
1406*700637cbSDimitry Andric
1407*700637cbSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1408*700637cbSDimitry Andric  typename aligned_storage<3 * sizeof(void*)>::type __buf_;
1409*700637cbSDimitry Andric  _LIBCPP_SUPPRESS_DEPRECATED_POP
1410*700637cbSDimitry Andric  __base* __f_;
1411*700637cbSDimitry Andric
1412*700637cbSDimitry Andricpublic:
1413*700637cbSDimitry Andric  typedef _Rp result_type;
1414*700637cbSDimitry Andric
1415*700637cbSDimitry Andric  // construct/copy/destroy:
1416*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1417*700637cbSDimitry Andric  template <class _Fp>
1418*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
1419*700637cbSDimitry Andric  template <class _Fp, class _Alloc>
1420*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1421*700637cbSDimitry Andric
1422*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1423*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1424*700637cbSDimitry Andric
1425*700637cbSDimitry Andric  __packaged_task_function(const __packaged_task_function&)            = delete;
1426*700637cbSDimitry Andric  __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1427*700637cbSDimitry Andric
1428*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function();
1429*700637cbSDimitry Andric
1430*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT;
1431*700637cbSDimitry Andric
1432*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
1433*700637cbSDimitry Andric};
1434*700637cbSDimitry Andric
1435*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1436*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT {
1437*700637cbSDimitry Andric  if (__f.__f_ == nullptr)
1438*700637cbSDimitry Andric    __f_ = nullptr;
1439*700637cbSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1440*700637cbSDimitry Andric    __f.__f_->__move_to(__get_buf());
1441*700637cbSDimitry Andric    __f_ = (__base*)&__buf_;
1442*700637cbSDimitry Andric  } else {
1443*700637cbSDimitry Andric    __f_     = __f.__f_;
1444*700637cbSDimitry Andric    __f.__f_ = nullptr;
1445*700637cbSDimitry Andric  }
1446*700637cbSDimitry Andric}
1447*700637cbSDimitry Andric
1448*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1449*700637cbSDimitry Andrictemplate <class _Fp>
1450*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) : __f_(nullptr) {
1451*700637cbSDimitry Andric  typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
1452*700637cbSDimitry Andric  typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1453*700637cbSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
1454*700637cbSDimitry Andric    ::new ((void*)&__buf_) _FF(std::forward<_Fp>(__f));
1455*700637cbSDimitry Andric    __f_ = (__base*)&__buf_;
1456*700637cbSDimitry Andric  } else {
1457*700637cbSDimitry Andric    typedef allocator<_FF> _Ap;
1458*700637cbSDimitry Andric    _Ap __a;
1459*700637cbSDimitry Andric    typedef __allocator_destructor<_Ap> _Dp;
1460*700637cbSDimitry Andric    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1461*700637cbSDimitry Andric    ::new ((void*)__hold.get()) _FF(std::forward<_Fp>(__f), allocator<_FR>(__a));
1462*700637cbSDimitry Andric    __f_ = __hold.release();
1463*700637cbSDimitry Andric  }
1464*700637cbSDimitry Andric}
1465*700637cbSDimitry Andric
1466*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1467*700637cbSDimitry Andrictemplate <class _Fp, class _Alloc>
1468*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1469*700637cbSDimitry Andric    : __f_(nullptr) {
1470*700637cbSDimitry Andric  typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR;
1471*700637cbSDimitry Andric  typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1472*700637cbSDimitry Andric  if (sizeof(_FF) <= sizeof(__buf_)) {
1473*700637cbSDimitry Andric    __f_ = (__base*)&__buf_;
1474*700637cbSDimitry Andric    ::new ((void*)__f_) _FF(std::forward<_Fp>(__f));
1475*700637cbSDimitry Andric  } else {
1476*700637cbSDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
1477*700637cbSDimitry Andric    _Ap __a(__a0);
1478*700637cbSDimitry Andric    typedef __allocator_destructor<_Ap> _Dp;
1479*700637cbSDimitry Andric    unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1480*700637cbSDimitry Andric    ::new ((void*)std::addressof(*__hold.get())) _FF(std::forward<_Fp>(__f), _Alloc(__a));
1481*700637cbSDimitry Andric    __f_ = std::addressof(*__hold.release());
1482*700637cbSDimitry Andric  }
1483*700637cbSDimitry Andric}
1484*700637cbSDimitry Andric
1485*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1486*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>&
1487*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT {
1488*700637cbSDimitry Andric  if (__f_ == __get_buf())
1489*700637cbSDimitry Andric    __f_->destroy();
1490*700637cbSDimitry Andric  else if (__f_)
1491*700637cbSDimitry Andric    __f_->destroy_deallocate();
1492*700637cbSDimitry Andric  __f_ = nullptr;
1493*700637cbSDimitry Andric  if (__f.__f_ == nullptr)
1494*700637cbSDimitry Andric    __f_ = nullptr;
1495*700637cbSDimitry Andric  else if (__f.__f_ == __f.__get_buf()) {
1496*700637cbSDimitry Andric    __f.__f_->__move_to(__get_buf());
1497*700637cbSDimitry Andric    __f_ = __get_buf();
1498*700637cbSDimitry Andric  } else {
1499*700637cbSDimitry Andric    __f_     = __f.__f_;
1500*700637cbSDimitry Andric    __f.__f_ = nullptr;
1501*700637cbSDimitry Andric  }
1502*700637cbSDimitry Andric  return *this;
1503*700637cbSDimitry Andric}
1504*700637cbSDimitry Andric
1505*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1506*700637cbSDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function() {
1507*700637cbSDimitry Andric  if (__f_ == __get_buf())
1508*700637cbSDimitry Andric    __f_->destroy();
1509*700637cbSDimitry Andric  else if (__f_)
1510*700637cbSDimitry Andric    __f_->destroy_deallocate();
1511*700637cbSDimitry Andric}
1512*700637cbSDimitry Andric
1513*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1514*700637cbSDimitry Andric_LIBCPP_NO_CFI void __packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT {
1515*700637cbSDimitry Andric  if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) {
1516*700637cbSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1517*700637cbSDimitry Andric    typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1518*700637cbSDimitry Andric    _LIBCPP_SUPPRESS_DEPRECATED_POP
1519*700637cbSDimitry Andric    __base* __t = (__base*)&__tempbuf;
1520*700637cbSDimitry Andric    __f_->__move_to(__t);
1521*700637cbSDimitry Andric    __f_->destroy();
1522*700637cbSDimitry Andric    __f_ = nullptr;
1523*700637cbSDimitry Andric    __f.__f_->__move_to((__base*)&__buf_);
1524*700637cbSDimitry Andric    __f.__f_->destroy();
1525*700637cbSDimitry Andric    __f.__f_ = nullptr;
1526*700637cbSDimitry Andric    __f_     = (__base*)&__buf_;
1527*700637cbSDimitry Andric    __t->__move_to((__base*)&__f.__buf_);
1528*700637cbSDimitry Andric    __t->destroy();
1529*700637cbSDimitry Andric    __f.__f_ = (__base*)&__f.__buf_;
1530*700637cbSDimitry Andric  } else if (__f_ == (__base*)&__buf_) {
1531*700637cbSDimitry Andric    __f_->__move_to((__base*)&__f.__buf_);
1532*700637cbSDimitry Andric    __f_->destroy();
1533*700637cbSDimitry Andric    __f_     = __f.__f_;
1534*700637cbSDimitry Andric    __f.__f_ = (__base*)&__f.__buf_;
1535*700637cbSDimitry Andric  } else if (__f.__f_ == (__base*)&__f.__buf_) {
1536*700637cbSDimitry Andric    __f.__f_->__move_to((__base*)&__buf_);
1537*700637cbSDimitry Andric    __f.__f_->destroy();
1538*700637cbSDimitry Andric    __f.__f_ = __f_;
1539*700637cbSDimitry Andric    __f_     = (__base*)&__buf_;
1540*700637cbSDimitry Andric  } else
1541*700637cbSDimitry Andric    std::swap(__f_, __f.__f_);
1542*700637cbSDimitry Andric}
1543*700637cbSDimitry Andric
1544*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1545*700637cbSDimitry Andricinline _Rp __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
1546*700637cbSDimitry Andric  return (*__f_)(std::forward<_ArgTypes>(__arg)...);
1547*700637cbSDimitry Andric}
1548*700637cbSDimitry Andric
1549*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1550*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)> {
1551*700637cbSDimitry Andricpublic:
1552*700637cbSDimitry Andric  typedef _Rp result_type; // extension
1553*700637cbSDimitry Andric
1554*700637cbSDimitry Andricprivate:
1555*700637cbSDimitry Andric  __packaged_task_function<result_type(_ArgTypes...)> __f_;
1556*700637cbSDimitry Andric  promise<result_type> __p_;
1557*700637cbSDimitry Andric
1558*700637cbSDimitry Andricpublic:
1559*700637cbSDimitry Andric  // construction and destruction
1560*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1561*700637cbSDimitry Andric
1562*700637cbSDimitry Andric  template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1563*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1564*700637cbSDimitry Andric
1565*700637cbSDimitry Andric  template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1566*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1567*700637cbSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
1568*700637cbSDimitry Andric  // ~packaged_task() = default;
1569*700637cbSDimitry Andric
1570*700637cbSDimitry Andric  // no copy
1571*700637cbSDimitry Andric  packaged_task(const packaged_task&)            = delete;
1572*700637cbSDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
1573*700637cbSDimitry Andric
1574*700637cbSDimitry Andric  // move support
1575*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1576*700637cbSDimitry Andric      : __f_(std::move(__other.__f_)),
1577*700637cbSDimitry Andric        __p_(std::move(__other.__p_)) {}
1578*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
1579*700637cbSDimitry Andric    __f_ = std::move(__other.__f_);
1580*700637cbSDimitry Andric    __p_ = std::move(__other.__p_);
1581*700637cbSDimitry Andric    return *this;
1582*700637cbSDimitry Andric  }
1583*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
1584*700637cbSDimitry Andric    __f_.swap(__other.__f_);
1585*700637cbSDimitry Andric    __p_.swap(__other.__p_);
1586*700637cbSDimitry Andric  }
1587*700637cbSDimitry Andric
1588*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
1589*700637cbSDimitry Andric
1590*700637cbSDimitry Andric  // result retrieval
1591*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
1592*700637cbSDimitry Andric
1593*700637cbSDimitry Andric  // execution
1594*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
1595*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
1596*700637cbSDimitry Andric
1597*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
1598*700637cbSDimitry Andric};
1599*700637cbSDimitry Andric
1600*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1601*700637cbSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) {
1602*700637cbSDimitry Andric  if (__p_.__state_ == nullptr)
1603*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1604*700637cbSDimitry Andric  if (__p_.__state_->__has_value())
1605*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
1606*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1607*700637cbSDimitry Andric  try {
1608*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1609*700637cbSDimitry Andric    __p_.set_value(__f_(std::forward<_ArgTypes>(__args)...));
1610*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1611*700637cbSDimitry Andric  } catch (...) {
1612*700637cbSDimitry Andric    __p_.set_exception(current_exception());
1613*700637cbSDimitry Andric  }
1614*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1615*700637cbSDimitry Andric}
1616*700637cbSDimitry Andric
1617*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1618*700637cbSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
1619*700637cbSDimitry Andric  if (__p_.__state_ == nullptr)
1620*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1621*700637cbSDimitry Andric  if (__p_.__state_->__has_value())
1622*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
1623*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1624*700637cbSDimitry Andric  try {
1625*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1626*700637cbSDimitry Andric    __p_.set_value_at_thread_exit(__f_(std::forward<_ArgTypes>(__args)...));
1627*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1628*700637cbSDimitry Andric  } catch (...) {
1629*700637cbSDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
1630*700637cbSDimitry Andric  }
1631*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1632*700637cbSDimitry Andric}
1633*700637cbSDimitry Andric
1634*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1635*700637cbSDimitry Andricvoid packaged_task<_Rp(_ArgTypes...)>::reset() {
1636*700637cbSDimitry Andric  if (!valid())
1637*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1638*700637cbSDimitry Andric  __p_ = promise<result_type>();
1639*700637cbSDimitry Andric}
1640*700637cbSDimitry Andric
1641*700637cbSDimitry Andrictemplate <class... _ArgTypes>
1642*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)> {
1643*700637cbSDimitry Andricpublic:
1644*700637cbSDimitry Andric  typedef void result_type; // extension
1645*700637cbSDimitry Andric
1646*700637cbSDimitry Andricprivate:
1647*700637cbSDimitry Andric  __packaged_task_function<result_type(_ArgTypes...)> __f_;
1648*700637cbSDimitry Andric  promise<result_type> __p_;
1649*700637cbSDimitry Andric
1650*700637cbSDimitry Andricpublic:
1651*700637cbSDimitry Andric  // construction and destruction
1652*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
1653*700637cbSDimitry Andric  template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1654*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
1655*700637cbSDimitry Andric  template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
1656*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1657*700637cbSDimitry Andric      : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
1658*700637cbSDimitry Andric  // ~packaged_task() = default;
1659*700637cbSDimitry Andric
1660*700637cbSDimitry Andric  // no copy
1661*700637cbSDimitry Andric  packaged_task(const packaged_task&)            = delete;
1662*700637cbSDimitry Andric  packaged_task& operator=(const packaged_task&) = delete;
1663*700637cbSDimitry Andric
1664*700637cbSDimitry Andric  // move support
1665*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task(packaged_task&& __other) _NOEXCEPT
1666*700637cbSDimitry Andric      : __f_(std::move(__other.__f_)),
1667*700637cbSDimitry Andric        __p_(std::move(__other.__p_)) {}
1668*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI packaged_task& operator=(packaged_task&& __other) _NOEXCEPT {
1669*700637cbSDimitry Andric    __f_ = std::move(__other.__f_);
1670*700637cbSDimitry Andric    __p_ = std::move(__other.__p_);
1671*700637cbSDimitry Andric    return *this;
1672*700637cbSDimitry Andric  }
1673*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(packaged_task& __other) _NOEXCEPT {
1674*700637cbSDimitry Andric    __f_.swap(__other.__f_);
1675*700637cbSDimitry Andric    __p_.swap(__other.__p_);
1676*700637cbSDimitry Andric  }
1677*700637cbSDimitry Andric
1678*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __p_.__state_ != nullptr; }
1679*700637cbSDimitry Andric
1680*700637cbSDimitry Andric  // result retrieval
1681*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future<result_type> get_future() { return __p_.get_future(); }
1682*700637cbSDimitry Andric
1683*700637cbSDimitry Andric  // execution
1684*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args);
1685*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args);
1686*700637cbSDimitry Andric
1687*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset();
1688*700637cbSDimitry Andric};
1689*700637cbSDimitry Andric
1690*700637cbSDimitry Andrictemplate <class... _ArgTypes>
1691*700637cbSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) {
1692*700637cbSDimitry Andric  if (__p_.__state_ == nullptr)
1693*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1694*700637cbSDimitry Andric  if (__p_.__state_->__has_value())
1695*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
1696*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1697*700637cbSDimitry Andric  try {
1698*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1699*700637cbSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
1700*700637cbSDimitry Andric    __p_.set_value();
1701*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1702*700637cbSDimitry Andric  } catch (...) {
1703*700637cbSDimitry Andric    __p_.set_exception(current_exception());
1704*700637cbSDimitry Andric  }
1705*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1706*700637cbSDimitry Andric}
1707*700637cbSDimitry Andric
1708*700637cbSDimitry Andrictemplate <class... _ArgTypes>
1709*700637cbSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) {
1710*700637cbSDimitry Andric  if (__p_.__state_ == nullptr)
1711*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1712*700637cbSDimitry Andric  if (__p_.__state_->__has_value())
1713*700637cbSDimitry Andric    __throw_future_error(future_errc::promise_already_satisfied);
1714*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1715*700637cbSDimitry Andric  try {
1716*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1717*700637cbSDimitry Andric    __f_(std::forward<_ArgTypes>(__args)...);
1718*700637cbSDimitry Andric    __p_.set_value_at_thread_exit();
1719*700637cbSDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1720*700637cbSDimitry Andric  } catch (...) {
1721*700637cbSDimitry Andric    __p_.set_exception_at_thread_exit(current_exception());
1722*700637cbSDimitry Andric  }
1723*700637cbSDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
1724*700637cbSDimitry Andric}
1725*700637cbSDimitry Andric
1726*700637cbSDimitry Andrictemplate <class... _ArgTypes>
1727*700637cbSDimitry Andricvoid packaged_task<void(_ArgTypes...)>::reset() {
1728*700637cbSDimitry Andric  if (!valid())
1729*700637cbSDimitry Andric    __throw_future_error(future_errc::no_state);
1730*700637cbSDimitry Andric  __p_ = promise<result_type>();
1731*700637cbSDimitry Andric}
1732*700637cbSDimitry Andric
1733*700637cbSDimitry Andrictemplate <class _Rp, class... _ArgTypes>
1734*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
1735*700637cbSDimitry Andricswap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT {
1736*700637cbSDimitry Andric  __x.swap(__y);
1737*700637cbSDimitry Andric}
1738*700637cbSDimitry Andric
1739*700637cbSDimitry Andrictemplate <class _Callable, class _Alloc>
1740*700637cbSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
1741*700637cbSDimitry Andric
1742*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
1743*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) {
1744*700637cbSDimitry Andric  unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1745*700637cbSDimitry Andric      new __deferred_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
1746*700637cbSDimitry Andric  return future<_Rp>(__h.get());
1747*700637cbSDimitry Andric}
1748*700637cbSDimitry Andric
1749*700637cbSDimitry Andrictemplate <class _Rp, class _Fp>
1750*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state(_Fp&& __f) {
1751*700637cbSDimitry Andric  unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h(
1752*700637cbSDimitry Andric      new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
1753*700637cbSDimitry Andric  std::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
1754*700637cbSDimitry Andric  return future<_Rp>(__h.get());
1755*700637cbSDimitry Andric}
1756*700637cbSDimitry Andric
1757*700637cbSDimitry Andric// shared_future
1758*700637cbSDimitry Andric
1759*700637cbSDimitry Andrictemplate <class _Rp>
1760*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future {
1761*700637cbSDimitry Andric  __assoc_state<_Rp>* __state_;
1762*700637cbSDimitry Andric
1763*700637cbSDimitry Andricpublic:
1764*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1765*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1766*700637cbSDimitry Andric    if (__state_)
1767*700637cbSDimitry Andric      __state_->__add_shared();
1768*700637cbSDimitry Andric  }
1769*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1770*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1771*700637cbSDimitry Andric    __rhs.__state_ = nullptr;
1772*700637cbSDimitry Andric  }
1773*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
1774*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
1775*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
1776*700637cbSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
1777*700637cbSDimitry Andric    return *this;
1778*700637cbSDimitry Andric  }
1779*700637cbSDimitry Andric
1780*700637cbSDimitry Andric  // retrieving the value
1781*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const _Rp& get() const { return __state_->copy(); }
1782*700637cbSDimitry Andric
1783*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
1784*700637cbSDimitry Andric
1785*700637cbSDimitry Andric  // functions to check state
1786*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1787*700637cbSDimitry Andric
1788*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
1789*700637cbSDimitry Andric  template <class _Rep, class _Period>
1790*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1791*700637cbSDimitry Andric    return __state_->wait_for(__rel_time);
1792*700637cbSDimitry Andric  }
1793*700637cbSDimitry Andric  template <class _Clock, class _Duration>
1794*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1795*700637cbSDimitry Andric    return __state_->wait_until(__abs_time);
1796*700637cbSDimitry Andric  }
1797*700637cbSDimitry Andric};
1798*700637cbSDimitry Andric
1799*700637cbSDimitry Andrictemplate <class _Rp>
1800*700637cbSDimitry Andricshared_future<_Rp>::~shared_future() {
1801*700637cbSDimitry Andric  if (__state_)
1802*700637cbSDimitry Andric    __state_->__release_shared();
1803*700637cbSDimitry Andric}
1804*700637cbSDimitry Andric
1805*700637cbSDimitry Andrictemplate <class _Rp>
1806*700637cbSDimitry Andricshared_future<_Rp>& shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT {
1807*700637cbSDimitry Andric  if (__rhs.__state_)
1808*700637cbSDimitry Andric    __rhs.__state_->__add_shared();
1809*700637cbSDimitry Andric  if (__state_)
1810*700637cbSDimitry Andric    __state_->__release_shared();
1811*700637cbSDimitry Andric  __state_ = __rhs.__state_;
1812*700637cbSDimitry Andric  return *this;
1813*700637cbSDimitry Andric}
1814*700637cbSDimitry Andric
1815*700637cbSDimitry Andrictemplate <class _Rp>
1816*700637cbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&> {
1817*700637cbSDimitry Andric  __assoc_state<_Rp&>* __state_;
1818*700637cbSDimitry Andric
1819*700637cbSDimitry Andricpublic:
1820*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1821*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1822*700637cbSDimitry Andric    if (__state_)
1823*700637cbSDimitry Andric      __state_->__add_shared();
1824*700637cbSDimitry Andric  }
1825*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1826*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1827*700637cbSDimitry Andric    __rhs.__state_ = nullptr;
1828*700637cbSDimitry Andric  }
1829*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~shared_future();
1830*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs);
1831*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
1832*700637cbSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
1833*700637cbSDimitry Andric    return *this;
1834*700637cbSDimitry Andric  }
1835*700637cbSDimitry Andric
1836*700637cbSDimitry Andric  // retrieving the value
1837*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Rp& get() const { return __state_->copy(); }
1838*700637cbSDimitry Andric
1839*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
1840*700637cbSDimitry Andric
1841*700637cbSDimitry Andric  // functions to check state
1842*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1843*700637cbSDimitry Andric
1844*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
1845*700637cbSDimitry Andric  template <class _Rep, class _Period>
1846*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1847*700637cbSDimitry Andric    return __state_->wait_for(__rel_time);
1848*700637cbSDimitry Andric  }
1849*700637cbSDimitry Andric  template <class _Clock, class _Duration>
1850*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1851*700637cbSDimitry Andric    return __state_->wait_until(__abs_time);
1852*700637cbSDimitry Andric  }
1853*700637cbSDimitry Andric};
1854*700637cbSDimitry Andric
1855*700637cbSDimitry Andrictemplate <class _Rp>
1856*700637cbSDimitry Andricshared_future<_Rp&>::~shared_future() {
1857*700637cbSDimitry Andric  if (__state_)
1858*700637cbSDimitry Andric    __state_->__release_shared();
1859*700637cbSDimitry Andric}
1860*700637cbSDimitry Andric
1861*700637cbSDimitry Andrictemplate <class _Rp>
1862*700637cbSDimitry Andricshared_future<_Rp&>& shared_future<_Rp&>::operator=(const shared_future& __rhs) {
1863*700637cbSDimitry Andric  if (__rhs.__state_)
1864*700637cbSDimitry Andric    __rhs.__state_->__add_shared();
1865*700637cbSDimitry Andric  if (__state_)
1866*700637cbSDimitry Andric    __state_->__release_shared();
1867*700637cbSDimitry Andric  __state_ = __rhs.__state_;
1868*700637cbSDimitry Andric  return *this;
1869*700637cbSDimitry Andric}
1870*700637cbSDimitry Andric
1871*700637cbSDimitry Andrictemplate <>
1872*700637cbSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI shared_future<void> {
1873*700637cbSDimitry Andric  __assoc_sub_state* __state_;
1874*700637cbSDimitry Andric
1875*700637cbSDimitry Andricpublic:
1876*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future() _NOEXCEPT : __state_(nullptr) {}
1877*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) {
1878*700637cbSDimitry Andric    if (__state_)
1879*700637cbSDimitry Andric      __state_->__add_shared();
1880*700637cbSDimitry Andric  }
1881*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_) { __f.__state_ = nullptr; }
1882*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {
1883*700637cbSDimitry Andric    __rhs.__state_ = nullptr;
1884*700637cbSDimitry Andric  }
1885*700637cbSDimitry Andric  ~shared_future();
1886*700637cbSDimitry Andric  shared_future& operator=(const shared_future& __rhs);
1887*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI shared_future& operator=(shared_future&& __rhs) _NOEXCEPT {
1888*700637cbSDimitry Andric    shared_future(std::move(__rhs)).swap(*this);
1889*700637cbSDimitry Andric    return *this;
1890*700637cbSDimitry Andric  }
1891*700637cbSDimitry Andric
1892*700637cbSDimitry Andric  // retrieving the value
1893*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void get() const { __state_->copy(); }
1894*700637cbSDimitry Andric
1895*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(shared_future& __rhs) _NOEXCEPT { std::swap(__state_, __rhs.__state_); }
1896*700637cbSDimitry Andric
1897*700637cbSDimitry Andric  // functions to check state
1898*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool valid() const _NOEXCEPT { return __state_ != nullptr; }
1899*700637cbSDimitry Andric
1900*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void wait() const { __state_->wait(); }
1901*700637cbSDimitry Andric  template <class _Rep, class _Period>
1902*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
1903*700637cbSDimitry Andric    return __state_->wait_for(__rel_time);
1904*700637cbSDimitry Andric  }
1905*700637cbSDimitry Andric  template <class _Clock, class _Duration>
1906*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
1907*700637cbSDimitry Andric    return __state_->wait_until(__abs_time);
1908*700637cbSDimitry Andric  }
1909*700637cbSDimitry Andric};
1910*700637cbSDimitry Andric
1911*700637cbSDimitry Andrictemplate <class _Rp>
1912*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT {
1913*700637cbSDimitry Andric  __x.swap(__y);
1914*700637cbSDimitry Andric}
1915*700637cbSDimitry Andric
1916*700637cbSDimitry Andrictemplate <class _Rp>
1917*700637cbSDimitry Andricinline shared_future<_Rp> future<_Rp>::share() _NOEXCEPT {
1918*700637cbSDimitry Andric  return shared_future<_Rp>(std::move(*this));
1919*700637cbSDimitry Andric}
1920*700637cbSDimitry Andric
1921*700637cbSDimitry Andrictemplate <class _Rp>
1922*700637cbSDimitry Andricinline shared_future<_Rp&> future<_Rp&>::share() _NOEXCEPT {
1923*700637cbSDimitry Andric  return shared_future<_Rp&>(std::move(*this));
1924*700637cbSDimitry Andric}
1925*700637cbSDimitry Andric
1926*700637cbSDimitry Andricinline shared_future<void> future<void>::share() _NOEXCEPT { return shared_future<void>(std::move(*this)); }
1927*700637cbSDimitry Andric
1928*700637cbSDimitry Andric_LIBCPP_END_NAMESPACE_STD
1929*700637cbSDimitry Andric
1930*700637cbSDimitry Andric_LIBCPP_POP_MACROS
1931*700637cbSDimitry Andric
1932*700637cbSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_THREADS)
1933*700637cbSDimitry Andric
1934*700637cbSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
1935*700637cbSDimitry Andric#  include <__cxx03/chrono>
1936*700637cbSDimitry Andric#endif
1937*700637cbSDimitry Andric
1938*700637cbSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
1939*700637cbSDimitry Andric#  include <__cxx03/atomic>
1940*700637cbSDimitry Andric#  include <__cxx03/cstdlib>
1941*700637cbSDimitry Andric#  include <__cxx03/exception>
1942*700637cbSDimitry Andric#  include <__cxx03/iosfwd>
1943*700637cbSDimitry Andric#  include <__cxx03/system_error>
1944*700637cbSDimitry Andric#endif
1945*700637cbSDimitry Andric
1946*700637cbSDimitry Andric#endif // _LIBCPP___CXX03_FUTURE
1947