future revision 253159
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===--------------------------- future -----------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_FUTURE
12227825Stheraven#define _LIBCPP_FUTURE
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    future synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheravenenum class future_errc
21227825Stheraven{
22227825Stheraven    broken_promise,
23227825Stheraven    future_already_retrieved,
24227825Stheraven    promise_already_satisfied,
25227825Stheraven    no_state
26227825Stheraven};
27227825Stheraven
28227825Stheravenenum class launch
29227825Stheraven{
30227825Stheraven    async = 1,
31227825Stheraven    deferred = 2,
32227825Stheraven    any = async | deferred
33227825Stheraven};
34227825Stheraven
35227825Stheravenenum class future_status
36227825Stheraven{
37227825Stheraven    ready,
38227825Stheraven    timeout,
39227825Stheraven    deferred
40227825Stheraven};
41227825Stheraven
42227825Stheraventemplate <> struct is_error_code_enum<future_errc> : public true_type { };
43241903Sdimerror_code make_error_code(future_errc e) noexcept;
44241903Sdimerror_condition make_error_condition(future_errc e) noexcept;
45227825Stheraven
46241903Sdimconst error_category& future_category() noexcept;
47227825Stheraven
48227825Stheravenclass future_error
49227825Stheraven    : public logic_error
50227825Stheraven{
51227825Stheravenpublic:
52227825Stheraven    future_error(error_code ec);  // exposition only
53227825Stheraven
54241903Sdim    const error_code& code() const noexcept;
55241903Sdim    const char*       what() const noexcept;
56227825Stheraven};
57227825Stheraven
58227825Stheraventemplate <class R>
59227825Stheravenclass promise
60227825Stheraven{
61227825Stheravenpublic:
62227825Stheraven    promise();
63227825Stheraven    template <class Allocator>
64227825Stheraven        promise(allocator_arg_t, const Allocator& a);
65241903Sdim    promise(promise&& rhs) noexcept;
66227825Stheraven    promise(const promise& rhs) = delete;
67227825Stheraven    ~promise();
68227825Stheraven
69227825Stheraven    // assignment
70241903Sdim    promise& operator=(promise&& rhs) noexcept;
71227825Stheraven    promise& operator=(const promise& rhs) = delete;
72241903Sdim    void swap(promise& other) noexcept;
73227825Stheraven
74227825Stheraven    // retrieving the result
75227825Stheraven    future<R> get_future();
76227825Stheraven
77227825Stheraven    // setting the result
78227825Stheraven    void set_value(const R& r);
79227825Stheraven    void set_value(R&& r);
80227825Stheraven    void set_exception(exception_ptr p);
81227825Stheraven
82227825Stheraven    // setting the result with deferred notification
83227825Stheraven    void set_value_at_thread_exit(const R& r);
84227825Stheraven    void set_value_at_thread_exit(R&& r);
85227825Stheraven    void set_exception_at_thread_exit(exception_ptr p);
86227825Stheraven};
87227825Stheraven
88227825Stheraventemplate <class R>
89227825Stheravenclass promise<R&>
90227825Stheraven{
91227825Stheravenpublic:
92227825Stheraven    promise();
93227825Stheraven    template <class Allocator>
94227825Stheraven        promise(allocator_arg_t, const Allocator& a);
95241903Sdim    promise(promise&& rhs) noexcept;
96227825Stheraven    promise(const promise& rhs) = delete;
97227825Stheraven    ~promise();
98227825Stheraven
99227825Stheraven    // assignment
100241903Sdim    promise& operator=(promise&& rhs) noexcept;
101227825Stheraven    promise& operator=(const promise& rhs) = delete;
102241903Sdim    void swap(promise& other) noexcept;
103227825Stheraven
104227825Stheraven    // retrieving the result
105227825Stheraven    future<R&> get_future();
106227825Stheraven
107227825Stheraven    // setting the result
108227825Stheraven    void set_value(R& r);
109227825Stheraven    void set_exception(exception_ptr p);
110227825Stheraven
111227825Stheraven    // setting the result with deferred notification
112227825Stheraven    void set_value_at_thread_exit(R&);
113227825Stheraven    void set_exception_at_thread_exit(exception_ptr p);
114227825Stheraven};
115227825Stheraven
116227825Stheraventemplate <>
117227825Stheravenclass promise<void>
118227825Stheraven{
119227825Stheravenpublic:
120227825Stheraven    promise();
121227825Stheraven    template <class Allocator>
122227825Stheraven        promise(allocator_arg_t, const Allocator& a);
123241903Sdim    promise(promise&& rhs) noexcept;
124227825Stheraven    promise(const promise& rhs) = delete;
125227825Stheraven    ~promise();
126227825Stheraven
127227825Stheraven    // assignment
128241903Sdim    promise& operator=(promise&& rhs) noexcept;
129227825Stheraven    promise& operator=(const promise& rhs) = delete;
130241903Sdim    void swap(promise& other) noexcept;
131227825Stheraven
132227825Stheraven    // retrieving the result
133227825Stheraven    future<void> get_future();
134227825Stheraven
135227825Stheraven    // setting the result
136227825Stheraven    void set_value();
137227825Stheraven    void set_exception(exception_ptr p);
138227825Stheraven
139227825Stheraven    // setting the result with deferred notification
140227825Stheraven    void set_value_at_thread_exit();
141227825Stheraven    void set_exception_at_thread_exit(exception_ptr p);
142227825Stheraven};
143227825Stheraven
144241903Sdimtemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
145227825Stheraven
146227825Stheraventemplate <class R, class Alloc>
147227825Stheraven    struct uses_allocator<promise<R>, Alloc> : public true_type {};
148227825Stheraven
149227825Stheraventemplate <class R>
150227825Stheravenclass future
151227825Stheraven{
152227825Stheravenpublic:
153241903Sdim    future() noexcept;
154241903Sdim    future(future&&) noexcept;
155227825Stheraven    future(const future& rhs) = delete;
156227825Stheraven    ~future();
157227825Stheraven    future& operator=(const future& rhs) = delete;
158241903Sdim    future& operator=(future&&) noexcept;
159241903Sdim    shared_future<R> share();
160227825Stheraven
161227825Stheraven    // retrieving the value
162227825Stheraven    R get();
163227825Stheraven
164227825Stheraven    // functions to check state
165241903Sdim    bool valid() const noexcept;
166227825Stheraven
167227825Stheraven    void wait() const;
168227825Stheraven    template <class Rep, class Period>
169227825Stheraven        future_status
170227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171227825Stheraven    template <class Clock, class Duration>
172227825Stheraven        future_status
173227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174227825Stheraven};
175227825Stheraven
176227825Stheraventemplate <class R>
177227825Stheravenclass future<R&>
178227825Stheraven{
179227825Stheravenpublic:
180241903Sdim    future() noexcept;
181241903Sdim    future(future&&) noexcept;
182227825Stheraven    future(const future& rhs) = delete;
183227825Stheraven    ~future();
184227825Stheraven    future& operator=(const future& rhs) = delete;
185241903Sdim    future& operator=(future&&) noexcept;
186241903Sdim    shared_future<R&> share();
187227825Stheraven
188227825Stheraven    // retrieving the value
189227825Stheraven    R& get();
190227825Stheraven
191227825Stheraven    // functions to check state
192241903Sdim    bool valid() const noexcept;
193227825Stheraven
194227825Stheraven    void wait() const;
195227825Stheraven    template <class Rep, class Period>
196227825Stheraven        future_status
197227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198227825Stheraven    template <class Clock, class Duration>
199227825Stheraven        future_status
200227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201227825Stheraven};
202227825Stheraven
203227825Stheraventemplate <>
204227825Stheravenclass future<void>
205227825Stheraven{
206227825Stheravenpublic:
207241903Sdim    future() noexcept;
208241903Sdim    future(future&&) noexcept;
209227825Stheraven    future(const future& rhs) = delete;
210227825Stheraven    ~future();
211227825Stheraven    future& operator=(const future& rhs) = delete;
212241903Sdim    future& operator=(future&&) noexcept;
213241903Sdim    shared_future<void> share();
214227825Stheraven
215227825Stheraven    // retrieving the value
216227825Stheraven    void get();
217227825Stheraven
218227825Stheraven    // functions to check state
219241903Sdim    bool valid() const noexcept;
220227825Stheraven
221227825Stheraven    void wait() const;
222227825Stheraven    template <class Rep, class Period>
223227825Stheraven        future_status
224227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225227825Stheraven    template <class Clock, class Duration>
226227825Stheraven        future_status
227227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228227825Stheraven};
229227825Stheraven
230227825Stheraventemplate <class R>
231227825Stheravenclass shared_future
232227825Stheraven{
233227825Stheravenpublic:
234241903Sdim    shared_future() noexcept;
235227825Stheraven    shared_future(const shared_future& rhs);
236241903Sdim    shared_future(future<R>&&) noexcept;
237241903Sdim    shared_future(shared_future&& rhs) noexcept;
238227825Stheraven    ~shared_future();
239227825Stheraven    shared_future& operator=(const shared_future& rhs);
240241903Sdim    shared_future& operator=(shared_future&& rhs) noexcept;
241227825Stheraven
242227825Stheraven    // retrieving the value
243227825Stheraven    const R& get() const;
244227825Stheraven
245227825Stheraven    // functions to check state
246241903Sdim    bool valid() const noexcept;
247227825Stheraven
248227825Stheraven    void wait() const;
249227825Stheraven    template <class Rep, class Period>
250227825Stheraven        future_status
251227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252227825Stheraven    template <class Clock, class Duration>
253227825Stheraven        future_status
254227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255227825Stheraven};
256227825Stheraven
257227825Stheraventemplate <class R>
258227825Stheravenclass shared_future<R&>
259227825Stheraven{
260227825Stheravenpublic:
261241903Sdim    shared_future() noexcept;
262227825Stheraven    shared_future(const shared_future& rhs);
263241903Sdim    shared_future(future<R&>&&) noexcept;
264241903Sdim    shared_future(shared_future&& rhs) noexcept;
265227825Stheraven    ~shared_future();
266227825Stheraven    shared_future& operator=(const shared_future& rhs);
267241903Sdim    shared_future& operator=(shared_future&& rhs) noexcept;
268227825Stheraven
269227825Stheraven    // retrieving the value
270227825Stheraven    R& get() const;
271227825Stheraven
272227825Stheraven    // functions to check state
273241903Sdim    bool valid() const noexcept;
274227825Stheraven
275227825Stheraven    void wait() const;
276227825Stheraven    template <class Rep, class Period>
277227825Stheraven        future_status
278227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279227825Stheraven    template <class Clock, class Duration>
280227825Stheraven        future_status
281227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282227825Stheraven};
283227825Stheraven
284227825Stheraventemplate <>
285227825Stheravenclass shared_future<void>
286227825Stheraven{
287227825Stheravenpublic:
288241903Sdim    shared_future() noexcept;
289227825Stheraven    shared_future(const shared_future& rhs);
290241903Sdim    shared_future(future<void>&&) noexcept;
291241903Sdim    shared_future(shared_future&& rhs) noexcept;
292227825Stheraven    ~shared_future();
293227825Stheraven    shared_future& operator=(const shared_future& rhs);
294241903Sdim    shared_future& operator=(shared_future&& rhs) noexcept;
295227825Stheraven
296227825Stheraven    // retrieving the value
297227825Stheraven    void get() const;
298227825Stheraven
299227825Stheraven    // functions to check state
300241903Sdim    bool valid() const noexcept;
301227825Stheraven
302227825Stheraven    void wait() const;
303227825Stheraven    template <class Rep, class Period>
304227825Stheraven        future_status
305227825Stheraven        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306227825Stheraven    template <class Clock, class Duration>
307227825Stheraven        future_status
308227825Stheraven        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309227825Stheraven};
310227825Stheraven
311227825Stheraventemplate <class F, class... Args>
312227825Stheraven  future<typename result_of<F(Args...)>::type>
313227825Stheraven  async(F&& f, Args&&... args);
314227825Stheraven
315227825Stheraventemplate <class F, class... Args>
316227825Stheraven  future<typename result_of<F(Args...)>::type>
317227825Stheraven  async(launch policy, F&& f, Args&&... args);
318227825Stheraven
319227825Stheraventemplate <class> class packaged_task; // undefined
320227825Stheraven
321227825Stheraventemplate <class R, class... ArgTypes>
322227825Stheravenclass packaged_task<R(ArgTypes...)>
323227825Stheraven{
324227825Stheravenpublic:
325227825Stheraven    typedef R result_type;
326227825Stheraven
327227825Stheraven    // construction and destruction
328241903Sdim    packaged_task() noexcept;
329227825Stheraven    template <class F>
330227825Stheraven        explicit packaged_task(F&& f);
331227825Stheraven    template <class F, class Allocator>
332227825Stheraven        explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333227825Stheraven    ~packaged_task();
334227825Stheraven
335227825Stheraven    // no copy
336241903Sdim    packaged_task(const packaged_task&) = delete;
337241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
338227825Stheraven
339227825Stheraven    // move support
340241903Sdim    packaged_task(packaged_task&& other) noexcept;
341241903Sdim    packaged_task& operator=(packaged_task&& other) noexcept;
342241903Sdim    void swap(packaged_task& other) noexcept;
343227825Stheraven
344241903Sdim    bool valid() const noexcept;
345227825Stheraven
346227825Stheraven    // result retrieval
347227825Stheraven    future<R> get_future();
348227825Stheraven
349227825Stheraven    // execution
350227825Stheraven    void operator()(ArgTypes... );
351227825Stheraven    void make_ready_at_thread_exit(ArgTypes...);
352227825Stheraven
353227825Stheraven    void reset();
354227825Stheraven};
355227825Stheraven
356227825Stheraventemplate <class R>
357241903Sdim  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
358227825Stheraven
359227825Stheraventemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360227825Stheraven
361227825Stheraven}  // std
362227825Stheraven
363227825Stheraven*/
364227825Stheraven
365227825Stheraven#include <__config>
366227825Stheraven#include <system_error>
367227825Stheraven#include <memory>
368227825Stheraven#include <chrono>
369227825Stheraven#include <exception>
370227825Stheraven#include <mutex>
371227825Stheraven#include <thread>
372227825Stheraven
373227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
374227825Stheraven#pragma GCC system_header
375227825Stheraven#endif
376227825Stheraven
377227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
378227825Stheraven
379227825Stheraven//enum class future_errc
380232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
381227825Stheraven{
382227825Stheraven    broken_promise,
383227825Stheraven    future_already_retrieved,
384227825Stheraven    promise_already_satisfied,
385227825Stheraven    no_state
386227825Stheraven};
387232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
388227825Stheraven
389227825Stheraventemplate <>
390249998Sdimstruct _LIBCPP_TYPE_VIS is_error_code_enum<future_errc> : public true_type {};
391227825Stheraven
392232950Stheraven#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
393232950Stheraventemplate <>
394249998Sdimstruct _LIBCPP_TYPE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
395232950Stheraven#endif
396232950Stheraven
397227825Stheraven//enum class launch
398232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(launch)
399227825Stheraven{
400227825Stheraven    async = 1,
401227825Stheraven    deferred = 2,
402227825Stheraven    any = async | deferred
403227825Stheraven};
404232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
405227825Stheraven
406253159Stheraven#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
407253159Stheraven
408253159Stheraven#ifdef _LIBCXX_UNDERLYING_TYPE
409253159Stheraventypedef underlying_type<launch>::type __launch_underlying_type;
410253159Stheraven#else
411253159Stheraventypedef int __launch_underlying_type;
412253159Stheraven#endif
413253159Stheraven
414253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
415253159Stheraven_LIBCPP_CONSTEXPR
416253159Stheravenlaunch
417253159Stheravenoperator&(launch __x, launch __y)
418253159Stheraven{
419253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
420253159Stheraven                               static_cast<__launch_underlying_type>(__y));
421253159Stheraven}
422253159Stheraven
423253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
424253159Stheraven_LIBCPP_CONSTEXPR
425253159Stheravenlaunch
426253159Stheravenoperator|(launch __x, launch __y)
427253159Stheraven{
428253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
429253159Stheraven                               static_cast<__launch_underlying_type>(__y));
430253159Stheraven}
431253159Stheraven
432253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
433253159Stheraven_LIBCPP_CONSTEXPR
434253159Stheravenlaunch
435253159Stheravenoperator^(launch __x, launch __y)
436253159Stheraven{
437253159Stheraven    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
438253159Stheraven                               static_cast<__launch_underlying_type>(__y));
439253159Stheraven}
440253159Stheraven
441253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
442253159Stheraven_LIBCPP_CONSTEXPR
443253159Stheravenlaunch
444253159Stheravenoperator~(launch __x)
445253159Stheraven{
446253159Stheraven    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
447253159Stheraven}
448253159Stheraven
449253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
450253159Stheravenlaunch&
451253159Stheravenoperator&=(launch& __x, launch __y)
452253159Stheraven{
453253159Stheraven    __x = __x & __y; return __x;
454253159Stheraven}
455253159Stheraven
456253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
457253159Stheravenlaunch&
458253159Stheravenoperator|=(launch& __x, launch __y)
459253159Stheraven{
460253159Stheraven    __x = __x | __y; return __x;
461253159Stheraven}
462253159Stheraven
463253159Stheraveninline _LIBCPP_INLINE_VISIBILITY
464253159Stheravenlaunch&
465253159Stheravenoperator^=(launch& __x, launch __y)
466253159Stheraven{
467253159Stheraven    __x = __x ^ __y; return __x;
468253159Stheraven}
469253159Stheraven
470253159Stheraven#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
471253159Stheraven
472227825Stheraven//enum class future_status
473232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_status)
474227825Stheraven{
475227825Stheraven    ready,
476227825Stheraven    timeout,
477227825Stheraven    deferred
478227825Stheraven};
479232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
480227825Stheraven
481249998Sdim_LIBCPP_FUNC_VIS
482241903Sdimconst error_category& future_category() _NOEXCEPT;
483227825Stheraven
484227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
485227825Stheravenerror_code
486241903Sdimmake_error_code(future_errc __e) _NOEXCEPT
487227825Stheraven{
488227825Stheraven    return error_code(static_cast<int>(__e), future_category());
489227825Stheraven}
490227825Stheraven
491227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
492227825Stheravenerror_condition
493241903Sdimmake_error_condition(future_errc __e) _NOEXCEPT
494227825Stheraven{
495227825Stheraven    return error_condition(static_cast<int>(__e), future_category());
496227825Stheraven}
497227825Stheraven
498227825Stheravenclass _LIBCPP_EXCEPTION_ABI future_error
499227825Stheraven    : public logic_error
500227825Stheraven{
501227825Stheraven    error_code __ec_;
502227825Stheravenpublic:
503227825Stheraven    future_error(error_code __ec);
504227825Stheraven
505227825Stheraven    _LIBCPP_INLINE_VISIBILITY
506241903Sdim    const error_code& code() const _NOEXCEPT {return __ec_;}
507227825Stheraven
508227825Stheraven    virtual ~future_error() _NOEXCEPT;
509227825Stheraven};
510227825Stheraven
511227825Stheravenclass __assoc_sub_state
512227825Stheraven    : public __shared_count
513227825Stheraven{
514227825Stheravenprotected:
515227825Stheraven    exception_ptr __exception_;
516227825Stheraven    mutable mutex __mut_;
517227825Stheraven    mutable condition_variable __cv_;
518227825Stheraven    unsigned __state_;
519227825Stheraven
520227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
521227825Stheraven    void __sub_wait(unique_lock<mutex>& __lk);
522227825Stheravenpublic:
523227825Stheraven    enum
524227825Stheraven    {
525227825Stheraven        __constructed = 1,
526227825Stheraven        __future_attached = 2,
527227825Stheraven        ready = 4,
528227825Stheraven        deferred = 8
529227825Stheraven    };
530227825Stheraven
531227825Stheraven    _LIBCPP_INLINE_VISIBILITY
532227825Stheraven    __assoc_sub_state() : __state_(0) {}
533227825Stheraven
534227825Stheraven    _LIBCPP_INLINE_VISIBILITY
535227825Stheraven    bool __has_value() const
536227825Stheraven        {return (__state_ & __constructed) || (__exception_ != nullptr);}
537227825Stheraven
538227825Stheraven    _LIBCPP_INLINE_VISIBILITY
539246487Stheraven    void __set_future_attached()
540246487Stheraven    {
541246487Stheraven        lock_guard<mutex> __lk(__mut_);
542246487Stheraven        __state_ |= __future_attached;
543246487Stheraven    }
544227825Stheraven    _LIBCPP_INLINE_VISIBILITY
545227825Stheraven    bool __has_future_attached() const {return __state_ & __future_attached;}
546227825Stheraven
547227825Stheraven    _LIBCPP_INLINE_VISIBILITY
548227825Stheraven    void __set_deferred() {__state_ |= deferred;}
549227825Stheraven
550227825Stheraven    void __make_ready();
551227825Stheraven    _LIBCPP_INLINE_VISIBILITY
552227825Stheraven    bool __is_ready() const {return __state_ & ready;}
553227825Stheraven
554227825Stheraven    void set_value();
555227825Stheraven    void set_value_at_thread_exit();
556227825Stheraven
557227825Stheraven    void set_exception(exception_ptr __p);
558227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
559227825Stheraven
560227825Stheraven    void copy();
561227825Stheraven
562227825Stheraven    void wait();
563227825Stheraven    template <class _Rep, class _Period>
564227825Stheraven        future_status
565227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
566227825Stheraven    template <class _Clock, class _Duration>
567227825Stheraven        future_status
568227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
569227825Stheraven
570227825Stheraven    virtual void __execute();
571227825Stheraven};
572227825Stheraven
573227825Stheraventemplate <class _Clock, class _Duration>
574227825Stheravenfuture_status
575227825Stheraven__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
576227825Stheraven{
577227825Stheraven    unique_lock<mutex> __lk(__mut_);
578227825Stheraven    if (__state_ & deferred)
579227825Stheraven        return future_status::deferred;
580227825Stheraven    while (!(__state_ & ready) && _Clock::now() < __abs_time)
581227825Stheraven        __cv_.wait_until(__lk, __abs_time);
582227825Stheraven    if (__state_ & ready)
583227825Stheraven        return future_status::ready;
584227825Stheraven    return future_status::timeout;
585227825Stheraven}
586227825Stheraven
587227825Stheraventemplate <class _Rep, class _Period>
588227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
589227825Stheravenfuture_status
590227825Stheraven__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
591227825Stheraven{
592227825Stheraven    return wait_until(chrono::steady_clock::now() + __rel_time);
593227825Stheraven}
594227825Stheraven
595232950Stheraventemplate <class _Rp>
596227825Stheravenclass __assoc_state
597227825Stheraven    : public __assoc_sub_state
598227825Stheraven{
599227825Stheraven    typedef __assoc_sub_state base;
600232950Stheraven    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
601227825Stheravenprotected:
602232950Stheraven    _Up __value_;
603227825Stheraven
604227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
605227825Stheravenpublic:
606227825Stheraven
607227825Stheraven    template <class _Arg>
608227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
609227825Stheraven        void set_value(_Arg&& __arg);
610227825Stheraven#else
611227825Stheraven        void set_value(_Arg& __arg);
612227825Stheraven#endif
613227825Stheraven
614227825Stheraven    template <class _Arg>
615227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
616227825Stheraven        void set_value_at_thread_exit(_Arg&& __arg);
617227825Stheraven#else
618227825Stheraven        void set_value_at_thread_exit(_Arg& __arg);
619227825Stheraven#endif
620227825Stheraven
621232950Stheraven    _Rp move();
622232950Stheraven    typename add_lvalue_reference<_Rp>::type copy();
623227825Stheraven};
624227825Stheraven
625232950Stheraventemplate <class _Rp>
626227825Stheravenvoid
627232950Stheraven__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
628227825Stheraven{
629227825Stheraven    if (this->__state_ & base::__constructed)
630232950Stheraven        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
631227825Stheraven    delete this;
632227825Stheraven}
633227825Stheraven
634232950Stheraventemplate <class _Rp>
635227825Stheraventemplate <class _Arg>
636227825Stheravenvoid
637227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
638232950Stheraven__assoc_state<_Rp>::set_value(_Arg&& __arg)
639227825Stheraven#else
640232950Stheraven__assoc_state<_Rp>::set_value(_Arg& __arg)
641227825Stheraven#endif
642227825Stheraven{
643227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
644227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
645227825Stheraven    if (this->__has_value())
646227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
647227825Stheraven#endif
648232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
649227825Stheraven    this->__state_ |= base::__constructed | base::ready;
650227825Stheraven    __lk.unlock();
651227825Stheraven    __cv_.notify_all();
652227825Stheraven}
653227825Stheraven
654232950Stheraventemplate <class _Rp>
655227825Stheraventemplate <class _Arg>
656227825Stheravenvoid
657227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
658232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
659227825Stheraven#else
660232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
661227825Stheraven#endif
662227825Stheraven{
663227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
664227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
665227825Stheraven    if (this->__has_value())
666227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
667227825Stheraven#endif
668232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
669227825Stheraven    this->__state_ |= base::__constructed;
670227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
671227825Stheraven    __lk.unlock();
672227825Stheraven}
673227825Stheraven
674232950Stheraventemplate <class _Rp>
675232950Stheraven_Rp
676232950Stheraven__assoc_state<_Rp>::move()
677227825Stheraven{
678227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
679227825Stheraven    this->__sub_wait(__lk);
680227825Stheraven    if (this->__exception_ != nullptr)
681227825Stheraven        rethrow_exception(this->__exception_);
682232950Stheraven    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
683227825Stheraven}
684227825Stheraven
685232950Stheraventemplate <class _Rp>
686232950Stheraventypename add_lvalue_reference<_Rp>::type
687232950Stheraven__assoc_state<_Rp>::copy()
688227825Stheraven{
689227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
690227825Stheraven    this->__sub_wait(__lk);
691227825Stheraven    if (this->__exception_ != nullptr)
692227825Stheraven        rethrow_exception(this->__exception_);
693232950Stheraven    return *reinterpret_cast<_Rp*>(&__value_);
694227825Stheraven}
695227825Stheraven
696232950Stheraventemplate <class _Rp>
697232950Stheravenclass __assoc_state<_Rp&>
698227825Stheraven    : public __assoc_sub_state
699227825Stheraven{
700227825Stheraven    typedef __assoc_sub_state base;
701232950Stheraven    typedef _Rp* _Up;
702227825Stheravenprotected:
703232950Stheraven    _Up __value_;
704227825Stheraven
705227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
706227825Stheravenpublic:
707227825Stheraven
708232950Stheraven    void set_value(_Rp& __arg);
709232950Stheraven    void set_value_at_thread_exit(_Rp& __arg);
710227825Stheraven
711232950Stheraven    _Rp& copy();
712227825Stheraven};
713227825Stheraven
714232950Stheraventemplate <class _Rp>
715227825Stheravenvoid
716232950Stheraven__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
717227825Stheraven{
718227825Stheraven    delete this;
719227825Stheraven}
720227825Stheraven
721232950Stheraventemplate <class _Rp>
722227825Stheravenvoid
723232950Stheraven__assoc_state<_Rp&>::set_value(_Rp& __arg)
724227825Stheraven{
725227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
726227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
727227825Stheraven    if (this->__has_value())
728227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
729227825Stheraven#endif
730227825Stheraven    __value_ = &__arg;
731227825Stheraven    this->__state_ |= base::__constructed | base::ready;
732227825Stheraven    __lk.unlock();
733227825Stheraven    __cv_.notify_all();
734227825Stheraven}
735227825Stheraven
736232950Stheraventemplate <class _Rp>
737227825Stheravenvoid
738232950Stheraven__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
739227825Stheraven{
740227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
741227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
742227825Stheraven    if (this->__has_value())
743227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
744227825Stheraven#endif
745227825Stheraven    __value_ = &__arg;
746227825Stheraven    this->__state_ |= base::__constructed;
747227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
748227825Stheraven    __lk.unlock();
749227825Stheraven}
750227825Stheraven
751232950Stheraventemplate <class _Rp>
752232950Stheraven_Rp&
753232950Stheraven__assoc_state<_Rp&>::copy()
754227825Stheraven{
755227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
756227825Stheraven    this->__sub_wait(__lk);
757227825Stheraven    if (this->__exception_ != nullptr)
758227825Stheraven        rethrow_exception(this->__exception_);
759227825Stheraven    return *__value_;
760227825Stheraven}
761227825Stheraven
762232950Stheraventemplate <class _Rp, class _Alloc>
763227825Stheravenclass __assoc_state_alloc
764232950Stheraven    : public __assoc_state<_Rp>
765227825Stheraven{
766232950Stheraven    typedef __assoc_state<_Rp> base;
767227825Stheraven    _Alloc __alloc_;
768227825Stheraven
769227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
770227825Stheravenpublic:
771227825Stheraven    _LIBCPP_INLINE_VISIBILITY
772227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
773227825Stheraven        : __alloc_(__a) {}
774227825Stheraven};
775227825Stheraven
776232950Stheraventemplate <class _Rp, class _Alloc>
777227825Stheravenvoid
778232950Stheraven__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
779227825Stheraven{
780227825Stheraven    if (this->__state_ & base::__constructed)
781232950Stheraven        reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
782227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
783227825Stheraven    this->~__assoc_state_alloc();
784227825Stheraven    __a.deallocate(this, 1);
785227825Stheraven}
786227825Stheraven
787232950Stheraventemplate <class _Rp, class _Alloc>
788232950Stheravenclass __assoc_state_alloc<_Rp&, _Alloc>
789232950Stheraven    : public __assoc_state<_Rp&>
790227825Stheraven{
791232950Stheraven    typedef __assoc_state<_Rp&> base;
792227825Stheraven    _Alloc __alloc_;
793227825Stheraven
794227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
795227825Stheravenpublic:
796227825Stheraven    _LIBCPP_INLINE_VISIBILITY
797227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
798227825Stheraven        : __alloc_(__a) {}
799227825Stheraven};
800227825Stheraven
801232950Stheraventemplate <class _Rp, class _Alloc>
802227825Stheravenvoid
803232950Stheraven__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
804227825Stheraven{
805227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
806227825Stheraven    this->~__assoc_state_alloc();
807227825Stheraven    __a.deallocate(this, 1);
808227825Stheraven}
809227825Stheraven
810227825Stheraventemplate <class _Alloc>
811227825Stheravenclass __assoc_sub_state_alloc
812227825Stheraven    : public __assoc_sub_state
813227825Stheraven{
814227825Stheraven    typedef __assoc_sub_state base;
815227825Stheraven    _Alloc __alloc_;
816227825Stheraven
817227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
818227825Stheravenpublic:
819227825Stheraven    _LIBCPP_INLINE_VISIBILITY
820227825Stheraven    explicit __assoc_sub_state_alloc(const _Alloc& __a)
821227825Stheraven        : __alloc_(__a) {}
822227825Stheraven};
823227825Stheraven
824227825Stheraventemplate <class _Alloc>
825227825Stheravenvoid
826227825Stheraven__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
827227825Stheraven{
828227825Stheraven    typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
829227825Stheraven    this->~__assoc_sub_state_alloc();
830227825Stheraven    __a.deallocate(this, 1);
831227825Stheraven}
832227825Stheraven
833232950Stheraventemplate <class _Rp, class _Fp>
834227825Stheravenclass __deferred_assoc_state
835232950Stheraven    : public __assoc_state<_Rp>
836227825Stheraven{
837232950Stheraven    typedef __assoc_state<_Rp> base;
838227825Stheraven
839232950Stheraven    _Fp __func_;
840227825Stheraven
841227825Stheravenpublic:
842227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
843232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
844227825Stheraven#endif
845227825Stheraven
846227825Stheraven    virtual void __execute();
847227825Stheraven};
848227825Stheraven
849227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
850227825Stheraven
851232950Stheraventemplate <class _Rp, class _Fp>
852227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
853232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
854232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
855227825Stheraven{
856227825Stheraven    this->__set_deferred();
857227825Stheraven}
858227825Stheraven
859227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
860227825Stheraven
861232950Stheraventemplate <class _Rp, class _Fp>
862227825Stheravenvoid
863232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__execute()
864227825Stheraven{
865227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
866227825Stheraven    try
867227825Stheraven    {
868227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
869227825Stheraven        this->set_value(__func_());
870227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
871227825Stheraven    }
872227825Stheraven    catch (...)
873227825Stheraven    {
874227825Stheraven        this->set_exception(current_exception());
875227825Stheraven    }
876227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
877227825Stheraven}
878227825Stheraven
879232950Stheraventemplate <class _Fp>
880232950Stheravenclass __deferred_assoc_state<void, _Fp>
881227825Stheraven    : public __assoc_sub_state
882227825Stheraven{
883227825Stheraven    typedef __assoc_sub_state base;
884227825Stheraven
885232950Stheraven    _Fp __func_;
886227825Stheraven
887227825Stheravenpublic:
888227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
889232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
890227825Stheraven#endif
891227825Stheraven
892227825Stheraven    virtual void __execute();
893227825Stheraven};
894227825Stheraven
895227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
896227825Stheraven
897232950Stheraventemplate <class _Fp>
898227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
899232950Stheraven__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
900232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
901227825Stheraven{
902227825Stheraven    this->__set_deferred();
903227825Stheraven}
904227825Stheraven
905227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
906227825Stheraven
907232950Stheraventemplate <class _Fp>
908227825Stheravenvoid
909232950Stheraven__deferred_assoc_state<void, _Fp>::__execute()
910227825Stheraven{
911227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
912227825Stheraven    try
913227825Stheraven    {
914227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
915227825Stheraven        __func_();
916227825Stheraven        this->set_value();
917227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
918227825Stheraven    }
919227825Stheraven    catch (...)
920227825Stheraven    {
921227825Stheraven        this->set_exception(current_exception());
922227825Stheraven    }
923227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
924227825Stheraven}
925227825Stheraven
926232950Stheraventemplate <class _Rp, class _Fp>
927227825Stheravenclass __async_assoc_state
928232950Stheraven    : public __assoc_state<_Rp>
929227825Stheraven{
930232950Stheraven    typedef __assoc_state<_Rp> base;
931227825Stheraven
932232950Stheraven    _Fp __func_;
933227825Stheraven
934227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
935227825Stheravenpublic:
936227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
937232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
938227825Stheraven#endif
939227825Stheraven
940227825Stheraven    virtual void __execute();
941227825Stheraven};
942227825Stheraven
943227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
944227825Stheraven
945232950Stheraventemplate <class _Rp, class _Fp>
946227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
947232950Stheraven__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
948232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
949227825Stheraven{
950227825Stheraven}
951227825Stheraven
952227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
953227825Stheraven
954232950Stheraventemplate <class _Rp, class _Fp>
955227825Stheravenvoid
956232950Stheraven__async_assoc_state<_Rp, _Fp>::__execute()
957227825Stheraven{
958227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
959227825Stheraven    try
960227825Stheraven    {
961227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
962227825Stheraven        this->set_value(__func_());
963227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
964227825Stheraven    }
965227825Stheraven    catch (...)
966227825Stheraven    {
967227825Stheraven        this->set_exception(current_exception());
968227825Stheraven    }
969227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
970227825Stheraven}
971227825Stheraven
972232950Stheraventemplate <class _Rp, class _Fp>
973227825Stheravenvoid
974232950Stheraven__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
975227825Stheraven{
976227825Stheraven    this->wait();
977227825Stheraven    base::__on_zero_shared();
978227825Stheraven}
979227825Stheraven
980232950Stheraventemplate <class _Fp>
981232950Stheravenclass __async_assoc_state<void, _Fp>
982227825Stheraven    : public __assoc_sub_state
983227825Stheraven{
984227825Stheraven    typedef __assoc_sub_state base;
985227825Stheraven
986232950Stheraven    _Fp __func_;
987227825Stheraven
988227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
989227825Stheravenpublic:
990227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
991232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
992227825Stheraven#endif
993227825Stheraven
994227825Stheraven    virtual void __execute();
995227825Stheraven};
996227825Stheraven
997227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
998227825Stheraven
999232950Stheraventemplate <class _Fp>
1000227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1001232950Stheraven__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1002232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
1003227825Stheraven{
1004227825Stheraven}
1005227825Stheraven
1006227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1007227825Stheraven
1008232950Stheraventemplate <class _Fp>
1009227825Stheravenvoid
1010232950Stheraven__async_assoc_state<void, _Fp>::__execute()
1011227825Stheraven{
1012227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1013227825Stheraven    try
1014227825Stheraven    {
1015227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
1016227825Stheraven        __func_();
1017227825Stheraven        this->set_value();
1018227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1019227825Stheraven    }
1020227825Stheraven    catch (...)
1021227825Stheraven    {
1022227825Stheraven        this->set_exception(current_exception());
1023227825Stheraven    }
1024227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
1025227825Stheraven}
1026227825Stheraven
1027232950Stheraventemplate <class _Fp>
1028227825Stheravenvoid
1029232950Stheraven__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
1030227825Stheraven{
1031227825Stheraven    this->wait();
1032227825Stheraven    base::__on_zero_shared();
1033227825Stheraven}
1034227825Stheraven
1035249998Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS promise;
1036249998Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS shared_future;
1037227825Stheraven
1038227825Stheraven// future
1039227825Stheraven
1040249998Sdimtemplate <class _Rp> class _LIBCPP_TYPE_VIS future;
1041227825Stheraven
1042232950Stheraventemplate <class _Rp, class _Fp>
1043232950Stheravenfuture<_Rp>
1044227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1045232950Stheraven__make_deferred_assoc_state(_Fp&& __f);
1046227825Stheraven#else
1047232950Stheraven__make_deferred_assoc_state(_Fp __f);
1048227825Stheraven#endif
1049227825Stheraven
1050232950Stheraventemplate <class _Rp, class _Fp>
1051232950Stheravenfuture<_Rp>
1052227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1053232950Stheraven__make_async_assoc_state(_Fp&& __f);
1054227825Stheraven#else
1055232950Stheraven__make_async_assoc_state(_Fp __f);
1056227825Stheraven#endif
1057227825Stheraven
1058232950Stheraventemplate <class _Rp>
1059249998Sdimclass _LIBCPP_TYPE_VIS future
1060227825Stheraven{
1061232950Stheraven    __assoc_state<_Rp>* __state_;
1062227825Stheraven
1063232950Stheraven    explicit future(__assoc_state<_Rp>* __state);
1064227825Stheraven
1065227825Stheraven    template <class> friend class promise;
1066227825Stheraven    template <class> friend class shared_future;
1067227825Stheraven
1068227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1069232950Stheraven    template <class _R1, class _Fp>
1070232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1071232950Stheraven    template <class _R1, class _Fp>
1072232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1073227825Stheraven#else
1074232950Stheraven    template <class _R1, class _Fp>
1075232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1076232950Stheraven    template <class _R1, class _Fp>
1077232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1078227825Stheraven#endif
1079227825Stheraven
1080227825Stheravenpublic:
1081227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1082241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1083227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1084227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1085241903Sdim    future(future&& __rhs) _NOEXCEPT
1086227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1087227825Stheraven    future(const future&) = delete;
1088227825Stheraven    future& operator=(const future&) = delete;
1089227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1090241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1091227825Stheraven        {
1092227825Stheraven            future(std::move(__rhs)).swap(*this);
1093227825Stheraven            return *this;
1094227825Stheraven        }
1095227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1096227825Stheravenprivate:
1097227825Stheraven    future(const future&);
1098227825Stheraven    future& operator=(const future&);
1099227825Stheravenpublic:
1100227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1101227825Stheraven    ~future();
1102232950Stheraven    shared_future<_Rp> share();
1103227825Stheraven
1104227825Stheraven    // retrieving the value
1105232950Stheraven    _Rp get();
1106227825Stheraven
1107227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1108241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1109227825Stheraven
1110227825Stheraven    // functions to check state
1111227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1112241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1113227825Stheraven
1114227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1115227825Stheraven    void wait() const {__state_->wait();}
1116227825Stheraven    template <class _Rep, class _Period>
1117227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1118227825Stheraven        future_status
1119227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1120227825Stheraven            {return __state_->wait_for(__rel_time);}
1121227825Stheraven    template <class _Clock, class _Duration>
1122227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1123227825Stheraven        future_status
1124227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1125227825Stheraven            {return __state_->wait_until(__abs_time);}
1126227825Stheraven};
1127227825Stheraven
1128232950Stheraventemplate <class _Rp>
1129232950Stheravenfuture<_Rp>::future(__assoc_state<_Rp>* __state)
1130227825Stheraven    : __state_(__state)
1131227825Stheraven{
1132227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1133227825Stheraven    if (__state_->__has_future_attached())
1134227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1135227825Stheraven#endif
1136227825Stheraven    __state_->__add_shared();
1137227825Stheraven    __state_->__set_future_attached();
1138227825Stheraven}
1139227825Stheraven
1140227825Stheravenstruct __release_shared_count
1141227825Stheraven{
1142227825Stheraven    void operator()(__shared_count* p) {p->__release_shared();}
1143227825Stheraven};
1144227825Stheraven
1145232950Stheraventemplate <class _Rp>
1146232950Stheravenfuture<_Rp>::~future()
1147227825Stheraven{
1148227825Stheraven    if (__state_)
1149227825Stheraven        __state_->__release_shared();
1150227825Stheraven}
1151227825Stheraven
1152232950Stheraventemplate <class _Rp>
1153232950Stheraven_Rp
1154232950Stheravenfuture<_Rp>::get()
1155227825Stheraven{
1156227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1157232950Stheraven    __assoc_state<_Rp>* __s = __state_;
1158227825Stheraven    __state_ = nullptr;
1159227825Stheraven    return __s->move();
1160227825Stheraven}
1161227825Stheraven
1162232950Stheraventemplate <class _Rp>
1163249998Sdimclass _LIBCPP_TYPE_VIS future<_Rp&>
1164227825Stheraven{
1165232950Stheraven    __assoc_state<_Rp&>* __state_;
1166227825Stheraven
1167232950Stheraven    explicit future(__assoc_state<_Rp&>* __state);
1168227825Stheraven
1169227825Stheraven    template <class> friend class promise;
1170227825Stheraven    template <class> friend class shared_future;
1171227825Stheraven
1172227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1173232950Stheraven    template <class _R1, class _Fp>
1174232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1175232950Stheraven    template <class _R1, class _Fp>
1176232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1177227825Stheraven#else
1178232950Stheraven    template <class _R1, class _Fp>
1179232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1180232950Stheraven    template <class _R1, class _Fp>
1181232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1182227825Stheraven#endif
1183227825Stheraven
1184227825Stheravenpublic:
1185227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1186241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1187227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1188227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1189241903Sdim    future(future&& __rhs) _NOEXCEPT
1190227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1191227825Stheraven    future(const future&) = delete;
1192227825Stheraven    future& operator=(const future&) = delete;
1193227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1194241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1195227825Stheraven        {
1196227825Stheraven            future(std::move(__rhs)).swap(*this);
1197227825Stheraven            return *this;
1198227825Stheraven        }
1199227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1200227825Stheravenprivate:
1201227825Stheraven    future(const future&);
1202227825Stheraven    future& operator=(const future&);
1203227825Stheravenpublic:
1204227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1205227825Stheraven    ~future();
1206232950Stheraven    shared_future<_Rp&> share();
1207227825Stheraven
1208227825Stheraven    // retrieving the value
1209232950Stheraven    _Rp& get();
1210227825Stheraven
1211227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1212241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1213227825Stheraven
1214227825Stheraven    // functions to check state
1215227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1216241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1217227825Stheraven
1218227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1219227825Stheraven    void wait() const {__state_->wait();}
1220227825Stheraven    template <class _Rep, class _Period>
1221227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1222227825Stheraven        future_status
1223227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1224227825Stheraven            {return __state_->wait_for(__rel_time);}
1225227825Stheraven    template <class _Clock, class _Duration>
1226227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1227227825Stheraven        future_status
1228227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1229227825Stheraven            {return __state_->wait_until(__abs_time);}
1230227825Stheraven};
1231227825Stheraven
1232232950Stheraventemplate <class _Rp>
1233232950Stheravenfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
1234227825Stheraven    : __state_(__state)
1235227825Stheraven{
1236227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1237227825Stheraven    if (__state_->__has_future_attached())
1238227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1239227825Stheraven#endif
1240227825Stheraven    __state_->__add_shared();
1241227825Stheraven    __state_->__set_future_attached();
1242227825Stheraven}
1243227825Stheraven
1244232950Stheraventemplate <class _Rp>
1245232950Stheravenfuture<_Rp&>::~future()
1246227825Stheraven{
1247227825Stheraven    if (__state_)
1248227825Stheraven        __state_->__release_shared();
1249227825Stheraven}
1250227825Stheraven
1251232950Stheraventemplate <class _Rp>
1252232950Stheraven_Rp&
1253232950Stheravenfuture<_Rp&>::get()
1254227825Stheraven{
1255227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1256232950Stheraven    __assoc_state<_Rp&>* __s = __state_;
1257227825Stheraven    __state_ = nullptr;
1258227825Stheraven    return __s->copy();
1259227825Stheraven}
1260227825Stheraven
1261227825Stheraventemplate <>
1262249998Sdimclass _LIBCPP_TYPE_VIS future<void>
1263227825Stheraven{
1264227825Stheraven    __assoc_sub_state* __state_;
1265227825Stheraven
1266227825Stheraven    explicit future(__assoc_sub_state* __state);
1267227825Stheraven
1268227825Stheraven    template <class> friend class promise;
1269227825Stheraven    template <class> friend class shared_future;
1270227825Stheraven
1271227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1272232950Stheraven    template <class _R1, class _Fp>
1273232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1274232950Stheraven    template <class _R1, class _Fp>
1275232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1276227825Stheraven#else
1277232950Stheraven    template <class _R1, class _Fp>
1278232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1279232950Stheraven    template <class _R1, class _Fp>
1280232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1281227825Stheraven#endif
1282227825Stheraven
1283227825Stheravenpublic:
1284227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1285241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1286227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1287227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1288241903Sdim    future(future&& __rhs) _NOEXCEPT
1289227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1290227825Stheraven    future(const future&) = delete;
1291227825Stheraven    future& operator=(const future&) = delete;
1292227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1293241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1294227825Stheraven        {
1295227825Stheraven            future(std::move(__rhs)).swap(*this);
1296227825Stheraven            return *this;
1297227825Stheraven        }
1298227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1299227825Stheravenprivate:
1300227825Stheraven    future(const future&);
1301227825Stheraven    future& operator=(const future&);
1302227825Stheravenpublic:
1303227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1304227825Stheraven    ~future();
1305227825Stheraven    shared_future<void> share();
1306227825Stheraven
1307227825Stheraven    // retrieving the value
1308227825Stheraven    void get();
1309227825Stheraven
1310227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1311241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1312227825Stheraven
1313227825Stheraven    // functions to check state
1314227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1315241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1316227825Stheraven
1317227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1318227825Stheraven    void wait() const {__state_->wait();}
1319227825Stheraven    template <class _Rep, class _Period>
1320227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1321227825Stheraven        future_status
1322227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1323227825Stheraven            {return __state_->wait_for(__rel_time);}
1324227825Stheraven    template <class _Clock, class _Duration>
1325227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1326227825Stheraven        future_status
1327227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1328227825Stheraven            {return __state_->wait_until(__abs_time);}
1329227825Stheraven};
1330227825Stheraven
1331232950Stheraventemplate <class _Rp>
1332227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1333227825Stheravenvoid
1334241903Sdimswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1335227825Stheraven{
1336227825Stheraven    __x.swap(__y);
1337227825Stheraven}
1338227825Stheraven
1339227825Stheraven// promise<R>
1340227825Stheraven
1341227825Stheraventemplate <class _Callable> class packaged_task;
1342227825Stheraven
1343232950Stheraventemplate <class _Rp>
1344249998Sdimclass _LIBCPP_TYPE_VIS promise
1345227825Stheraven{
1346232950Stheraven    __assoc_state<_Rp>* __state_;
1347227825Stheraven
1348227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1349241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1350227825Stheraven
1351227825Stheraven    template <class> friend class packaged_task;
1352227825Stheravenpublic:
1353227825Stheraven    promise();
1354227825Stheraven    template <class _Alloc>
1355227825Stheraven        promise(allocator_arg_t, const _Alloc& __a);
1356227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1357227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1358241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1359227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1360227825Stheraven    promise(const promise& __rhs) = delete;
1361227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1362227825Stheravenprivate:
1363227825Stheraven    promise(const promise& __rhs);
1364227825Stheravenpublic:
1365227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1366227825Stheraven    ~promise();
1367227825Stheraven
1368227825Stheraven    // assignment
1369227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1370227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1371241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1372227825Stheraven        {
1373227825Stheraven            promise(std::move(__rhs)).swap(*this);
1374227825Stheraven            return *this;
1375227825Stheraven        }
1376227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1377227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1378227825Stheravenprivate:
1379227825Stheraven    promise& operator=(const promise& __rhs);
1380227825Stheravenpublic:
1381227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1382227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1383241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1384227825Stheraven
1385227825Stheraven    // retrieving the result
1386232950Stheraven    future<_Rp> get_future();
1387227825Stheraven
1388227825Stheraven    // setting the result
1389232950Stheraven    void set_value(const _Rp& __r);
1390227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1391232950Stheraven    void set_value(_Rp&& __r);
1392227825Stheraven#endif
1393227825Stheraven    void set_exception(exception_ptr __p);
1394227825Stheraven
1395227825Stheraven    // setting the result with deferred notification
1396232950Stheraven    void set_value_at_thread_exit(const _Rp& __r);
1397227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1398232950Stheraven    void set_value_at_thread_exit(_Rp&& __r);
1399227825Stheraven#endif
1400227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1401227825Stheraven};
1402227825Stheraven
1403232950Stheraventemplate <class _Rp>
1404232950Stheravenpromise<_Rp>::promise()
1405232950Stheraven    : __state_(new __assoc_state<_Rp>)
1406227825Stheraven{
1407227825Stheraven}
1408227825Stheraven
1409232950Stheraventemplate <class _Rp>
1410227825Stheraventemplate <class _Alloc>
1411232950Stheravenpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1412227825Stheraven{
1413232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
1414227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1415227825Stheraven    _A2 __a(__a0);
1416232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1417232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
1418227825Stheraven    __state_ = __hold.release();
1419227825Stheraven}
1420227825Stheraven
1421232950Stheraventemplate <class _Rp>
1422232950Stheravenpromise<_Rp>::~promise()
1423227825Stheraven{
1424227825Stheraven    if (__state_)
1425227825Stheraven    {
1426227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1427227825Stheraven            __state_->set_exception(make_exception_ptr(
1428227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1429227825Stheraven                                                      ));
1430227825Stheraven        __state_->__release_shared();
1431227825Stheraven    }
1432227825Stheraven}
1433227825Stheraven
1434232950Stheraventemplate <class _Rp>
1435232950Stheravenfuture<_Rp>
1436232950Stheravenpromise<_Rp>::get_future()
1437227825Stheraven{
1438227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1439227825Stheraven    if (__state_ == nullptr)
1440227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1441227825Stheraven#endif
1442232950Stheraven    return future<_Rp>(__state_);
1443227825Stheraven}
1444227825Stheraven
1445232950Stheraventemplate <class _Rp>
1446227825Stheravenvoid
1447232950Stheravenpromise<_Rp>::set_value(const _Rp& __r)
1448227825Stheraven{
1449227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1450227825Stheraven    if (__state_ == nullptr)
1451227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1452227825Stheraven#endif
1453227825Stheraven    __state_->set_value(__r);
1454227825Stheraven}
1455227825Stheraven
1456227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1457227825Stheraven
1458232950Stheraventemplate <class _Rp>
1459227825Stheravenvoid
1460232950Stheravenpromise<_Rp>::set_value(_Rp&& __r)
1461227825Stheraven{
1462227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1463227825Stheraven    if (__state_ == nullptr)
1464227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1465227825Stheraven#endif
1466227825Stheraven    __state_->set_value(_VSTD::move(__r));
1467227825Stheraven}
1468227825Stheraven
1469227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1470227825Stheraven
1471232950Stheraventemplate <class _Rp>
1472227825Stheravenvoid
1473232950Stheravenpromise<_Rp>::set_exception(exception_ptr __p)
1474227825Stheraven{
1475227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1476227825Stheraven    if (__state_ == nullptr)
1477227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1478227825Stheraven#endif
1479227825Stheraven    __state_->set_exception(__p);
1480227825Stheraven}
1481227825Stheraven
1482232950Stheraventemplate <class _Rp>
1483227825Stheravenvoid
1484232950Stheravenpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1485227825Stheraven{
1486227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1487227825Stheraven    if (__state_ == nullptr)
1488227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1489227825Stheraven#endif
1490227825Stheraven    __state_->set_value_at_thread_exit(__r);
1491227825Stheraven}
1492227825Stheraven
1493227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1494227825Stheraven
1495232950Stheraventemplate <class _Rp>
1496227825Stheravenvoid
1497232950Stheravenpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1498227825Stheraven{
1499227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1500227825Stheraven    if (__state_ == nullptr)
1501227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1502227825Stheraven#endif
1503227825Stheraven    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1504227825Stheraven}
1505227825Stheraven
1506227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1507227825Stheraven
1508232950Stheraventemplate <class _Rp>
1509227825Stheravenvoid
1510232950Stheravenpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1511227825Stheraven{
1512227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1513227825Stheraven    if (__state_ == nullptr)
1514227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1515227825Stheraven#endif
1516227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1517227825Stheraven}
1518227825Stheraven
1519227825Stheraven// promise<R&>
1520227825Stheraven
1521232950Stheraventemplate <class _Rp>
1522249998Sdimclass _LIBCPP_TYPE_VIS promise<_Rp&>
1523227825Stheraven{
1524232950Stheraven    __assoc_state<_Rp&>* __state_;
1525227825Stheraven
1526227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1527241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1528227825Stheraven
1529227825Stheraven    template <class> friend class packaged_task;
1530227825Stheraven
1531227825Stheravenpublic:
1532227825Stheraven    promise();
1533227825Stheraven    template <class _Allocator>
1534227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1535227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1536227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1537241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1538227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1539227825Stheraven    promise(const promise& __rhs) = delete;
1540227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1541227825Stheravenprivate:
1542227825Stheraven    promise(const promise& __rhs);
1543227825Stheravenpublic:
1544227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1545227825Stheraven    ~promise();
1546227825Stheraven
1547227825Stheraven    // assignment
1548227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1549227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1550241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1551227825Stheraven        {
1552227825Stheraven            promise(std::move(__rhs)).swap(*this);
1553227825Stheraven            return *this;
1554227825Stheraven        }
1555227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1556227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1557227825Stheravenprivate:
1558227825Stheraven    promise& operator=(const promise& __rhs);
1559227825Stheravenpublic:
1560227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1561227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1562241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1563227825Stheraven
1564227825Stheraven    // retrieving the result
1565232950Stheraven    future<_Rp&> get_future();
1566227825Stheraven
1567227825Stheraven    // setting the result
1568232950Stheraven    void set_value(_Rp& __r);
1569227825Stheraven    void set_exception(exception_ptr __p);
1570227825Stheraven
1571227825Stheraven    // setting the result with deferred notification
1572232950Stheraven    void set_value_at_thread_exit(_Rp&);
1573227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1574227825Stheraven};
1575227825Stheraven
1576232950Stheraventemplate <class _Rp>
1577232950Stheravenpromise<_Rp&>::promise()
1578232950Stheraven    : __state_(new __assoc_state<_Rp&>)
1579227825Stheraven{
1580227825Stheraven}
1581227825Stheraven
1582232950Stheraventemplate <class _Rp>
1583227825Stheraventemplate <class _Alloc>
1584232950Stheravenpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1585227825Stheraven{
1586232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
1587227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1588227825Stheraven    _A2 __a(__a0);
1589232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1590232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
1591227825Stheraven    __state_ = __hold.release();
1592227825Stheraven}
1593227825Stheraven
1594232950Stheraventemplate <class _Rp>
1595232950Stheravenpromise<_Rp&>::~promise()
1596227825Stheraven{
1597227825Stheraven    if (__state_)
1598227825Stheraven    {
1599227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1600227825Stheraven            __state_->set_exception(make_exception_ptr(
1601227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1602227825Stheraven                                                      ));
1603227825Stheraven        __state_->__release_shared();
1604227825Stheraven    }
1605227825Stheraven}
1606227825Stheraven
1607232950Stheraventemplate <class _Rp>
1608232950Stheravenfuture<_Rp&>
1609232950Stheravenpromise<_Rp&>::get_future()
1610227825Stheraven{
1611227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1612227825Stheraven    if (__state_ == nullptr)
1613227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1614227825Stheraven#endif
1615232950Stheraven    return future<_Rp&>(__state_);
1616227825Stheraven}
1617227825Stheraven
1618232950Stheraventemplate <class _Rp>
1619227825Stheravenvoid
1620232950Stheravenpromise<_Rp&>::set_value(_Rp& __r)
1621227825Stheraven{
1622227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1623227825Stheraven    if (__state_ == nullptr)
1624227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1625227825Stheraven#endif
1626227825Stheraven    __state_->set_value(__r);
1627227825Stheraven}
1628227825Stheraven
1629232950Stheraventemplate <class _Rp>
1630227825Stheravenvoid
1631232950Stheravenpromise<_Rp&>::set_exception(exception_ptr __p)
1632227825Stheraven{
1633227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1634227825Stheraven    if (__state_ == nullptr)
1635227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1636227825Stheraven#endif
1637227825Stheraven    __state_->set_exception(__p);
1638227825Stheraven}
1639227825Stheraven
1640232950Stheraventemplate <class _Rp>
1641227825Stheravenvoid
1642232950Stheravenpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1643227825Stheraven{
1644227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1645227825Stheraven    if (__state_ == nullptr)
1646227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1647227825Stheraven#endif
1648227825Stheraven    __state_->set_value_at_thread_exit(__r);
1649227825Stheraven}
1650227825Stheraven
1651232950Stheraventemplate <class _Rp>
1652227825Stheravenvoid
1653232950Stheravenpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1654227825Stheraven{
1655227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1656227825Stheraven    if (__state_ == nullptr)
1657227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1658227825Stheraven#endif
1659227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1660227825Stheraven}
1661227825Stheraven
1662227825Stheraven// promise<void>
1663227825Stheraven
1664227825Stheraventemplate <>
1665249998Sdimclass _LIBCPP_TYPE_VIS promise<void>
1666227825Stheraven{
1667227825Stheraven    __assoc_sub_state* __state_;
1668227825Stheraven
1669227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1670241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1671227825Stheraven
1672227825Stheraven    template <class> friend class packaged_task;
1673227825Stheraven
1674227825Stheravenpublic:
1675227825Stheraven    promise();
1676227825Stheraven    template <class _Allocator>
1677227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1678227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1679227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1680241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1681227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1682227825Stheraven    promise(const promise& __rhs) = delete;
1683227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1684227825Stheravenprivate:
1685227825Stheraven    promise(const promise& __rhs);
1686227825Stheravenpublic:
1687227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1688227825Stheraven    ~promise();
1689227825Stheraven
1690227825Stheraven    // assignment
1691227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1692227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1693241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1694227825Stheraven        {
1695227825Stheraven            promise(std::move(__rhs)).swap(*this);
1696227825Stheraven            return *this;
1697227825Stheraven        }
1698227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1699227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1700227825Stheravenprivate:
1701227825Stheraven    promise& operator=(const promise& __rhs);
1702227825Stheravenpublic:
1703227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1704227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1705241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1706227825Stheraven
1707227825Stheraven    // retrieving the result
1708227825Stheraven    future<void> get_future();
1709227825Stheraven
1710227825Stheraven    // setting the result
1711227825Stheraven    void set_value();
1712227825Stheraven    void set_exception(exception_ptr __p);
1713227825Stheraven
1714227825Stheraven    // setting the result with deferred notification
1715227825Stheraven    void set_value_at_thread_exit();
1716227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1717227825Stheraven};
1718227825Stheraven
1719227825Stheraventemplate <class _Alloc>
1720227825Stheravenpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1721227825Stheraven{
1722227825Stheraven    typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1723227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1724227825Stheraven    _A2 __a(__a0);
1725227825Stheraven    unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1726227825Stheraven    ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1727227825Stheraven    __state_ = __hold.release();
1728227825Stheraven}
1729227825Stheraven
1730232950Stheraventemplate <class _Rp>
1731227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1732227825Stheravenvoid
1733241903Sdimswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1734227825Stheraven{
1735227825Stheraven    __x.swap(__y);
1736227825Stheraven}
1737227825Stheraven
1738232950Stheraventemplate <class _Rp, class _Alloc>
1739249998Sdim    struct _LIBCPP_TYPE_VIS uses_allocator<promise<_Rp>, _Alloc>
1740227825Stheraven        : public true_type {};
1741227825Stheraven
1742227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
1743227825Stheraven
1744227825Stheraven// packaged_task
1745227825Stheraven
1746227825Stheraventemplate<class _Fp> class __packaged_task_base;
1747227825Stheraven
1748232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1749232950Stheravenclass __packaged_task_base<_Rp(_ArgTypes...)>
1750227825Stheraven{
1751227825Stheraven    __packaged_task_base(const __packaged_task_base&);
1752227825Stheraven    __packaged_task_base& operator=(const __packaged_task_base&);
1753227825Stheravenpublic:
1754227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1755227825Stheraven    __packaged_task_base() {}
1756227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1757227825Stheraven    virtual ~__packaged_task_base() {}
1758241903Sdim    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1759227825Stheraven    virtual void destroy() = 0;
1760227825Stheraven    virtual void destroy_deallocate() = 0;
1761232950Stheraven    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1762227825Stheraven};
1763227825Stheraven
1764227825Stheraventemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1765227825Stheraven
1766232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1767232950Stheravenclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1768232950Stheraven    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1769227825Stheraven{
1770232950Stheraven    __compressed_pair<_Fp, _Alloc> __f_;
1771227825Stheravenpublic:
1772227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1773232950Stheraven    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1774227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1775232950Stheraven    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1776227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1777232950Stheraven    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1778227825Stheraven        : __f_(__f, __a) {}
1779227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1780232950Stheraven    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1781227825Stheraven        : __f_(_VSTD::move(__f), __a) {}
1782241903Sdim    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1783227825Stheraven    virtual void destroy();
1784227825Stheraven    virtual void destroy_deallocate();
1785232950Stheraven    virtual _Rp operator()(_ArgTypes&& ... __args);
1786227825Stheraven};
1787227825Stheraven
1788232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1789227825Stheravenvoid
1790232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1791241903Sdim                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1792227825Stheraven{
1793227825Stheraven    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1794227825Stheraven}
1795227825Stheraven
1796232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1797227825Stheravenvoid
1798232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1799227825Stheraven{
1800232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1801227825Stheraven}
1802227825Stheraven
1803232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1804227825Stheravenvoid
1805232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1806227825Stheraven{
1807232950Stheraven    typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1808232950Stheraven    _Ap __a(__f_.second());
1809232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1810227825Stheraven    __a.deallocate(this, 1);
1811227825Stheraven}
1812227825Stheraven
1813232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1814232950Stheraven_Rp
1815232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1816227825Stheraven{
1817227825Stheraven    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1818227825Stheraven}
1819227825Stheraven
1820227825Stheraventemplate <class _Callable> class __packaged_task_function;
1821227825Stheraven
1822232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1823232950Stheravenclass __packaged_task_function<_Rp(_ArgTypes...)>
1824227825Stheraven{
1825232950Stheraven    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1826246487Stheraven    typename aligned_storage<3*sizeof(void*)>::type __buf_;
1827227825Stheraven    __base* __f_;
1828227825Stheraven
1829227825Stheravenpublic:
1830232950Stheraven    typedef _Rp result_type;
1831227825Stheraven
1832227825Stheraven    // construct/copy/destroy:
1833227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1834241903Sdim    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1835232950Stheraven    template<class _Fp>
1836232950Stheraven      __packaged_task_function(_Fp&& __f);
1837232950Stheraven    template<class _Fp, class _Alloc>
1838232950Stheraven      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1839227825Stheraven
1840241903Sdim    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1841241903Sdim    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1842227825Stheraven
1843227825Stheraven    __packaged_task_function(const __packaged_task_function&) =  delete;
1844227825Stheraven    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1845227825Stheraven
1846227825Stheraven    ~__packaged_task_function();
1847227825Stheraven
1848241903Sdim    void swap(__packaged_task_function&) _NOEXCEPT;
1849227825Stheraven
1850232950Stheraven    _Rp operator()(_ArgTypes...) const;
1851227825Stheraven};
1852227825Stheraven
1853232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1854241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1855227825Stheraven{
1856227825Stheraven    if (__f.__f_ == nullptr)
1857227825Stheraven        __f_ = nullptr;
1858227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1859227825Stheraven    {
1860227825Stheraven        __f_ = (__base*)&__buf_;
1861227825Stheraven        __f.__f_->__move_to(__f_);
1862227825Stheraven    }
1863227825Stheraven    else
1864227825Stheraven    {
1865227825Stheraven        __f_ = __f.__f_;
1866227825Stheraven        __f.__f_ = nullptr;
1867227825Stheraven    }
1868227825Stheraven}
1869227825Stheraven
1870232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1871232950Stheraventemplate <class _Fp>
1872232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1873227825Stheraven    : __f_(nullptr)
1874227825Stheraven{
1875232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1876232950Stheraven    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1877227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1878227825Stheraven    {
1879227825Stheraven        __f_ = (__base*)&__buf_;
1880232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1881227825Stheraven    }
1882227825Stheraven    else
1883227825Stheraven    {
1884232950Stheraven        typedef allocator<_FF> _Ap;
1885232950Stheraven        _Ap __a;
1886232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1887232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1888232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1889227825Stheraven        __f_ = __hold.release();
1890227825Stheraven    }
1891227825Stheraven}
1892227825Stheraven
1893232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1894232950Stheraventemplate <class _Fp, class _Alloc>
1895232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1896232950Stheraven                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1897227825Stheraven    : __f_(nullptr)
1898227825Stheraven{
1899227825Stheraven    typedef allocator_traits<_Alloc> __alloc_traits;
1900232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1901232950Stheraven    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1902227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1903227825Stheraven    {
1904227825Stheraven        __f_ = (__base*)&__buf_;
1905232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1906227825Stheraven    }
1907227825Stheraven    else
1908227825Stheraven    {
1909227825Stheraven        typedef typename __alloc_traits::template
1910227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1911227825Stheraven            rebind_alloc<_FF>
1912227825Stheraven#else
1913227825Stheraven            rebind_alloc<_FF>::other
1914227825Stheraven#endif
1915232950Stheraven                                                     _Ap;
1916232950Stheraven        _Ap __a(__a0);
1917232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1918232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1919232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1920227825Stheraven        __f_ = __hold.release();
1921227825Stheraven    }
1922227825Stheraven}
1923227825Stheraven
1924232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1925232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>&
1926241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1927227825Stheraven{
1928227825Stheraven    if (__f_ == (__base*)&__buf_)
1929227825Stheraven        __f_->destroy();
1930227825Stheraven    else if (__f_)
1931227825Stheraven        __f_->destroy_deallocate();
1932227825Stheraven    __f_ = nullptr;
1933227825Stheraven    if (__f.__f_ == nullptr)
1934227825Stheraven        __f_ = nullptr;
1935227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1936227825Stheraven    {
1937227825Stheraven        __f_ = (__base*)&__buf_;
1938227825Stheraven        __f.__f_->__move_to(__f_);
1939227825Stheraven    }
1940227825Stheraven    else
1941227825Stheraven    {
1942227825Stheraven        __f_ = __f.__f_;
1943227825Stheraven        __f.__f_ = nullptr;
1944227825Stheraven    }
1945241903Sdim    return *this;
1946227825Stheraven}
1947227825Stheraven
1948232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1949232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1950227825Stheraven{
1951227825Stheraven    if (__f_ == (__base*)&__buf_)
1952227825Stheraven        __f_->destroy();
1953227825Stheraven    else if (__f_)
1954227825Stheraven        __f_->destroy_deallocate();
1955227825Stheraven}
1956227825Stheraven
1957232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1958227825Stheravenvoid
1959241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1960227825Stheraven{
1961227825Stheraven    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1962227825Stheraven    {
1963227825Stheraven        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1964227825Stheraven        __base* __t = (__base*)&__tempbuf;
1965227825Stheraven        __f_->__move_to(__t);
1966227825Stheraven        __f_->destroy();
1967227825Stheraven        __f_ = nullptr;
1968227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1969227825Stheraven        __f.__f_->destroy();
1970227825Stheraven        __f.__f_ = nullptr;
1971227825Stheraven        __f_ = (__base*)&__buf_;
1972227825Stheraven        __t->__move_to((__base*)&__f.__buf_);
1973227825Stheraven        __t->destroy();
1974227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1975227825Stheraven    }
1976227825Stheraven    else if (__f_ == (__base*)&__buf_)
1977227825Stheraven    {
1978227825Stheraven        __f_->__move_to((__base*)&__f.__buf_);
1979227825Stheraven        __f_->destroy();
1980227825Stheraven        __f_ = __f.__f_;
1981227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1982227825Stheraven    }
1983227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1984227825Stheraven    {
1985227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1986227825Stheraven        __f.__f_->destroy();
1987227825Stheraven        __f.__f_ = __f_;
1988227825Stheraven        __f_ = (__base*)&__buf_;
1989227825Stheraven    }
1990227825Stheraven    else
1991227825Stheraven        _VSTD::swap(__f_, __f.__f_);
1992227825Stheraven}
1993227825Stheraven
1994232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1995227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1996232950Stheraven_Rp
1997232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1998227825Stheraven{
1999227825Stheraven    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
2000227825Stheraven}
2001227825Stheraven
2002232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2003249998Sdimclass _LIBCPP_TYPE_VIS packaged_task<_Rp(_ArgTypes...)>
2004227825Stheraven{
2005227825Stheravenpublic:
2006232950Stheraven    typedef _Rp result_type;
2007227825Stheraven
2008227825Stheravenprivate:
2009227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2010227825Stheraven    promise<result_type>                                __p_;
2011227825Stheraven
2012227825Stheravenpublic:
2013227825Stheraven    // construction and destruction
2014227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2015241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2016232950Stheraven    template <class _Fp>
2017227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2018232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2019232950Stheraven    template <class _Fp, class _Allocator>
2020227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2021232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2022232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2023227825Stheraven               __p_(allocator_arg, __a) {}
2024227825Stheraven    // ~packaged_task() = default;
2025227825Stheraven
2026227825Stheraven    // no copy
2027241903Sdim    packaged_task(const packaged_task&) = delete;
2028241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2029227825Stheraven
2030227825Stheraven    // move support
2031227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2032241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2033227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2034227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2035241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2036227825Stheraven    {
2037227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2038227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2039227825Stheraven        return *this;
2040227825Stheraven    }
2041227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2042241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2043227825Stheraven    {
2044227825Stheraven        __f_.swap(__other.__f_);
2045227825Stheraven        __p_.swap(__other.__p_);
2046227825Stheraven    }
2047227825Stheraven
2048227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2049241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2050227825Stheraven
2051227825Stheraven    // result retrieval
2052227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2053227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2054227825Stheraven
2055227825Stheraven    // execution
2056227825Stheraven    void operator()(_ArgTypes... __args);
2057227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2058227825Stheraven
2059227825Stheraven    void reset();
2060227825Stheraven};
2061227825Stheraven
2062232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2063227825Stheravenvoid
2064232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
2065227825Stheraven{
2066227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2067227825Stheraven    if (__p_.__state_ == nullptr)
2068227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2069227825Stheraven    if (__p_.__state_->__has_value())
2070227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2071227825Stheraven    try
2072227825Stheraven    {
2073227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2074227825Stheraven        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2075227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2076227825Stheraven    }
2077227825Stheraven    catch (...)
2078227825Stheraven    {
2079227825Stheraven        __p_.set_exception(current_exception());
2080227825Stheraven    }
2081227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2082227825Stheraven}
2083227825Stheraven
2084232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2085227825Stheravenvoid
2086232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2087227825Stheraven{
2088227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2089227825Stheraven    if (__p_.__state_ == nullptr)
2090227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2091227825Stheraven    if (__p_.__state_->__has_value())
2092227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2093227825Stheraven    try
2094227825Stheraven    {
2095227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2096227825Stheraven        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2097227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2098227825Stheraven    }
2099227825Stheraven    catch (...)
2100227825Stheraven    {
2101227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2102227825Stheraven    }
2103227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2104227825Stheraven}
2105227825Stheraven
2106232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2107227825Stheravenvoid
2108232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::reset()
2109227825Stheraven{
2110227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2111227825Stheraven    if (!valid())
2112227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2113227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2114227825Stheraven    __p_ = promise<result_type>();
2115227825Stheraven}
2116227825Stheraven
2117227825Stheraventemplate<class ..._ArgTypes>
2118249998Sdimclass _LIBCPP_TYPE_VIS packaged_task<void(_ArgTypes...)>
2119227825Stheraven{
2120227825Stheravenpublic:
2121227825Stheraven    typedef void result_type;
2122227825Stheraven
2123227825Stheravenprivate:
2124227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2125227825Stheraven    promise<result_type>                                __p_;
2126227825Stheraven
2127227825Stheravenpublic:
2128227825Stheraven    // construction and destruction
2129227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2130241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2131232950Stheraven    template <class _Fp>
2132227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2133232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2134232950Stheraven    template <class _Fp, class _Allocator>
2135227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2136232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2137232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2138227825Stheraven               __p_(allocator_arg, __a) {}
2139227825Stheraven    // ~packaged_task() = default;
2140227825Stheraven
2141227825Stheraven    // no copy
2142241903Sdim    packaged_task(const packaged_task&) = delete;
2143241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2144227825Stheraven
2145227825Stheraven    // move support
2146227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2147241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2148227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2149227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2150241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2151227825Stheraven    {
2152227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2153227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2154227825Stheraven        return *this;
2155227825Stheraven    }
2156227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2157241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2158227825Stheraven    {
2159227825Stheraven        __f_.swap(__other.__f_);
2160227825Stheraven        __p_.swap(__other.__p_);
2161227825Stheraven    }
2162227825Stheraven
2163227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2164241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2165227825Stheraven
2166227825Stheraven    // result retrieval
2167227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2168227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2169227825Stheraven
2170227825Stheraven    // execution
2171227825Stheraven    void operator()(_ArgTypes... __args);
2172227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2173227825Stheraven
2174227825Stheraven    void reset();
2175227825Stheraven};
2176227825Stheraven
2177227825Stheraventemplate<class ..._ArgTypes>
2178227825Stheravenvoid
2179227825Stheravenpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2180227825Stheraven{
2181227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2182227825Stheraven    if (__p_.__state_ == nullptr)
2183227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2184227825Stheraven    if (__p_.__state_->__has_value())
2185227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2186227825Stheraven    try
2187227825Stheraven    {
2188227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2189227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2190227825Stheraven        __p_.set_value();
2191227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2192227825Stheraven    }
2193227825Stheraven    catch (...)
2194227825Stheraven    {
2195227825Stheraven        __p_.set_exception(current_exception());
2196227825Stheraven    }
2197227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2198227825Stheraven}
2199227825Stheraven
2200227825Stheraventemplate<class ..._ArgTypes>
2201227825Stheravenvoid
2202227825Stheravenpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2203227825Stheraven{
2204227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2205227825Stheraven    if (__p_.__state_ == nullptr)
2206227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2207227825Stheraven    if (__p_.__state_->__has_value())
2208227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2209227825Stheraven    try
2210227825Stheraven    {
2211227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2212227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2213227825Stheraven        __p_.set_value_at_thread_exit();
2214227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2215227825Stheraven    }
2216227825Stheraven    catch (...)
2217227825Stheraven    {
2218227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2219227825Stheraven    }
2220227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2221227825Stheraven}
2222227825Stheraven
2223227825Stheraventemplate<class ..._ArgTypes>
2224227825Stheravenvoid
2225227825Stheravenpackaged_task<void(_ArgTypes...)>::reset()
2226227825Stheraven{
2227227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2228227825Stheraven    if (!valid())
2229227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2230227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2231227825Stheraven    __p_ = promise<result_type>();
2232227825Stheraven}
2233227825Stheraven
2234227825Stheraventemplate <class _Callable>
2235227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2236227825Stheravenvoid
2237241903Sdimswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2238227825Stheraven{
2239227825Stheraven    __x.swap(__y);
2240227825Stheraven}
2241227825Stheraven
2242227825Stheraventemplate <class _Callable, class _Alloc>
2243249998Sdimstruct _LIBCPP_TYPE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2244227825Stheraven    : public true_type {};
2245227825Stheraven
2246232950Stheraventemplate <class _Rp, class _Fp>
2247232950Stheravenfuture<_Rp>
2248227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2249232950Stheraven__make_deferred_assoc_state(_Fp&& __f)
2250227825Stheraven#else
2251232950Stheraven__make_deferred_assoc_state(_Fp __f)
2252227825Stheraven#endif
2253227825Stheraven{
2254232950Stheraven    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2255232950Stheraven        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2256232950Stheraven    return future<_Rp>(__h.get());
2257227825Stheraven}
2258227825Stheraven
2259232950Stheraventemplate <class _Rp, class _Fp>
2260232950Stheravenfuture<_Rp>
2261227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2262232950Stheraven__make_async_assoc_state(_Fp&& __f)
2263227825Stheraven#else
2264232950Stheraven__make_async_assoc_state(_Fp __f)
2265227825Stheraven#endif
2266227825Stheraven{
2267232950Stheraven    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2268232950Stheraven        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2269232950Stheraven    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2270232950Stheraven    return future<_Rp>(__h.get());
2271227825Stheraven}
2272227825Stheraven
2273232950Stheraventemplate <class _Fp, class... _Args>
2274227825Stheravenclass __async_func
2275227825Stheraven{
2276232950Stheraven    tuple<_Fp, _Args...> __f_;
2277227825Stheraven
2278227825Stheravenpublic:
2279232950Stheraven    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2280227825Stheraven
2281227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2282232950Stheraven    explicit __async_func(_Fp&& __f, _Args&&... __args)
2283227825Stheraven        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2284227825Stheraven
2285227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2286227825Stheraven    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2287227825Stheraven
2288232950Stheraven    _Rp operator()()
2289227825Stheraven    {
2290227825Stheraven        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2291227825Stheraven        return __execute(_Index());
2292227825Stheraven    }
2293227825Stheravenprivate:
2294227825Stheraven    template <size_t ..._Indices>
2295232950Stheraven    _Rp
2296227825Stheraven    __execute(__tuple_indices<_Indices...>)
2297227825Stheraven    {
2298227825Stheraven        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2299227825Stheraven    }
2300227825Stheraven};
2301227825Stheraven
2302232950Stheraventemplate <class _Fp, class... _Args>
2303232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2304232950Stheravenasync(launch __policy, _Fp&& __f, _Args&&... __args)
2305227825Stheraven{
2306232950Stheraven    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2307232950Stheraven    typedef typename _BF::_Rp _Rp;
2308232950Stheraven    future<_Rp> __r;
2309232950Stheraven    if (int(__policy) & int(launch::async))
2310232950Stheraven        __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2311227825Stheraven                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2312232950Stheraven    else if (int(__policy) & int(launch::deferred))
2313232950Stheraven        __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2314227825Stheraven                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2315227825Stheraven    return __r;
2316227825Stheraven}
2317227825Stheraven
2318232950Stheraventemplate <class _Fp, class... _Args>
2319227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2320232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2321232950Stheravenasync(_Fp&& __f, _Args&&... __args)
2322227825Stheraven{
2323232950Stheraven    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2324227825Stheraven                                    _VSTD::forward<_Args>(__args)...);
2325227825Stheraven}
2326227825Stheraven
2327227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
2328227825Stheraven
2329227825Stheraven// shared_future
2330227825Stheraven
2331232950Stheraventemplate <class _Rp>
2332249998Sdimclass _LIBCPP_TYPE_VIS shared_future
2333227825Stheraven{
2334232950Stheraven    __assoc_state<_Rp>* __state_;
2335227825Stheraven
2336227825Stheravenpublic:
2337227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2338241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2339227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2340227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2341227825Stheraven        {if (__state_) __state_->__add_shared();}
2342227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2343227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2344241903Sdim    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2345227825Stheraven        {__f.__state_ = nullptr;}
2346227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2347241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2348227825Stheraven        {__rhs.__state_ = nullptr;}
2349227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2350227825Stheraven    ~shared_future();
2351227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2352227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2353227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2354241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2355227825Stheraven        {
2356227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2357227825Stheraven            return *this;
2358227825Stheraven        }
2359227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2360227825Stheraven
2361227825Stheraven    // retrieving the value
2362227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2363232950Stheraven    const _Rp& get() const {return __state_->copy();}
2364227825Stheraven
2365227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2366241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2367227825Stheraven
2368227825Stheraven    // functions to check state
2369227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2370241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2371227825Stheraven
2372227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2373227825Stheraven    void wait() const {__state_->wait();}
2374227825Stheraven    template <class _Rep, class _Period>
2375227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2376227825Stheraven        future_status
2377227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2378227825Stheraven            {return __state_->wait_for(__rel_time);}
2379227825Stheraven    template <class _Clock, class _Duration>
2380227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2381227825Stheraven        future_status
2382227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2383227825Stheraven            {return __state_->wait_until(__abs_time);}
2384227825Stheraven};
2385227825Stheraven
2386232950Stheraventemplate <class _Rp>
2387232950Stheravenshared_future<_Rp>::~shared_future()
2388227825Stheraven{
2389227825Stheraven    if (__state_)
2390227825Stheraven        __state_->__release_shared();
2391227825Stheraven}
2392227825Stheraven
2393232950Stheraventemplate <class _Rp>
2394232950Stheravenshared_future<_Rp>&
2395232950Stheravenshared_future<_Rp>::operator=(const shared_future& __rhs)
2396227825Stheraven{
2397227825Stheraven    if (__rhs.__state_)
2398227825Stheraven        __rhs.__state_->__add_shared();
2399227825Stheraven    if (__state_)
2400227825Stheraven        __state_->__release_shared();
2401227825Stheraven    __state_ = __rhs.__state_;
2402227825Stheraven    return *this;
2403227825Stheraven}
2404227825Stheraven
2405232950Stheraventemplate <class _Rp>
2406249998Sdimclass _LIBCPP_TYPE_VIS shared_future<_Rp&>
2407227825Stheraven{
2408232950Stheraven    __assoc_state<_Rp&>* __state_;
2409227825Stheraven
2410227825Stheravenpublic:
2411227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2412241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2413227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2414227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2415227825Stheraven        {if (__state_) __state_->__add_shared();}
2416227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2417227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2418241903Sdim    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2419227825Stheraven        {__f.__state_ = nullptr;}
2420227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2421241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2422227825Stheraven        {__rhs.__state_ = nullptr;}
2423227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2424227825Stheraven    ~shared_future();
2425227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2426227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2427227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2428241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2429227825Stheraven        {
2430227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2431227825Stheraven            return *this;
2432227825Stheraven        }
2433227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2434227825Stheraven
2435227825Stheraven    // retrieving the value
2436227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2437232950Stheraven    _Rp& get() const {return __state_->copy();}
2438227825Stheraven
2439227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2440241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2441227825Stheraven
2442227825Stheraven    // functions to check state
2443227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2444241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2445227825Stheraven
2446227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2447227825Stheraven    void wait() const {__state_->wait();}
2448227825Stheraven    template <class _Rep, class _Period>
2449227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2450227825Stheraven        future_status
2451227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2452227825Stheraven            {return __state_->wait_for(__rel_time);}
2453227825Stheraven    template <class _Clock, class _Duration>
2454227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2455227825Stheraven        future_status
2456227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2457227825Stheraven            {return __state_->wait_until(__abs_time);}
2458227825Stheraven};
2459227825Stheraven
2460232950Stheraventemplate <class _Rp>
2461232950Stheravenshared_future<_Rp&>::~shared_future()
2462227825Stheraven{
2463227825Stheraven    if (__state_)
2464227825Stheraven        __state_->__release_shared();
2465227825Stheraven}
2466227825Stheraven
2467232950Stheraventemplate <class _Rp>
2468232950Stheravenshared_future<_Rp&>&
2469232950Stheravenshared_future<_Rp&>::operator=(const shared_future& __rhs)
2470227825Stheraven{
2471227825Stheraven    if (__rhs.__state_)
2472227825Stheraven        __rhs.__state_->__add_shared();
2473227825Stheraven    if (__state_)
2474227825Stheraven        __state_->__release_shared();
2475227825Stheraven    __state_ = __rhs.__state_;
2476227825Stheraven    return *this;
2477227825Stheraven}
2478227825Stheraven
2479227825Stheraventemplate <>
2480249998Sdimclass _LIBCPP_TYPE_VIS shared_future<void>
2481227825Stheraven{
2482227825Stheraven    __assoc_sub_state* __state_;
2483227825Stheraven
2484227825Stheravenpublic:
2485227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2486241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2487227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2488227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2489227825Stheraven        {if (__state_) __state_->__add_shared();}
2490227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2491227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2492241903Sdim    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2493227825Stheraven        {__f.__state_ = nullptr;}
2494227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2495241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2496227825Stheraven        {__rhs.__state_ = nullptr;}
2497227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2498227825Stheraven    ~shared_future();
2499227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2500227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2501227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2502241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2503227825Stheraven        {
2504227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2505227825Stheraven            return *this;
2506227825Stheraven        }
2507227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2508227825Stheraven
2509227825Stheraven    // retrieving the value
2510227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2511227825Stheraven    void get() const {__state_->copy();}
2512227825Stheraven
2513227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2514241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2515227825Stheraven
2516227825Stheraven    // functions to check state
2517227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2518241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2519227825Stheraven
2520227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2521227825Stheraven    void wait() const {__state_->wait();}
2522227825Stheraven    template <class _Rep, class _Period>
2523227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2524227825Stheraven        future_status
2525227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2526227825Stheraven            {return __state_->wait_for(__rel_time);}
2527227825Stheraven    template <class _Clock, class _Duration>
2528227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2529227825Stheraven        future_status
2530227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2531227825Stheraven            {return __state_->wait_until(__abs_time);}
2532227825Stheraven};
2533227825Stheraven
2534232950Stheraventemplate <class _Rp>
2535227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2536227825Stheravenvoid
2537241903Sdimswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2538227825Stheraven{
2539227825Stheraven    __x.swap(__y);
2540227825Stheraven}
2541227825Stheraven
2542232950Stheraventemplate <class _Rp>
2543227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2544232950Stheravenshared_future<_Rp>
2545232950Stheravenfuture<_Rp>::share()
2546227825Stheraven{
2547232950Stheraven    return shared_future<_Rp>(_VSTD::move(*this));
2548227825Stheraven}
2549227825Stheraven
2550232950Stheraventemplate <class _Rp>
2551227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2552232950Stheravenshared_future<_Rp&>
2553232950Stheravenfuture<_Rp&>::share()
2554227825Stheraven{
2555232950Stheraven    return shared_future<_Rp&>(_VSTD::move(*this));
2556227825Stheraven}
2557227825Stheraven
2558227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2559227825Stheraven
2560227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2561227825Stheravenshared_future<void>
2562227825Stheravenfuture<void>::share()
2563227825Stheraven{
2564227825Stheraven    return shared_future<void>(_VSTD::move(*this));
2565227825Stheraven}
2566227825Stheraven
2567227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2568227825Stheraven
2569227825Stheraven_LIBCPP_END_NAMESPACE_STD
2570227825Stheraven
2571227825Stheraven#endif  // _LIBCPP_FUTURE
2572