future revision 241903
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 <>
390227825Stheravenstruct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
391227825Stheraven
392232950Stheraven#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
393232950Stheraventemplate <>
394232950Stheravenstruct _LIBCPP_VISIBLE is_error_code_enum<future_errc::_> : 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
406227825Stheraven//enum class future_status
407232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM(future_status)
408227825Stheraven{
409227825Stheraven    ready,
410227825Stheraven    timeout,
411227825Stheraven    deferred
412227825Stheraven};
413232950Stheraven_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
414227825Stheraven
415227825Stheraven_LIBCPP_VISIBLE
416241903Sdimconst error_category& future_category() _NOEXCEPT;
417227825Stheraven
418227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
419227825Stheravenerror_code
420241903Sdimmake_error_code(future_errc __e) _NOEXCEPT
421227825Stheraven{
422227825Stheraven    return error_code(static_cast<int>(__e), future_category());
423227825Stheraven}
424227825Stheraven
425227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
426227825Stheravenerror_condition
427241903Sdimmake_error_condition(future_errc __e) _NOEXCEPT
428227825Stheraven{
429227825Stheraven    return error_condition(static_cast<int>(__e), future_category());
430227825Stheraven}
431227825Stheraven
432227825Stheravenclass _LIBCPP_EXCEPTION_ABI future_error
433227825Stheraven    : public logic_error
434227825Stheraven{
435227825Stheraven    error_code __ec_;
436227825Stheravenpublic:
437227825Stheraven    future_error(error_code __ec);
438227825Stheraven
439227825Stheraven    _LIBCPP_INLINE_VISIBILITY
440241903Sdim    const error_code& code() const _NOEXCEPT {return __ec_;}
441227825Stheraven
442227825Stheraven    virtual ~future_error() _NOEXCEPT;
443227825Stheraven};
444227825Stheraven
445227825Stheravenclass __assoc_sub_state
446227825Stheraven    : public __shared_count
447227825Stheraven{
448227825Stheravenprotected:
449227825Stheraven    exception_ptr __exception_;
450227825Stheraven    mutable mutex __mut_;
451227825Stheraven    mutable condition_variable __cv_;
452227825Stheraven    unsigned __state_;
453227825Stheraven
454227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
455227825Stheraven    void __sub_wait(unique_lock<mutex>& __lk);
456227825Stheravenpublic:
457227825Stheraven    enum
458227825Stheraven    {
459227825Stheraven        __constructed = 1,
460227825Stheraven        __future_attached = 2,
461227825Stheraven        ready = 4,
462227825Stheraven        deferred = 8
463227825Stheraven    };
464227825Stheraven
465227825Stheraven    _LIBCPP_INLINE_VISIBILITY
466227825Stheraven    __assoc_sub_state() : __state_(0) {}
467227825Stheraven
468227825Stheraven    _LIBCPP_INLINE_VISIBILITY
469227825Stheraven    bool __has_value() const
470227825Stheraven        {return (__state_ & __constructed) || (__exception_ != nullptr);}
471227825Stheraven
472227825Stheraven    _LIBCPP_INLINE_VISIBILITY
473227825Stheraven    void __set_future_attached() {__state_ |= __future_attached;}
474227825Stheraven    _LIBCPP_INLINE_VISIBILITY
475227825Stheraven    bool __has_future_attached() const {return __state_ & __future_attached;}
476227825Stheraven
477227825Stheraven    _LIBCPP_INLINE_VISIBILITY
478227825Stheraven    void __set_deferred() {__state_ |= deferred;}
479227825Stheraven
480227825Stheraven    void __make_ready();
481227825Stheraven    _LIBCPP_INLINE_VISIBILITY
482227825Stheraven    bool __is_ready() const {return __state_ & ready;}
483227825Stheraven
484227825Stheraven    void set_value();
485227825Stheraven    void set_value_at_thread_exit();
486227825Stheraven
487227825Stheraven    void set_exception(exception_ptr __p);
488227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
489227825Stheraven
490227825Stheraven    void copy();
491227825Stheraven
492227825Stheraven    void wait();
493227825Stheraven    template <class _Rep, class _Period>
494227825Stheraven        future_status
495227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
496227825Stheraven    template <class _Clock, class _Duration>
497227825Stheraven        future_status
498227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
499227825Stheraven
500227825Stheraven    virtual void __execute();
501227825Stheraven};
502227825Stheraven
503227825Stheraventemplate <class _Clock, class _Duration>
504227825Stheravenfuture_status
505227825Stheraven__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
506227825Stheraven{
507227825Stheraven    unique_lock<mutex> __lk(__mut_);
508227825Stheraven    if (__state_ & deferred)
509227825Stheraven        return future_status::deferred;
510227825Stheraven    while (!(__state_ & ready) && _Clock::now() < __abs_time)
511227825Stheraven        __cv_.wait_until(__lk, __abs_time);
512227825Stheraven    if (__state_ & ready)
513227825Stheraven        return future_status::ready;
514227825Stheraven    return future_status::timeout;
515227825Stheraven}
516227825Stheraven
517227825Stheraventemplate <class _Rep, class _Period>
518227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
519227825Stheravenfuture_status
520227825Stheraven__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
521227825Stheraven{
522227825Stheraven    return wait_until(chrono::steady_clock::now() + __rel_time);
523227825Stheraven}
524227825Stheraven
525232950Stheraventemplate <class _Rp>
526227825Stheravenclass __assoc_state
527227825Stheraven    : public __assoc_sub_state
528227825Stheraven{
529227825Stheraven    typedef __assoc_sub_state base;
530232950Stheraven    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
531227825Stheravenprotected:
532232950Stheraven    _Up __value_;
533227825Stheraven
534227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
535227825Stheravenpublic:
536227825Stheraven
537227825Stheraven    template <class _Arg>
538227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
539227825Stheraven        void set_value(_Arg&& __arg);
540227825Stheraven#else
541227825Stheraven        void set_value(_Arg& __arg);
542227825Stheraven#endif
543227825Stheraven
544227825Stheraven    template <class _Arg>
545227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
546227825Stheraven        void set_value_at_thread_exit(_Arg&& __arg);
547227825Stheraven#else
548227825Stheraven        void set_value_at_thread_exit(_Arg& __arg);
549227825Stheraven#endif
550227825Stheraven
551232950Stheraven    _Rp move();
552232950Stheraven    typename add_lvalue_reference<_Rp>::type copy();
553227825Stheraven};
554227825Stheraven
555232950Stheraventemplate <class _Rp>
556227825Stheravenvoid
557232950Stheraven__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
558227825Stheraven{
559227825Stheraven    if (this->__state_ & base::__constructed)
560232950Stheraven        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
561227825Stheraven    delete this;
562227825Stheraven}
563227825Stheraven
564232950Stheraventemplate <class _Rp>
565227825Stheraventemplate <class _Arg>
566227825Stheravenvoid
567227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
568232950Stheraven__assoc_state<_Rp>::set_value(_Arg&& __arg)
569227825Stheraven#else
570232950Stheraven__assoc_state<_Rp>::set_value(_Arg& __arg)
571227825Stheraven#endif
572227825Stheraven{
573227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
574227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
575227825Stheraven    if (this->__has_value())
576227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
577227825Stheraven#endif
578232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
579227825Stheraven    this->__state_ |= base::__constructed | base::ready;
580227825Stheraven    __lk.unlock();
581227825Stheraven    __cv_.notify_all();
582227825Stheraven}
583227825Stheraven
584232950Stheraventemplate <class _Rp>
585227825Stheraventemplate <class _Arg>
586227825Stheravenvoid
587227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
588232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
589227825Stheraven#else
590232950Stheraven__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
591227825Stheraven#endif
592227825Stheraven{
593227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
594227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
595227825Stheraven    if (this->__has_value())
596227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
597227825Stheraven#endif
598232950Stheraven    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
599227825Stheraven    this->__state_ |= base::__constructed;
600227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
601227825Stheraven    __lk.unlock();
602227825Stheraven}
603227825Stheraven
604232950Stheraventemplate <class _Rp>
605232950Stheraven_Rp
606232950Stheraven__assoc_state<_Rp>::move()
607227825Stheraven{
608227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
609227825Stheraven    this->__sub_wait(__lk);
610227825Stheraven    if (this->__exception_ != nullptr)
611227825Stheraven        rethrow_exception(this->__exception_);
612232950Stheraven    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
613227825Stheraven}
614227825Stheraven
615232950Stheraventemplate <class _Rp>
616232950Stheraventypename add_lvalue_reference<_Rp>::type
617232950Stheraven__assoc_state<_Rp>::copy()
618227825Stheraven{
619227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
620227825Stheraven    this->__sub_wait(__lk);
621227825Stheraven    if (this->__exception_ != nullptr)
622227825Stheraven        rethrow_exception(this->__exception_);
623232950Stheraven    return *reinterpret_cast<_Rp*>(&__value_);
624227825Stheraven}
625227825Stheraven
626232950Stheraventemplate <class _Rp>
627232950Stheravenclass __assoc_state<_Rp&>
628227825Stheraven    : public __assoc_sub_state
629227825Stheraven{
630227825Stheraven    typedef __assoc_sub_state base;
631232950Stheraven    typedef _Rp* _Up;
632227825Stheravenprotected:
633232950Stheraven    _Up __value_;
634227825Stheraven
635227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
636227825Stheravenpublic:
637227825Stheraven
638232950Stheraven    void set_value(_Rp& __arg);
639232950Stheraven    void set_value_at_thread_exit(_Rp& __arg);
640227825Stheraven
641232950Stheraven    _Rp& copy();
642227825Stheraven};
643227825Stheraven
644232950Stheraventemplate <class _Rp>
645227825Stheravenvoid
646232950Stheraven__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
647227825Stheraven{
648227825Stheraven    delete this;
649227825Stheraven}
650227825Stheraven
651232950Stheraventemplate <class _Rp>
652227825Stheravenvoid
653232950Stheraven__assoc_state<_Rp&>::set_value(_Rp& __arg)
654227825Stheraven{
655227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
656227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
657227825Stheraven    if (this->__has_value())
658227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
659227825Stheraven#endif
660227825Stheraven    __value_ = &__arg;
661227825Stheraven    this->__state_ |= base::__constructed | base::ready;
662227825Stheraven    __lk.unlock();
663227825Stheraven    __cv_.notify_all();
664227825Stheraven}
665227825Stheraven
666232950Stheraventemplate <class _Rp>
667227825Stheravenvoid
668232950Stheraven__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
669227825Stheraven{
670227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
671227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
672227825Stheraven    if (this->__has_value())
673227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
674227825Stheraven#endif
675227825Stheraven    __value_ = &__arg;
676227825Stheraven    this->__state_ |= base::__constructed;
677227825Stheraven    __thread_local_data()->__make_ready_at_thread_exit(this);
678227825Stheraven    __lk.unlock();
679227825Stheraven}
680227825Stheraven
681232950Stheraventemplate <class _Rp>
682232950Stheraven_Rp&
683232950Stheraven__assoc_state<_Rp&>::copy()
684227825Stheraven{
685227825Stheraven    unique_lock<mutex> __lk(this->__mut_);
686227825Stheraven    this->__sub_wait(__lk);
687227825Stheraven    if (this->__exception_ != nullptr)
688227825Stheraven        rethrow_exception(this->__exception_);
689227825Stheraven    return *__value_;
690227825Stheraven}
691227825Stheraven
692232950Stheraventemplate <class _Rp, class _Alloc>
693227825Stheravenclass __assoc_state_alloc
694232950Stheraven    : public __assoc_state<_Rp>
695227825Stheraven{
696232950Stheraven    typedef __assoc_state<_Rp> base;
697227825Stheraven    _Alloc __alloc_;
698227825Stheraven
699227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
700227825Stheravenpublic:
701227825Stheraven    _LIBCPP_INLINE_VISIBILITY
702227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
703227825Stheraven        : __alloc_(__a) {}
704227825Stheraven};
705227825Stheraven
706232950Stheraventemplate <class _Rp, class _Alloc>
707227825Stheravenvoid
708232950Stheraven__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
709227825Stheraven{
710227825Stheraven    if (this->__state_ & base::__constructed)
711232950Stheraven        reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
712227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
713227825Stheraven    this->~__assoc_state_alloc();
714227825Stheraven    __a.deallocate(this, 1);
715227825Stheraven}
716227825Stheraven
717232950Stheraventemplate <class _Rp, class _Alloc>
718232950Stheravenclass __assoc_state_alloc<_Rp&, _Alloc>
719232950Stheraven    : public __assoc_state<_Rp&>
720227825Stheraven{
721232950Stheraven    typedef __assoc_state<_Rp&> base;
722227825Stheraven    _Alloc __alloc_;
723227825Stheraven
724227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
725227825Stheravenpublic:
726227825Stheraven    _LIBCPP_INLINE_VISIBILITY
727227825Stheraven    explicit __assoc_state_alloc(const _Alloc& __a)
728227825Stheraven        : __alloc_(__a) {}
729227825Stheraven};
730227825Stheraven
731232950Stheraventemplate <class _Rp, class _Alloc>
732227825Stheravenvoid
733232950Stheraven__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
734227825Stheraven{
735227825Stheraven    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
736227825Stheraven    this->~__assoc_state_alloc();
737227825Stheraven    __a.deallocate(this, 1);
738227825Stheraven}
739227825Stheraven
740227825Stheraventemplate <class _Alloc>
741227825Stheravenclass __assoc_sub_state_alloc
742227825Stheraven    : public __assoc_sub_state
743227825Stheraven{
744227825Stheraven    typedef __assoc_sub_state base;
745227825Stheraven    _Alloc __alloc_;
746227825Stheraven
747227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
748227825Stheravenpublic:
749227825Stheraven    _LIBCPP_INLINE_VISIBILITY
750227825Stheraven    explicit __assoc_sub_state_alloc(const _Alloc& __a)
751227825Stheraven        : __alloc_(__a) {}
752227825Stheraven};
753227825Stheraven
754227825Stheraventemplate <class _Alloc>
755227825Stheravenvoid
756227825Stheraven__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
757227825Stheraven{
758227825Stheraven    typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
759227825Stheraven    this->~__assoc_sub_state_alloc();
760227825Stheraven    __a.deallocate(this, 1);
761227825Stheraven}
762227825Stheraven
763232950Stheraventemplate <class _Rp, class _Fp>
764227825Stheravenclass __deferred_assoc_state
765232950Stheraven    : public __assoc_state<_Rp>
766227825Stheraven{
767232950Stheraven    typedef __assoc_state<_Rp> base;
768227825Stheraven
769232950Stheraven    _Fp __func_;
770227825Stheraven
771227825Stheravenpublic:
772227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
773232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
774227825Stheraven#endif
775227825Stheraven
776227825Stheraven    virtual void __execute();
777227825Stheraven};
778227825Stheraven
779227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
780227825Stheraven
781232950Stheraventemplate <class _Rp, class _Fp>
782227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
783232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
784232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
785227825Stheraven{
786227825Stheraven    this->__set_deferred();
787227825Stheraven}
788227825Stheraven
789227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
790227825Stheraven
791232950Stheraventemplate <class _Rp, class _Fp>
792227825Stheravenvoid
793232950Stheraven__deferred_assoc_state<_Rp, _Fp>::__execute()
794227825Stheraven{
795227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
796227825Stheraven    try
797227825Stheraven    {
798227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
799227825Stheraven        this->set_value(__func_());
800227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
801227825Stheraven    }
802227825Stheraven    catch (...)
803227825Stheraven    {
804227825Stheraven        this->set_exception(current_exception());
805227825Stheraven    }
806227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
807227825Stheraven}
808227825Stheraven
809232950Stheraventemplate <class _Fp>
810232950Stheravenclass __deferred_assoc_state<void, _Fp>
811227825Stheraven    : public __assoc_sub_state
812227825Stheraven{
813227825Stheraven    typedef __assoc_sub_state base;
814227825Stheraven
815232950Stheraven    _Fp __func_;
816227825Stheraven
817227825Stheravenpublic:
818227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
819232950Stheraven    explicit __deferred_assoc_state(_Fp&& __f);
820227825Stheraven#endif
821227825Stheraven
822227825Stheraven    virtual void __execute();
823227825Stheraven};
824227825Stheraven
825227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
826227825Stheraven
827232950Stheraventemplate <class _Fp>
828227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
829232950Stheraven__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
830232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
831227825Stheraven{
832227825Stheraven    this->__set_deferred();
833227825Stheraven}
834227825Stheraven
835227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
836227825Stheraven
837232950Stheraventemplate <class _Fp>
838227825Stheravenvoid
839232950Stheraven__deferred_assoc_state<void, _Fp>::__execute()
840227825Stheraven{
841227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
842227825Stheraven    try
843227825Stheraven    {
844227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
845227825Stheraven        __func_();
846227825Stheraven        this->set_value();
847227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
848227825Stheraven    }
849227825Stheraven    catch (...)
850227825Stheraven    {
851227825Stheraven        this->set_exception(current_exception());
852227825Stheraven    }
853227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
854227825Stheraven}
855227825Stheraven
856232950Stheraventemplate <class _Rp, class _Fp>
857227825Stheravenclass __async_assoc_state
858232950Stheraven    : public __assoc_state<_Rp>
859227825Stheraven{
860232950Stheraven    typedef __assoc_state<_Rp> base;
861227825Stheraven
862232950Stheraven    _Fp __func_;
863227825Stheraven
864227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
865227825Stheravenpublic:
866227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
867232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
868227825Stheraven#endif
869227825Stheraven
870227825Stheraven    virtual void __execute();
871227825Stheraven};
872227825Stheraven
873227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
874227825Stheraven
875232950Stheraventemplate <class _Rp, class _Fp>
876227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
877232950Stheraven__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
878232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
879227825Stheraven{
880227825Stheraven}
881227825Stheraven
882227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
883227825Stheraven
884232950Stheraventemplate <class _Rp, class _Fp>
885227825Stheravenvoid
886232950Stheraven__async_assoc_state<_Rp, _Fp>::__execute()
887227825Stheraven{
888227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
889227825Stheraven    try
890227825Stheraven    {
891227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
892227825Stheraven        this->set_value(__func_());
893227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
894227825Stheraven    }
895227825Stheraven    catch (...)
896227825Stheraven    {
897227825Stheraven        this->set_exception(current_exception());
898227825Stheraven    }
899227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
900227825Stheraven}
901227825Stheraven
902232950Stheraventemplate <class _Rp, class _Fp>
903227825Stheravenvoid
904232950Stheraven__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
905227825Stheraven{
906227825Stheraven    this->wait();
907227825Stheraven    base::__on_zero_shared();
908227825Stheraven}
909227825Stheraven
910232950Stheraventemplate <class _Fp>
911232950Stheravenclass __async_assoc_state<void, _Fp>
912227825Stheraven    : public __assoc_sub_state
913227825Stheraven{
914227825Stheraven    typedef __assoc_sub_state base;
915227825Stheraven
916232950Stheraven    _Fp __func_;
917227825Stheraven
918227825Stheraven    virtual void __on_zero_shared() _NOEXCEPT;
919227825Stheravenpublic:
920227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
921232950Stheraven    explicit __async_assoc_state(_Fp&& __f);
922227825Stheraven#endif
923227825Stheraven
924227825Stheraven    virtual void __execute();
925227825Stheraven};
926227825Stheraven
927227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
928227825Stheraven
929232950Stheraventemplate <class _Fp>
930227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
931232950Stheraven__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
932232950Stheraven    : __func_(_VSTD::forward<_Fp>(__f))
933227825Stheraven{
934227825Stheraven}
935227825Stheraven
936227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
937227825Stheraven
938232950Stheraventemplate <class _Fp>
939227825Stheravenvoid
940232950Stheraven__async_assoc_state<void, _Fp>::__execute()
941227825Stheraven{
942227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
943227825Stheraven    try
944227825Stheraven    {
945227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
946227825Stheraven        __func_();
947227825Stheraven        this->set_value();
948227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
949227825Stheraven    }
950227825Stheraven    catch (...)
951227825Stheraven    {
952227825Stheraven        this->set_exception(current_exception());
953227825Stheraven    }
954227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
955227825Stheraven}
956227825Stheraven
957232950Stheraventemplate <class _Fp>
958227825Stheravenvoid
959232950Stheraven__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
960227825Stheraven{
961227825Stheraven    this->wait();
962227825Stheraven    base::__on_zero_shared();
963227825Stheraven}
964227825Stheraven
965241903Sdimtemplate <class _Rp> class _LIBCPP_VISIBLE promise;
966241903Sdimtemplate <class _Rp> class _LIBCPP_VISIBLE shared_future;
967227825Stheraven
968227825Stheraven// future
969227825Stheraven
970241903Sdimtemplate <class _Rp> class _LIBCPP_VISIBLE future;
971227825Stheraven
972232950Stheraventemplate <class _Rp, class _Fp>
973232950Stheravenfuture<_Rp>
974227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
975232950Stheraven__make_deferred_assoc_state(_Fp&& __f);
976227825Stheraven#else
977232950Stheraven__make_deferred_assoc_state(_Fp __f);
978227825Stheraven#endif
979227825Stheraven
980232950Stheraventemplate <class _Rp, class _Fp>
981232950Stheravenfuture<_Rp>
982227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
983232950Stheraven__make_async_assoc_state(_Fp&& __f);
984227825Stheraven#else
985232950Stheraven__make_async_assoc_state(_Fp __f);
986227825Stheraven#endif
987227825Stheraven
988232950Stheraventemplate <class _Rp>
989227825Stheravenclass _LIBCPP_VISIBLE future
990227825Stheraven{
991232950Stheraven    __assoc_state<_Rp>* __state_;
992227825Stheraven
993232950Stheraven    explicit future(__assoc_state<_Rp>* __state);
994227825Stheraven
995227825Stheraven    template <class> friend class promise;
996227825Stheraven    template <class> friend class shared_future;
997227825Stheraven
998227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
999232950Stheraven    template <class _R1, class _Fp>
1000232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1001232950Stheraven    template <class _R1, class _Fp>
1002232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1003227825Stheraven#else
1004232950Stheraven    template <class _R1, class _Fp>
1005232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1006232950Stheraven    template <class _R1, class _Fp>
1007232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1008227825Stheraven#endif
1009227825Stheraven
1010227825Stheravenpublic:
1011227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1012241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1013227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1014227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1015241903Sdim    future(future&& __rhs) _NOEXCEPT
1016227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1017227825Stheraven    future(const future&) = delete;
1018227825Stheraven    future& operator=(const future&) = delete;
1019227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1020241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1021227825Stheraven        {
1022227825Stheraven            future(std::move(__rhs)).swap(*this);
1023227825Stheraven            return *this;
1024227825Stheraven        }
1025227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1026227825Stheravenprivate:
1027227825Stheraven    future(const future&);
1028227825Stheraven    future& operator=(const future&);
1029227825Stheravenpublic:
1030227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1031227825Stheraven    ~future();
1032232950Stheraven    shared_future<_Rp> share();
1033227825Stheraven
1034227825Stheraven    // retrieving the value
1035232950Stheraven    _Rp get();
1036227825Stheraven
1037227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1038241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1039227825Stheraven
1040227825Stheraven    // functions to check state
1041227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1042241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1043227825Stheraven
1044227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1045227825Stheraven    void wait() const {__state_->wait();}
1046227825Stheraven    template <class _Rep, class _Period>
1047227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1048227825Stheraven        future_status
1049227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1050227825Stheraven            {return __state_->wait_for(__rel_time);}
1051227825Stheraven    template <class _Clock, class _Duration>
1052227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1053227825Stheraven        future_status
1054227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1055227825Stheraven            {return __state_->wait_until(__abs_time);}
1056227825Stheraven};
1057227825Stheraven
1058232950Stheraventemplate <class _Rp>
1059232950Stheravenfuture<_Rp>::future(__assoc_state<_Rp>* __state)
1060227825Stheraven    : __state_(__state)
1061227825Stheraven{
1062227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1063227825Stheraven    if (__state_->__has_future_attached())
1064227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1065227825Stheraven#endif
1066227825Stheraven    __state_->__add_shared();
1067227825Stheraven    __state_->__set_future_attached();
1068227825Stheraven}
1069227825Stheraven
1070227825Stheravenstruct __release_shared_count
1071227825Stheraven{
1072227825Stheraven    void operator()(__shared_count* p) {p->__release_shared();}
1073227825Stheraven};
1074227825Stheraven
1075232950Stheraventemplate <class _Rp>
1076232950Stheravenfuture<_Rp>::~future()
1077227825Stheraven{
1078227825Stheraven    if (__state_)
1079227825Stheraven        __state_->__release_shared();
1080227825Stheraven}
1081227825Stheraven
1082232950Stheraventemplate <class _Rp>
1083232950Stheraven_Rp
1084232950Stheravenfuture<_Rp>::get()
1085227825Stheraven{
1086227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1087232950Stheraven    __assoc_state<_Rp>* __s = __state_;
1088227825Stheraven    __state_ = nullptr;
1089227825Stheraven    return __s->move();
1090227825Stheraven}
1091227825Stheraven
1092232950Stheraventemplate <class _Rp>
1093232950Stheravenclass _LIBCPP_VISIBLE future<_Rp&>
1094227825Stheraven{
1095232950Stheraven    __assoc_state<_Rp&>* __state_;
1096227825Stheraven
1097232950Stheraven    explicit future(__assoc_state<_Rp&>* __state);
1098227825Stheraven
1099227825Stheraven    template <class> friend class promise;
1100227825Stheraven    template <class> friend class shared_future;
1101227825Stheraven
1102227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1103232950Stheraven    template <class _R1, class _Fp>
1104232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1105232950Stheraven    template <class _R1, class _Fp>
1106232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1107227825Stheraven#else
1108232950Stheraven    template <class _R1, class _Fp>
1109232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1110232950Stheraven    template <class _R1, class _Fp>
1111232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1112227825Stheraven#endif
1113227825Stheraven
1114227825Stheravenpublic:
1115227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1116241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1117227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1118227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1119241903Sdim    future(future&& __rhs) _NOEXCEPT
1120227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1121227825Stheraven    future(const future&) = delete;
1122227825Stheraven    future& operator=(const future&) = delete;
1123227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1124241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1125227825Stheraven        {
1126227825Stheraven            future(std::move(__rhs)).swap(*this);
1127227825Stheraven            return *this;
1128227825Stheraven        }
1129227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1130227825Stheravenprivate:
1131227825Stheraven    future(const future&);
1132227825Stheraven    future& operator=(const future&);
1133227825Stheravenpublic:
1134227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1135227825Stheraven    ~future();
1136232950Stheraven    shared_future<_Rp&> share();
1137227825Stheraven
1138227825Stheraven    // retrieving the value
1139232950Stheraven    _Rp& get();
1140227825Stheraven
1141227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1142241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1143227825Stheraven
1144227825Stheraven    // functions to check state
1145227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1146241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1147227825Stheraven
1148227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1149227825Stheraven    void wait() const {__state_->wait();}
1150227825Stheraven    template <class _Rep, class _Period>
1151227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1152227825Stheraven        future_status
1153227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1154227825Stheraven            {return __state_->wait_for(__rel_time);}
1155227825Stheraven    template <class _Clock, class _Duration>
1156227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1157227825Stheraven        future_status
1158227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1159227825Stheraven            {return __state_->wait_until(__abs_time);}
1160227825Stheraven};
1161227825Stheraven
1162232950Stheraventemplate <class _Rp>
1163232950Stheravenfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
1164227825Stheraven    : __state_(__state)
1165227825Stheraven{
1166227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1167227825Stheraven    if (__state_->__has_future_attached())
1168227825Stheraven        throw future_error(make_error_code(future_errc::future_already_retrieved));
1169227825Stheraven#endif
1170227825Stheraven    __state_->__add_shared();
1171227825Stheraven    __state_->__set_future_attached();
1172227825Stheraven}
1173227825Stheraven
1174232950Stheraventemplate <class _Rp>
1175232950Stheravenfuture<_Rp&>::~future()
1176227825Stheraven{
1177227825Stheraven    if (__state_)
1178227825Stheraven        __state_->__release_shared();
1179227825Stheraven}
1180227825Stheraven
1181232950Stheraventemplate <class _Rp>
1182232950Stheraven_Rp&
1183232950Stheravenfuture<_Rp&>::get()
1184227825Stheraven{
1185227825Stheraven    unique_ptr<__shared_count, __release_shared_count> __(__state_);
1186232950Stheraven    __assoc_state<_Rp&>* __s = __state_;
1187227825Stheraven    __state_ = nullptr;
1188227825Stheraven    return __s->copy();
1189227825Stheraven}
1190227825Stheraven
1191227825Stheraventemplate <>
1192227825Stheravenclass _LIBCPP_VISIBLE future<void>
1193227825Stheraven{
1194227825Stheraven    __assoc_sub_state* __state_;
1195227825Stheraven
1196227825Stheraven    explicit future(__assoc_sub_state* __state);
1197227825Stheraven
1198227825Stheraven    template <class> friend class promise;
1199227825Stheraven    template <class> friend class shared_future;
1200227825Stheraven
1201227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1202232950Stheraven    template <class _R1, class _Fp>
1203232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1204232950Stheraven    template <class _R1, class _Fp>
1205232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
1206227825Stheraven#else
1207232950Stheraven    template <class _R1, class _Fp>
1208232950Stheraven        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1209232950Stheraven    template <class _R1, class _Fp>
1210232950Stheraven        friend future<_R1> __make_async_assoc_state(_Fp __f);
1211227825Stheraven#endif
1212227825Stheraven
1213227825Stheravenpublic:
1214227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1215241903Sdim    future() _NOEXCEPT : __state_(nullptr) {}
1216227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1217227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1218241903Sdim    future(future&& __rhs) _NOEXCEPT
1219227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1220227825Stheraven    future(const future&) = delete;
1221227825Stheraven    future& operator=(const future&) = delete;
1222227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1223241903Sdim    future& operator=(future&& __rhs) _NOEXCEPT
1224227825Stheraven        {
1225227825Stheraven            future(std::move(__rhs)).swap(*this);
1226227825Stheraven            return *this;
1227227825Stheraven        }
1228227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1229227825Stheravenprivate:
1230227825Stheraven    future(const future&);
1231227825Stheraven    future& operator=(const future&);
1232227825Stheravenpublic:
1233227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1234227825Stheraven    ~future();
1235227825Stheraven    shared_future<void> share();
1236227825Stheraven
1237227825Stheraven    // retrieving the value
1238227825Stheraven    void get();
1239227825Stheraven
1240227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1241241903Sdim    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1242227825Stheraven
1243227825Stheraven    // functions to check state
1244227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1245241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
1246227825Stheraven
1247227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1248227825Stheraven    void wait() const {__state_->wait();}
1249227825Stheraven    template <class _Rep, class _Period>
1250227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1251227825Stheraven        future_status
1252227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1253227825Stheraven            {return __state_->wait_for(__rel_time);}
1254227825Stheraven    template <class _Clock, class _Duration>
1255227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1256227825Stheraven        future_status
1257227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1258227825Stheraven            {return __state_->wait_until(__abs_time);}
1259227825Stheraven};
1260227825Stheraven
1261232950Stheraventemplate <class _Rp>
1262227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1263227825Stheravenvoid
1264241903Sdimswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
1265227825Stheraven{
1266227825Stheraven    __x.swap(__y);
1267227825Stheraven}
1268227825Stheraven
1269227825Stheraven// promise<R>
1270227825Stheraven
1271227825Stheraventemplate <class _Callable> class packaged_task;
1272227825Stheraven
1273232950Stheraventemplate <class _Rp>
1274227825Stheravenclass _LIBCPP_VISIBLE promise
1275227825Stheraven{
1276232950Stheraven    __assoc_state<_Rp>* __state_;
1277227825Stheraven
1278227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1279241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1280227825Stheraven
1281227825Stheraven    template <class> friend class packaged_task;
1282227825Stheravenpublic:
1283227825Stheraven    promise();
1284227825Stheraven    template <class _Alloc>
1285227825Stheraven        promise(allocator_arg_t, const _Alloc& __a);
1286227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1287227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1288241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1289227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1290227825Stheraven    promise(const promise& __rhs) = delete;
1291227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1292227825Stheravenprivate:
1293227825Stheraven    promise(const promise& __rhs);
1294227825Stheravenpublic:
1295227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1296227825Stheraven    ~promise();
1297227825Stheraven
1298227825Stheraven    // assignment
1299227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1300227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1301241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1302227825Stheraven        {
1303227825Stheraven            promise(std::move(__rhs)).swap(*this);
1304227825Stheraven            return *this;
1305227825Stheraven        }
1306227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1307227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1308227825Stheravenprivate:
1309227825Stheraven    promise& operator=(const promise& __rhs);
1310227825Stheravenpublic:
1311227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1312227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1313241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1314227825Stheraven
1315227825Stheraven    // retrieving the result
1316232950Stheraven    future<_Rp> get_future();
1317227825Stheraven
1318227825Stheraven    // setting the result
1319232950Stheraven    void set_value(const _Rp& __r);
1320227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1321232950Stheraven    void set_value(_Rp&& __r);
1322227825Stheraven#endif
1323227825Stheraven    void set_exception(exception_ptr __p);
1324227825Stheraven
1325227825Stheraven    // setting the result with deferred notification
1326232950Stheraven    void set_value_at_thread_exit(const _Rp& __r);
1327227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1328232950Stheraven    void set_value_at_thread_exit(_Rp&& __r);
1329227825Stheraven#endif
1330227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1331227825Stheraven};
1332227825Stheraven
1333232950Stheraventemplate <class _Rp>
1334232950Stheravenpromise<_Rp>::promise()
1335232950Stheraven    : __state_(new __assoc_state<_Rp>)
1336227825Stheraven{
1337227825Stheraven}
1338227825Stheraven
1339232950Stheraventemplate <class _Rp>
1340227825Stheraventemplate <class _Alloc>
1341232950Stheravenpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
1342227825Stheraven{
1343232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
1344227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1345227825Stheraven    _A2 __a(__a0);
1346232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1347232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
1348227825Stheraven    __state_ = __hold.release();
1349227825Stheraven}
1350227825Stheraven
1351232950Stheraventemplate <class _Rp>
1352232950Stheravenpromise<_Rp>::~promise()
1353227825Stheraven{
1354227825Stheraven    if (__state_)
1355227825Stheraven    {
1356227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1357227825Stheraven            __state_->set_exception(make_exception_ptr(
1358227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1359227825Stheraven                                                      ));
1360227825Stheraven        __state_->__release_shared();
1361227825Stheraven    }
1362227825Stheraven}
1363227825Stheraven
1364232950Stheraventemplate <class _Rp>
1365232950Stheravenfuture<_Rp>
1366232950Stheravenpromise<_Rp>::get_future()
1367227825Stheraven{
1368227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1369227825Stheraven    if (__state_ == nullptr)
1370227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1371227825Stheraven#endif
1372232950Stheraven    return future<_Rp>(__state_);
1373227825Stheraven}
1374227825Stheraven
1375232950Stheraventemplate <class _Rp>
1376227825Stheravenvoid
1377232950Stheravenpromise<_Rp>::set_value(const _Rp& __r)
1378227825Stheraven{
1379227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1380227825Stheraven    if (__state_ == nullptr)
1381227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1382227825Stheraven#endif
1383227825Stheraven    __state_->set_value(__r);
1384227825Stheraven}
1385227825Stheraven
1386227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1387227825Stheraven
1388232950Stheraventemplate <class _Rp>
1389227825Stheravenvoid
1390232950Stheravenpromise<_Rp>::set_value(_Rp&& __r)
1391227825Stheraven{
1392227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1393227825Stheraven    if (__state_ == nullptr)
1394227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1395227825Stheraven#endif
1396227825Stheraven    __state_->set_value(_VSTD::move(__r));
1397227825Stheraven}
1398227825Stheraven
1399227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1400227825Stheraven
1401232950Stheraventemplate <class _Rp>
1402227825Stheravenvoid
1403232950Stheravenpromise<_Rp>::set_exception(exception_ptr __p)
1404227825Stheraven{
1405227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1406227825Stheraven    if (__state_ == nullptr)
1407227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1408227825Stheraven#endif
1409227825Stheraven    __state_->set_exception(__p);
1410227825Stheraven}
1411227825Stheraven
1412232950Stheraventemplate <class _Rp>
1413227825Stheravenvoid
1414232950Stheravenpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
1415227825Stheraven{
1416227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1417227825Stheraven    if (__state_ == nullptr)
1418227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1419227825Stheraven#endif
1420227825Stheraven    __state_->set_value_at_thread_exit(__r);
1421227825Stheraven}
1422227825Stheraven
1423227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1424227825Stheraven
1425232950Stheraventemplate <class _Rp>
1426227825Stheravenvoid
1427232950Stheravenpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
1428227825Stheraven{
1429227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1430227825Stheraven    if (__state_ == nullptr)
1431227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1432227825Stheraven#endif
1433227825Stheraven    __state_->set_value_at_thread_exit(_VSTD::move(__r));
1434227825Stheraven}
1435227825Stheraven
1436227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1437227825Stheraven
1438232950Stheraventemplate <class _Rp>
1439227825Stheravenvoid
1440232950Stheravenpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
1441227825Stheraven{
1442227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1443227825Stheraven    if (__state_ == nullptr)
1444227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1445227825Stheraven#endif
1446227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1447227825Stheraven}
1448227825Stheraven
1449227825Stheraven// promise<R&>
1450227825Stheraven
1451232950Stheraventemplate <class _Rp>
1452232950Stheravenclass _LIBCPP_VISIBLE promise<_Rp&>
1453227825Stheraven{
1454232950Stheraven    __assoc_state<_Rp&>* __state_;
1455227825Stheraven
1456227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1457241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1458227825Stheraven
1459227825Stheraven    template <class> friend class packaged_task;
1460227825Stheraven
1461227825Stheravenpublic:
1462227825Stheraven    promise();
1463227825Stheraven    template <class _Allocator>
1464227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1465227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1466227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1467241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1468227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1469227825Stheraven    promise(const promise& __rhs) = delete;
1470227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1471227825Stheravenprivate:
1472227825Stheraven    promise(const promise& __rhs);
1473227825Stheravenpublic:
1474227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1475227825Stheraven    ~promise();
1476227825Stheraven
1477227825Stheraven    // assignment
1478227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1479227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1480241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1481227825Stheraven        {
1482227825Stheraven            promise(std::move(__rhs)).swap(*this);
1483227825Stheraven            return *this;
1484227825Stheraven        }
1485227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1486227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1487227825Stheravenprivate:
1488227825Stheraven    promise& operator=(const promise& __rhs);
1489227825Stheravenpublic:
1490227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1491227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1492241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1493227825Stheraven
1494227825Stheraven    // retrieving the result
1495232950Stheraven    future<_Rp&> get_future();
1496227825Stheraven
1497227825Stheraven    // setting the result
1498232950Stheraven    void set_value(_Rp& __r);
1499227825Stheraven    void set_exception(exception_ptr __p);
1500227825Stheraven
1501227825Stheraven    // setting the result with deferred notification
1502232950Stheraven    void set_value_at_thread_exit(_Rp&);
1503227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1504227825Stheraven};
1505227825Stheraven
1506232950Stheraventemplate <class _Rp>
1507232950Stheravenpromise<_Rp&>::promise()
1508232950Stheraven    : __state_(new __assoc_state<_Rp&>)
1509227825Stheraven{
1510227825Stheraven}
1511227825Stheraven
1512232950Stheraventemplate <class _Rp>
1513227825Stheraventemplate <class _Alloc>
1514232950Stheravenpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
1515227825Stheraven{
1516232950Stheraven    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
1517227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1518227825Stheraven    _A2 __a(__a0);
1519232950Stheraven    unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1520232950Stheraven    ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
1521227825Stheraven    __state_ = __hold.release();
1522227825Stheraven}
1523227825Stheraven
1524232950Stheraventemplate <class _Rp>
1525232950Stheravenpromise<_Rp&>::~promise()
1526227825Stheraven{
1527227825Stheraven    if (__state_)
1528227825Stheraven    {
1529227825Stheraven        if (!__state_->__has_value() && __state_->use_count() > 1)
1530227825Stheraven            __state_->set_exception(make_exception_ptr(
1531227825Stheraven                      future_error(make_error_code(future_errc::broken_promise))
1532227825Stheraven                                                      ));
1533227825Stheraven        __state_->__release_shared();
1534227825Stheraven    }
1535227825Stheraven}
1536227825Stheraven
1537232950Stheraventemplate <class _Rp>
1538232950Stheravenfuture<_Rp&>
1539232950Stheravenpromise<_Rp&>::get_future()
1540227825Stheraven{
1541227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1542227825Stheraven    if (__state_ == nullptr)
1543227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1544227825Stheraven#endif
1545232950Stheraven    return future<_Rp&>(__state_);
1546227825Stheraven}
1547227825Stheraven
1548232950Stheraventemplate <class _Rp>
1549227825Stheravenvoid
1550232950Stheravenpromise<_Rp&>::set_value(_Rp& __r)
1551227825Stheraven{
1552227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1553227825Stheraven    if (__state_ == nullptr)
1554227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1555227825Stheraven#endif
1556227825Stheraven    __state_->set_value(__r);
1557227825Stheraven}
1558227825Stheraven
1559232950Stheraventemplate <class _Rp>
1560227825Stheravenvoid
1561232950Stheravenpromise<_Rp&>::set_exception(exception_ptr __p)
1562227825Stheraven{
1563227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1564227825Stheraven    if (__state_ == nullptr)
1565227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1566227825Stheraven#endif
1567227825Stheraven    __state_->set_exception(__p);
1568227825Stheraven}
1569227825Stheraven
1570232950Stheraventemplate <class _Rp>
1571227825Stheravenvoid
1572232950Stheravenpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
1573227825Stheraven{
1574227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1575227825Stheraven    if (__state_ == nullptr)
1576227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1577227825Stheraven#endif
1578227825Stheraven    __state_->set_value_at_thread_exit(__r);
1579227825Stheraven}
1580227825Stheraven
1581232950Stheraventemplate <class _Rp>
1582227825Stheravenvoid
1583232950Stheravenpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
1584227825Stheraven{
1585227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1586227825Stheraven    if (__state_ == nullptr)
1587227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1588227825Stheraven#endif
1589227825Stheraven    __state_->set_exception_at_thread_exit(__p);
1590227825Stheraven}
1591227825Stheraven
1592227825Stheraven// promise<void>
1593227825Stheraven
1594227825Stheraventemplate <>
1595227825Stheravenclass _LIBCPP_VISIBLE promise<void>
1596227825Stheraven{
1597227825Stheraven    __assoc_sub_state* __state_;
1598227825Stheraven
1599227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1600241903Sdim    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
1601227825Stheraven
1602227825Stheraven    template <class> friend class packaged_task;
1603227825Stheraven
1604227825Stheravenpublic:
1605227825Stheraven    promise();
1606227825Stheraven    template <class _Allocator>
1607227825Stheraven        promise(allocator_arg_t, const _Allocator& __a);
1608227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1609227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1610241903Sdim    promise(promise&& __rhs) _NOEXCEPT
1611227825Stheraven        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1612227825Stheraven    promise(const promise& __rhs) = delete;
1613227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1614227825Stheravenprivate:
1615227825Stheraven    promise(const promise& __rhs);
1616227825Stheravenpublic:
1617227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1618227825Stheraven    ~promise();
1619227825Stheraven
1620227825Stheraven    // assignment
1621227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1622227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1623241903Sdim    promise& operator=(promise&& __rhs) _NOEXCEPT
1624227825Stheraven        {
1625227825Stheraven            promise(std::move(__rhs)).swap(*this);
1626227825Stheraven            return *this;
1627227825Stheraven        }
1628227825Stheraven    promise& operator=(const promise& __rhs) = delete;
1629227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1630227825Stheravenprivate:
1631227825Stheraven    promise& operator=(const promise& __rhs);
1632227825Stheravenpublic:
1633227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1634227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1635241903Sdim    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
1636227825Stheraven
1637227825Stheraven    // retrieving the result
1638227825Stheraven    future<void> get_future();
1639227825Stheraven
1640227825Stheraven    // setting the result
1641227825Stheraven    void set_value();
1642227825Stheraven    void set_exception(exception_ptr __p);
1643227825Stheraven
1644227825Stheraven    // setting the result with deferred notification
1645227825Stheraven    void set_value_at_thread_exit();
1646227825Stheraven    void set_exception_at_thread_exit(exception_ptr __p);
1647227825Stheraven};
1648227825Stheraven
1649227825Stheraventemplate <class _Alloc>
1650227825Stheravenpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1651227825Stheraven{
1652227825Stheraven    typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1653227825Stheraven    typedef __allocator_destructor<_A2> _D2;
1654227825Stheraven    _A2 __a(__a0);
1655227825Stheraven    unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1656227825Stheraven    ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1657227825Stheraven    __state_ = __hold.release();
1658227825Stheraven}
1659227825Stheraven
1660232950Stheraventemplate <class _Rp>
1661227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1662227825Stheravenvoid
1663241903Sdimswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
1664227825Stheraven{
1665227825Stheraven    __x.swap(__y);
1666227825Stheraven}
1667227825Stheraven
1668232950Stheraventemplate <class _Rp, class _Alloc>
1669232950Stheraven    struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc>
1670227825Stheraven        : public true_type {};
1671227825Stheraven
1672227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
1673227825Stheraven
1674227825Stheraven// packaged_task
1675227825Stheraven
1676227825Stheraventemplate<class _Fp> class __packaged_task_base;
1677227825Stheraven
1678232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1679232950Stheravenclass __packaged_task_base<_Rp(_ArgTypes...)>
1680227825Stheraven{
1681227825Stheraven    __packaged_task_base(const __packaged_task_base&);
1682227825Stheraven    __packaged_task_base& operator=(const __packaged_task_base&);
1683227825Stheravenpublic:
1684227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1685227825Stheraven    __packaged_task_base() {}
1686227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1687227825Stheraven    virtual ~__packaged_task_base() {}
1688241903Sdim    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
1689227825Stheraven    virtual void destroy() = 0;
1690227825Stheraven    virtual void destroy_deallocate() = 0;
1691232950Stheraven    virtual _Rp operator()(_ArgTypes&& ...) = 0;
1692227825Stheraven};
1693227825Stheraven
1694227825Stheraventemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1695227825Stheraven
1696232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1697232950Stheravenclass __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1698232950Stheraven    : public  __packaged_task_base<_Rp(_ArgTypes...)>
1699227825Stheraven{
1700232950Stheraven    __compressed_pair<_Fp, _Alloc> __f_;
1701227825Stheravenpublic:
1702227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1703232950Stheraven    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
1704227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1705232950Stheraven    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
1706227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1707232950Stheraven    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
1708227825Stheraven        : __f_(__f, __a) {}
1709227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1710232950Stheraven    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
1711227825Stheraven        : __f_(_VSTD::move(__f), __a) {}
1712241903Sdim    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
1713227825Stheraven    virtual void destroy();
1714227825Stheraven    virtual void destroy_deallocate();
1715232950Stheraven    virtual _Rp operator()(_ArgTypes&& ... __args);
1716227825Stheraven};
1717227825Stheraven
1718232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1719227825Stheravenvoid
1720232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1721241903Sdim                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
1722227825Stheraven{
1723227825Stheraven    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
1724227825Stheraven}
1725227825Stheraven
1726232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1727227825Stheravenvoid
1728232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
1729227825Stheraven{
1730232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1731227825Stheraven}
1732227825Stheraven
1733232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1734227825Stheravenvoid
1735232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
1736227825Stheraven{
1737232950Stheraven    typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1738232950Stheraven    _Ap __a(__f_.second());
1739232950Stheraven    __f_.~__compressed_pair<_Fp, _Alloc>();
1740227825Stheraven    __a.deallocate(this, 1);
1741227825Stheraven}
1742227825Stheraven
1743232950Stheraventemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1744232950Stheraven_Rp
1745232950Stheraven__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
1746227825Stheraven{
1747227825Stheraven    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
1748227825Stheraven}
1749227825Stheraven
1750227825Stheraventemplate <class _Callable> class __packaged_task_function;
1751227825Stheraven
1752232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1753232950Stheravenclass __packaged_task_function<_Rp(_ArgTypes...)>
1754227825Stheraven{
1755232950Stheraven    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1756227825Stheraven    aligned_storage<3*sizeof(void*)>::type __buf_;
1757227825Stheraven    __base* __f_;
1758227825Stheraven
1759227825Stheravenpublic:
1760232950Stheraven    typedef _Rp result_type;
1761227825Stheraven
1762227825Stheraven    // construct/copy/destroy:
1763227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1764241903Sdim    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
1765232950Stheraven    template<class _Fp>
1766232950Stheraven      __packaged_task_function(_Fp&& __f);
1767232950Stheraven    template<class _Fp, class _Alloc>
1768232950Stheraven      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
1769227825Stheraven
1770241903Sdim    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1771241903Sdim    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
1772227825Stheraven
1773227825Stheraven    __packaged_task_function(const __packaged_task_function&) =  delete;
1774227825Stheraven    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
1775227825Stheraven
1776227825Stheraven    ~__packaged_task_function();
1777227825Stheraven
1778241903Sdim    void swap(__packaged_task_function&) _NOEXCEPT;
1779227825Stheraven
1780232950Stheraven    _Rp operator()(_ArgTypes...) const;
1781227825Stheraven};
1782227825Stheraven
1783232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1784241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
1785227825Stheraven{
1786227825Stheraven    if (__f.__f_ == nullptr)
1787227825Stheraven        __f_ = nullptr;
1788227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1789227825Stheraven    {
1790227825Stheraven        __f_ = (__base*)&__buf_;
1791227825Stheraven        __f.__f_->__move_to(__f_);
1792227825Stheraven    }
1793227825Stheraven    else
1794227825Stheraven    {
1795227825Stheraven        __f_ = __f.__f_;
1796227825Stheraven        __f.__f_ = nullptr;
1797227825Stheraven    }
1798227825Stheraven}
1799227825Stheraven
1800232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1801232950Stheraventemplate <class _Fp>
1802232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
1803227825Stheraven    : __f_(nullptr)
1804227825Stheraven{
1805232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1806232950Stheraven    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
1807227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1808227825Stheraven    {
1809227825Stheraven        __f_ = (__base*)&__buf_;
1810232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1811227825Stheraven    }
1812227825Stheraven    else
1813227825Stheraven    {
1814232950Stheraven        typedef allocator<_FF> _Ap;
1815232950Stheraven        _Ap __a;
1816232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1817232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1818232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
1819227825Stheraven        __f_ = __hold.release();
1820227825Stheraven    }
1821227825Stheraven}
1822227825Stheraven
1823232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1824232950Stheraventemplate <class _Fp, class _Alloc>
1825232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1826232950Stheraven                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
1827227825Stheraven    : __f_(nullptr)
1828227825Stheraven{
1829227825Stheraven    typedef allocator_traits<_Alloc> __alloc_traits;
1830232950Stheraven    typedef typename remove_reference<_Fp>::type _FR;
1831232950Stheraven    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
1832227825Stheraven    if (sizeof(_FF) <= sizeof(__buf_))
1833227825Stheraven    {
1834227825Stheraven        __f_ = (__base*)&__buf_;
1835232950Stheraven        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
1836227825Stheraven    }
1837227825Stheraven    else
1838227825Stheraven    {
1839227825Stheraven        typedef typename __alloc_traits::template
1840227825Stheraven#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1841227825Stheraven            rebind_alloc<_FF>
1842227825Stheraven#else
1843227825Stheraven            rebind_alloc<_FF>::other
1844227825Stheraven#endif
1845232950Stheraven                                                     _Ap;
1846232950Stheraven        _Ap __a(__a0);
1847232950Stheraven        typedef __allocator_destructor<_Ap> _Dp;
1848232950Stheraven        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1849232950Stheraven        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1850227825Stheraven        __f_ = __hold.release();
1851227825Stheraven    }
1852227825Stheraven}
1853227825Stheraven
1854232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1855232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>&
1856241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
1857227825Stheraven{
1858227825Stheraven    if (__f_ == (__base*)&__buf_)
1859227825Stheraven        __f_->destroy();
1860227825Stheraven    else if (__f_)
1861227825Stheraven        __f_->destroy_deallocate();
1862227825Stheraven    __f_ = nullptr;
1863227825Stheraven    if (__f.__f_ == nullptr)
1864227825Stheraven        __f_ = nullptr;
1865227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1866227825Stheraven    {
1867227825Stheraven        __f_ = (__base*)&__buf_;
1868227825Stheraven        __f.__f_->__move_to(__f_);
1869227825Stheraven    }
1870227825Stheraven    else
1871227825Stheraven    {
1872227825Stheraven        __f_ = __f.__f_;
1873227825Stheraven        __f.__f_ = nullptr;
1874227825Stheraven    }
1875241903Sdim    return *this;
1876227825Stheraven}
1877227825Stheraven
1878232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1879232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
1880227825Stheraven{
1881227825Stheraven    if (__f_ == (__base*)&__buf_)
1882227825Stheraven        __f_->destroy();
1883227825Stheraven    else if (__f_)
1884227825Stheraven        __f_->destroy_deallocate();
1885227825Stheraven}
1886227825Stheraven
1887232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1888227825Stheravenvoid
1889241903Sdim__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
1890227825Stheraven{
1891227825Stheraven    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1892227825Stheraven    {
1893227825Stheraven        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1894227825Stheraven        __base* __t = (__base*)&__tempbuf;
1895227825Stheraven        __f_->__move_to(__t);
1896227825Stheraven        __f_->destroy();
1897227825Stheraven        __f_ = nullptr;
1898227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1899227825Stheraven        __f.__f_->destroy();
1900227825Stheraven        __f.__f_ = nullptr;
1901227825Stheraven        __f_ = (__base*)&__buf_;
1902227825Stheraven        __t->__move_to((__base*)&__f.__buf_);
1903227825Stheraven        __t->destroy();
1904227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1905227825Stheraven    }
1906227825Stheraven    else if (__f_ == (__base*)&__buf_)
1907227825Stheraven    {
1908227825Stheraven        __f_->__move_to((__base*)&__f.__buf_);
1909227825Stheraven        __f_->destroy();
1910227825Stheraven        __f_ = __f.__f_;
1911227825Stheraven        __f.__f_ = (__base*)&__f.__buf_;
1912227825Stheraven    }
1913227825Stheraven    else if (__f.__f_ == (__base*)&__f.__buf_)
1914227825Stheraven    {
1915227825Stheraven        __f.__f_->__move_to((__base*)&__buf_);
1916227825Stheraven        __f.__f_->destroy();
1917227825Stheraven        __f.__f_ = __f_;
1918227825Stheraven        __f_ = (__base*)&__buf_;
1919227825Stheraven    }
1920227825Stheraven    else
1921227825Stheraven        _VSTD::swap(__f_, __f.__f_);
1922227825Stheraven}
1923227825Stheraven
1924232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1925227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1926232950Stheraven_Rp
1927232950Stheraven__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
1928227825Stheraven{
1929227825Stheraven    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
1930227825Stheraven}
1931227825Stheraven
1932232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1933232950Stheravenclass _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)>
1934227825Stheraven{
1935227825Stheravenpublic:
1936232950Stheraven    typedef _Rp result_type;
1937227825Stheraven
1938227825Stheravenprivate:
1939227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
1940227825Stheraven    promise<result_type>                                __p_;
1941227825Stheraven
1942227825Stheravenpublic:
1943227825Stheraven    // construction and destruction
1944227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1945241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
1946232950Stheraven    template <class _Fp>
1947227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1948232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
1949232950Stheraven    template <class _Fp, class _Allocator>
1950227825Stheraven        _LIBCPP_INLINE_VISIBILITY
1951232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1952232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1953227825Stheraven               __p_(allocator_arg, __a) {}
1954227825Stheraven    // ~packaged_task() = default;
1955227825Stheraven
1956227825Stheraven    // no copy
1957241903Sdim    packaged_task(const packaged_task&) = delete;
1958241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
1959227825Stheraven
1960227825Stheraven    // move support
1961227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1962241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
1963227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
1964227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1965241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
1966227825Stheraven    {
1967227825Stheraven        __f_ = _VSTD::move(__other.__f_);
1968227825Stheraven        __p_ = _VSTD::move(__other.__p_);
1969227825Stheraven        return *this;
1970227825Stheraven    }
1971227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1972241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
1973227825Stheraven    {
1974227825Stheraven        __f_.swap(__other.__f_);
1975227825Stheraven        __p_.swap(__other.__p_);
1976227825Stheraven    }
1977227825Stheraven
1978227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1979241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
1980227825Stheraven
1981227825Stheraven    // result retrieval
1982227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1983227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
1984227825Stheraven
1985227825Stheraven    // execution
1986227825Stheraven    void operator()(_ArgTypes... __args);
1987227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
1988227825Stheraven
1989227825Stheraven    void reset();
1990227825Stheraven};
1991227825Stheraven
1992232950Stheraventemplate<class _Rp, class ..._ArgTypes>
1993227825Stheravenvoid
1994232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
1995227825Stheraven{
1996227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
1997227825Stheraven    if (__p_.__state_ == nullptr)
1998227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
1999227825Stheraven    if (__p_.__state_->__has_value())
2000227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2001227825Stheraven    try
2002227825Stheraven    {
2003227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2004227825Stheraven        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2005227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2006227825Stheraven    }
2007227825Stheraven    catch (...)
2008227825Stheraven    {
2009227825Stheraven        __p_.set_exception(current_exception());
2010227825Stheraven    }
2011227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2012227825Stheraven}
2013227825Stheraven
2014232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2015227825Stheravenvoid
2016232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2017227825Stheraven{
2018227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2019227825Stheraven    if (__p_.__state_ == nullptr)
2020227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2021227825Stheraven    if (__p_.__state_->__has_value())
2022227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2023227825Stheraven    try
2024227825Stheraven    {
2025227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2026227825Stheraven        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
2027227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2028227825Stheraven    }
2029227825Stheraven    catch (...)
2030227825Stheraven    {
2031227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2032227825Stheraven    }
2033227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2034227825Stheraven}
2035227825Stheraven
2036232950Stheraventemplate<class _Rp, class ..._ArgTypes>
2037227825Stheravenvoid
2038232950Stheravenpackaged_task<_Rp(_ArgTypes...)>::reset()
2039227825Stheraven{
2040227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2041227825Stheraven    if (!valid())
2042227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2043227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2044227825Stheraven    __p_ = promise<result_type>();
2045227825Stheraven}
2046227825Stheraven
2047227825Stheraventemplate<class ..._ArgTypes>
2048227825Stheravenclass _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
2049227825Stheraven{
2050227825Stheravenpublic:
2051227825Stheraven    typedef void result_type;
2052227825Stheraven
2053227825Stheravenprivate:
2054227825Stheraven    __packaged_task_function<result_type(_ArgTypes...)> __f_;
2055227825Stheraven    promise<result_type>                                __p_;
2056227825Stheraven
2057227825Stheravenpublic:
2058227825Stheraven    // construction and destruction
2059227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2060241903Sdim    packaged_task() _NOEXCEPT : __p_(nullptr) {}
2061232950Stheraven    template <class _Fp>
2062227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2063232950Stheraven        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2064232950Stheraven    template <class _Fp, class _Allocator>
2065227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2066232950Stheraven        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2067232950Stheraven             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2068227825Stheraven               __p_(allocator_arg, __a) {}
2069227825Stheraven    // ~packaged_task() = default;
2070227825Stheraven
2071227825Stheraven    // no copy
2072241903Sdim    packaged_task(const packaged_task&) = delete;
2073241903Sdim    packaged_task& operator=(const packaged_task&) = delete;
2074227825Stheraven
2075227825Stheraven    // move support
2076227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2077241903Sdim    packaged_task(packaged_task&& __other) _NOEXCEPT
2078227825Stheraven        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
2079227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2080241903Sdim    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
2081227825Stheraven    {
2082227825Stheraven        __f_ = _VSTD::move(__other.__f_);
2083227825Stheraven        __p_ = _VSTD::move(__other.__p_);
2084227825Stheraven        return *this;
2085227825Stheraven    }
2086227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2087241903Sdim    void swap(packaged_task& __other) _NOEXCEPT
2088227825Stheraven    {
2089227825Stheraven        __f_.swap(__other.__f_);
2090227825Stheraven        __p_.swap(__other.__p_);
2091227825Stheraven    }
2092227825Stheraven
2093227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2094241903Sdim    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
2095227825Stheraven
2096227825Stheraven    // result retrieval
2097227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2098227825Stheraven    future<result_type> get_future() {return __p_.get_future();}
2099227825Stheraven
2100227825Stheraven    // execution
2101227825Stheraven    void operator()(_ArgTypes... __args);
2102227825Stheraven    void make_ready_at_thread_exit(_ArgTypes... __args);
2103227825Stheraven
2104227825Stheraven    void reset();
2105227825Stheraven};
2106227825Stheraven
2107227825Stheraventemplate<class ..._ArgTypes>
2108227825Stheravenvoid
2109227825Stheravenpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2110227825Stheraven{
2111227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2112227825Stheraven    if (__p_.__state_ == nullptr)
2113227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2114227825Stheraven    if (__p_.__state_->__has_value())
2115227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2116227825Stheraven    try
2117227825Stheraven    {
2118227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2119227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2120227825Stheraven        __p_.set_value();
2121227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2122227825Stheraven    }
2123227825Stheraven    catch (...)
2124227825Stheraven    {
2125227825Stheraven        __p_.set_exception(current_exception());
2126227825Stheraven    }
2127227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2128227825Stheraven}
2129227825Stheraven
2130227825Stheraventemplate<class ..._ArgTypes>
2131227825Stheravenvoid
2132227825Stheravenpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2133227825Stheraven{
2134227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2135227825Stheraven    if (__p_.__state_ == nullptr)
2136227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2137227825Stheraven    if (__p_.__state_->__has_value())
2138227825Stheraven        throw future_error(make_error_code(future_errc::promise_already_satisfied));
2139227825Stheraven    try
2140227825Stheraven    {
2141227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2142227825Stheraven        __f_(_VSTD::forward<_ArgTypes>(__args)...);
2143227825Stheraven        __p_.set_value_at_thread_exit();
2144227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2145227825Stheraven    }
2146227825Stheraven    catch (...)
2147227825Stheraven    {
2148227825Stheraven        __p_.set_exception_at_thread_exit(current_exception());
2149227825Stheraven    }
2150227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2151227825Stheraven}
2152227825Stheraven
2153227825Stheraventemplate<class ..._ArgTypes>
2154227825Stheravenvoid
2155227825Stheravenpackaged_task<void(_ArgTypes...)>::reset()
2156227825Stheraven{
2157227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
2158227825Stheraven    if (!valid())
2159227825Stheraven        throw future_error(make_error_code(future_errc::no_state));
2160227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
2161227825Stheraven    __p_ = promise<result_type>();
2162227825Stheraven}
2163227825Stheraven
2164227825Stheraventemplate <class _Callable>
2165227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2166227825Stheravenvoid
2167241903Sdimswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
2168227825Stheraven{
2169227825Stheraven    __x.swap(__y);
2170227825Stheraven}
2171227825Stheraven
2172227825Stheraventemplate <class _Callable, class _Alloc>
2173227825Stheravenstruct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2174227825Stheraven    : public true_type {};
2175227825Stheraven
2176232950Stheraventemplate <class _Rp, class _Fp>
2177232950Stheravenfuture<_Rp>
2178227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2179232950Stheraven__make_deferred_assoc_state(_Fp&& __f)
2180227825Stheraven#else
2181232950Stheraven__make_deferred_assoc_state(_Fp __f)
2182227825Stheraven#endif
2183227825Stheraven{
2184232950Stheraven    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2185232950Stheraven        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2186232950Stheraven    return future<_Rp>(__h.get());
2187227825Stheraven}
2188227825Stheraven
2189232950Stheraventemplate <class _Rp, class _Fp>
2190232950Stheravenfuture<_Rp>
2191227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2192232950Stheraven__make_async_assoc_state(_Fp&& __f)
2193227825Stheraven#else
2194232950Stheraven__make_async_assoc_state(_Fp __f)
2195227825Stheraven#endif
2196227825Stheraven{
2197232950Stheraven    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2198232950Stheraven        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2199232950Stheraven    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2200232950Stheraven    return future<_Rp>(__h.get());
2201227825Stheraven}
2202227825Stheraven
2203232950Stheraventemplate <class _Fp, class... _Args>
2204227825Stheravenclass __async_func
2205227825Stheraven{
2206232950Stheraven    tuple<_Fp, _Args...> __f_;
2207227825Stheraven
2208227825Stheravenpublic:
2209232950Stheraven    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
2210227825Stheraven
2211227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2212232950Stheraven    explicit __async_func(_Fp&& __f, _Args&&... __args)
2213227825Stheraven        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
2214227825Stheraven
2215227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2216227825Stheraven    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
2217227825Stheraven
2218232950Stheraven    _Rp operator()()
2219227825Stheraven    {
2220227825Stheraven        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2221227825Stheraven        return __execute(_Index());
2222227825Stheraven    }
2223227825Stheravenprivate:
2224227825Stheraven    template <size_t ..._Indices>
2225232950Stheraven    _Rp
2226227825Stheraven    __execute(__tuple_indices<_Indices...>)
2227227825Stheraven    {
2228227825Stheraven        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
2229227825Stheraven    }
2230227825Stheraven};
2231227825Stheraven
2232232950Stheraventemplate <class _Fp, class... _Args>
2233232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2234232950Stheravenasync(launch __policy, _Fp&& __f, _Args&&... __args)
2235227825Stheraven{
2236232950Stheraven    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2237232950Stheraven    typedef typename _BF::_Rp _Rp;
2238232950Stheraven    future<_Rp> __r;
2239232950Stheraven    if (int(__policy) & int(launch::async))
2240232950Stheraven        __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2241227825Stheraven                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
2242232950Stheraven    else if (int(__policy) & int(launch::deferred))
2243232950Stheraven        __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
2244227825Stheraven                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
2245227825Stheraven    return __r;
2246227825Stheraven}
2247227825Stheraven
2248232950Stheraventemplate <class _Fp, class... _Args>
2249227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2250232950Stheravenfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2251232950Stheravenasync(_Fp&& __f, _Args&&... __args)
2252227825Stheraven{
2253232950Stheraven    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
2254227825Stheraven                                    _VSTD::forward<_Args>(__args)...);
2255227825Stheraven}
2256227825Stheraven
2257227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
2258227825Stheraven
2259227825Stheraven// shared_future
2260227825Stheraven
2261232950Stheraventemplate <class _Rp>
2262227825Stheravenclass _LIBCPP_VISIBLE shared_future
2263227825Stheraven{
2264232950Stheraven    __assoc_state<_Rp>* __state_;
2265227825Stheraven
2266227825Stheravenpublic:
2267227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2268241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2269227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2270227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2271227825Stheraven        {if (__state_) __state_->__add_shared();}
2272227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2273227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2274241903Sdim    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
2275227825Stheraven        {__f.__state_ = nullptr;}
2276227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2277241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2278227825Stheraven        {__rhs.__state_ = nullptr;}
2279227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2280227825Stheraven    ~shared_future();
2281227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2282227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2283227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2284241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2285227825Stheraven        {
2286227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2287227825Stheraven            return *this;
2288227825Stheraven        }
2289227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2290227825Stheraven
2291227825Stheraven    // retrieving the value
2292227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2293232950Stheraven    const _Rp& get() const {return __state_->copy();}
2294227825Stheraven
2295227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2296241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2297227825Stheraven
2298227825Stheraven    // functions to check state
2299227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2300241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2301227825Stheraven
2302227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2303227825Stheraven    void wait() const {__state_->wait();}
2304227825Stheraven    template <class _Rep, class _Period>
2305227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2306227825Stheraven        future_status
2307227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2308227825Stheraven            {return __state_->wait_for(__rel_time);}
2309227825Stheraven    template <class _Clock, class _Duration>
2310227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2311227825Stheraven        future_status
2312227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2313227825Stheraven            {return __state_->wait_until(__abs_time);}
2314227825Stheraven};
2315227825Stheraven
2316232950Stheraventemplate <class _Rp>
2317232950Stheravenshared_future<_Rp>::~shared_future()
2318227825Stheraven{
2319227825Stheraven    if (__state_)
2320227825Stheraven        __state_->__release_shared();
2321227825Stheraven}
2322227825Stheraven
2323232950Stheraventemplate <class _Rp>
2324232950Stheravenshared_future<_Rp>&
2325232950Stheravenshared_future<_Rp>::operator=(const shared_future& __rhs)
2326227825Stheraven{
2327227825Stheraven    if (__rhs.__state_)
2328227825Stheraven        __rhs.__state_->__add_shared();
2329227825Stheraven    if (__state_)
2330227825Stheraven        __state_->__release_shared();
2331227825Stheraven    __state_ = __rhs.__state_;
2332227825Stheraven    return *this;
2333227825Stheraven}
2334227825Stheraven
2335232950Stheraventemplate <class _Rp>
2336232950Stheravenclass _LIBCPP_VISIBLE shared_future<_Rp&>
2337227825Stheraven{
2338232950Stheraven    __assoc_state<_Rp&>* __state_;
2339227825Stheraven
2340227825Stheravenpublic:
2341227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2342241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2343227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2344227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2345227825Stheraven        {if (__state_) __state_->__add_shared();}
2346227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2347227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2348241903Sdim    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
2349227825Stheraven        {__f.__state_ = nullptr;}
2350227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2351241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2352227825Stheraven        {__rhs.__state_ = nullptr;}
2353227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2354227825Stheraven    ~shared_future();
2355227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2356227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2357227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2358241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2359227825Stheraven        {
2360227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2361227825Stheraven            return *this;
2362227825Stheraven        }
2363227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2364227825Stheraven
2365227825Stheraven    // retrieving the value
2366227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2367232950Stheraven    _Rp& get() const {return __state_->copy();}
2368227825Stheraven
2369227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2370241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2371227825Stheraven
2372227825Stheraven    // functions to check state
2373227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2374241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2375227825Stheraven
2376227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2377227825Stheraven    void wait() const {__state_->wait();}
2378227825Stheraven    template <class _Rep, class _Period>
2379227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2380227825Stheraven        future_status
2381227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2382227825Stheraven            {return __state_->wait_for(__rel_time);}
2383227825Stheraven    template <class _Clock, class _Duration>
2384227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2385227825Stheraven        future_status
2386227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2387227825Stheraven            {return __state_->wait_until(__abs_time);}
2388227825Stheraven};
2389227825Stheraven
2390232950Stheraventemplate <class _Rp>
2391232950Stheravenshared_future<_Rp&>::~shared_future()
2392227825Stheraven{
2393227825Stheraven    if (__state_)
2394227825Stheraven        __state_->__release_shared();
2395227825Stheraven}
2396227825Stheraven
2397232950Stheraventemplate <class _Rp>
2398232950Stheravenshared_future<_Rp&>&
2399232950Stheravenshared_future<_Rp&>::operator=(const shared_future& __rhs)
2400227825Stheraven{
2401227825Stheraven    if (__rhs.__state_)
2402227825Stheraven        __rhs.__state_->__add_shared();
2403227825Stheraven    if (__state_)
2404227825Stheraven        __state_->__release_shared();
2405227825Stheraven    __state_ = __rhs.__state_;
2406227825Stheraven    return *this;
2407227825Stheraven}
2408227825Stheraven
2409227825Stheraventemplate <>
2410227825Stheravenclass _LIBCPP_VISIBLE shared_future<void>
2411227825Stheraven{
2412227825Stheraven    __assoc_sub_state* __state_;
2413227825Stheraven
2414227825Stheravenpublic:
2415227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2416241903Sdim    shared_future() _NOEXCEPT : __state_(nullptr) {}
2417227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2418227825Stheraven    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2419227825Stheraven        {if (__state_) __state_->__add_shared();}
2420227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2421227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2422241903Sdim    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
2423227825Stheraven        {__f.__state_ = nullptr;}
2424227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2425241903Sdim    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
2426227825Stheraven        {__rhs.__state_ = nullptr;}
2427227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2428227825Stheraven    ~shared_future();
2429227825Stheraven    shared_future& operator=(const shared_future& __rhs);
2430227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2431227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2432241903Sdim    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
2433227825Stheraven        {
2434227825Stheraven            shared_future(std::move(__rhs)).swap(*this);
2435227825Stheraven            return *this;
2436227825Stheraven        }
2437227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2438227825Stheraven
2439227825Stheraven    // retrieving the value
2440227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2441227825Stheraven    void get() const {__state_->copy();}
2442227825Stheraven
2443227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2444241903Sdim    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
2445227825Stheraven
2446227825Stheraven    // functions to check state
2447227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2448241903Sdim    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
2449227825Stheraven
2450227825Stheraven    _LIBCPP_INLINE_VISIBILITY
2451227825Stheraven    void wait() const {__state_->wait();}
2452227825Stheraven    template <class _Rep, class _Period>
2453227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2454227825Stheraven        future_status
2455227825Stheraven        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2456227825Stheraven            {return __state_->wait_for(__rel_time);}
2457227825Stheraven    template <class _Clock, class _Duration>
2458227825Stheraven        _LIBCPP_INLINE_VISIBILITY
2459227825Stheraven        future_status
2460227825Stheraven        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2461227825Stheraven            {return __state_->wait_until(__abs_time);}
2462227825Stheraven};
2463227825Stheraven
2464232950Stheraventemplate <class _Rp>
2465227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2466227825Stheravenvoid
2467241903Sdimswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
2468227825Stheraven{
2469227825Stheraven    __x.swap(__y);
2470227825Stheraven}
2471227825Stheraven
2472232950Stheraventemplate <class _Rp>
2473227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2474232950Stheravenshared_future<_Rp>
2475232950Stheravenfuture<_Rp>::share()
2476227825Stheraven{
2477232950Stheraven    return shared_future<_Rp>(_VSTD::move(*this));
2478227825Stheraven}
2479227825Stheraven
2480232950Stheraventemplate <class _Rp>
2481227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2482232950Stheravenshared_future<_Rp&>
2483232950Stheravenfuture<_Rp&>::share()
2484227825Stheraven{
2485232950Stheraven    return shared_future<_Rp&>(_VSTD::move(*this));
2486227825Stheraven}
2487227825Stheraven
2488227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2489227825Stheraven
2490227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
2491227825Stheravenshared_future<void>
2492227825Stheravenfuture<void>::share()
2493227825Stheraven{
2494227825Stheraven    return shared_future<void>(_VSTD::move(*this));
2495227825Stheraven}
2496227825Stheraven
2497227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2498227825Stheraven
2499227825Stheraven_LIBCPP_END_NAMESPACE_STD
2500227825Stheraven
2501227825Stheraven#endif  // _LIBCPP_FUTURE
2502