xref: /freebsd-12.1/contrib/libc++/include/future (revision b5893f02)
17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===--------------------------- future -----------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_FUTURE
127a984708SDavid Chisnall#define _LIBCPP_FUTURE
137a984708SDavid Chisnall
147a984708SDavid Chisnall/*
157a984708SDavid Chisnall    future synopsis
167a984708SDavid Chisnall
177a984708SDavid Chisnallnamespace std
187a984708SDavid Chisnall{
197a984708SDavid Chisnall
207a984708SDavid Chisnallenum class future_errc
217a984708SDavid Chisnall{
224f7ab58eSDimitry Andric    future_already_retrieved = 1,
237a984708SDavid Chisnall    promise_already_satisfied,
244f7ab58eSDimitry Andric    no_state,
254f7ab58eSDimitry Andric    broken_promise
267a984708SDavid Chisnall};
277a984708SDavid Chisnall
287a984708SDavid Chisnallenum class launch
297a984708SDavid Chisnall{
307a984708SDavid Chisnall    async = 1,
317a984708SDavid Chisnall    deferred = 2,
327a984708SDavid Chisnall    any = async | deferred
337a984708SDavid Chisnall};
347a984708SDavid Chisnall
357a984708SDavid Chisnallenum class future_status
367a984708SDavid Chisnall{
377a984708SDavid Chisnall    ready,
387a984708SDavid Chisnall    timeout,
397a984708SDavid Chisnall    deferred
407a984708SDavid Chisnall};
417a984708SDavid Chisnall
427a984708SDavid Chisnalltemplate <> struct is_error_code_enum<future_errc> : public true_type { };
43936e9439SDimitry Andricerror_code make_error_code(future_errc e) noexcept;
44936e9439SDimitry Andricerror_condition make_error_condition(future_errc e) noexcept;
457a984708SDavid Chisnall
46936e9439SDimitry Andricconst error_category& future_category() noexcept;
477a984708SDavid Chisnall
487a984708SDavid Chisnallclass future_error
497a984708SDavid Chisnall    : public logic_error
507a984708SDavid Chisnall{
517a984708SDavid Chisnallpublic:
527a984708SDavid Chisnall    future_error(error_code ec);  // exposition only
53aed8d94eSDimitry Andric    explicit future_error(future_errc); // C++17
54936e9439SDimitry Andric    const error_code& code() const noexcept;
55936e9439SDimitry Andric    const char*       what() const noexcept;
567a984708SDavid Chisnall};
577a984708SDavid Chisnall
587a984708SDavid Chisnalltemplate <class R>
597a984708SDavid Chisnallclass promise
607a984708SDavid Chisnall{
617a984708SDavid Chisnallpublic:
627a984708SDavid Chisnall    promise();
637a984708SDavid Chisnall    template <class Allocator>
647a984708SDavid Chisnall        promise(allocator_arg_t, const Allocator& a);
65936e9439SDimitry Andric    promise(promise&& rhs) noexcept;
667a984708SDavid Chisnall    promise(const promise& rhs) = delete;
677a984708SDavid Chisnall    ~promise();
687a984708SDavid Chisnall
697a984708SDavid Chisnall    // assignment
70936e9439SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
717a984708SDavid Chisnall    promise& operator=(const promise& rhs) = delete;
72936e9439SDimitry Andric    void swap(promise& other) noexcept;
737a984708SDavid Chisnall
747a984708SDavid Chisnall    // retrieving the result
757a984708SDavid Chisnall    future<R> get_future();
767a984708SDavid Chisnall
777a984708SDavid Chisnall    // setting the result
787a984708SDavid Chisnall    void set_value(const R& r);
797a984708SDavid Chisnall    void set_value(R&& r);
807a984708SDavid Chisnall    void set_exception(exception_ptr p);
817a984708SDavid Chisnall
827a984708SDavid Chisnall    // setting the result with deferred notification
837a984708SDavid Chisnall    void set_value_at_thread_exit(const R& r);
847a984708SDavid Chisnall    void set_value_at_thread_exit(R&& r);
857a984708SDavid Chisnall    void set_exception_at_thread_exit(exception_ptr p);
867a984708SDavid Chisnall};
877a984708SDavid Chisnall
887a984708SDavid Chisnalltemplate <class R>
897a984708SDavid Chisnallclass promise<R&>
907a984708SDavid Chisnall{
917a984708SDavid Chisnallpublic:
927a984708SDavid Chisnall    promise();
937a984708SDavid Chisnall    template <class Allocator>
947a984708SDavid Chisnall        promise(allocator_arg_t, const Allocator& a);
95936e9439SDimitry Andric    promise(promise&& rhs) noexcept;
967a984708SDavid Chisnall    promise(const promise& rhs) = delete;
977a984708SDavid Chisnall    ~promise();
987a984708SDavid Chisnall
997a984708SDavid Chisnall    // assignment
100936e9439SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1017a984708SDavid Chisnall    promise& operator=(const promise& rhs) = delete;
102936e9439SDimitry Andric    void swap(promise& other) noexcept;
1037a984708SDavid Chisnall
1047a984708SDavid Chisnall    // retrieving the result
1057a984708SDavid Chisnall    future<R&> get_future();
1067a984708SDavid Chisnall
1077a984708SDavid Chisnall    // setting the result
1087a984708SDavid Chisnall    void set_value(R& r);
1097a984708SDavid Chisnall    void set_exception(exception_ptr p);
1107a984708SDavid Chisnall
1117a984708SDavid Chisnall    // setting the result with deferred notification
1127a984708SDavid Chisnall    void set_value_at_thread_exit(R&);
1137a984708SDavid Chisnall    void set_exception_at_thread_exit(exception_ptr p);
1147a984708SDavid Chisnall};
1157a984708SDavid Chisnall
1167a984708SDavid Chisnalltemplate <>
1177a984708SDavid Chisnallclass promise<void>
1187a984708SDavid Chisnall{
1197a984708SDavid Chisnallpublic:
1207a984708SDavid Chisnall    promise();
1217a984708SDavid Chisnall    template <class Allocator>
1227a984708SDavid Chisnall        promise(allocator_arg_t, const Allocator& a);
123936e9439SDimitry Andric    promise(promise&& rhs) noexcept;
1247a984708SDavid Chisnall    promise(const promise& rhs) = delete;
1257a984708SDavid Chisnall    ~promise();
1267a984708SDavid Chisnall
1277a984708SDavid Chisnall    // assignment
128936e9439SDimitry Andric    promise& operator=(promise&& rhs) noexcept;
1297a984708SDavid Chisnall    promise& operator=(const promise& rhs) = delete;
130936e9439SDimitry Andric    void swap(promise& other) noexcept;
1317a984708SDavid Chisnall
1327a984708SDavid Chisnall    // retrieving the result
1337a984708SDavid Chisnall    future<void> get_future();
1347a984708SDavid Chisnall
1357a984708SDavid Chisnall    // setting the result
1367a984708SDavid Chisnall    void set_value();
1377a984708SDavid Chisnall    void set_exception(exception_ptr p);
1387a984708SDavid Chisnall
1397a984708SDavid Chisnall    // setting the result with deferred notification
1407a984708SDavid Chisnall    void set_value_at_thread_exit();
1417a984708SDavid Chisnall    void set_exception_at_thread_exit(exception_ptr p);
1427a984708SDavid Chisnall};
1437a984708SDavid Chisnall
144936e9439SDimitry Andrictemplate <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
1457a984708SDavid Chisnall
1467a984708SDavid Chisnalltemplate <class R, class Alloc>
1477a984708SDavid Chisnall    struct uses_allocator<promise<R>, Alloc> : public true_type {};
1487a984708SDavid Chisnall
1497a984708SDavid Chisnalltemplate <class R>
1507a984708SDavid Chisnallclass future
1517a984708SDavid Chisnall{
1527a984708SDavid Chisnallpublic:
153936e9439SDimitry Andric    future() noexcept;
154936e9439SDimitry Andric    future(future&&) noexcept;
1557a984708SDavid Chisnall    future(const future& rhs) = delete;
1567a984708SDavid Chisnall    ~future();
1577a984708SDavid Chisnall    future& operator=(const future& rhs) = delete;
158936e9439SDimitry Andric    future& operator=(future&&) noexcept;
159540d2a8bSDimitry Andric    shared_future<R> share() noexcept;
1607a984708SDavid Chisnall
1617a984708SDavid Chisnall    // retrieving the value
1627a984708SDavid Chisnall    R get();
1637a984708SDavid Chisnall
1647a984708SDavid Chisnall    // functions to check state
165936e9439SDimitry Andric    bool valid() const noexcept;
1667a984708SDavid Chisnall
1677a984708SDavid Chisnall    void wait() const;
1687a984708SDavid Chisnall    template <class Rep, class Period>
1697a984708SDavid Chisnall        future_status
1707a984708SDavid Chisnall        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1717a984708SDavid Chisnall    template <class Clock, class Duration>
1727a984708SDavid Chisnall        future_status
1737a984708SDavid Chisnall        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
1747a984708SDavid Chisnall};
1757a984708SDavid Chisnall
1767a984708SDavid Chisnalltemplate <class R>
1777a984708SDavid Chisnallclass future<R&>
1787a984708SDavid Chisnall{
1797a984708SDavid Chisnallpublic:
180936e9439SDimitry Andric    future() noexcept;
181936e9439SDimitry Andric    future(future&&) noexcept;
1827a984708SDavid Chisnall    future(const future& rhs) = delete;
1837a984708SDavid Chisnall    ~future();
1847a984708SDavid Chisnall    future& operator=(const future& rhs) = delete;
185936e9439SDimitry Andric    future& operator=(future&&) noexcept;
186540d2a8bSDimitry Andric    shared_future<R&> share() noexcept;
1877a984708SDavid Chisnall
1887a984708SDavid Chisnall    // retrieving the value
1897a984708SDavid Chisnall    R& get();
1907a984708SDavid Chisnall
1917a984708SDavid Chisnall    // functions to check state
192936e9439SDimitry Andric    bool valid() const noexcept;
1937a984708SDavid Chisnall
1947a984708SDavid Chisnall    void wait() const;
1957a984708SDavid Chisnall    template <class Rep, class Period>
1967a984708SDavid Chisnall        future_status
1977a984708SDavid Chisnall        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
1987a984708SDavid Chisnall    template <class Clock, class Duration>
1997a984708SDavid Chisnall        future_status
2007a984708SDavid Chisnall        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2017a984708SDavid Chisnall};
2027a984708SDavid Chisnall
2037a984708SDavid Chisnalltemplate <>
2047a984708SDavid Chisnallclass future<void>
2057a984708SDavid Chisnall{
2067a984708SDavid Chisnallpublic:
207936e9439SDimitry Andric    future() noexcept;
208936e9439SDimitry Andric    future(future&&) noexcept;
2097a984708SDavid Chisnall    future(const future& rhs) = delete;
2107a984708SDavid Chisnall    ~future();
2117a984708SDavid Chisnall    future& operator=(const future& rhs) = delete;
212936e9439SDimitry Andric    future& operator=(future&&) noexcept;
213540d2a8bSDimitry Andric    shared_future<void> share() noexcept;
2147a984708SDavid Chisnall
2157a984708SDavid Chisnall    // retrieving the value
2167a984708SDavid Chisnall    void get();
2177a984708SDavid Chisnall
2187a984708SDavid Chisnall    // functions to check state
219936e9439SDimitry Andric    bool valid() const noexcept;
2207a984708SDavid Chisnall
2217a984708SDavid Chisnall    void wait() const;
2227a984708SDavid Chisnall    template <class Rep, class Period>
2237a984708SDavid Chisnall        future_status
2247a984708SDavid Chisnall        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2257a984708SDavid Chisnall    template <class Clock, class Duration>
2267a984708SDavid Chisnall        future_status
2277a984708SDavid Chisnall        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2287a984708SDavid Chisnall};
2297a984708SDavid Chisnall
2307a984708SDavid Chisnalltemplate <class R>
2317a984708SDavid Chisnallclass shared_future
2327a984708SDavid Chisnall{
2337a984708SDavid Chisnallpublic:
234936e9439SDimitry Andric    shared_future() noexcept;
2357a984708SDavid Chisnall    shared_future(const shared_future& rhs);
236936e9439SDimitry Andric    shared_future(future<R>&&) noexcept;
237936e9439SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2387a984708SDavid Chisnall    ~shared_future();
2397a984708SDavid Chisnall    shared_future& operator=(const shared_future& rhs);
240936e9439SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2417a984708SDavid Chisnall
2427a984708SDavid Chisnall    // retrieving the value
2437a984708SDavid Chisnall    const R& get() const;
2447a984708SDavid Chisnall
2457a984708SDavid Chisnall    // functions to check state
246936e9439SDimitry Andric    bool valid() const noexcept;
2477a984708SDavid Chisnall
2487a984708SDavid Chisnall    void wait() const;
2497a984708SDavid Chisnall    template <class Rep, class Period>
2507a984708SDavid Chisnall        future_status
2517a984708SDavid Chisnall        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2527a984708SDavid Chisnall    template <class Clock, class Duration>
2537a984708SDavid Chisnall        future_status
2547a984708SDavid Chisnall        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2557a984708SDavid Chisnall};
2567a984708SDavid Chisnall
2577a984708SDavid Chisnalltemplate <class R>
2587a984708SDavid Chisnallclass shared_future<R&>
2597a984708SDavid Chisnall{
2607a984708SDavid Chisnallpublic:
261936e9439SDimitry Andric    shared_future() noexcept;
2627a984708SDavid Chisnall    shared_future(const shared_future& rhs);
263936e9439SDimitry Andric    shared_future(future<R&>&&) noexcept;
264936e9439SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2657a984708SDavid Chisnall    ~shared_future();
2667a984708SDavid Chisnall    shared_future& operator=(const shared_future& rhs);
267936e9439SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2687a984708SDavid Chisnall
2697a984708SDavid Chisnall    // retrieving the value
2707a984708SDavid Chisnall    R& get() const;
2717a984708SDavid Chisnall
2727a984708SDavid Chisnall    // functions to check state
273936e9439SDimitry Andric    bool valid() const noexcept;
2747a984708SDavid Chisnall
2757a984708SDavid Chisnall    void wait() const;
2767a984708SDavid Chisnall    template <class Rep, class Period>
2777a984708SDavid Chisnall        future_status
2787a984708SDavid Chisnall        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
2797a984708SDavid Chisnall    template <class Clock, class Duration>
2807a984708SDavid Chisnall        future_status
2817a984708SDavid Chisnall        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
2827a984708SDavid Chisnall};
2837a984708SDavid Chisnall
2847a984708SDavid Chisnalltemplate <>
2857a984708SDavid Chisnallclass shared_future<void>
2867a984708SDavid Chisnall{
2877a984708SDavid Chisnallpublic:
288936e9439SDimitry Andric    shared_future() noexcept;
2897a984708SDavid Chisnall    shared_future(const shared_future& rhs);
290936e9439SDimitry Andric    shared_future(future<void>&&) noexcept;
291936e9439SDimitry Andric    shared_future(shared_future&& rhs) noexcept;
2927a984708SDavid Chisnall    ~shared_future();
2937a984708SDavid Chisnall    shared_future& operator=(const shared_future& rhs);
294936e9439SDimitry Andric    shared_future& operator=(shared_future&& rhs) noexcept;
2957a984708SDavid Chisnall
2967a984708SDavid Chisnall    // retrieving the value
2977a984708SDavid Chisnall    void get() const;
2987a984708SDavid Chisnall
2997a984708SDavid Chisnall    // functions to check state
300936e9439SDimitry Andric    bool valid() const noexcept;
3017a984708SDavid Chisnall
3027a984708SDavid Chisnall    void wait() const;
3037a984708SDavid Chisnall    template <class Rep, class Period>
3047a984708SDavid Chisnall        future_status
3057a984708SDavid Chisnall        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
3067a984708SDavid Chisnall    template <class Clock, class Duration>
3077a984708SDavid Chisnall        future_status
3087a984708SDavid Chisnall        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3097a984708SDavid Chisnall};
3107a984708SDavid Chisnall
3117a984708SDavid Chisnalltemplate <class F, class... Args>
3124f7ab58eSDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3137a984708SDavid Chisnall  async(F&& f, Args&&... args);
3147a984708SDavid Chisnall
3157a984708SDavid Chisnalltemplate <class F, class... Args>
3164f7ab58eSDimitry Andric  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
3177a984708SDavid Chisnall  async(launch policy, F&& f, Args&&... args);
3187a984708SDavid Chisnall
3197a984708SDavid Chisnalltemplate <class> class packaged_task; // undefined
3207a984708SDavid Chisnall
3217a984708SDavid Chisnalltemplate <class R, class... ArgTypes>
3227a984708SDavid Chisnallclass packaged_task<R(ArgTypes...)>
3237a984708SDavid Chisnall{
3247a984708SDavid Chisnallpublic:
3257c82a1ecSDimitry Andric    typedef R result_type; // extension
3267a984708SDavid Chisnall
3277a984708SDavid Chisnall    // construction and destruction
328936e9439SDimitry Andric    packaged_task() noexcept;
3297a984708SDavid Chisnall    template <class F>
3307a984708SDavid Chisnall        explicit packaged_task(F&& f);
3317a984708SDavid Chisnall    template <class F, class Allocator>
332854fa44bSDimitry Andric        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
3337a984708SDavid Chisnall    ~packaged_task();
3347a984708SDavid Chisnall
3357a984708SDavid Chisnall    // no copy
336936e9439SDimitry Andric    packaged_task(const packaged_task&) = delete;
337936e9439SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
3387a984708SDavid Chisnall
3397a984708SDavid Chisnall    // move support
340936e9439SDimitry Andric    packaged_task(packaged_task&& other) noexcept;
341936e9439SDimitry Andric    packaged_task& operator=(packaged_task&& other) noexcept;
342936e9439SDimitry Andric    void swap(packaged_task& other) noexcept;
3437a984708SDavid Chisnall
344936e9439SDimitry Andric    bool valid() const noexcept;
3457a984708SDavid Chisnall
3467a984708SDavid Chisnall    // result retrieval
3477a984708SDavid Chisnall    future<R> get_future();
3487a984708SDavid Chisnall
3497a984708SDavid Chisnall    // execution
3507a984708SDavid Chisnall    void operator()(ArgTypes... );
3517a984708SDavid Chisnall    void make_ready_at_thread_exit(ArgTypes...);
3527a984708SDavid Chisnall
3537a984708SDavid Chisnall    void reset();
3547a984708SDavid Chisnall};
3557a984708SDavid Chisnall
3567a984708SDavid Chisnalltemplate <class R>
357936e9439SDimitry Andric  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
3587a984708SDavid Chisnall
3597a984708SDavid Chisnalltemplate <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
3607a984708SDavid Chisnall
3617a984708SDavid Chisnall}  // std
3627a984708SDavid Chisnall
3637a984708SDavid Chisnall*/
3647a984708SDavid Chisnall
3657a984708SDavid Chisnall#include <__config>
3667a984708SDavid Chisnall#include <system_error>
3677a984708SDavid Chisnall#include <memory>
3687a984708SDavid Chisnall#include <chrono>
3697a984708SDavid Chisnall#include <exception>
3707a984708SDavid Chisnall#include <mutex>
3717a984708SDavid Chisnall#include <thread>
3727a984708SDavid Chisnall
3737a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3747a984708SDavid Chisnall#pragma GCC system_header
3757a984708SDavid Chisnall#endif
3767a984708SDavid Chisnall
377d72607e9SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
378d72607e9SDimitry Andric#error <future> is not supported on this single threaded system
379d72607e9SDimitry Andric#else // !_LIBCPP_HAS_NO_THREADS
380d72607e9SDimitry Andric
3817a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
3827a984708SDavid Chisnall
3837a984708SDavid Chisnall//enum class future_errc
38494e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
3857a984708SDavid Chisnall{
3864f7ab58eSDimitry Andric    future_already_retrieved = 1,
3877a984708SDavid Chisnall    promise_already_satisfied,
3884f7ab58eSDimitry Andric    no_state,
3894f7ab58eSDimitry Andric    broken_promise
3907a984708SDavid Chisnall};
39194e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
3927a984708SDavid Chisnall
3937a984708SDavid Chisnalltemplate <>
394aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
3957a984708SDavid Chisnall
39694e3ee44SDavid Chisnall#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
39794e3ee44SDavid Chisnalltemplate <>
398aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
39994e3ee44SDavid Chisnall#endif
40094e3ee44SDavid Chisnall
4017a984708SDavid Chisnall//enum class launch
40294e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM(launch)
4037a984708SDavid Chisnall{
4047a984708SDavid Chisnall    async = 1,
4057a984708SDavid Chisnall    deferred = 2,
4067a984708SDavid Chisnall    any = async | deferred
4077a984708SDavid Chisnall};
40894e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
4097a984708SDavid Chisnall
4104bab9fd9SDavid Chisnall#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
4114bab9fd9SDavid Chisnall
4124ba319b5SDimitry Andric#ifdef _LIBCPP_UNDERLYING_TYPE
4134bab9fd9SDavid Chisnalltypedef underlying_type<launch>::type __launch_underlying_type;
4144bab9fd9SDavid Chisnall#else
4154bab9fd9SDavid Chisnalltypedef int __launch_underlying_type;
4164bab9fd9SDavid Chisnall#endif
4174bab9fd9SDavid Chisnall
4184bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4194bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR
4204bab9fd9SDavid Chisnalllaunch
4214bab9fd9SDavid Chisnalloperator&(launch __x, launch __y)
4224bab9fd9SDavid Chisnall{
4234bab9fd9SDavid Chisnall    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
4244bab9fd9SDavid Chisnall                               static_cast<__launch_underlying_type>(__y));
4254bab9fd9SDavid Chisnall}
4264bab9fd9SDavid Chisnall
4274bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4284bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR
4294bab9fd9SDavid Chisnalllaunch
4304bab9fd9SDavid Chisnalloperator|(launch __x, launch __y)
4314bab9fd9SDavid Chisnall{
4324bab9fd9SDavid Chisnall    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
4334bab9fd9SDavid Chisnall                               static_cast<__launch_underlying_type>(__y));
4344bab9fd9SDavid Chisnall}
4354bab9fd9SDavid Chisnall
4364bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4374bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR
4384bab9fd9SDavid Chisnalllaunch
4394bab9fd9SDavid Chisnalloperator^(launch __x, launch __y)
4404bab9fd9SDavid Chisnall{
4414bab9fd9SDavid Chisnall    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
4424bab9fd9SDavid Chisnall                               static_cast<__launch_underlying_type>(__y));
4434bab9fd9SDavid Chisnall}
4444bab9fd9SDavid Chisnall
4454bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4464bab9fd9SDavid Chisnall_LIBCPP_CONSTEXPR
4474bab9fd9SDavid Chisnalllaunch
4484bab9fd9SDavid Chisnalloperator~(launch __x)
4494bab9fd9SDavid Chisnall{
4504bab9fd9SDavid Chisnall    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
4514bab9fd9SDavid Chisnall}
4524bab9fd9SDavid Chisnall
4534bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4544bab9fd9SDavid Chisnalllaunch&
4554bab9fd9SDavid Chisnalloperator&=(launch& __x, launch __y)
4564bab9fd9SDavid Chisnall{
4574bab9fd9SDavid Chisnall    __x = __x & __y; return __x;
4584bab9fd9SDavid Chisnall}
4594bab9fd9SDavid Chisnall
4604bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4614bab9fd9SDavid Chisnalllaunch&
4624bab9fd9SDavid Chisnalloperator|=(launch& __x, launch __y)
4634bab9fd9SDavid Chisnall{
4644bab9fd9SDavid Chisnall    __x = __x | __y; return __x;
4654bab9fd9SDavid Chisnall}
4664bab9fd9SDavid Chisnall
4674bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4684bab9fd9SDavid Chisnalllaunch&
4694bab9fd9SDavid Chisnalloperator^=(launch& __x, launch __y)
4704bab9fd9SDavid Chisnall{
4714bab9fd9SDavid Chisnall    __x = __x ^ __y; return __x;
4724bab9fd9SDavid Chisnall}
4734bab9fd9SDavid Chisnall
4744bab9fd9SDavid Chisnall#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
4754bab9fd9SDavid Chisnall
4767a984708SDavid Chisnall//enum class future_status
47794e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM(future_status)
4787a984708SDavid Chisnall{
4797a984708SDavid Chisnall    ready,
4807a984708SDavid Chisnall    timeout,
4817a984708SDavid Chisnall    deferred
4827a984708SDavid Chisnall};
48394e3ee44SDavid Chisnall_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
4847a984708SDavid Chisnall
4851bf9f7c1SDimitry Andric_LIBCPP_FUNC_VIS
486936e9439SDimitry Andricconst error_category& future_category() _NOEXCEPT;
4877a984708SDavid Chisnall
4887a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4897a984708SDavid Chisnallerror_code
490936e9439SDimitry Andricmake_error_code(future_errc __e) _NOEXCEPT
4917a984708SDavid Chisnall{
4927a984708SDavid Chisnall    return error_code(static_cast<int>(__e), future_category());
4937a984708SDavid Chisnall}
4947a984708SDavid Chisnall
4957a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
4967a984708SDavid Chisnallerror_condition
497936e9439SDimitry Andricmake_error_condition(future_errc __e) _NOEXCEPT
4987a984708SDavid Chisnall{
4997a984708SDavid Chisnall    return error_condition(static_cast<int>(__e), future_category());
5007a984708SDavid Chisnall}
5017a984708SDavid Chisnall
5020f5676f4SDimitry Andricclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
5037a984708SDavid Chisnall    : public logic_error
5047a984708SDavid Chisnall{
5057a984708SDavid Chisnall    error_code __ec_;
5067a984708SDavid Chisnallpublic:
5077a984708SDavid Chisnall    future_error(error_code __ec);
508aed8d94eSDimitry Andric#if _LIBCPP_STD_VERS > 14
509aed8d94eSDimitry Andric    explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
510aed8d94eSDimitry Andric#endif
5117a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
512936e9439SDimitry Andric    const error_code& code() const _NOEXCEPT {return __ec_;}
5137a984708SDavid Chisnall
5147a984708SDavid Chisnall    virtual ~future_error() _NOEXCEPT;
5157a984708SDavid Chisnall};
5167a984708SDavid Chisnall
5174ba319b5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
5180f5676f4SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
5190f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE_ERROR
5200f5676f4SDimitry Andric#endif
5219729cf09SDimitry Andricvoid __throw_future_error(future_errc _Ev)
5229729cf09SDimitry Andric{
5239729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
5249729cf09SDimitry Andric    throw future_error(make_error_code(_Ev));
5259729cf09SDimitry Andric#else
526aed8d94eSDimitry Andric    ((void)_Ev);
527aed8d94eSDimitry Andric    _VSTD::abort();
5289729cf09SDimitry Andric#endif
5299729cf09SDimitry Andric}
5309729cf09SDimitry Andric
5310f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
5327a984708SDavid Chisnall    : public __shared_count
5337a984708SDavid Chisnall{
5347a984708SDavid Chisnallprotected:
5357a984708SDavid Chisnall    exception_ptr __exception_;
5367a984708SDavid Chisnall    mutable mutex __mut_;
5377a984708SDavid Chisnall    mutable condition_variable __cv_;
5387a984708SDavid Chisnall    unsigned __state_;
5397a984708SDavid Chisnall
5407a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
5417a984708SDavid Chisnall    void __sub_wait(unique_lock<mutex>& __lk);
5427a984708SDavid Chisnallpublic:
5437a984708SDavid Chisnall    enum
5447a984708SDavid Chisnall    {
5457a984708SDavid Chisnall        __constructed = 1,
5467a984708SDavid Chisnall        __future_attached = 2,
5477a984708SDavid Chisnall        ready = 4,
5487a984708SDavid Chisnall        deferred = 8
5497a984708SDavid Chisnall    };
5507a984708SDavid Chisnall
5517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5527a984708SDavid Chisnall    __assoc_sub_state() : __state_(0) {}
5537a984708SDavid Chisnall
5547a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5557a984708SDavid Chisnall    bool __has_value() const
5567a984708SDavid Chisnall        {return (__state_ & __constructed) || (__exception_ != nullptr);}
5577a984708SDavid Chisnall
5587a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
559*b5893f02SDimitry Andric    void __attach_future() {
560cfdf2879SDavid Chisnall        lock_guard<mutex> __lk(__mut_);
561*b5893f02SDimitry Andric        bool __has_future_attached = (__state_ & __future_attached) != 0;
562*b5893f02SDimitry Andric        if (__has_future_attached)
563*b5893f02SDimitry Andric            __throw_future_error(future_errc::future_already_retrieved);
564*b5893f02SDimitry Andric        this->__add_shared();
565cfdf2879SDavid Chisnall        __state_ |= __future_attached;
566cfdf2879SDavid Chisnall    }
5677a984708SDavid Chisnall
5687a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5697a984708SDavid Chisnall    void __set_deferred() {__state_ |= deferred;}
5707a984708SDavid Chisnall
5717a984708SDavid Chisnall    void __make_ready();
5727a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5734f7ab58eSDimitry Andric    bool __is_ready() const {return (__state_ & ready) != 0;}
5747a984708SDavid Chisnall
5757a984708SDavid Chisnall    void set_value();
5767a984708SDavid Chisnall    void set_value_at_thread_exit();
5777a984708SDavid Chisnall
5787a984708SDavid Chisnall    void set_exception(exception_ptr __p);
5797a984708SDavid Chisnall    void set_exception_at_thread_exit(exception_ptr __p);
5807a984708SDavid Chisnall
5817a984708SDavid Chisnall    void copy();
5827a984708SDavid Chisnall
5837a984708SDavid Chisnall    void wait();
5847a984708SDavid Chisnall    template <class _Rep, class _Period>
5857a984708SDavid Chisnall        future_status
5869729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
5877a984708SDavid Chisnall        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
5887a984708SDavid Chisnall    template <class _Clock, class _Duration>
589540d2a8bSDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
5907a984708SDavid Chisnall        future_status
5917a984708SDavid Chisnall        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
5927a984708SDavid Chisnall
5937a984708SDavid Chisnall    virtual void __execute();
5947a984708SDavid Chisnall};
5957a984708SDavid Chisnall
5967a984708SDavid Chisnalltemplate <class _Clock, class _Duration>
5977a984708SDavid Chisnallfuture_status
5987a984708SDavid Chisnall__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
5997a984708SDavid Chisnall{
6007a984708SDavid Chisnall    unique_lock<mutex> __lk(__mut_);
6017a984708SDavid Chisnall    if (__state_ & deferred)
6027a984708SDavid Chisnall        return future_status::deferred;
6037a984708SDavid Chisnall    while (!(__state_ & ready) && _Clock::now() < __abs_time)
6047a984708SDavid Chisnall        __cv_.wait_until(__lk, __abs_time);
6057a984708SDavid Chisnall    if (__state_ & ready)
6067a984708SDavid Chisnall        return future_status::ready;
6077a984708SDavid Chisnall    return future_status::timeout;
6087a984708SDavid Chisnall}
6097a984708SDavid Chisnall
6107a984708SDavid Chisnalltemplate <class _Rep, class _Period>
6119729cf09SDimitry Andricinline
6127a984708SDavid Chisnallfuture_status
6137a984708SDavid Chisnall__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
6147a984708SDavid Chisnall{
6157a984708SDavid Chisnall    return wait_until(chrono::steady_clock::now() + __rel_time);
6167a984708SDavid Chisnall}
6177a984708SDavid Chisnall
61894e3ee44SDavid Chisnalltemplate <class _Rp>
6190f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state
6207a984708SDavid Chisnall    : public __assoc_sub_state
6217a984708SDavid Chisnall{
6227a984708SDavid Chisnall    typedef __assoc_sub_state base;
62394e3ee44SDavid Chisnall    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
6247a984708SDavid Chisnallprotected:
62594e3ee44SDavid Chisnall    _Up __value_;
6267a984708SDavid Chisnall
6277a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
6287a984708SDavid Chisnallpublic:
6297a984708SDavid Chisnall
6307a984708SDavid Chisnall    template <class _Arg>
6317a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
6327a984708SDavid Chisnall        void set_value(_Arg&& __arg);
6337a984708SDavid Chisnall#else
6347a984708SDavid Chisnall        void set_value(_Arg& __arg);
6357a984708SDavid Chisnall#endif
6367a984708SDavid Chisnall
6377a984708SDavid Chisnall    template <class _Arg>
6387a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
6397a984708SDavid Chisnall        void set_value_at_thread_exit(_Arg&& __arg);
6407a984708SDavid Chisnall#else
6417a984708SDavid Chisnall        void set_value_at_thread_exit(_Arg& __arg);
6427a984708SDavid Chisnall#endif
6437a984708SDavid Chisnall
64494e3ee44SDavid Chisnall    _Rp move();
64594e3ee44SDavid Chisnall    typename add_lvalue_reference<_Rp>::type copy();
6467a984708SDavid Chisnall};
6477a984708SDavid Chisnall
64894e3ee44SDavid Chisnalltemplate <class _Rp>
6497a984708SDavid Chisnallvoid
65094e3ee44SDavid Chisnall__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
6517a984708SDavid Chisnall{
6527a984708SDavid Chisnall    if (this->__state_ & base::__constructed)
65394e3ee44SDavid Chisnall        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
6547a984708SDavid Chisnall    delete this;
6557a984708SDavid Chisnall}
6567a984708SDavid Chisnall
65794e3ee44SDavid Chisnalltemplate <class _Rp>
6587a984708SDavid Chisnalltemplate <class _Arg>
6590f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_FUTURE
6607a984708SDavid Chisnallvoid
6617a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
66294e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value(_Arg&& __arg)
6637a984708SDavid Chisnall#else
66494e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value(_Arg& __arg)
6657a984708SDavid Chisnall#endif
6667a984708SDavid Chisnall{
6677a984708SDavid Chisnall    unique_lock<mutex> __lk(this->__mut_);
6687a984708SDavid Chisnall    if (this->__has_value())
6699729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
67094e3ee44SDavid Chisnall    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
6717a984708SDavid Chisnall    this->__state_ |= base::__constructed | base::ready;
6727a984708SDavid Chisnall    __cv_.notify_all();
6737a984708SDavid Chisnall}
6747a984708SDavid Chisnall
67594e3ee44SDavid Chisnalltemplate <class _Rp>
6767a984708SDavid Chisnalltemplate <class _Arg>
6777a984708SDavid Chisnallvoid
6787a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
67994e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
6807a984708SDavid Chisnall#else
68194e3ee44SDavid Chisnall__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
6827a984708SDavid Chisnall#endif
6837a984708SDavid Chisnall{
6847a984708SDavid Chisnall    unique_lock<mutex> __lk(this->__mut_);
6857a984708SDavid Chisnall    if (this->__has_value())
6869729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
68794e3ee44SDavid Chisnall    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
6887a984708SDavid Chisnall    this->__state_ |= base::__constructed;
6897a984708SDavid Chisnall    __thread_local_data()->__make_ready_at_thread_exit(this);
6907a984708SDavid Chisnall}
6917a984708SDavid Chisnall
69294e3ee44SDavid Chisnalltemplate <class _Rp>
69394e3ee44SDavid Chisnall_Rp
69494e3ee44SDavid Chisnall__assoc_state<_Rp>::move()
6957a984708SDavid Chisnall{
6967a984708SDavid Chisnall    unique_lock<mutex> __lk(this->__mut_);
6977a984708SDavid Chisnall    this->__sub_wait(__lk);
6987a984708SDavid Chisnall    if (this->__exception_ != nullptr)
6997a984708SDavid Chisnall        rethrow_exception(this->__exception_);
70094e3ee44SDavid Chisnall    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
7017a984708SDavid Chisnall}
7027a984708SDavid Chisnall
70394e3ee44SDavid Chisnalltemplate <class _Rp>
70494e3ee44SDavid Chisnalltypename add_lvalue_reference<_Rp>::type
70594e3ee44SDavid Chisnall__assoc_state<_Rp>::copy()
7067a984708SDavid Chisnall{
7077a984708SDavid Chisnall    unique_lock<mutex> __lk(this->__mut_);
7087a984708SDavid Chisnall    this->__sub_wait(__lk);
7097a984708SDavid Chisnall    if (this->__exception_ != nullptr)
7107a984708SDavid Chisnall        rethrow_exception(this->__exception_);
71194e3ee44SDavid Chisnall    return *reinterpret_cast<_Rp*>(&__value_);
7127a984708SDavid Chisnall}
7137a984708SDavid Chisnall
71494e3ee44SDavid Chisnalltemplate <class _Rp>
7150f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
7167a984708SDavid Chisnall    : public __assoc_sub_state
7177a984708SDavid Chisnall{
7187a984708SDavid Chisnall    typedef __assoc_sub_state base;
71994e3ee44SDavid Chisnall    typedef _Rp* _Up;
7207a984708SDavid Chisnallprotected:
72194e3ee44SDavid Chisnall    _Up __value_;
7227a984708SDavid Chisnall
7237a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
7247a984708SDavid Chisnallpublic:
7257a984708SDavid Chisnall
72694e3ee44SDavid Chisnall    void set_value(_Rp& __arg);
72794e3ee44SDavid Chisnall    void set_value_at_thread_exit(_Rp& __arg);
7287a984708SDavid Chisnall
72994e3ee44SDavid Chisnall    _Rp& copy();
7307a984708SDavid Chisnall};
7317a984708SDavid Chisnall
73294e3ee44SDavid Chisnalltemplate <class _Rp>
7337a984708SDavid Chisnallvoid
73494e3ee44SDavid Chisnall__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
7357a984708SDavid Chisnall{
7367a984708SDavid Chisnall    delete this;
7377a984708SDavid Chisnall}
7387a984708SDavid Chisnall
73994e3ee44SDavid Chisnalltemplate <class _Rp>
7407a984708SDavid Chisnallvoid
74194e3ee44SDavid Chisnall__assoc_state<_Rp&>::set_value(_Rp& __arg)
7427a984708SDavid Chisnall{
7437a984708SDavid Chisnall    unique_lock<mutex> __lk(this->__mut_);
7447a984708SDavid Chisnall    if (this->__has_value())
7459729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
7464f7ab58eSDimitry Andric    __value_ = _VSTD::addressof(__arg);
7477a984708SDavid Chisnall    this->__state_ |= base::__constructed | base::ready;
7487a984708SDavid Chisnall    __cv_.notify_all();
7497a984708SDavid Chisnall}
7507a984708SDavid Chisnall
75194e3ee44SDavid Chisnalltemplate <class _Rp>
7527a984708SDavid Chisnallvoid
75394e3ee44SDavid Chisnall__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
7547a984708SDavid Chisnall{
7557a984708SDavid Chisnall    unique_lock<mutex> __lk(this->__mut_);
7567a984708SDavid Chisnall    if (this->__has_value())
7579729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
7584f7ab58eSDimitry Andric    __value_ = _VSTD::addressof(__arg);
7597a984708SDavid Chisnall    this->__state_ |= base::__constructed;
7607a984708SDavid Chisnall    __thread_local_data()->__make_ready_at_thread_exit(this);
7617a984708SDavid Chisnall}
7627a984708SDavid Chisnall
76394e3ee44SDavid Chisnalltemplate <class _Rp>
76494e3ee44SDavid Chisnall_Rp&
76594e3ee44SDavid Chisnall__assoc_state<_Rp&>::copy()
7667a984708SDavid Chisnall{
7677a984708SDavid Chisnall    unique_lock<mutex> __lk(this->__mut_);
7687a984708SDavid Chisnall    this->__sub_wait(__lk);
7697a984708SDavid Chisnall    if (this->__exception_ != nullptr)
7707a984708SDavid Chisnall        rethrow_exception(this->__exception_);
7717a984708SDavid Chisnall    return *__value_;
7727a984708SDavid Chisnall}
7737a984708SDavid Chisnall
77494e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc>
7750f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
77694e3ee44SDavid Chisnall    : public __assoc_state<_Rp>
7777a984708SDavid Chisnall{
77894e3ee44SDavid Chisnall    typedef __assoc_state<_Rp> base;
7797a984708SDavid Chisnall    _Alloc __alloc_;
7807a984708SDavid Chisnall
7817a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
7827a984708SDavid Chisnallpublic:
7837a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
7847a984708SDavid Chisnall    explicit __assoc_state_alloc(const _Alloc& __a)
7857a984708SDavid Chisnall        : __alloc_(__a) {}
7867a984708SDavid Chisnall};
7877a984708SDavid Chisnall
78894e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc>
7897a984708SDavid Chisnallvoid
79094e3ee44SDavid Chisnall__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
7917a984708SDavid Chisnall{
7927a984708SDavid Chisnall    if (this->__state_ & base::__constructed)
7934f7ab58eSDimitry Andric        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
794854fa44bSDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
795854fa44bSDimitry Andric    typedef allocator_traits<_Al> _ATraits;
796d72607e9SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
797854fa44bSDimitry Andric    _Al __a(__alloc_);
7987a984708SDavid Chisnall    this->~__assoc_state_alloc();
799d72607e9SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8007a984708SDavid Chisnall}
8017a984708SDavid Chisnall
80294e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc>
8030f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
80494e3ee44SDavid Chisnall    : public __assoc_state<_Rp&>
8057a984708SDavid Chisnall{
80694e3ee44SDavid Chisnall    typedef __assoc_state<_Rp&> base;
8077a984708SDavid Chisnall    _Alloc __alloc_;
8087a984708SDavid Chisnall
8097a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
8107a984708SDavid Chisnallpublic:
8117a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8127a984708SDavid Chisnall    explicit __assoc_state_alloc(const _Alloc& __a)
8137a984708SDavid Chisnall        : __alloc_(__a) {}
8147a984708SDavid Chisnall};
8157a984708SDavid Chisnall
81694e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc>
8177a984708SDavid Chisnallvoid
81894e3ee44SDavid Chisnall__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
8197a984708SDavid Chisnall{
820854fa44bSDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
821854fa44bSDimitry Andric    typedef allocator_traits<_Al> _ATraits;
822d72607e9SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
823854fa44bSDimitry Andric    _Al __a(__alloc_);
8247a984708SDavid Chisnall    this->~__assoc_state_alloc();
825d72607e9SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8267a984708SDavid Chisnall}
8277a984708SDavid Chisnall
8287a984708SDavid Chisnalltemplate <class _Alloc>
8290f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
8307a984708SDavid Chisnall    : public __assoc_sub_state
8317a984708SDavid Chisnall{
8327a984708SDavid Chisnall    typedef __assoc_sub_state base;
8337a984708SDavid Chisnall    _Alloc __alloc_;
8347a984708SDavid Chisnall
8357a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
8367a984708SDavid Chisnallpublic:
8377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8387a984708SDavid Chisnall    explicit __assoc_sub_state_alloc(const _Alloc& __a)
8397a984708SDavid Chisnall        : __alloc_(__a) {}
8407a984708SDavid Chisnall};
8417a984708SDavid Chisnall
8427a984708SDavid Chisnalltemplate <class _Alloc>
8437a984708SDavid Chisnallvoid
8447a984708SDavid Chisnall__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
8457a984708SDavid Chisnall{
846854fa44bSDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
847854fa44bSDimitry Andric    typedef allocator_traits<_Al> _ATraits;
848d72607e9SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
849854fa44bSDimitry Andric    _Al __a(__alloc_);
8507a984708SDavid Chisnall    this->~__assoc_sub_state_alloc();
851d72607e9SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
8527a984708SDavid Chisnall}
8537a984708SDavid Chisnall
85494e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
8550f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
85694e3ee44SDavid Chisnall    : public __assoc_state<_Rp>
8577a984708SDavid Chisnall{
85894e3ee44SDavid Chisnall    typedef __assoc_state<_Rp> base;
8597a984708SDavid Chisnall
86094e3ee44SDavid Chisnall    _Fp __func_;
8617a984708SDavid Chisnall
8627a984708SDavid Chisnallpublic:
8637a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
8649729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
86594e3ee44SDavid Chisnall    explicit __deferred_assoc_state(_Fp&& __f);
8667a984708SDavid Chisnall#endif
8677a984708SDavid Chisnall
8687a984708SDavid Chisnall    virtual void __execute();
8697a984708SDavid Chisnall};
8707a984708SDavid Chisnall
8717a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
8727a984708SDavid Chisnall
87394e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
8749729cf09SDimitry Andricinline
87594e3ee44SDavid Chisnall__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
87694e3ee44SDavid Chisnall    : __func_(_VSTD::forward<_Fp>(__f))
8777a984708SDavid Chisnall{
8787a984708SDavid Chisnall    this->__set_deferred();
8797a984708SDavid Chisnall}
8807a984708SDavid Chisnall
8817a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
8827a984708SDavid Chisnall
88394e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
8847a984708SDavid Chisnallvoid
88594e3ee44SDavid Chisnall__deferred_assoc_state<_Rp, _Fp>::__execute()
8867a984708SDavid Chisnall{
8877a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
8887a984708SDavid Chisnall    try
8897a984708SDavid Chisnall    {
8907a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
8917a984708SDavid Chisnall        this->set_value(__func_());
8927a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
8937a984708SDavid Chisnall    }
8947a984708SDavid Chisnall    catch (...)
8957a984708SDavid Chisnall    {
8967a984708SDavid Chisnall        this->set_exception(current_exception());
8977a984708SDavid Chisnall    }
8987a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
8997a984708SDavid Chisnall}
9007a984708SDavid Chisnall
90194e3ee44SDavid Chisnalltemplate <class _Fp>
9020f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
9037a984708SDavid Chisnall    : public __assoc_sub_state
9047a984708SDavid Chisnall{
9057a984708SDavid Chisnall    typedef __assoc_sub_state base;
9067a984708SDavid Chisnall
90794e3ee44SDavid Chisnall    _Fp __func_;
9087a984708SDavid Chisnall
9097a984708SDavid Chisnallpublic:
9107a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9119729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
91294e3ee44SDavid Chisnall    explicit __deferred_assoc_state(_Fp&& __f);
9137a984708SDavid Chisnall#endif
9147a984708SDavid Chisnall
9157a984708SDavid Chisnall    virtual void __execute();
9167a984708SDavid Chisnall};
9177a984708SDavid Chisnall
9187a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9197a984708SDavid Chisnall
92094e3ee44SDavid Chisnalltemplate <class _Fp>
9219729cf09SDimitry Andricinline
92294e3ee44SDavid Chisnall__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
92394e3ee44SDavid Chisnall    : __func_(_VSTD::forward<_Fp>(__f))
9247a984708SDavid Chisnall{
9257a984708SDavid Chisnall    this->__set_deferred();
9267a984708SDavid Chisnall}
9277a984708SDavid Chisnall
9287a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
9297a984708SDavid Chisnall
93094e3ee44SDavid Chisnalltemplate <class _Fp>
9317a984708SDavid Chisnallvoid
93294e3ee44SDavid Chisnall__deferred_assoc_state<void, _Fp>::__execute()
9337a984708SDavid Chisnall{
9347a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
9357a984708SDavid Chisnall    try
9367a984708SDavid Chisnall    {
9377a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
9387a984708SDavid Chisnall        __func_();
9397a984708SDavid Chisnall        this->set_value();
9407a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
9417a984708SDavid Chisnall    }
9427a984708SDavid Chisnall    catch (...)
9437a984708SDavid Chisnall    {
9447a984708SDavid Chisnall        this->set_exception(current_exception());
9457a984708SDavid Chisnall    }
9467a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
9477a984708SDavid Chisnall}
9487a984708SDavid Chisnall
94994e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
9500f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
95194e3ee44SDavid Chisnall    : public __assoc_state<_Rp>
9527a984708SDavid Chisnall{
95394e3ee44SDavid Chisnall    typedef __assoc_state<_Rp> base;
9547a984708SDavid Chisnall
95594e3ee44SDavid Chisnall    _Fp __func_;
9567a984708SDavid Chisnall
9577a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
9587a984708SDavid Chisnallpublic:
9597a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9609729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
96194e3ee44SDavid Chisnall    explicit __async_assoc_state(_Fp&& __f);
9627a984708SDavid Chisnall#endif
9637a984708SDavid Chisnall
9647a984708SDavid Chisnall    virtual void __execute();
9657a984708SDavid Chisnall};
9667a984708SDavid Chisnall
9677a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
9687a984708SDavid Chisnall
96994e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
9709729cf09SDimitry Andricinline
97194e3ee44SDavid Chisnall__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
97294e3ee44SDavid Chisnall    : __func_(_VSTD::forward<_Fp>(__f))
9737a984708SDavid Chisnall{
9747a984708SDavid Chisnall}
9757a984708SDavid Chisnall
9767a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
9777a984708SDavid Chisnall
97894e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
9797a984708SDavid Chisnallvoid
98094e3ee44SDavid Chisnall__async_assoc_state<_Rp, _Fp>::__execute()
9817a984708SDavid Chisnall{
9827a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
9837a984708SDavid Chisnall    try
9847a984708SDavid Chisnall    {
9857a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
9867a984708SDavid Chisnall        this->set_value(__func_());
9877a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
9887a984708SDavid Chisnall    }
9897a984708SDavid Chisnall    catch (...)
9907a984708SDavid Chisnall    {
9917a984708SDavid Chisnall        this->set_exception(current_exception());
9927a984708SDavid Chisnall    }
9937a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
9947a984708SDavid Chisnall}
9957a984708SDavid Chisnall
99694e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
9977a984708SDavid Chisnallvoid
99894e3ee44SDavid Chisnall__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
9997a984708SDavid Chisnall{
10007a984708SDavid Chisnall    this->wait();
10017a984708SDavid Chisnall    base::__on_zero_shared();
10027a984708SDavid Chisnall}
10037a984708SDavid Chisnall
100494e3ee44SDavid Chisnalltemplate <class _Fp>
10050f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
10067a984708SDavid Chisnall    : public __assoc_sub_state
10077a984708SDavid Chisnall{
10087a984708SDavid Chisnall    typedef __assoc_sub_state base;
10097a984708SDavid Chisnall
101094e3ee44SDavid Chisnall    _Fp __func_;
10117a984708SDavid Chisnall
10127a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
10137a984708SDavid Chisnallpublic:
10147a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
10159729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
101694e3ee44SDavid Chisnall    explicit __async_assoc_state(_Fp&& __f);
10177a984708SDavid Chisnall#endif
10187a984708SDavid Chisnall
10197a984708SDavid Chisnall    virtual void __execute();
10207a984708SDavid Chisnall};
10217a984708SDavid Chisnall
10227a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
10237a984708SDavid Chisnall
102494e3ee44SDavid Chisnalltemplate <class _Fp>
10259729cf09SDimitry Andricinline
102694e3ee44SDavid Chisnall__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
102794e3ee44SDavid Chisnall    : __func_(_VSTD::forward<_Fp>(__f))
10287a984708SDavid Chisnall{
10297a984708SDavid Chisnall}
10307a984708SDavid Chisnall
10317a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
10327a984708SDavid Chisnall
103394e3ee44SDavid Chisnalltemplate <class _Fp>
10347a984708SDavid Chisnallvoid
103594e3ee44SDavid Chisnall__async_assoc_state<void, _Fp>::__execute()
10367a984708SDavid Chisnall{
10377a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
10387a984708SDavid Chisnall    try
10397a984708SDavid Chisnall    {
10407a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
10417a984708SDavid Chisnall        __func_();
10427a984708SDavid Chisnall        this->set_value();
10437a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
10447a984708SDavid Chisnall    }
10457a984708SDavid Chisnall    catch (...)
10467a984708SDavid Chisnall    {
10477a984708SDavid Chisnall        this->set_exception(current_exception());
10487a984708SDavid Chisnall    }
10497a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
10507a984708SDavid Chisnall}
10517a984708SDavid Chisnall
105294e3ee44SDavid Chisnalltemplate <class _Fp>
10537a984708SDavid Chisnallvoid
105494e3ee44SDavid Chisnall__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
10557a984708SDavid Chisnall{
10567a984708SDavid Chisnall    this->wait();
10577a984708SDavid Chisnall    base::__on_zero_shared();
10587a984708SDavid Chisnall}
10597a984708SDavid Chisnall
1060aed8d94eSDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1061aed8d94eSDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
10627a984708SDavid Chisnall
10637a984708SDavid Chisnall// future
10647a984708SDavid Chisnall
1065aed8d94eSDimitry Andrictemplate <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
10667a984708SDavid Chisnall
106794e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
106894e3ee44SDavid Chisnallfuture<_Rp>
10697a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
107094e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp&& __f);
10717a984708SDavid Chisnall#else
107294e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp __f);
10737a984708SDavid Chisnall#endif
10747a984708SDavid Chisnall
107594e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
107694e3ee44SDavid Chisnallfuture<_Rp>
10777a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
107894e3ee44SDavid Chisnall__make_async_assoc_state(_Fp&& __f);
10797a984708SDavid Chisnall#else
108094e3ee44SDavid Chisnall__make_async_assoc_state(_Fp __f);
10817a984708SDavid Chisnall#endif
10827a984708SDavid Chisnall
108394e3ee44SDavid Chisnalltemplate <class _Rp>
10840f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
10857a984708SDavid Chisnall{
108694e3ee44SDavid Chisnall    __assoc_state<_Rp>* __state_;
10877a984708SDavid Chisnall
108894e3ee44SDavid Chisnall    explicit future(__assoc_state<_Rp>* __state);
10897a984708SDavid Chisnall
10907a984708SDavid Chisnall    template <class> friend class promise;
10917a984708SDavid Chisnall    template <class> friend class shared_future;
10927a984708SDavid Chisnall
10937a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
109494e3ee44SDavid Chisnall    template <class _R1, class _Fp>
109594e3ee44SDavid Chisnall        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
109694e3ee44SDavid Chisnall    template <class _R1, class _Fp>
109794e3ee44SDavid Chisnall        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
10987a984708SDavid Chisnall#else
109994e3ee44SDavid Chisnall    template <class _R1, class _Fp>
110094e3ee44SDavid Chisnall        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
110194e3ee44SDavid Chisnall    template <class _R1, class _Fp>
110294e3ee44SDavid Chisnall        friend future<_R1> __make_async_assoc_state(_Fp __f);
11037a984708SDavid Chisnall#endif
11047a984708SDavid Chisnall
11057a984708SDavid Chisnallpublic:
11067a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1107936e9439SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
11087a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
11097a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1110936e9439SDimitry Andric    future(future&& __rhs) _NOEXCEPT
11117a984708SDavid Chisnall        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
11127a984708SDavid Chisnall    future(const future&) = delete;
11137a984708SDavid Chisnall    future& operator=(const future&) = delete;
11147a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1115936e9439SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
11167a984708SDavid Chisnall        {
11177a984708SDavid Chisnall            future(std::move(__rhs)).swap(*this);
11187a984708SDavid Chisnall            return *this;
11197a984708SDavid Chisnall        }
11207a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
11217a984708SDavid Chisnallprivate:
11227a984708SDavid Chisnall    future(const future&);
11237a984708SDavid Chisnall    future& operator=(const future&);
11247a984708SDavid Chisnallpublic:
11257a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
11267a984708SDavid Chisnall    ~future();
11279729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1128540d2a8bSDimitry Andric    shared_future<_Rp> share() _NOEXCEPT;
11297a984708SDavid Chisnall
11307a984708SDavid Chisnall    // retrieving the value
113194e3ee44SDavid Chisnall    _Rp get();
11327a984708SDavid Chisnall
11337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1134936e9439SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
11357a984708SDavid Chisnall
11367a984708SDavid Chisnall    // functions to check state
11377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1138936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
11397a984708SDavid Chisnall
11407a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
11417a984708SDavid Chisnall    void wait() const {__state_->wait();}
11427a984708SDavid Chisnall    template <class _Rep, class _Period>
11437a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
11447a984708SDavid Chisnall        future_status
11457a984708SDavid Chisnall        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
11467a984708SDavid Chisnall            {return __state_->wait_for(__rel_time);}
11477a984708SDavid Chisnall    template <class _Clock, class _Duration>
11487a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
11497a984708SDavid Chisnall        future_status
11507a984708SDavid Chisnall        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
11517a984708SDavid Chisnall            {return __state_->wait_until(__abs_time);}
11527a984708SDavid Chisnall};
11537a984708SDavid Chisnall
115494e3ee44SDavid Chisnalltemplate <class _Rp>
115594e3ee44SDavid Chisnallfuture<_Rp>::future(__assoc_state<_Rp>* __state)
11567a984708SDavid Chisnall    : __state_(__state)
11577a984708SDavid Chisnall{
1158*b5893f02SDimitry Andric    __state_->__attach_future();
11597a984708SDavid Chisnall}
11607a984708SDavid Chisnall
11617a984708SDavid Chisnallstruct __release_shared_count
11627a984708SDavid Chisnall{
11637a984708SDavid Chisnall    void operator()(__shared_count* p) {p->__release_shared();}
11647a984708SDavid Chisnall};
11657a984708SDavid Chisnall
116694e3ee44SDavid Chisnalltemplate <class _Rp>
116794e3ee44SDavid Chisnallfuture<_Rp>::~future()
11687a984708SDavid Chisnall{
11697a984708SDavid Chisnall    if (__state_)
11707a984708SDavid Chisnall        __state_->__release_shared();
11717a984708SDavid Chisnall}
11727a984708SDavid Chisnall
117394e3ee44SDavid Chisnalltemplate <class _Rp>
117494e3ee44SDavid Chisnall_Rp
117594e3ee44SDavid Chisnallfuture<_Rp>::get()
11767a984708SDavid Chisnall{
11777a984708SDavid Chisnall    unique_ptr<__shared_count, __release_shared_count> __(__state_);
117894e3ee44SDavid Chisnall    __assoc_state<_Rp>* __s = __state_;
11797a984708SDavid Chisnall    __state_ = nullptr;
11807a984708SDavid Chisnall    return __s->move();
11817a984708SDavid Chisnall}
11827a984708SDavid Chisnall
118394e3ee44SDavid Chisnalltemplate <class _Rp>
11840f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
11857a984708SDavid Chisnall{
118694e3ee44SDavid Chisnall    __assoc_state<_Rp&>* __state_;
11877a984708SDavid Chisnall
118894e3ee44SDavid Chisnall    explicit future(__assoc_state<_Rp&>* __state);
11897a984708SDavid Chisnall
11907a984708SDavid Chisnall    template <class> friend class promise;
11917a984708SDavid Chisnall    template <class> friend class shared_future;
11927a984708SDavid Chisnall
11937a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
119494e3ee44SDavid Chisnall    template <class _R1, class _Fp>
119594e3ee44SDavid Chisnall        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
119694e3ee44SDavid Chisnall    template <class _R1, class _Fp>
119794e3ee44SDavid Chisnall        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
11987a984708SDavid Chisnall#else
119994e3ee44SDavid Chisnall    template <class _R1, class _Fp>
120094e3ee44SDavid Chisnall        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
120194e3ee44SDavid Chisnall    template <class _R1, class _Fp>
120294e3ee44SDavid Chisnall        friend future<_R1> __make_async_assoc_state(_Fp __f);
12037a984708SDavid Chisnall#endif
12047a984708SDavid Chisnall
12057a984708SDavid Chisnallpublic:
12067a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1207936e9439SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
12087a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
12097a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1210936e9439SDimitry Andric    future(future&& __rhs) _NOEXCEPT
12117a984708SDavid Chisnall        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
12127a984708SDavid Chisnall    future(const future&) = delete;
12137a984708SDavid Chisnall    future& operator=(const future&) = delete;
12147a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1215936e9439SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
12167a984708SDavid Chisnall        {
12177a984708SDavid Chisnall            future(std::move(__rhs)).swap(*this);
12187a984708SDavid Chisnall            return *this;
12197a984708SDavid Chisnall        }
12207a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
12217a984708SDavid Chisnallprivate:
12227a984708SDavid Chisnall    future(const future&);
12237a984708SDavid Chisnall    future& operator=(const future&);
12247a984708SDavid Chisnallpublic:
12257a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
12267a984708SDavid Chisnall    ~future();
12279729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1228540d2a8bSDimitry Andric    shared_future<_Rp&> share() _NOEXCEPT;
12297a984708SDavid Chisnall
12307a984708SDavid Chisnall    // retrieving the value
123194e3ee44SDavid Chisnall    _Rp& get();
12327a984708SDavid Chisnall
12337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1234936e9439SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
12357a984708SDavid Chisnall
12367a984708SDavid Chisnall    // functions to check state
12377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1238936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
12397a984708SDavid Chisnall
12407a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
12417a984708SDavid Chisnall    void wait() const {__state_->wait();}
12427a984708SDavid Chisnall    template <class _Rep, class _Period>
12437a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
12447a984708SDavid Chisnall        future_status
12457a984708SDavid Chisnall        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
12467a984708SDavid Chisnall            {return __state_->wait_for(__rel_time);}
12477a984708SDavid Chisnall    template <class _Clock, class _Duration>
12487a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
12497a984708SDavid Chisnall        future_status
12507a984708SDavid Chisnall        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
12517a984708SDavid Chisnall            {return __state_->wait_until(__abs_time);}
12527a984708SDavid Chisnall};
12537a984708SDavid Chisnall
125494e3ee44SDavid Chisnalltemplate <class _Rp>
125594e3ee44SDavid Chisnallfuture<_Rp&>::future(__assoc_state<_Rp&>* __state)
12567a984708SDavid Chisnall    : __state_(__state)
12577a984708SDavid Chisnall{
1258*b5893f02SDimitry Andric    __state_->__attach_future();
12597a984708SDavid Chisnall}
12607a984708SDavid Chisnall
126194e3ee44SDavid Chisnalltemplate <class _Rp>
126294e3ee44SDavid Chisnallfuture<_Rp&>::~future()
12637a984708SDavid Chisnall{
12647a984708SDavid Chisnall    if (__state_)
12657a984708SDavid Chisnall        __state_->__release_shared();
12667a984708SDavid Chisnall}
12677a984708SDavid Chisnall
126894e3ee44SDavid Chisnalltemplate <class _Rp>
126994e3ee44SDavid Chisnall_Rp&
127094e3ee44SDavid Chisnallfuture<_Rp&>::get()
12717a984708SDavid Chisnall{
12727a984708SDavid Chisnall    unique_ptr<__shared_count, __release_shared_count> __(__state_);
127394e3ee44SDavid Chisnall    __assoc_state<_Rp&>* __s = __state_;
12747a984708SDavid Chisnall    __state_ = nullptr;
12757a984708SDavid Chisnall    return __s->copy();
12767a984708SDavid Chisnall}
12777a984708SDavid Chisnall
12787a984708SDavid Chisnalltemplate <>
12790f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
12807a984708SDavid Chisnall{
12817a984708SDavid Chisnall    __assoc_sub_state* __state_;
12827a984708SDavid Chisnall
12837a984708SDavid Chisnall    explicit future(__assoc_sub_state* __state);
12847a984708SDavid Chisnall
12857a984708SDavid Chisnall    template <class> friend class promise;
12867a984708SDavid Chisnall    template <class> friend class shared_future;
12877a984708SDavid Chisnall
12887a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
128994e3ee44SDavid Chisnall    template <class _R1, class _Fp>
129094e3ee44SDavid Chisnall        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
129194e3ee44SDavid Chisnall    template <class _R1, class _Fp>
129294e3ee44SDavid Chisnall        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
12937a984708SDavid Chisnall#else
129494e3ee44SDavid Chisnall    template <class _R1, class _Fp>
129594e3ee44SDavid Chisnall        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
129694e3ee44SDavid Chisnall    template <class _R1, class _Fp>
129794e3ee44SDavid Chisnall        friend future<_R1> __make_async_assoc_state(_Fp __f);
12987a984708SDavid Chisnall#endif
12997a984708SDavid Chisnall
13007a984708SDavid Chisnallpublic:
13017a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1302936e9439SDimitry Andric    future() _NOEXCEPT : __state_(nullptr) {}
13037a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
13047a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1305936e9439SDimitry Andric    future(future&& __rhs) _NOEXCEPT
13067a984708SDavid Chisnall        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
13077a984708SDavid Chisnall    future(const future&) = delete;
13087a984708SDavid Chisnall    future& operator=(const future&) = delete;
13097a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1310936e9439SDimitry Andric    future& operator=(future&& __rhs) _NOEXCEPT
13117a984708SDavid Chisnall        {
13127a984708SDavid Chisnall            future(std::move(__rhs)).swap(*this);
13137a984708SDavid Chisnall            return *this;
13147a984708SDavid Chisnall        }
13157a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13167a984708SDavid Chisnallprivate:
13177a984708SDavid Chisnall    future(const future&);
13187a984708SDavid Chisnall    future& operator=(const future&);
13197a984708SDavid Chisnallpublic:
13207a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13217a984708SDavid Chisnall    ~future();
13229729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1323540d2a8bSDimitry Andric    shared_future<void> share() _NOEXCEPT;
13247a984708SDavid Chisnall
13257a984708SDavid Chisnall    // retrieving the value
13267a984708SDavid Chisnall    void get();
13277a984708SDavid Chisnall
13287a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1329936e9439SDimitry Andric    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
13307a984708SDavid Chisnall
13317a984708SDavid Chisnall    // functions to check state
13327a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1333936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
13347a984708SDavid Chisnall
13357a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
13367a984708SDavid Chisnall    void wait() const {__state_->wait();}
13377a984708SDavid Chisnall    template <class _Rep, class _Period>
13387a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
13397a984708SDavid Chisnall        future_status
13407a984708SDavid Chisnall        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
13417a984708SDavid Chisnall            {return __state_->wait_for(__rel_time);}
13427a984708SDavid Chisnall    template <class _Clock, class _Duration>
13437a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
13447a984708SDavid Chisnall        future_status
13457a984708SDavid Chisnall        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
13467a984708SDavid Chisnall            {return __state_->wait_until(__abs_time);}
13477a984708SDavid Chisnall};
13487a984708SDavid Chisnall
134994e3ee44SDavid Chisnalltemplate <class _Rp>
13507a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13517a984708SDavid Chisnallvoid
1352936e9439SDimitry Andricswap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
13537a984708SDavid Chisnall{
13547a984708SDavid Chisnall    __x.swap(__y);
13557a984708SDavid Chisnall}
13567a984708SDavid Chisnall
13577a984708SDavid Chisnall// promise<R>
13587a984708SDavid Chisnall
13597a984708SDavid Chisnalltemplate <class _Callable> class packaged_task;
13607a984708SDavid Chisnall
136194e3ee44SDavid Chisnalltemplate <class _Rp>
13620f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
13637a984708SDavid Chisnall{
136494e3ee44SDavid Chisnall    __assoc_state<_Rp>* __state_;
13657a984708SDavid Chisnall
13667a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1367936e9439SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
13687a984708SDavid Chisnall
13697a984708SDavid Chisnall    template <class> friend class packaged_task;
13707a984708SDavid Chisnallpublic:
13717a984708SDavid Chisnall    promise();
13727a984708SDavid Chisnall    template <class _Alloc>
13737a984708SDavid Chisnall        promise(allocator_arg_t, const _Alloc& __a);
13747a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
13757a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1376936e9439SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
13777a984708SDavid Chisnall        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
13787a984708SDavid Chisnall    promise(const promise& __rhs) = delete;
13797a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13807a984708SDavid Chisnallprivate:
13817a984708SDavid Chisnall    promise(const promise& __rhs);
13827a984708SDavid Chisnallpublic:
13837a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13847a984708SDavid Chisnall    ~promise();
13857a984708SDavid Chisnall
13867a984708SDavid Chisnall    // assignment
13877a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
13887a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1389936e9439SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
13907a984708SDavid Chisnall        {
13917a984708SDavid Chisnall            promise(std::move(__rhs)).swap(*this);
13927a984708SDavid Chisnall            return *this;
13937a984708SDavid Chisnall        }
13947a984708SDavid Chisnall    promise& operator=(const promise& __rhs) = delete;
13957a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
13967a984708SDavid Chisnallprivate:
13977a984708SDavid Chisnall    promise& operator=(const promise& __rhs);
13987a984708SDavid Chisnallpublic:
13997a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
14007a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1401936e9439SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
14027a984708SDavid Chisnall
14037a984708SDavid Chisnall    // retrieving the result
140494e3ee44SDavid Chisnall    future<_Rp> get_future();
14057a984708SDavid Chisnall
14067a984708SDavid Chisnall    // setting the result
140794e3ee44SDavid Chisnall    void set_value(const _Rp& __r);
14087a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
140994e3ee44SDavid Chisnall    void set_value(_Rp&& __r);
14107a984708SDavid Chisnall#endif
14117a984708SDavid Chisnall    void set_exception(exception_ptr __p);
14127a984708SDavid Chisnall
14137a984708SDavid Chisnall    // setting the result with deferred notification
141494e3ee44SDavid Chisnall    void set_value_at_thread_exit(const _Rp& __r);
14157a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
141694e3ee44SDavid Chisnall    void set_value_at_thread_exit(_Rp&& __r);
14177a984708SDavid Chisnall#endif
14187a984708SDavid Chisnall    void set_exception_at_thread_exit(exception_ptr __p);
14197a984708SDavid Chisnall};
14207a984708SDavid Chisnall
142194e3ee44SDavid Chisnalltemplate <class _Rp>
142294e3ee44SDavid Chisnallpromise<_Rp>::promise()
142394e3ee44SDavid Chisnall    : __state_(new __assoc_state<_Rp>)
14247a984708SDavid Chisnall{
14257a984708SDavid Chisnall}
14267a984708SDavid Chisnall
142794e3ee44SDavid Chisnalltemplate <class _Rp>
14287a984708SDavid Chisnalltemplate <class _Alloc>
142994e3ee44SDavid Chisnallpromise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
14307a984708SDavid Chisnall{
1431d72607e9SDimitry Andric    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1432d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
14337a984708SDavid Chisnall    typedef __allocator_destructor<_A2> _D2;
14347a984708SDavid Chisnall    _A2 __a(__a0);
1435d72607e9SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1436d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1437d72607e9SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
14387a984708SDavid Chisnall}
14397a984708SDavid Chisnall
144094e3ee44SDavid Chisnalltemplate <class _Rp>
144194e3ee44SDavid Chisnallpromise<_Rp>::~promise()
14427a984708SDavid Chisnall{
14437a984708SDavid Chisnall    if (__state_)
14447a984708SDavid Chisnall    {
14457a984708SDavid Chisnall        if (!__state_->__has_value() && __state_->use_count() > 1)
14467a984708SDavid Chisnall            __state_->set_exception(make_exception_ptr(
14477a984708SDavid Chisnall                      future_error(make_error_code(future_errc::broken_promise))
14487a984708SDavid Chisnall                                                      ));
14497a984708SDavid Chisnall        __state_->__release_shared();
14507a984708SDavid Chisnall    }
14517a984708SDavid Chisnall}
14527a984708SDavid Chisnall
145394e3ee44SDavid Chisnalltemplate <class _Rp>
145494e3ee44SDavid Chisnallfuture<_Rp>
145594e3ee44SDavid Chisnallpromise<_Rp>::get_future()
14567a984708SDavid Chisnall{
14577a984708SDavid Chisnall    if (__state_ == nullptr)
14589729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
145994e3ee44SDavid Chisnall    return future<_Rp>(__state_);
14607a984708SDavid Chisnall}
14617a984708SDavid Chisnall
146294e3ee44SDavid Chisnalltemplate <class _Rp>
14637a984708SDavid Chisnallvoid
146494e3ee44SDavid Chisnallpromise<_Rp>::set_value(const _Rp& __r)
14657a984708SDavid Chisnall{
14667a984708SDavid Chisnall    if (__state_ == nullptr)
14679729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
14687a984708SDavid Chisnall    __state_->set_value(__r);
14697a984708SDavid Chisnall}
14707a984708SDavid Chisnall
14717a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
14727a984708SDavid Chisnall
147394e3ee44SDavid Chisnalltemplate <class _Rp>
14747a984708SDavid Chisnallvoid
147594e3ee44SDavid Chisnallpromise<_Rp>::set_value(_Rp&& __r)
14767a984708SDavid Chisnall{
14777a984708SDavid Chisnall    if (__state_ == nullptr)
14789729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
14797a984708SDavid Chisnall    __state_->set_value(_VSTD::move(__r));
14807a984708SDavid Chisnall}
14817a984708SDavid Chisnall
14827a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
14837a984708SDavid Chisnall
148494e3ee44SDavid Chisnalltemplate <class _Rp>
14857a984708SDavid Chisnallvoid
148694e3ee44SDavid Chisnallpromise<_Rp>::set_exception(exception_ptr __p)
14877a984708SDavid Chisnall{
14887c82a1ecSDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
14897a984708SDavid Chisnall    if (__state_ == nullptr)
14909729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
14917a984708SDavid Chisnall    __state_->set_exception(__p);
14927a984708SDavid Chisnall}
14937a984708SDavid Chisnall
149494e3ee44SDavid Chisnalltemplate <class _Rp>
14957a984708SDavid Chisnallvoid
149694e3ee44SDavid Chisnallpromise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
14977a984708SDavid Chisnall{
14987a984708SDavid Chisnall    if (__state_ == nullptr)
14999729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
15007a984708SDavid Chisnall    __state_->set_value_at_thread_exit(__r);
15017a984708SDavid Chisnall}
15027a984708SDavid Chisnall
15037a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
15047a984708SDavid Chisnall
150594e3ee44SDavid Chisnalltemplate <class _Rp>
15067a984708SDavid Chisnallvoid
150794e3ee44SDavid Chisnallpromise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
15087a984708SDavid Chisnall{
15097a984708SDavid Chisnall    if (__state_ == nullptr)
15109729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
15117a984708SDavid Chisnall    __state_->set_value_at_thread_exit(_VSTD::move(__r));
15127a984708SDavid Chisnall}
15137a984708SDavid Chisnall
15147a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15157a984708SDavid Chisnall
151694e3ee44SDavid Chisnalltemplate <class _Rp>
15177a984708SDavid Chisnallvoid
151894e3ee44SDavid Chisnallpromise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
15197a984708SDavid Chisnall{
15207c82a1ecSDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
15217a984708SDavid Chisnall    if (__state_ == nullptr)
15229729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
15237a984708SDavid Chisnall    __state_->set_exception_at_thread_exit(__p);
15247a984708SDavid Chisnall}
15257a984708SDavid Chisnall
15267a984708SDavid Chisnall// promise<R&>
15277a984708SDavid Chisnall
152894e3ee44SDavid Chisnalltemplate <class _Rp>
15290f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
15307a984708SDavid Chisnall{
153194e3ee44SDavid Chisnall    __assoc_state<_Rp&>* __state_;
15327a984708SDavid Chisnall
15337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1534936e9439SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
15357a984708SDavid Chisnall
15367a984708SDavid Chisnall    template <class> friend class packaged_task;
15377a984708SDavid Chisnall
15387a984708SDavid Chisnallpublic:
15397a984708SDavid Chisnall    promise();
15407a984708SDavid Chisnall    template <class _Allocator>
15417a984708SDavid Chisnall        promise(allocator_arg_t, const _Allocator& __a);
15427a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
15437a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1544936e9439SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
15457a984708SDavid Chisnall        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
15467a984708SDavid Chisnall    promise(const promise& __rhs) = delete;
15477a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15487a984708SDavid Chisnallprivate:
15497a984708SDavid Chisnall    promise(const promise& __rhs);
15507a984708SDavid Chisnallpublic:
15517a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15527a984708SDavid Chisnall    ~promise();
15537a984708SDavid Chisnall
15547a984708SDavid Chisnall    // assignment
15557a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
15567a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1557936e9439SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
15587a984708SDavid Chisnall        {
15597a984708SDavid Chisnall            promise(std::move(__rhs)).swap(*this);
15607a984708SDavid Chisnall            return *this;
15617a984708SDavid Chisnall        }
15627a984708SDavid Chisnall    promise& operator=(const promise& __rhs) = delete;
15637a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15647a984708SDavid Chisnallprivate:
15657a984708SDavid Chisnall    promise& operator=(const promise& __rhs);
15667a984708SDavid Chisnallpublic:
15677a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
15687a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1569936e9439SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
15707a984708SDavid Chisnall
15717a984708SDavid Chisnall    // retrieving the result
157294e3ee44SDavid Chisnall    future<_Rp&> get_future();
15737a984708SDavid Chisnall
15747a984708SDavid Chisnall    // setting the result
157594e3ee44SDavid Chisnall    void set_value(_Rp& __r);
15767a984708SDavid Chisnall    void set_exception(exception_ptr __p);
15777a984708SDavid Chisnall
15787a984708SDavid Chisnall    // setting the result with deferred notification
157994e3ee44SDavid Chisnall    void set_value_at_thread_exit(_Rp&);
15807a984708SDavid Chisnall    void set_exception_at_thread_exit(exception_ptr __p);
15817a984708SDavid Chisnall};
15827a984708SDavid Chisnall
158394e3ee44SDavid Chisnalltemplate <class _Rp>
158494e3ee44SDavid Chisnallpromise<_Rp&>::promise()
158594e3ee44SDavid Chisnall    : __state_(new __assoc_state<_Rp&>)
15867a984708SDavid Chisnall{
15877a984708SDavid Chisnall}
15887a984708SDavid Chisnall
158994e3ee44SDavid Chisnalltemplate <class _Rp>
15907a984708SDavid Chisnalltemplate <class _Alloc>
159194e3ee44SDavid Chisnallpromise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
15927a984708SDavid Chisnall{
1593d72607e9SDimitry Andric    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1594d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
15957a984708SDavid Chisnall    typedef __allocator_destructor<_A2> _D2;
15967a984708SDavid Chisnall    _A2 __a(__a0);
1597d72607e9SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1598d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1599d72607e9SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
16007a984708SDavid Chisnall}
16017a984708SDavid Chisnall
160294e3ee44SDavid Chisnalltemplate <class _Rp>
160394e3ee44SDavid Chisnallpromise<_Rp&>::~promise()
16047a984708SDavid Chisnall{
16057a984708SDavid Chisnall    if (__state_)
16067a984708SDavid Chisnall    {
16077a984708SDavid Chisnall        if (!__state_->__has_value() && __state_->use_count() > 1)
16087a984708SDavid Chisnall            __state_->set_exception(make_exception_ptr(
16097a984708SDavid Chisnall                      future_error(make_error_code(future_errc::broken_promise))
16107a984708SDavid Chisnall                                                      ));
16117a984708SDavid Chisnall        __state_->__release_shared();
16127a984708SDavid Chisnall    }
16137a984708SDavid Chisnall}
16147a984708SDavid Chisnall
161594e3ee44SDavid Chisnalltemplate <class _Rp>
161694e3ee44SDavid Chisnallfuture<_Rp&>
161794e3ee44SDavid Chisnallpromise<_Rp&>::get_future()
16187a984708SDavid Chisnall{
16197a984708SDavid Chisnall    if (__state_ == nullptr)
16209729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
162194e3ee44SDavid Chisnall    return future<_Rp&>(__state_);
16227a984708SDavid Chisnall}
16237a984708SDavid Chisnall
162494e3ee44SDavid Chisnalltemplate <class _Rp>
16257a984708SDavid Chisnallvoid
162694e3ee44SDavid Chisnallpromise<_Rp&>::set_value(_Rp& __r)
16277a984708SDavid Chisnall{
16287a984708SDavid Chisnall    if (__state_ == nullptr)
16299729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
16307a984708SDavid Chisnall    __state_->set_value(__r);
16317a984708SDavid Chisnall}
16327a984708SDavid Chisnall
163394e3ee44SDavid Chisnalltemplate <class _Rp>
16347a984708SDavid Chisnallvoid
163594e3ee44SDavid Chisnallpromise<_Rp&>::set_exception(exception_ptr __p)
16367a984708SDavid Chisnall{
16377c82a1ecSDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
16387a984708SDavid Chisnall    if (__state_ == nullptr)
16399729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
16407a984708SDavid Chisnall    __state_->set_exception(__p);
16417a984708SDavid Chisnall}
16427a984708SDavid Chisnall
164394e3ee44SDavid Chisnalltemplate <class _Rp>
16447a984708SDavid Chisnallvoid
164594e3ee44SDavid Chisnallpromise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
16467a984708SDavid Chisnall{
16477a984708SDavid Chisnall    if (__state_ == nullptr)
16489729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
16497a984708SDavid Chisnall    __state_->set_value_at_thread_exit(__r);
16507a984708SDavid Chisnall}
16517a984708SDavid Chisnall
165294e3ee44SDavid Chisnalltemplate <class _Rp>
16537a984708SDavid Chisnallvoid
165494e3ee44SDavid Chisnallpromise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
16557a984708SDavid Chisnall{
16567c82a1ecSDimitry Andric    _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
16577a984708SDavid Chisnall    if (__state_ == nullptr)
16589729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
16597a984708SDavid Chisnall    __state_->set_exception_at_thread_exit(__p);
16607a984708SDavid Chisnall}
16617a984708SDavid Chisnall
16627a984708SDavid Chisnall// promise<void>
16637a984708SDavid Chisnall
16647a984708SDavid Chisnalltemplate <>
16650f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
16667a984708SDavid Chisnall{
16677a984708SDavid Chisnall    __assoc_sub_state* __state_;
16687a984708SDavid Chisnall
16697a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1670936e9439SDimitry Andric    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
16717a984708SDavid Chisnall
16727a984708SDavid Chisnall    template <class> friend class packaged_task;
16737a984708SDavid Chisnall
16747a984708SDavid Chisnallpublic:
16757a984708SDavid Chisnall    promise();
16767a984708SDavid Chisnall    template <class _Allocator>
1677540d2a8bSDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
16787a984708SDavid Chisnall        promise(allocator_arg_t, const _Allocator& __a);
16797a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
16807a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1681936e9439SDimitry Andric    promise(promise&& __rhs) _NOEXCEPT
16827a984708SDavid Chisnall        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
16837a984708SDavid Chisnall    promise(const promise& __rhs) = delete;
16847a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
16857a984708SDavid Chisnallprivate:
16867a984708SDavid Chisnall    promise(const promise& __rhs);
16877a984708SDavid Chisnallpublic:
16887a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
16897a984708SDavid Chisnall    ~promise();
16907a984708SDavid Chisnall
16917a984708SDavid Chisnall    // assignment
16927a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
16937a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1694936e9439SDimitry Andric    promise& operator=(promise&& __rhs) _NOEXCEPT
16957a984708SDavid Chisnall        {
16967a984708SDavid Chisnall            promise(std::move(__rhs)).swap(*this);
16977a984708SDavid Chisnall            return *this;
16987a984708SDavid Chisnall        }
16997a984708SDavid Chisnall    promise& operator=(const promise& __rhs) = delete;
17007a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
17017a984708SDavid Chisnallprivate:
17027a984708SDavid Chisnall    promise& operator=(const promise& __rhs);
17037a984708SDavid Chisnallpublic:
17047a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
17057a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1706936e9439SDimitry Andric    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
17077a984708SDavid Chisnall
17087a984708SDavid Chisnall    // retrieving the result
17097a984708SDavid Chisnall    future<void> get_future();
17107a984708SDavid Chisnall
17117a984708SDavid Chisnall    // setting the result
17127a984708SDavid Chisnall    void set_value();
17137a984708SDavid Chisnall    void set_exception(exception_ptr __p);
17147a984708SDavid Chisnall
17157a984708SDavid Chisnall    // setting the result with deferred notification
17167a984708SDavid Chisnall    void set_value_at_thread_exit();
17177a984708SDavid Chisnall    void set_exception_at_thread_exit(exception_ptr __p);
17187a984708SDavid Chisnall};
17197a984708SDavid Chisnall
17207a984708SDavid Chisnalltemplate <class _Alloc>
17217a984708SDavid Chisnallpromise<void>::promise(allocator_arg_t, const _Alloc& __a0)
17227a984708SDavid Chisnall{
1723d72607e9SDimitry Andric    typedef __assoc_sub_state_alloc<_Alloc> _State;
1724d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
17257a984708SDavid Chisnall    typedef __allocator_destructor<_A2> _D2;
17267a984708SDavid Chisnall    _A2 __a(__a0);
1727d72607e9SDimitry Andric    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1728d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1729d72607e9SDimitry Andric    __state_ = _VSTD::addressof(*__hold.release());
17307a984708SDavid Chisnall}
17317a984708SDavid Chisnall
173294e3ee44SDavid Chisnalltemplate <class _Rp>
17337a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17347a984708SDavid Chisnallvoid
1735936e9439SDimitry Andricswap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
17367a984708SDavid Chisnall{
17377a984708SDavid Chisnall    __x.swap(__y);
17387a984708SDavid Chisnall}
17397a984708SDavid Chisnall
174094e3ee44SDavid Chisnalltemplate <class _Rp, class _Alloc>
1741aed8d94eSDimitry Andric    struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
17427a984708SDavid Chisnall        : public true_type {};
17437a984708SDavid Chisnall
17447a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
17457a984708SDavid Chisnall
17467a984708SDavid Chisnall// packaged_task
17477a984708SDavid Chisnall
17487a984708SDavid Chisnalltemplate<class _Fp> class __packaged_task_base;
17497a984708SDavid Chisnall
175094e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
17510f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
17527a984708SDavid Chisnall{
17537a984708SDavid Chisnall    __packaged_task_base(const __packaged_task_base&);
17547a984708SDavid Chisnall    __packaged_task_base& operator=(const __packaged_task_base&);
17557a984708SDavid Chisnallpublic:
17567a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
17577a984708SDavid Chisnall    __packaged_task_base() {}
17587a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
17597a984708SDavid Chisnall    virtual ~__packaged_task_base() {}
1760936e9439SDimitry Andric    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
17617a984708SDavid Chisnall    virtual void destroy() = 0;
17627a984708SDavid Chisnall    virtual void destroy_deallocate() = 0;
176394e3ee44SDavid Chisnall    virtual _Rp operator()(_ArgTypes&& ...) = 0;
17647a984708SDavid Chisnall};
17657a984708SDavid Chisnall
17667a984708SDavid Chisnalltemplate<class _FD, class _Alloc, class _FB> class __packaged_task_func;
17677a984708SDavid Chisnall
176894e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
17690f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
177094e3ee44SDavid Chisnall    : public  __packaged_task_base<_Rp(_ArgTypes...)>
17717a984708SDavid Chisnall{
177294e3ee44SDavid Chisnall    __compressed_pair<_Fp, _Alloc> __f_;
17737a984708SDavid Chisnallpublic:
17747a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
177594e3ee44SDavid Chisnall    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
17767a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
177794e3ee44SDavid Chisnall    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
17787a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
177994e3ee44SDavid Chisnall    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
17807a984708SDavid Chisnall        : __f_(__f, __a) {}
17817a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
178294e3ee44SDavid Chisnall    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
17837a984708SDavid Chisnall        : __f_(_VSTD::move(__f), __a) {}
1784936e9439SDimitry Andric    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
17857a984708SDavid Chisnall    virtual void destroy();
17867a984708SDavid Chisnall    virtual void destroy_deallocate();
178794e3ee44SDavid Chisnall    virtual _Rp operator()(_ArgTypes&& ... __args);
17887a984708SDavid Chisnall};
17897a984708SDavid Chisnall
179094e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
17917a984708SDavid Chisnallvoid
179294e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
1793936e9439SDimitry Andric                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
17947a984708SDavid Chisnall{
17957a984708SDavid Chisnall    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
17967a984708SDavid Chisnall}
17977a984708SDavid Chisnall
179894e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
17997a984708SDavid Chisnallvoid
180094e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
18017a984708SDavid Chisnall{
180294e3ee44SDavid Chisnall    __f_.~__compressed_pair<_Fp, _Alloc>();
18037a984708SDavid Chisnall}
18047a984708SDavid Chisnall
180594e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
18067a984708SDavid Chisnallvoid
180794e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
18087a984708SDavid Chisnall{
1809d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1810d72607e9SDimitry Andric    typedef allocator_traits<_Ap> _ATraits;
1811d72607e9SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
181294e3ee44SDavid Chisnall    _Ap __a(__f_.second());
181394e3ee44SDavid Chisnall    __f_.~__compressed_pair<_Fp, _Alloc>();
1814d72607e9SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
18157a984708SDavid Chisnall}
18167a984708SDavid Chisnall
181794e3ee44SDavid Chisnalltemplate<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
181894e3ee44SDavid Chisnall_Rp
181994e3ee44SDavid Chisnall__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
18207a984708SDavid Chisnall{
18217a984708SDavid Chisnall    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
18227a984708SDavid Chisnall}
18237a984708SDavid Chisnall
18247a984708SDavid Chisnalltemplate <class _Callable> class __packaged_task_function;
18257a984708SDavid Chisnall
182694e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
18270f5676f4SDimitry Andricclass _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
18287a984708SDavid Chisnall{
182994e3ee44SDavid Chisnall    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
1830cfdf2879SDavid Chisnall    typename aligned_storage<3*sizeof(void*)>::type __buf_;
18317a984708SDavid Chisnall    __base* __f_;
18327a984708SDavid Chisnall
18337a984708SDavid Chisnallpublic:
183494e3ee44SDavid Chisnall    typedef _Rp result_type;
18357a984708SDavid Chisnall
18367a984708SDavid Chisnall    // construct/copy/destroy:
18377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1838936e9439SDimitry Andric    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
183994e3ee44SDavid Chisnall    template<class _Fp>
184094e3ee44SDavid Chisnall      __packaged_task_function(_Fp&& __f);
184194e3ee44SDavid Chisnall    template<class _Fp, class _Alloc>
184294e3ee44SDavid Chisnall      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
18437a984708SDavid Chisnall
1844936e9439SDimitry Andric    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1845936e9439SDimitry Andric    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
18467a984708SDavid Chisnall
18477a984708SDavid Chisnall    __packaged_task_function(const __packaged_task_function&) =  delete;
18487a984708SDavid Chisnall    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
18497a984708SDavid Chisnall
18507a984708SDavid Chisnall    ~__packaged_task_function();
18517a984708SDavid Chisnall
1852936e9439SDimitry Andric    void swap(__packaged_task_function&) _NOEXCEPT;
18537a984708SDavid Chisnall
18549729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
185594e3ee44SDavid Chisnall    _Rp operator()(_ArgTypes...) const;
18567a984708SDavid Chisnall};
18577a984708SDavid Chisnall
185894e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
1859936e9439SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
18607a984708SDavid Chisnall{
18617a984708SDavid Chisnall    if (__f.__f_ == nullptr)
18627a984708SDavid Chisnall        __f_ = nullptr;
18637a984708SDavid Chisnall    else if (__f.__f_ == (__base*)&__f.__buf_)
18647a984708SDavid Chisnall    {
18657a984708SDavid Chisnall        __f_ = (__base*)&__buf_;
18667a984708SDavid Chisnall        __f.__f_->__move_to(__f_);
18677a984708SDavid Chisnall    }
18687a984708SDavid Chisnall    else
18697a984708SDavid Chisnall    {
18707a984708SDavid Chisnall        __f_ = __f.__f_;
18717a984708SDavid Chisnall        __f.__f_ = nullptr;
18727a984708SDavid Chisnall    }
18737a984708SDavid Chisnall}
18747a984708SDavid Chisnall
187594e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
187694e3ee44SDavid Chisnalltemplate <class _Fp>
187794e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
18787a984708SDavid Chisnall    : __f_(nullptr)
18797a984708SDavid Chisnall{
1880d72607e9SDimitry Andric    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
188194e3ee44SDavid Chisnall    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
18827a984708SDavid Chisnall    if (sizeof(_FF) <= sizeof(__buf_))
18837a984708SDavid Chisnall    {
18847a984708SDavid Chisnall        __f_ = (__base*)&__buf_;
188594e3ee44SDavid Chisnall        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
18867a984708SDavid Chisnall    }
18877a984708SDavid Chisnall    else
18887a984708SDavid Chisnall    {
188994e3ee44SDavid Chisnall        typedef allocator<_FF> _Ap;
189094e3ee44SDavid Chisnall        _Ap __a;
189194e3ee44SDavid Chisnall        typedef __allocator_destructor<_Ap> _Dp;
189294e3ee44SDavid Chisnall        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
189394e3ee44SDavid Chisnall        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
18947a984708SDavid Chisnall        __f_ = __hold.release();
18957a984708SDavid Chisnall    }
18967a984708SDavid Chisnall}
18977a984708SDavid Chisnall
189894e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
189994e3ee44SDavid Chisnalltemplate <class _Fp, class _Alloc>
190094e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
190194e3ee44SDavid Chisnall                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
19027a984708SDavid Chisnall    : __f_(nullptr)
19037a984708SDavid Chisnall{
1904d72607e9SDimitry Andric    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
190594e3ee44SDavid Chisnall    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
19067a984708SDavid Chisnall    if (sizeof(_FF) <= sizeof(__buf_))
19077a984708SDavid Chisnall    {
19087a984708SDavid Chisnall        __f_ = (__base*)&__buf_;
190994e3ee44SDavid Chisnall        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
19107a984708SDavid Chisnall    }
19117a984708SDavid Chisnall    else
19127a984708SDavid Chisnall    {
1913d72607e9SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
191494e3ee44SDavid Chisnall        _Ap __a(__a0);
191594e3ee44SDavid Chisnall        typedef __allocator_destructor<_Ap> _Dp;
191694e3ee44SDavid Chisnall        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1917d72607e9SDimitry Andric        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1918d72607e9SDimitry Andric            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1919d72607e9SDimitry Andric        __f_ = _VSTD::addressof(*__hold.release());
19207a984708SDavid Chisnall    }
19217a984708SDavid Chisnall}
19227a984708SDavid Chisnall
192394e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
192494e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>&
1925936e9439SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
19267a984708SDavid Chisnall{
19277a984708SDavid Chisnall    if (__f_ == (__base*)&__buf_)
19287a984708SDavid Chisnall        __f_->destroy();
19297a984708SDavid Chisnall    else if (__f_)
19307a984708SDavid Chisnall        __f_->destroy_deallocate();
19317a984708SDavid Chisnall    __f_ = nullptr;
19327a984708SDavid Chisnall    if (__f.__f_ == nullptr)
19337a984708SDavid Chisnall        __f_ = nullptr;
19347a984708SDavid Chisnall    else if (__f.__f_ == (__base*)&__f.__buf_)
19357a984708SDavid Chisnall    {
19367a984708SDavid Chisnall        __f_ = (__base*)&__buf_;
19377a984708SDavid Chisnall        __f.__f_->__move_to(__f_);
19387a984708SDavid Chisnall    }
19397a984708SDavid Chisnall    else
19407a984708SDavid Chisnall    {
19417a984708SDavid Chisnall        __f_ = __f.__f_;
19427a984708SDavid Chisnall        __f.__f_ = nullptr;
19437a984708SDavid Chisnall    }
1944936e9439SDimitry Andric    return *this;
19457a984708SDavid Chisnall}
19467a984708SDavid Chisnall
194794e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
194894e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
19497a984708SDavid Chisnall{
19507a984708SDavid Chisnall    if (__f_ == (__base*)&__buf_)
19517a984708SDavid Chisnall        __f_->destroy();
19527a984708SDavid Chisnall    else if (__f_)
19537a984708SDavid Chisnall        __f_->destroy_deallocate();
19547a984708SDavid Chisnall}
19557a984708SDavid Chisnall
195694e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
19577a984708SDavid Chisnallvoid
1958936e9439SDimitry Andric__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
19597a984708SDavid Chisnall{
19607a984708SDavid Chisnall    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
19617a984708SDavid Chisnall    {
19627a984708SDavid Chisnall        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
19637a984708SDavid Chisnall        __base* __t = (__base*)&__tempbuf;
19647a984708SDavid Chisnall        __f_->__move_to(__t);
19657a984708SDavid Chisnall        __f_->destroy();
19667a984708SDavid Chisnall        __f_ = nullptr;
19677a984708SDavid Chisnall        __f.__f_->__move_to((__base*)&__buf_);
19687a984708SDavid Chisnall        __f.__f_->destroy();
19697a984708SDavid Chisnall        __f.__f_ = nullptr;
19707a984708SDavid Chisnall        __f_ = (__base*)&__buf_;
19717a984708SDavid Chisnall        __t->__move_to((__base*)&__f.__buf_);
19727a984708SDavid Chisnall        __t->destroy();
19737a984708SDavid Chisnall        __f.__f_ = (__base*)&__f.__buf_;
19747a984708SDavid Chisnall    }
19757a984708SDavid Chisnall    else if (__f_ == (__base*)&__buf_)
19767a984708SDavid Chisnall    {
19777a984708SDavid Chisnall        __f_->__move_to((__base*)&__f.__buf_);
19787a984708SDavid Chisnall        __f_->destroy();
19797a984708SDavid Chisnall        __f_ = __f.__f_;
19807a984708SDavid Chisnall        __f.__f_ = (__base*)&__f.__buf_;
19817a984708SDavid Chisnall    }
19827a984708SDavid Chisnall    else if (__f.__f_ == (__base*)&__f.__buf_)
19837a984708SDavid Chisnall    {
19847a984708SDavid Chisnall        __f.__f_->__move_to((__base*)&__buf_);
19857a984708SDavid Chisnall        __f.__f_->destroy();
19867a984708SDavid Chisnall        __f.__f_ = __f_;
19877a984708SDavid Chisnall        __f_ = (__base*)&__buf_;
19887a984708SDavid Chisnall    }
19897a984708SDavid Chisnall    else
19907a984708SDavid Chisnall        _VSTD::swap(__f_, __f.__f_);
19917a984708SDavid Chisnall}
19927a984708SDavid Chisnall
199394e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
19949729cf09SDimitry Andricinline
199594e3ee44SDavid Chisnall_Rp
199694e3ee44SDavid Chisnall__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
19977a984708SDavid Chisnall{
19987a984708SDavid Chisnall    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
19997a984708SDavid Chisnall}
20007a984708SDavid Chisnall
200194e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
20020f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
20037a984708SDavid Chisnall{
20047a984708SDavid Chisnallpublic:
20057c82a1ecSDimitry Andric    typedef _Rp result_type; // extension
20067a984708SDavid Chisnall
20077a984708SDavid Chisnallprivate:
20087a984708SDavid Chisnall    __packaged_task_function<result_type(_ArgTypes...)> __f_;
20097a984708SDavid Chisnall    promise<result_type>                                __p_;
20107a984708SDavid Chisnall
20117a984708SDavid Chisnallpublic:
20127a984708SDavid Chisnall    // construction and destruction
20137a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2014936e9439SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
20154f7ab58eSDimitry Andric    template <class _Fp,
20164f7ab58eSDimitry Andric              class = typename enable_if
20174f7ab58eSDimitry Andric              <
20184f7ab58eSDimitry Andric                  !is_same<
20194ba319b5SDimitry Andric                      typename __uncvref<_Fp>::type,
20204f7ab58eSDimitry Andric                      packaged_task
20214f7ab58eSDimitry Andric                      >::value
20224f7ab58eSDimitry Andric                  >::type
20234f7ab58eSDimitry Andric             >
20247a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
202594e3ee44SDavid Chisnall        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
20264f7ab58eSDimitry Andric    template <class _Fp, class _Allocator,
20274f7ab58eSDimitry Andric              class = typename enable_if
20284f7ab58eSDimitry Andric              <
20294f7ab58eSDimitry Andric                  !is_same<
20304ba319b5SDimitry Andric                      typename __uncvref<_Fp>::type,
20314f7ab58eSDimitry Andric                      packaged_task
20324f7ab58eSDimitry Andric                      >::value
20334f7ab58eSDimitry Andric                  >::type
20344f7ab58eSDimitry Andric              >
20357a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2036854fa44bSDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
203794e3ee44SDavid Chisnall             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
20387a984708SDavid Chisnall               __p_(allocator_arg, __a) {}
20397a984708SDavid Chisnall    // ~packaged_task() = default;
20407a984708SDavid Chisnall
20417a984708SDavid Chisnall    // no copy
2042936e9439SDimitry Andric    packaged_task(const packaged_task&) = delete;
2043936e9439SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
20447a984708SDavid Chisnall
20457a984708SDavid Chisnall    // move support
20467a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2047936e9439SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
20487a984708SDavid Chisnall        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
20497a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2050936e9439SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
20517a984708SDavid Chisnall    {
20527a984708SDavid Chisnall        __f_ = _VSTD::move(__other.__f_);
20537a984708SDavid Chisnall        __p_ = _VSTD::move(__other.__p_);
20547a984708SDavid Chisnall        return *this;
20557a984708SDavid Chisnall    }
20567a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2057936e9439SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
20587a984708SDavid Chisnall    {
20597a984708SDavid Chisnall        __f_.swap(__other.__f_);
20607a984708SDavid Chisnall        __p_.swap(__other.__p_);
20617a984708SDavid Chisnall    }
20627a984708SDavid Chisnall
20637a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2064936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
20657a984708SDavid Chisnall
20667a984708SDavid Chisnall    // result retrieval
20677a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
20687a984708SDavid Chisnall    future<result_type> get_future() {return __p_.get_future();}
20697a984708SDavid Chisnall
20707a984708SDavid Chisnall    // execution
20717a984708SDavid Chisnall    void operator()(_ArgTypes... __args);
20727a984708SDavid Chisnall    void make_ready_at_thread_exit(_ArgTypes... __args);
20737a984708SDavid Chisnall
20747a984708SDavid Chisnall    void reset();
20757a984708SDavid Chisnall};
20767a984708SDavid Chisnall
207794e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
20787a984708SDavid Chisnallvoid
207994e3ee44SDavid Chisnallpackaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
20807a984708SDavid Chisnall{
20817a984708SDavid Chisnall    if (__p_.__state_ == nullptr)
20829729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
20837a984708SDavid Chisnall    if (__p_.__state_->__has_value())
20849729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
20859729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
20867a984708SDavid Chisnall    try
20877a984708SDavid Chisnall    {
20887a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
20897a984708SDavid Chisnall        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
20907a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
20917a984708SDavid Chisnall    }
20927a984708SDavid Chisnall    catch (...)
20937a984708SDavid Chisnall    {
20947a984708SDavid Chisnall        __p_.set_exception(current_exception());
20957a984708SDavid Chisnall    }
20967a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
20977a984708SDavid Chisnall}
20987a984708SDavid Chisnall
209994e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
21007a984708SDavid Chisnallvoid
210194e3ee44SDavid Chisnallpackaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
21027a984708SDavid Chisnall{
21037a984708SDavid Chisnall    if (__p_.__state_ == nullptr)
21049729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
21057a984708SDavid Chisnall    if (__p_.__state_->__has_value())
21069729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
21079729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
21087a984708SDavid Chisnall    try
21097a984708SDavid Chisnall    {
21107a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
21117a984708SDavid Chisnall        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
21127a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
21137a984708SDavid Chisnall    }
21147a984708SDavid Chisnall    catch (...)
21157a984708SDavid Chisnall    {
21167a984708SDavid Chisnall        __p_.set_exception_at_thread_exit(current_exception());
21177a984708SDavid Chisnall    }
21187a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
21197a984708SDavid Chisnall}
21207a984708SDavid Chisnall
212194e3ee44SDavid Chisnalltemplate<class _Rp, class ..._ArgTypes>
21227a984708SDavid Chisnallvoid
212394e3ee44SDavid Chisnallpackaged_task<_Rp(_ArgTypes...)>::reset()
21247a984708SDavid Chisnall{
21257a984708SDavid Chisnall    if (!valid())
21269729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
21277a984708SDavid Chisnall    __p_ = promise<result_type>();
21287a984708SDavid Chisnall}
21297a984708SDavid Chisnall
21307a984708SDavid Chisnalltemplate<class ..._ArgTypes>
21310f5676f4SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
21327a984708SDavid Chisnall{
21337a984708SDavid Chisnallpublic:
21347c82a1ecSDimitry Andric    typedef void result_type; // extension
21357a984708SDavid Chisnall
21367a984708SDavid Chisnallprivate:
21377a984708SDavid Chisnall    __packaged_task_function<result_type(_ArgTypes...)> __f_;
21387a984708SDavid Chisnall    promise<result_type>                                __p_;
21397a984708SDavid Chisnall
21407a984708SDavid Chisnallpublic:
21417a984708SDavid Chisnall    // construction and destruction
21427a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2143936e9439SDimitry Andric    packaged_task() _NOEXCEPT : __p_(nullptr) {}
21444f7ab58eSDimitry Andric    template <class _Fp,
21454f7ab58eSDimitry Andric              class = typename enable_if
21464f7ab58eSDimitry Andric              <
21474f7ab58eSDimitry Andric                  !is_same<
21484ba319b5SDimitry Andric                      typename __uncvref<_Fp>::type,
21494f7ab58eSDimitry Andric                      packaged_task
21504f7ab58eSDimitry Andric                      >::value
21514f7ab58eSDimitry Andric                  >::type
21524f7ab58eSDimitry Andric              >
21537a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
215494e3ee44SDavid Chisnall        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
21554f7ab58eSDimitry Andric    template <class _Fp, class _Allocator,
21564f7ab58eSDimitry Andric              class = typename enable_if
21574f7ab58eSDimitry Andric              <
21584f7ab58eSDimitry Andric                  !is_same<
21594ba319b5SDimitry Andric                      typename __uncvref<_Fp>::type,
21604f7ab58eSDimitry Andric                      packaged_task
21614f7ab58eSDimitry Andric                      >::value
21624f7ab58eSDimitry Andric                  >::type
21634f7ab58eSDimitry Andric              >
21647a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
2165854fa44bSDimitry Andric        packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
216694e3ee44SDavid Chisnall             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
21677a984708SDavid Chisnall               __p_(allocator_arg, __a) {}
21687a984708SDavid Chisnall    // ~packaged_task() = default;
21697a984708SDavid Chisnall
21707a984708SDavid Chisnall    // no copy
2171936e9439SDimitry Andric    packaged_task(const packaged_task&) = delete;
2172936e9439SDimitry Andric    packaged_task& operator=(const packaged_task&) = delete;
21737a984708SDavid Chisnall
21747a984708SDavid Chisnall    // move support
21757a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2176936e9439SDimitry Andric    packaged_task(packaged_task&& __other) _NOEXCEPT
21777a984708SDavid Chisnall        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
21787a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2179936e9439SDimitry Andric    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
21807a984708SDavid Chisnall    {
21817a984708SDavid Chisnall        __f_ = _VSTD::move(__other.__f_);
21827a984708SDavid Chisnall        __p_ = _VSTD::move(__other.__p_);
21837a984708SDavid Chisnall        return *this;
21847a984708SDavid Chisnall    }
21857a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2186936e9439SDimitry Andric    void swap(packaged_task& __other) _NOEXCEPT
21877a984708SDavid Chisnall    {
21887a984708SDavid Chisnall        __f_.swap(__other.__f_);
21897a984708SDavid Chisnall        __p_.swap(__other.__p_);
21907a984708SDavid Chisnall    }
21917a984708SDavid Chisnall
21927a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2193936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
21947a984708SDavid Chisnall
21957a984708SDavid Chisnall    // result retrieval
21967a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
21977a984708SDavid Chisnall    future<result_type> get_future() {return __p_.get_future();}
21987a984708SDavid Chisnall
21997a984708SDavid Chisnall    // execution
22007a984708SDavid Chisnall    void operator()(_ArgTypes... __args);
22017a984708SDavid Chisnall    void make_ready_at_thread_exit(_ArgTypes... __args);
22027a984708SDavid Chisnall
22037a984708SDavid Chisnall    void reset();
22047a984708SDavid Chisnall};
22057a984708SDavid Chisnall
22067a984708SDavid Chisnalltemplate<class ..._ArgTypes>
22077a984708SDavid Chisnallvoid
22087a984708SDavid Chisnallpackaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
22097a984708SDavid Chisnall{
22107a984708SDavid Chisnall    if (__p_.__state_ == nullptr)
22119729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
22127a984708SDavid Chisnall    if (__p_.__state_->__has_value())
22139729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
22149729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22157a984708SDavid Chisnall    try
22167a984708SDavid Chisnall    {
22177a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
22187a984708SDavid Chisnall        __f_(_VSTD::forward<_ArgTypes>(__args)...);
22197a984708SDavid Chisnall        __p_.set_value();
22207a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
22217a984708SDavid Chisnall    }
22227a984708SDavid Chisnall    catch (...)
22237a984708SDavid Chisnall    {
22247a984708SDavid Chisnall        __p_.set_exception(current_exception());
22257a984708SDavid Chisnall    }
22267a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
22277a984708SDavid Chisnall}
22287a984708SDavid Chisnall
22297a984708SDavid Chisnalltemplate<class ..._ArgTypes>
22307a984708SDavid Chisnallvoid
22317a984708SDavid Chisnallpackaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
22327a984708SDavid Chisnall{
22337a984708SDavid Chisnall    if (__p_.__state_ == nullptr)
22349729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
22357a984708SDavid Chisnall    if (__p_.__state_->__has_value())
22369729cf09SDimitry Andric        __throw_future_error(future_errc::promise_already_satisfied);
22379729cf09SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22387a984708SDavid Chisnall    try
22397a984708SDavid Chisnall    {
22407a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
22417a984708SDavid Chisnall        __f_(_VSTD::forward<_ArgTypes>(__args)...);
22427a984708SDavid Chisnall        __p_.set_value_at_thread_exit();
22437a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
22447a984708SDavid Chisnall    }
22457a984708SDavid Chisnall    catch (...)
22467a984708SDavid Chisnall    {
22477a984708SDavid Chisnall        __p_.set_exception_at_thread_exit(current_exception());
22487a984708SDavid Chisnall    }
22497a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
22507a984708SDavid Chisnall}
22517a984708SDavid Chisnall
22527a984708SDavid Chisnalltemplate<class ..._ArgTypes>
22537a984708SDavid Chisnallvoid
22547a984708SDavid Chisnallpackaged_task<void(_ArgTypes...)>::reset()
22557a984708SDavid Chisnall{
22567a984708SDavid Chisnall    if (!valid())
22579729cf09SDimitry Andric        __throw_future_error(future_errc::no_state);
22587a984708SDavid Chisnall    __p_ = promise<result_type>();
22597a984708SDavid Chisnall}
22607a984708SDavid Chisnall
22617a984708SDavid Chisnalltemplate <class _Callable>
22627a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
22637a984708SDavid Chisnallvoid
2264936e9439SDimitry Andricswap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
22657a984708SDavid Chisnall{
22667a984708SDavid Chisnall    __x.swap(__y);
22677a984708SDavid Chisnall}
22687a984708SDavid Chisnall
22697a984708SDavid Chisnalltemplate <class _Callable, class _Alloc>
2270aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
22717a984708SDavid Chisnall    : public true_type {};
22727a984708SDavid Chisnall
227394e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
227494e3ee44SDavid Chisnallfuture<_Rp>
22757a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
227694e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp&& __f)
22777a984708SDavid Chisnall#else
227894e3ee44SDavid Chisnall__make_deferred_assoc_state(_Fp __f)
22797a984708SDavid Chisnall#endif
22807a984708SDavid Chisnall{
228194e3ee44SDavid Chisnall    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
228294e3ee44SDavid Chisnall        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
228394e3ee44SDavid Chisnall    return future<_Rp>(__h.get());
22847a984708SDavid Chisnall}
22857a984708SDavid Chisnall
228694e3ee44SDavid Chisnalltemplate <class _Rp, class _Fp>
228794e3ee44SDavid Chisnallfuture<_Rp>
22887a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
228994e3ee44SDavid Chisnall__make_async_assoc_state(_Fp&& __f)
22907a984708SDavid Chisnall#else
229194e3ee44SDavid Chisnall__make_async_assoc_state(_Fp __f)
22927a984708SDavid Chisnall#endif
22937a984708SDavid Chisnall{
229494e3ee44SDavid Chisnall    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
229594e3ee44SDavid Chisnall        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
229694e3ee44SDavid Chisnall    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
229794e3ee44SDavid Chisnall    return future<_Rp>(__h.get());
22987a984708SDavid Chisnall}
22997a984708SDavid Chisnall
230094e3ee44SDavid Chisnalltemplate <class _Fp, class... _Args>
23017a984708SDavid Chisnallclass __async_func
23027a984708SDavid Chisnall{
230394e3ee44SDavid Chisnall    tuple<_Fp, _Args...> __f_;
23047a984708SDavid Chisnall
23057a984708SDavid Chisnallpublic:
230694e3ee44SDavid Chisnall    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
23077a984708SDavid Chisnall
23087a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
230994e3ee44SDavid Chisnall    explicit __async_func(_Fp&& __f, _Args&&... __args)
23107a984708SDavid Chisnall        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
23117a984708SDavid Chisnall
23127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
23137a984708SDavid Chisnall    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
23147a984708SDavid Chisnall
231594e3ee44SDavid Chisnall    _Rp operator()()
23167a984708SDavid Chisnall    {
23177a984708SDavid Chisnall        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
23187a984708SDavid Chisnall        return __execute(_Index());
23197a984708SDavid Chisnall    }
23207a984708SDavid Chisnallprivate:
23217a984708SDavid Chisnall    template <size_t ..._Indices>
232294e3ee44SDavid Chisnall    _Rp
23237a984708SDavid Chisnall    __execute(__tuple_indices<_Indices...>)
23247a984708SDavid Chisnall    {
23257a984708SDavid Chisnall        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
23267a984708SDavid Chisnall    }
23277a984708SDavid Chisnall};
23287a984708SDavid Chisnall
23294f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
23304f7ab58eSDimitry Andric{ return (int(__policy) & int(__value)) != 0; }
23314f7ab58eSDimitry Andric
233294e3ee44SDavid Chisnalltemplate <class _Fp, class... _Args>
2333b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17
233494e3ee44SDavid Chisnallfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
233594e3ee44SDavid Chisnallasync(launch __policy, _Fp&& __f, _Args&&... __args)
23367a984708SDavid Chisnall{
233794e3ee44SDavid Chisnall    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
233894e3ee44SDavid Chisnall    typedef typename _BF::_Rp _Rp;
23394f7ab58eSDimitry Andric
23404f7ab58eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23414f7ab58eSDimitry Andric    try
23424f7ab58eSDimitry Andric    {
23434f7ab58eSDimitry Andric#endif
23444f7ab58eSDimitry Andric        if (__does_policy_contain(__policy, launch::async))
23454f7ab58eSDimitry Andric        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
23467a984708SDavid Chisnall                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
23474f7ab58eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23484f7ab58eSDimitry Andric    }
23494f7ab58eSDimitry Andric    catch ( ... ) { if (__policy == launch::async) throw ; }
23504f7ab58eSDimitry Andric#endif
23514f7ab58eSDimitry Andric
23524f7ab58eSDimitry Andric    if (__does_policy_contain(__policy, launch::deferred))
23534f7ab58eSDimitry Andric        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
23547a984708SDavid Chisnall                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
23554f7ab58eSDimitry Andric    return future<_Rp>{};
23567a984708SDavid Chisnall}
23577a984708SDavid Chisnall
235894e3ee44SDavid Chisnalltemplate <class _Fp, class... _Args>
2359b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
236094e3ee44SDavid Chisnallfuture<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
236194e3ee44SDavid Chisnallasync(_Fp&& __f, _Args&&... __args)
23627a984708SDavid Chisnall{
236394e3ee44SDavid Chisnall    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
23647a984708SDavid Chisnall                                    _VSTD::forward<_Args>(__args)...);
23657a984708SDavid Chisnall}
23667a984708SDavid Chisnall
23677a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
23687a984708SDavid Chisnall
23697a984708SDavid Chisnall// shared_future
23707a984708SDavid Chisnall
237194e3ee44SDavid Chisnalltemplate <class _Rp>
2372aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future
23737a984708SDavid Chisnall{
237494e3ee44SDavid Chisnall    __assoc_state<_Rp>* __state_;
23757a984708SDavid Chisnall
23767a984708SDavid Chisnallpublic:
23777a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2378936e9439SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
23797a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2380aed8d94eSDimitry Andric    shared_future(const shared_future& __rhs)  _NOEXCEPT : __state_(__rhs.__state_)
23817a984708SDavid Chisnall        {if (__state_) __state_->__add_shared();}
23827a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
23837a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2384936e9439SDimitry Andric    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
23857a984708SDavid Chisnall        {__f.__state_ = nullptr;}
23867a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2387936e9439SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
23887a984708SDavid Chisnall        {__rhs.__state_ = nullptr;}
23897a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
23907a984708SDavid Chisnall    ~shared_future();
2391aed8d94eSDimitry Andric    shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
23927a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
23937a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2394936e9439SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
23957a984708SDavid Chisnall        {
23967a984708SDavid Chisnall            shared_future(std::move(__rhs)).swap(*this);
23977a984708SDavid Chisnall            return *this;
23987a984708SDavid Chisnall        }
23997a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
24007a984708SDavid Chisnall
24017a984708SDavid Chisnall    // retrieving the value
24027a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
240394e3ee44SDavid Chisnall    const _Rp& get() const {return __state_->copy();}
24047a984708SDavid Chisnall
24057a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2406936e9439SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
24077a984708SDavid Chisnall
24087a984708SDavid Chisnall    // functions to check state
24097a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2410936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
24117a984708SDavid Chisnall
24127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
24137a984708SDavid Chisnall    void wait() const {__state_->wait();}
24147a984708SDavid Chisnall    template <class _Rep, class _Period>
24157a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
24167a984708SDavid Chisnall        future_status
24177a984708SDavid Chisnall        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
24187a984708SDavid Chisnall            {return __state_->wait_for(__rel_time);}
24197a984708SDavid Chisnall    template <class _Clock, class _Duration>
24207a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
24217a984708SDavid Chisnall        future_status
24227a984708SDavid Chisnall        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
24237a984708SDavid Chisnall            {return __state_->wait_until(__abs_time);}
24247a984708SDavid Chisnall};
24257a984708SDavid Chisnall
242694e3ee44SDavid Chisnalltemplate <class _Rp>
242794e3ee44SDavid Chisnallshared_future<_Rp>::~shared_future()
24287a984708SDavid Chisnall{
24297a984708SDavid Chisnall    if (__state_)
24307a984708SDavid Chisnall        __state_->__release_shared();
24317a984708SDavid Chisnall}
24327a984708SDavid Chisnall
243394e3ee44SDavid Chisnalltemplate <class _Rp>
243494e3ee44SDavid Chisnallshared_future<_Rp>&
2435aed8d94eSDimitry Andricshared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
24367a984708SDavid Chisnall{
24377a984708SDavid Chisnall    if (__rhs.__state_)
24387a984708SDavid Chisnall        __rhs.__state_->__add_shared();
24397a984708SDavid Chisnall    if (__state_)
24407a984708SDavid Chisnall        __state_->__release_shared();
24417a984708SDavid Chisnall    __state_ = __rhs.__state_;
24427a984708SDavid Chisnall    return *this;
24437a984708SDavid Chisnall}
24447a984708SDavid Chisnall
244594e3ee44SDavid Chisnalltemplate <class _Rp>
2446aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
24477a984708SDavid Chisnall{
244894e3ee44SDavid Chisnall    __assoc_state<_Rp&>* __state_;
24497a984708SDavid Chisnall
24507a984708SDavid Chisnallpublic:
24517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2452936e9439SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
24537a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
24547a984708SDavid Chisnall    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
24557a984708SDavid Chisnall        {if (__state_) __state_->__add_shared();}
24567a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
24577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2458936e9439SDimitry Andric    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
24597a984708SDavid Chisnall        {__f.__state_ = nullptr;}
24607a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2461936e9439SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
24627a984708SDavid Chisnall        {__rhs.__state_ = nullptr;}
24637a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
24647a984708SDavid Chisnall    ~shared_future();
24657a984708SDavid Chisnall    shared_future& operator=(const shared_future& __rhs);
24667a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
24677a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2468936e9439SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
24697a984708SDavid Chisnall        {
24707a984708SDavid Chisnall            shared_future(std::move(__rhs)).swap(*this);
24717a984708SDavid Chisnall            return *this;
24727a984708SDavid Chisnall        }
24737a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
24747a984708SDavid Chisnall
24757a984708SDavid Chisnall    // retrieving the value
24767a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
247794e3ee44SDavid Chisnall    _Rp& get() const {return __state_->copy();}
24787a984708SDavid Chisnall
24797a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2480936e9439SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
24817a984708SDavid Chisnall
24827a984708SDavid Chisnall    // functions to check state
24837a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2484936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
24857a984708SDavid Chisnall
24867a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
24877a984708SDavid Chisnall    void wait() const {__state_->wait();}
24887a984708SDavid Chisnall    template <class _Rep, class _Period>
24897a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
24907a984708SDavid Chisnall        future_status
24917a984708SDavid Chisnall        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
24927a984708SDavid Chisnall            {return __state_->wait_for(__rel_time);}
24937a984708SDavid Chisnall    template <class _Clock, class _Duration>
24947a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
24957a984708SDavid Chisnall        future_status
24967a984708SDavid Chisnall        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
24977a984708SDavid Chisnall            {return __state_->wait_until(__abs_time);}
24987a984708SDavid Chisnall};
24997a984708SDavid Chisnall
250094e3ee44SDavid Chisnalltemplate <class _Rp>
250194e3ee44SDavid Chisnallshared_future<_Rp&>::~shared_future()
25027a984708SDavid Chisnall{
25037a984708SDavid Chisnall    if (__state_)
25047a984708SDavid Chisnall        __state_->__release_shared();
25057a984708SDavid Chisnall}
25067a984708SDavid Chisnall
250794e3ee44SDavid Chisnalltemplate <class _Rp>
250894e3ee44SDavid Chisnallshared_future<_Rp&>&
250994e3ee44SDavid Chisnallshared_future<_Rp&>::operator=(const shared_future& __rhs)
25107a984708SDavid Chisnall{
25117a984708SDavid Chisnall    if (__rhs.__state_)
25127a984708SDavid Chisnall        __rhs.__state_->__add_shared();
25137a984708SDavid Chisnall    if (__state_)
25147a984708SDavid Chisnall        __state_->__release_shared();
25157a984708SDavid Chisnall    __state_ = __rhs.__state_;
25167a984708SDavid Chisnall    return *this;
25177a984708SDavid Chisnall}
25187a984708SDavid Chisnall
25197a984708SDavid Chisnalltemplate <>
25200f5676f4SDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
25217a984708SDavid Chisnall{
25227a984708SDavid Chisnall    __assoc_sub_state* __state_;
25237a984708SDavid Chisnall
25247a984708SDavid Chisnallpublic:
25257a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2526936e9439SDimitry Andric    shared_future() _NOEXCEPT : __state_(nullptr) {}
25277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
25287a984708SDavid Chisnall    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
25297a984708SDavid Chisnall        {if (__state_) __state_->__add_shared();}
25307a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
25317a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2532936e9439SDimitry Andric    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
25337a984708SDavid Chisnall        {__f.__state_ = nullptr;}
25347a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2535936e9439SDimitry Andric    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
25367a984708SDavid Chisnall        {__rhs.__state_ = nullptr;}
25377a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
25387a984708SDavid Chisnall    ~shared_future();
25397a984708SDavid Chisnall    shared_future& operator=(const shared_future& __rhs);
25407a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
25417a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2542936e9439SDimitry Andric    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
25437a984708SDavid Chisnall        {
25447a984708SDavid Chisnall            shared_future(std::move(__rhs)).swap(*this);
25457a984708SDavid Chisnall            return *this;
25467a984708SDavid Chisnall        }
25477a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
25487a984708SDavid Chisnall
25497a984708SDavid Chisnall    // retrieving the value
25507a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
25517a984708SDavid Chisnall    void get() const {__state_->copy();}
25527a984708SDavid Chisnall
25537a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2554936e9439SDimitry Andric    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
25557a984708SDavid Chisnall
25567a984708SDavid Chisnall    // functions to check state
25577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2558936e9439SDimitry Andric    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
25597a984708SDavid Chisnall
25607a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
25617a984708SDavid Chisnall    void wait() const {__state_->wait();}
25627a984708SDavid Chisnall    template <class _Rep, class _Period>
25637a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
25647a984708SDavid Chisnall        future_status
25657a984708SDavid Chisnall        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
25667a984708SDavid Chisnall            {return __state_->wait_for(__rel_time);}
25677a984708SDavid Chisnall    template <class _Clock, class _Duration>
25687a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
25697a984708SDavid Chisnall        future_status
25707a984708SDavid Chisnall        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
25717a984708SDavid Chisnall            {return __state_->wait_until(__abs_time);}
25727a984708SDavid Chisnall};
25737a984708SDavid Chisnall
257494e3ee44SDavid Chisnalltemplate <class _Rp>
25757a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
25767a984708SDavid Chisnallvoid
2577936e9439SDimitry Andricswap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
25787a984708SDavid Chisnall{
25797a984708SDavid Chisnall    __x.swap(__y);
25807a984708SDavid Chisnall}
25817a984708SDavid Chisnall
258294e3ee44SDavid Chisnalltemplate <class _Rp>
25839729cf09SDimitry Andricinline
258494e3ee44SDavid Chisnallshared_future<_Rp>
2585540d2a8bSDimitry Andricfuture<_Rp>::share() _NOEXCEPT
25867a984708SDavid Chisnall{
258794e3ee44SDavid Chisnall    return shared_future<_Rp>(_VSTD::move(*this));
25887a984708SDavid Chisnall}
25897a984708SDavid Chisnall
259094e3ee44SDavid Chisnalltemplate <class _Rp>
25919729cf09SDimitry Andricinline
259294e3ee44SDavid Chisnallshared_future<_Rp&>
2593540d2a8bSDimitry Andricfuture<_Rp&>::share() _NOEXCEPT
25947a984708SDavid Chisnall{
259594e3ee44SDavid Chisnall    return shared_future<_Rp&>(_VSTD::move(*this));
25967a984708SDavid Chisnall}
25977a984708SDavid Chisnall
25987a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
25997a984708SDavid Chisnall
26009729cf09SDimitry Andricinline
26017a984708SDavid Chisnallshared_future<void>
2602540d2a8bSDimitry Andricfuture<void>::share() _NOEXCEPT
26037a984708SDavid Chisnall{
26047a984708SDavid Chisnall    return shared_future<void>(_VSTD::move(*this));
26057a984708SDavid Chisnall}
26067a984708SDavid Chisnall
26077a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
26087a984708SDavid Chisnall
26097a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
26107a984708SDavid Chisnall
2611d72607e9SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS
2612d72607e9SDimitry Andric
26137a984708SDavid Chisnall#endif  // _LIBCPP_FUTURE
2614